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 24 matching lines...) Expand all Loading... | |
35 #include "content/public/browser/devtools_client_host.h" | 35 #include "content/public/browser/devtools_client_host.h" |
36 #include "content/public/browser/devtools_manager.h" | 36 #include "content/public/browser/devtools_manager.h" |
37 #include "content/public/browser/favicon_status.h" | 37 #include "content/public/browser/favicon_status.h" |
38 #include "content/public/browser/navigation_entry.h" | 38 #include "content/public/browser/navigation_entry.h" |
39 #include "content/public/browser/notification_service.h" | 39 #include "content/public/browser/notification_service.h" |
40 #include "content/public/browser/notification_source.h" | 40 #include "content/public/browser/notification_source.h" |
41 #include "content/public/browser/render_process_host.h" | 41 #include "content/public/browser/render_process_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/render_widget_host.h" | 43 #include "content/public/browser/render_widget_host.h" |
44 #include "content/public/browser/web_contents.h" | 44 #include "content/public/browser/web_contents.h" |
45 #include "content/public/browser/worker_service.h" | |
45 #include "content/public/common/content_client.h" | 46 #include "content/public/common/content_client.h" |
46 #include "content/public/common/url_constants.h" | 47 #include "content/public/common/url_constants.h" |
47 #include "extensions/common/error_utils.h" | 48 #include "extensions/common/error_utils.h" |
48 #include "grit/generated_resources.h" | 49 #include "grit/generated_resources.h" |
49 #include "ui/base/l10n/l10n_util.h" | 50 #include "ui/base/l10n/l10n_util.h" |
50 #include "webkit/glue/webkit_glue.h" | 51 #include "webkit/glue/webkit_glue.h" |
51 | 52 |
52 using content::DevToolsAgentHost; | 53 using content::DevToolsAgentHost; |
53 using content::DevToolsClientHost; | 54 using content::DevToolsClientHost; |
54 using content::DevToolsManager; | 55 using content::DevToolsManager; |
55 using content::RenderProcessHost; | 56 using content::RenderProcessHost; |
56 using content::RenderViewHost; | 57 using content::RenderViewHost; |
57 using content::RenderWidgetHost; | 58 using content::RenderWidgetHost; |
58 using content::WebContents; | 59 using content::WebContents; |
60 using content::WorkerService; | |
59 using extensions::ErrorUtils; | 61 using extensions::ErrorUtils; |
60 | 62 |
61 namespace keys = debugger_api_constants; | 63 namespace keys = debugger_api_constants; |
62 namespace Attach = extensions::api::debugger::Attach; | 64 namespace Attach = extensions::api::debugger::Attach; |
63 namespace Detach = extensions::api::debugger::Detach; | 65 namespace Detach = extensions::api::debugger::Detach; |
64 namespace OnDetach = extensions::api::debugger::OnDetach; | 66 namespace OnDetach = extensions::api::debugger::OnDetach; |
65 namespace OnEvent = extensions::api::debugger::OnEvent; | 67 namespace OnEvent = extensions::api::debugger::OnEvent; |
66 namespace SendCommand = extensions::api::debugger::SendCommand; | 68 namespace SendCommand = extensions::api::debugger::SendCommand; |
67 | 69 |
68 class ExtensionDevToolsClientHost; | 70 class ExtensionDevToolsClientHost; |
69 | 71 |
70 class ExtensionDevToolsInfoBarDelegate : public ConfirmInfoBarDelegate { | 72 class ExtensionDevToolsInfoBarDelegate : public ConfirmInfoBarDelegate { |
71 public: | 73 public: |
72 // Creates an extension dev tools delegate and adds it to |infobar_service|. | 74 // Creates an extension dev tools delegate and adds it to |infobar_service|. |
73 // Returns a pointer to the delegate if it was successfully added. | 75 // Returns a pointer to the delegate if it was successfully added. |
74 static ExtensionDevToolsInfoBarDelegate* Create( | 76 static ExtensionDevToolsInfoBarDelegate* Create( |
75 WebContents* web_contents, | 77 RenderViewHost* rvh, |
76 const std::string& client_name); | 78 const std::string& client_name); |
77 | 79 |
78 // Associates DevToolsClientHost with this infobar delegate. | 80 // Associates DevToolsClientHost with this infobar delegate. |
79 void AttachClientHost(ExtensionDevToolsClientHost* client_host); | 81 void AttachClientHost(ExtensionDevToolsClientHost* client_host); |
80 | 82 |
81 // Notifies infobar delegate that associated DevToolsClientHost will be | 83 // Notifies infobar delegate that associated DevToolsClientHost will be |
82 // destroyed. | 84 // destroyed. |
83 void DiscardClientHost(); | 85 void DiscardClientHost(); |
84 | 86 |
85 private: | 87 private: |
(...skipping 12 matching lines...) Expand all Loading... | |
98 | 100 |
99 std::string client_name_; | 101 std::string client_name_; |
100 ExtensionDevToolsClientHost* client_host_; | 102 ExtensionDevToolsClientHost* client_host_; |
101 DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsInfoBarDelegate); | 103 DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsInfoBarDelegate); |
102 }; | 104 }; |
103 | 105 |
104 class ExtensionDevToolsClientHost : public DevToolsClientHost, | 106 class ExtensionDevToolsClientHost : public DevToolsClientHost, |
105 public content::NotificationObserver { | 107 public content::NotificationObserver { |
106 public: | 108 public: |
107 ExtensionDevToolsClientHost( | 109 ExtensionDevToolsClientHost( |
108 WebContents* web_contents, | 110 Profile* profile, |
111 DevToolsAgentHost* agent_host, | |
109 const std::string& extension_id, | 112 const std::string& extension_id, |
110 const std::string& extension_name, | 113 const std::string& extension_name, |
111 const Debuggee& debuggee, | 114 const Debuggee& debuggee, |
112 ExtensionDevToolsInfoBarDelegate* infobar_delegate); | 115 ExtensionDevToolsInfoBarDelegate* infobar_delegate); |
113 | 116 |
114 virtual ~ExtensionDevToolsClientHost(); | 117 virtual ~ExtensionDevToolsClientHost(); |
115 | 118 |
116 bool MatchesContentsAndExtensionId(WebContents* web_contents, | 119 std::string extension_id() { return extension_id_; } |
Matt Perry
2013/04/04 19:11:00
return const ref
Vladislav Kaznacheev
2013/04/05 09:23:02
Done.
| |
117 const std::string& extension_id); | |
118 void Close(); | 120 void Close(); |
119 void SendMessageToBackend(DebuggerSendCommandFunction* function, | 121 void SendMessageToBackend(DebuggerSendCommandFunction* function, |
120 const std::string& method, | 122 const std::string& method, |
121 SendCommand::Params::CommandParams* command_params); | 123 SendCommand::Params::CommandParams* command_params); |
122 | 124 |
123 // Marks connection as to-be-terminated by the user. | 125 // Marks connection as to-be-terminated by the user. |
124 void MarkAsDismissed(); | 126 void MarkAsDismissed(); |
125 | 127 |
126 // DevToolsClientHost interface | 128 // DevToolsClientHost interface |
127 virtual void InspectedContentsClosing() OVERRIDE; | 129 virtual void InspectedContentsClosing() OVERRIDE; |
128 virtual void DispatchOnInspectorFrontend(const std::string& message) OVERRIDE; | 130 virtual void DispatchOnInspectorFrontend(const std::string& message) OVERRIDE; |
129 virtual void ReplacedWithAnotherClient() OVERRIDE; | 131 virtual void ReplacedWithAnotherClient() OVERRIDE; |
130 | 132 |
131 private: | 133 private: |
132 void SendDetachedEvent(); | 134 void SendDetachedEvent(); |
133 | 135 |
134 // content::NotificationObserver implementation. | 136 // content::NotificationObserver implementation. |
135 virtual void Observe(int type, | 137 virtual void Observe(int type, |
136 const content::NotificationSource& source, | 138 const content::NotificationSource& source, |
137 const content::NotificationDetails& details) OVERRIDE; | 139 const content::NotificationDetails& details) OVERRIDE; |
138 | 140 |
139 WebContents* web_contents_; | 141 Profile* profile_; |
142 scoped_refptr<DevToolsAgentHost> agent_host_; | |
140 std::string extension_id_; | 143 std::string extension_id_; |
141 Debuggee debuggee_; | 144 Debuggee debuggee_; |
142 content::NotificationRegistrar registrar_; | 145 content::NotificationRegistrar registrar_; |
143 int last_request_id_; | 146 int last_request_id_; |
144 typedef std::map<int, scoped_refptr<DebuggerSendCommandFunction> > | 147 typedef std::map<int, scoped_refptr<DebuggerSendCommandFunction> > |
145 PendingRequests; | 148 PendingRequests; |
146 PendingRequests pending_requests_; | 149 PendingRequests pending_requests_; |
147 ExtensionDevToolsInfoBarDelegate* infobar_delegate_; | 150 ExtensionDevToolsInfoBarDelegate* infobar_delegate_; |
148 OnDetach::Reason detach_reason_; | 151 OnDetach::Reason detach_reason_; |
149 | 152 |
(...skipping 12 matching lines...) Expand all Loading... | |
162 } | 165 } |
163 | 166 |
164 void Add(ExtensionDevToolsClientHost* client_host) { | 167 void Add(ExtensionDevToolsClientHost* client_host) { |
165 client_hosts_.insert(client_host); | 168 client_hosts_.insert(client_host); |
166 } | 169 } |
167 | 170 |
168 void Remove(ExtensionDevToolsClientHost* client_host) { | 171 void Remove(ExtensionDevToolsClientHost* client_host) { |
169 client_hosts_.erase(client_host); | 172 client_hosts_.erase(client_host); |
170 } | 173 } |
171 | 174 |
172 ExtensionDevToolsClientHost* Lookup(WebContents* contents) { | 175 ExtensionDevToolsClientHost* Lookup(DevToolsAgentHost* agent_host, |
173 for (std::set<DevToolsClientHost*>::iterator it = client_hosts_.begin(); | 176 const std::string& extension_id) { |
177 DevToolsManager* manager = DevToolsManager::GetInstance(); | |
178 for (ClientHostSet::iterator it = client_hosts_.begin(); | |
174 it != client_hosts_.end(); ++it) { | 179 it != client_hosts_.end(); ++it) { |
175 DevToolsAgentHost* agent_host = | 180 ExtensionDevToolsClientHost* client_host = *it; |
176 DevToolsManager::GetInstance()->GetDevToolsAgentHostFor(*it); | 181 if (manager->GetDevToolsAgentHostFor(client_host) == agent_host && |
177 if (!agent_host) | 182 client_host->extension_id() == extension_id) |
178 continue; | 183 return client_host; |
179 content::RenderViewHost* rvh = agent_host->GetRenderViewHost(); | |
180 if (rvh && WebContents::FromRenderViewHost(rvh) == contents) | |
181 return static_cast<ExtensionDevToolsClientHost*>(*it); | |
182 } | 184 } |
183 return NULL; | 185 return NULL; |
184 } | 186 } |
185 | 187 |
186 private: | 188 private: |
187 std::set<DevToolsClientHost*> client_hosts_; | 189 typedef std::set<ExtensionDevToolsClientHost*> ClientHostSet; |
190 ClientHostSet client_hosts_; | |
188 }; | 191 }; |
189 | 192 |
190 static extensions::ExtensionHost* GetExtensionBackgroundHost( | 193 static extensions::ExtensionHost* GetExtensionBackgroundHost( |
191 WebContents* web_contents) { | 194 WebContents* web_contents) { |
192 Profile* profile = | 195 Profile* profile = |
193 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 196 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
194 if (!profile) | 197 if (!profile) |
195 return NULL; | 198 return NULL; |
196 | 199 |
197 extensions::ExtensionHost* extension_host = | 200 extensions::ExtensionHost* extension_host = |
198 extensions::ExtensionSystem::Get(profile)->process_manager()-> | 201 extensions::ExtensionSystem::Get(profile)->process_manager()-> |
199 GetBackgroundHostForExtension(web_contents->GetURL().host()); | 202 GetBackgroundHostForExtension(web_contents->GetURL().host()); |
200 | 203 |
201 if (extension_host && extension_host->host_contents() == web_contents) | 204 if (extension_host && extension_host->host_contents() == web_contents) |
202 return extension_host; | 205 return extension_host; |
203 | 206 |
204 return NULL; | 207 return NULL; |
205 } | 208 } |
206 | 209 |
207 static const char kTargetIdField[] = "id"; | 210 static const char kTargetIdField[] = "id"; |
208 static const char kTargetTypeField[] = "type"; | 211 static const char kTargetTypeField[] = "type"; |
209 static const char kTargetTitleField[] = "title"; | 212 static const char kTargetTitleField[] = "title"; |
210 static const char kTargetAttachedField[] = "attached"; | 213 static const char kTargetAttachedField[] = "attached"; |
211 static const char kTargetUrlField[] = "url"; | 214 static const char kTargetUrlField[] = "url"; |
212 static const char kTargetFaviconUrlField[] = "faviconUrl"; | 215 static const char kTargetFaviconUrlField[] = "faviconUrl"; |
213 | 216 |
214 static const char kTargetTypePage[] = "page"; | 217 static const char kTargetTypePage[] = "page"; |
215 static const char kTargetTypeBackgroundPage[] = "background_page"; | 218 static const char kTargetTypeBackgroundPage[] = "background_page"; |
219 static const char kTargetTypeWorker[] = "worker"; | |
216 | 220 |
217 static base::Value* SerializePageInfo(RenderViewHost* rvh) { | 221 static base::Value* SerializePageInfo(RenderViewHost* rvh) { |
218 WebContents* web_contents = WebContents::FromRenderViewHost(rvh); | 222 WebContents* web_contents = WebContents::FromRenderViewHost(rvh); |
219 if (!web_contents) | 223 if (!web_contents) |
220 return NULL; | 224 return NULL; |
221 | 225 |
222 DevToolsAgentHost* agent_host = DevToolsAgentHost::GetOrCreateFor(rvh); | 226 DevToolsAgentHost* agent_host = DevToolsAgentHost::GetOrCreateFor(rvh); |
223 | 227 |
224 base::DictionaryValue* dictionary = new base::DictionaryValue(); | 228 base::DictionaryValue* dictionary = new base::DictionaryValue(); |
225 | 229 |
(...skipping 18 matching lines...) Expand all Loading... | |
244 content::NavigationEntry* entry = controller.GetActiveEntry(); | 248 content::NavigationEntry* entry = controller.GetActiveEntry(); |
245 if (entry != NULL && entry->GetURL().is_valid()) { | 249 if (entry != NULL && entry->GetURL().is_valid()) { |
246 dictionary->SetString(kTargetFaviconUrlField, | 250 dictionary->SetString(kTargetFaviconUrlField, |
247 entry->GetFavicon().url.spec()); | 251 entry->GetFavicon().url.spec()); |
248 } | 252 } |
249 } | 253 } |
250 | 254 |
251 return dictionary; | 255 return dictionary; |
252 } | 256 } |
253 | 257 |
258 static base::Value* SerializeWorkerInfo( | |
259 const WorkerService::WorkerInfo& worker) { | |
260 base::DictionaryValue* dictionary = new base::DictionaryValue; | |
261 | |
262 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetForWorker( | |
263 worker.process_id, worker.route_id)); | |
264 dictionary->SetString(kTargetIdField, agent->GetId()); | |
265 dictionary->SetString(kTargetTypeField, kTargetTypeWorker); | |
266 dictionary->SetString(kTargetTitleField, | |
267 UTF16ToUTF8(net::EscapeForHTML(worker.name))); | |
Matt Perry
2013/04/04 19:11:00
why does this need to be escaped? it's just used a
Vladislav Kaznacheev
2013/04/05 09:23:02
It does not really. This code was originally copie
| |
268 dictionary->SetString(kTargetUrlField, worker.url.spec()); | |
269 dictionary->SetBoolean(kTargetAttachedField, agent->IsAttached()); | |
270 | |
271 return dictionary; | |
272 } | |
273 | |
254 } // namespace | 274 } // namespace |
255 | 275 |
256 static void CopyDebuggee(Debuggee & dst, const Debuggee& src) { | 276 static void CopyDebuggee(Debuggee & dst, const Debuggee& src) { |
257 if (src.tab_id) | 277 if (src.tab_id) |
258 dst.tab_id.reset(new int(*src.tab_id)); | 278 dst.tab_id.reset(new int(*src.tab_id)); |
259 if (src.extension_id) | 279 if (src.extension_id) |
260 dst.extension_id.reset(new std::string(*src.extension_id)); | 280 dst.extension_id.reset(new std::string(*src.extension_id)); |
261 if (src.target_id) | 281 if (src.target_id) |
262 dst.target_id.reset(new std::string(*src.target_id)); | 282 dst.target_id.reset(new std::string(*src.target_id)); |
263 } | 283 } |
264 | 284 |
265 ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( | 285 ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( |
266 WebContents* web_contents, | 286 Profile* profile, |
287 DevToolsAgentHost* agent_host, | |
267 const std::string& extension_id, | 288 const std::string& extension_id, |
268 const std::string& extension_name, | 289 const std::string& extension_name, |
269 const Debuggee& debuggee, | 290 const Debuggee& debuggee, |
270 ExtensionDevToolsInfoBarDelegate* infobar_delegate) | 291 ExtensionDevToolsInfoBarDelegate* infobar_delegate) |
271 : web_contents_(web_contents), | 292 : profile_(profile), |
293 agent_host_(agent_host), | |
272 extension_id_(extension_id), | 294 extension_id_(extension_id), |
273 last_request_id_(0), | 295 last_request_id_(0), |
274 infobar_delegate_(infobar_delegate), | 296 infobar_delegate_(infobar_delegate), |
275 detach_reason_(OnDetach::REASON_TARGET_CLOSED) { | 297 detach_reason_(OnDetach::REASON_TARGET_CLOSED) { |
276 CopyDebuggee(debuggee_, debuggee); | 298 CopyDebuggee(debuggee_, debuggee); |
277 | 299 |
278 AttachedClientHosts::GetInstance()->Add(this); | 300 AttachedClientHosts::GetInstance()->Add(this); |
279 | 301 |
280 // Detach from debugger when extension unloads. | 302 // Detach from debugger when extension unloads. |
281 Profile* profile = | |
282 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); | |
283 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 303 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
284 content::Source<Profile>(profile)); | 304 content::Source<Profile>(profile_)); |
285 | 305 |
286 // Attach to debugger and tell it we are ready. | 306 // Attach to debugger and tell it we are ready. |
287 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor( | 307 DevToolsManager::GetInstance()-> |
288 web_contents_->GetRenderViewHost())); | 308 RegisterDevToolsClientHostFor(agent_host_, this); |
289 DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(agent, this); | |
290 | 309 |
291 if (infobar_delegate_) { | 310 if (infobar_delegate_) { |
292 infobar_delegate_->AttachClientHost(this); | 311 infobar_delegate_->AttachClientHost(this); |
293 registrar_.Add(this, | 312 registrar_.Add(this, |
294 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, | 313 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, |
295 content::Source<InfoBarService>(infobar_delegate_->owner())); | 314 content::Source<InfoBarService>(infobar_delegate_->owner())); |
296 } | 315 } |
297 } | 316 } |
298 | 317 |
299 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { | 318 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { |
300 // Ensure calling RemoveInfoBar() below won't result in Observe() trying to | 319 // Ensure calling RemoveInfoBar() below won't result in Observe() trying to |
301 // Close() us. | 320 // Close() us. |
302 registrar_.RemoveAll(); | 321 registrar_.RemoveAll(); |
303 | 322 |
304 if (infobar_delegate_) { | 323 if (infobar_delegate_) { |
305 infobar_delegate_->DiscardClientHost(); | 324 infobar_delegate_->DiscardClientHost(); |
306 if (infobar_delegate_->owner()) | 325 if (infobar_delegate_->owner()) |
307 infobar_delegate_->owner()->RemoveInfoBar(infobar_delegate_); | 326 infobar_delegate_->owner()->RemoveInfoBar(infobar_delegate_); |
308 } | 327 } |
309 AttachedClientHosts::GetInstance()->Remove(this); | 328 AttachedClientHosts::GetInstance()->Remove(this); |
310 } | 329 } |
311 | 330 |
312 bool ExtensionDevToolsClientHost::MatchesContentsAndExtensionId( | |
313 WebContents* web_contents, | |
314 const std::string& extension_id) { | |
315 return web_contents == web_contents_ && extension_id_ == extension_id; | |
316 } | |
317 | |
318 // DevToolsClientHost interface | 331 // DevToolsClientHost interface |
319 void ExtensionDevToolsClientHost::InspectedContentsClosing() { | 332 void ExtensionDevToolsClientHost::InspectedContentsClosing() { |
320 SendDetachedEvent(); | 333 SendDetachedEvent(); |
321 delete this; | 334 delete this; |
322 } | 335 } |
323 | 336 |
324 void ExtensionDevToolsClientHost::ReplacedWithAnotherClient() { | 337 void ExtensionDevToolsClientHost::ReplacedWithAnotherClient() { |
325 detach_reason_ = OnDetach::REASON_REPLACED_WITH_DEVTOOLS; | 338 detach_reason_ = OnDetach::REASON_REPLACED_WITH_DEVTOOLS; |
326 } | 339 } |
327 | 340 |
(...skipping 19 matching lines...) Expand all Loading... | |
347 std::string json_args; | 360 std::string json_args; |
348 base::JSONWriter::Write(&protocol_request, &json_args); | 361 base::JSONWriter::Write(&protocol_request, &json_args); |
349 DevToolsManager::GetInstance()->DispatchOnInspectorBackend(this, json_args); | 362 DevToolsManager::GetInstance()->DispatchOnInspectorBackend(this, json_args); |
350 } | 363 } |
351 | 364 |
352 void ExtensionDevToolsClientHost::MarkAsDismissed() { | 365 void ExtensionDevToolsClientHost::MarkAsDismissed() { |
353 detach_reason_ = OnDetach::REASON_CANCELED_BY_USER; | 366 detach_reason_ = OnDetach::REASON_CANCELED_BY_USER; |
354 } | 367 } |
355 | 368 |
356 void ExtensionDevToolsClientHost::SendDetachedEvent() { | 369 void ExtensionDevToolsClientHost::SendDetachedEvent() { |
357 Profile* profile = | 370 if (!extensions::ExtensionSystem::Get(profile_)->event_router()) |
358 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); | 371 return; |
359 if (profile != NULL && | 372 |
360 extensions::ExtensionSystem::Get(profile)->event_router()) { | 373 scoped_ptr<base::ListValue> args(OnDetach::Create(debuggee_, |
361 scoped_ptr<base::ListValue> args(OnDetach::Create(debuggee_, | 374 detach_reason_)); |
362 detach_reason_)); | 375 scoped_ptr<extensions::Event> event(new extensions::Event( |
363 scoped_ptr<extensions::Event> event(new extensions::Event( | 376 keys::kOnDetach, args.Pass())); |
364 keys::kOnDetach, args.Pass())); | 377 event->restrict_to_profile = profile_; |
365 event->restrict_to_profile = profile; | 378 extensions::ExtensionSystem::Get(profile_)->event_router()-> |
366 extensions::ExtensionSystem::Get(profile)->event_router()-> | 379 DispatchEventToExtension(extension_id_, event.Pass()); |
367 DispatchEventToExtension(extension_id_, event.Pass()); | |
368 } | |
369 } | 380 } |
370 | 381 |
371 void ExtensionDevToolsClientHost::Observe( | 382 void ExtensionDevToolsClientHost::Observe( |
372 int type, | 383 int type, |
373 const content::NotificationSource& source, | 384 const content::NotificationSource& source, |
374 const content::NotificationDetails& details) { | 385 const content::NotificationDetails& details) { |
375 if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { | 386 if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { |
376 std::string id = | 387 std::string id = |
377 content::Details<extensions::UnloadedExtensionInfo>(details)-> | 388 content::Details<extensions::UnloadedExtensionInfo>(details)-> |
378 extension->id(); | 389 extension->id(); |
379 if (id == extension_id_) | 390 if (id == extension_id_) |
380 Close(); | 391 Close(); |
381 } else { | 392 } else { |
382 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type); | 393 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type); |
383 if (content::Details<InfoBarRemovedDetails>(details)->first == | 394 if (content::Details<InfoBarRemovedDetails>(details)->first == |
384 infobar_delegate_) { | 395 infobar_delegate_) { |
385 infobar_delegate_ = NULL; | 396 infobar_delegate_ = NULL; |
386 SendDetachedEvent(); | 397 SendDetachedEvent(); |
387 Close(); | 398 Close(); |
388 } | 399 } |
389 } | 400 } |
390 } | 401 } |
391 | 402 |
392 void ExtensionDevToolsClientHost::DispatchOnInspectorFrontend( | 403 void ExtensionDevToolsClientHost::DispatchOnInspectorFrontend( |
393 const std::string& message) { | 404 const std::string& message) { |
394 Profile* profile = | 405 if (!extensions::ExtensionSystem::Get(profile_)->event_router()) |
395 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); | |
396 if (profile == NULL || | |
397 !extensions::ExtensionSystem::Get(profile)->event_router()) | |
398 return; | 406 return; |
399 | 407 |
400 scoped_ptr<Value> result(base::JSONReader::Read(message)); | 408 scoped_ptr<Value> result(base::JSONReader::Read(message)); |
401 if (!result->IsType(Value::TYPE_DICTIONARY)) | 409 if (!result->IsType(Value::TYPE_DICTIONARY)) |
402 return; | 410 return; |
403 DictionaryValue* dictionary = static_cast<DictionaryValue*>(result.get()); | 411 DictionaryValue* dictionary = static_cast<DictionaryValue*>(result.get()); |
404 | 412 |
405 int id; | 413 int id; |
406 if (!dictionary->GetInteger("id", &id)) { | 414 if (!dictionary->GetInteger("id", &id)) { |
407 std::string method_name; | 415 std::string method_name; |
408 if (!dictionary->GetString("method", &method_name)) | 416 if (!dictionary->GetString("method", &method_name)) |
409 return; | 417 return; |
410 | 418 |
411 OnEvent::Params params; | 419 OnEvent::Params params; |
412 DictionaryValue* params_value; | 420 DictionaryValue* params_value; |
413 if (dictionary->GetDictionary("params", ¶ms_value)) | 421 if (dictionary->GetDictionary("params", ¶ms_value)) |
414 params.additional_properties.Swap(params_value); | 422 params.additional_properties.Swap(params_value); |
415 | 423 |
416 scoped_ptr<ListValue> args(OnEvent::Create(debuggee_, method_name, params)); | 424 scoped_ptr<ListValue> args(OnEvent::Create(debuggee_, method_name, params)); |
417 scoped_ptr<extensions::Event> event(new extensions::Event( | 425 scoped_ptr<extensions::Event> event(new extensions::Event( |
418 keys::kOnEvent, args.Pass())); | 426 keys::kOnEvent, args.Pass())); |
419 event->restrict_to_profile = profile; | 427 event->restrict_to_profile = profile_; |
420 extensions::ExtensionSystem::Get(profile)->event_router()-> | 428 extensions::ExtensionSystem::Get(profile_)->event_router()-> |
421 DispatchEventToExtension(extension_id_, event.Pass()); | 429 DispatchEventToExtension(extension_id_, event.Pass()); |
422 } else { | 430 } else { |
423 DebuggerSendCommandFunction* function = pending_requests_[id]; | 431 DebuggerSendCommandFunction* function = pending_requests_[id]; |
424 if (!function) | 432 if (!function) |
425 return; | 433 return; |
426 | 434 |
427 function->SendResponseBody(dictionary); | 435 function->SendResponseBody(dictionary); |
428 pending_requests_.erase(id); | 436 pending_requests_.erase(id); |
429 } | 437 } |
430 } | 438 } |
431 | 439 |
432 // static | 440 // static |
433 ExtensionDevToolsInfoBarDelegate* ExtensionDevToolsInfoBarDelegate::Create( | 441 ExtensionDevToolsInfoBarDelegate* ExtensionDevToolsInfoBarDelegate::Create( |
434 WebContents* web_contents, | 442 RenderViewHost* rvh, |
435 const std::string& client_name) { | 443 const std::string& client_name) { |
444 if (!rvh) | |
445 return NULL; | |
446 | |
447 WebContents* web_contents = WebContents::FromRenderViewHost(rvh); | |
448 if (!web_contents) | |
449 return NULL; | |
450 | |
436 InfoBarService* infobar_service = | 451 InfoBarService* infobar_service = |
437 InfoBarService::FromWebContents(web_contents); | 452 InfoBarService::FromWebContents(web_contents); |
438 if (!infobar_service) | 453 if (!infobar_service) |
439 return NULL; | 454 return NULL; |
455 | |
440 return static_cast<ExtensionDevToolsInfoBarDelegate*>( | 456 return static_cast<ExtensionDevToolsInfoBarDelegate*>( |
441 infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>( | 457 infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>( |
442 new ExtensionDevToolsInfoBarDelegate(infobar_service, client_name)))); | 458 new ExtensionDevToolsInfoBarDelegate(infobar_service, client_name)))); |
443 } | 459 } |
444 | 460 |
445 void ExtensionDevToolsInfoBarDelegate::AttachClientHost( | 461 void ExtensionDevToolsInfoBarDelegate::AttachClientHost( |
446 ExtensionDevToolsClientHost* client_host) { | 462 ExtensionDevToolsClientHost* client_host) { |
447 client_host_ = client_host; | 463 client_host_ = client_host; |
448 } | 464 } |
449 | 465 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
485 client_host_->MarkAsDismissed(); | 501 client_host_->MarkAsDismissed(); |
486 } | 502 } |
487 | 503 |
488 bool ExtensionDevToolsInfoBarDelegate::Cancel() { | 504 bool ExtensionDevToolsInfoBarDelegate::Cancel() { |
489 if (client_host_) | 505 if (client_host_) |
490 client_host_->MarkAsDismissed(); | 506 client_host_->MarkAsDismissed(); |
491 return true; | 507 return true; |
492 } | 508 } |
493 | 509 |
494 DebuggerFunction::DebuggerFunction() | 510 DebuggerFunction::DebuggerFunction() |
495 : contents_(0), | 511 : client_host_(0) { |
496 client_host_(0) { | 512 } |
513 | |
514 DebuggerFunction::~DebuggerFunction() { | |
497 } | 515 } |
498 | 516 |
499 void DebuggerFunction::FormatErrorMessage(const std::string& format) { | 517 void DebuggerFunction::FormatErrorMessage(const std::string& format) { |
500 if (debuggee_.tab_id) | 518 if (debuggee_.tab_id) |
501 error_ = ErrorUtils::FormatErrorMessage( | 519 error_ = ErrorUtils::FormatErrorMessage( |
502 format, keys::kTabTargetType, base::IntToString(*debuggee_.tab_id)); | 520 format, keys::kTabTargetType, base::IntToString(*debuggee_.tab_id)); |
503 else if (debuggee_.extension_id) | 521 else if (debuggee_.extension_id) |
504 error_ = ErrorUtils::FormatErrorMessage( | 522 error_ = ErrorUtils::FormatErrorMessage( |
505 format, keys::kBackgroundPageTargetType, *debuggee_.extension_id); | 523 format, keys::kBackgroundPageTargetType, *debuggee_.extension_id); |
506 else | 524 else |
507 error_ = ErrorUtils::FormatErrorMessage( | 525 error_ = ErrorUtils::FormatErrorMessage( |
508 format, keys::kOpaqueTargetType, *debuggee_.target_id); | 526 format, keys::kOpaqueTargetType, *debuggee_.target_id); |
509 } | 527 } |
510 | 528 |
511 bool DebuggerFunction::InitWebContents() { | 529 bool DebuggerFunction::InitAgentHost() { |
512 if (debuggee_.tab_id) { | 530 if (debuggee_.tab_id) { |
513 WebContents* web_contents = NULL; | 531 WebContents* web_contents = NULL; |
514 bool result = ExtensionTabUtil::GetTabById( | 532 bool result = ExtensionTabUtil::GetTabById( |
515 *debuggee_.tab_id, profile(), include_incognito(), NULL, NULL, | 533 *debuggee_.tab_id, profile(), include_incognito(), NULL, NULL, |
516 &web_contents, NULL); | 534 &web_contents, NULL); |
517 if (result && web_contents) { | 535 if (result && web_contents) { |
518 if (content::HasWebUIScheme(web_contents->GetURL())) { | 536 if (content::HasWebUIScheme(web_contents->GetURL())) { |
519 error_ = ErrorUtils::FormatErrorMessage( | 537 error_ = ErrorUtils::FormatErrorMessage( |
520 keys::kAttachToWebUIError, | 538 keys::kAttachToWebUIError, |
521 web_contents->GetURL().scheme()); | 539 web_contents->GetURL().scheme()); |
522 return false; | 540 return false; |
523 } | 541 } |
524 contents_ = web_contents; | 542 agent_host_ = DevToolsAgentHost::GetOrCreateFor( |
543 web_contents->GetRenderViewHost()); | |
525 } | 544 } |
526 } else if (debuggee_.extension_id) { | 545 } else if (debuggee_.extension_id) { |
527 extensions::ExtensionHost* extension_host = | 546 extensions::ExtensionHost* extension_host = |
528 extensions::ExtensionSystem::Get(profile())->process_manager()-> | 547 extensions::ExtensionSystem::Get(profile())->process_manager()-> |
529 GetBackgroundHostForExtension(*debuggee_.extension_id); | 548 GetBackgroundHostForExtension(*debuggee_.extension_id); |
530 if (extension_host) { | 549 if (extension_host) { |
531 contents_ = WebContents::FromRenderViewHost( | 550 agent_host_ = DevToolsAgentHost::GetOrCreateFor( |
532 extension_host->render_view_host()); | 551 extension_host->render_view_host()); |
533 } | 552 } |
534 } else if (debuggee_.target_id) { | 553 } else if (debuggee_.target_id) { |
535 DevToolsAgentHost* agent_host = | 554 agent_host_ = DevToolsAgentHost::GetForId(*debuggee_.target_id); |
536 DevToolsAgentHost::GetForId(*debuggee_.target_id); | |
537 if (agent_host) { | |
538 contents_ = WebContents::FromRenderViewHost( | |
539 agent_host->GetRenderViewHost()); | |
540 } | |
541 } else { | 555 } else { |
542 error_ = keys::kInvalidTargetError; | 556 error_ = keys::kInvalidTargetError; |
543 return false; | 557 return false; |
544 } | 558 } |
545 | 559 |
546 if (!contents_) { | 560 if (!agent_host_) { |
547 FormatErrorMessage(keys::kNoTargetError); | 561 FormatErrorMessage(keys::kNoTargetError); |
548 return false; | 562 return false; |
549 } | 563 } |
550 return true; | 564 return true; |
551 } | 565 } |
552 | 566 |
553 bool DebuggerFunction::InitClientHost() { | 567 bool DebuggerFunction::InitClientHost() { |
554 if (!InitWebContents()) | 568 if (!InitAgentHost()) |
555 return false; | 569 return false; |
556 | 570 |
557 // Don't fetch rvh from the contents since it'll be wrong upon navigation. | 571 client_host_ = AttachedClientHosts::GetInstance()-> |
558 client_host_ = AttachedClientHosts::GetInstance()->Lookup(contents_); | 572 Lookup(agent_host_, GetExtension()->id()); |
559 | 573 |
560 if (!client_host_ || | 574 if (!client_host_) { |
561 !client_host_->MatchesContentsAndExtensionId(contents_, | |
562 GetExtension()->id())) { | |
563 FormatErrorMessage(keys::kNotAttachedError); | 575 FormatErrorMessage(keys::kNotAttachedError); |
564 return false; | 576 return false; |
565 } | 577 } |
566 return true; | 578 return true; |
567 } | 579 } |
568 | 580 |
569 DebuggerAttachFunction::DebuggerAttachFunction() {} | 581 DebuggerAttachFunction::DebuggerAttachFunction() {} |
570 | 582 |
571 DebuggerAttachFunction::~DebuggerAttachFunction() {} | 583 DebuggerAttachFunction::~DebuggerAttachFunction() {} |
572 | 584 |
573 bool DebuggerAttachFunction::RunImpl() { | 585 bool DebuggerAttachFunction::RunImpl() { |
574 scoped_ptr<Attach::Params> params(Attach::Params::Create(*args_)); | 586 scoped_ptr<Attach::Params> params(Attach::Params::Create(*args_)); |
575 EXTENSION_FUNCTION_VALIDATE(params.get()); | 587 EXTENSION_FUNCTION_VALIDATE(params.get()); |
576 | 588 |
577 CopyDebuggee(debuggee_, params->target); | 589 CopyDebuggee(debuggee_, params->target); |
578 if (!InitWebContents()) | 590 if (!InitAgentHost()) |
579 return false; | 591 return false; |
580 | 592 |
581 if (!webkit_glue::IsInspectorProtocolVersionSupported( | 593 if (!webkit_glue::IsInspectorProtocolVersionSupported( |
582 params->required_version)) { | 594 params->required_version)) { |
583 error_ = ErrorUtils::FormatErrorMessage( | 595 error_ = ErrorUtils::FormatErrorMessage( |
584 keys::kProtocolVersionNotSupportedError, | 596 keys::kProtocolVersionNotSupportedError, |
585 params->required_version); | 597 params->required_version); |
586 return false; | 598 return false; |
587 } | 599 } |
588 | 600 |
589 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor( | 601 if (agent_host_->IsAttached()) { |
590 contents_->GetRenderViewHost())); | |
591 if (agent->IsAttached()) { | |
592 FormatErrorMessage(keys::kAlreadyAttachedError); | 602 FormatErrorMessage(keys::kAlreadyAttachedError); |
593 return false; | 603 return false; |
594 } | 604 } |
595 | 605 |
596 ExtensionDevToolsInfoBarDelegate* infobar_delegate = NULL; | 606 ExtensionDevToolsInfoBarDelegate* infobar_delegate = NULL; |
597 | 607 |
598 if (!CommandLine::ForCurrentProcess()-> | 608 if (!CommandLine::ForCurrentProcess()-> |
599 HasSwitch(switches::kSilentDebuggerExtensionAPI)) { | 609 HasSwitch(switches::kSilentDebuggerExtensionAPI)) { |
600 // Do not attach to the target if for any reason the infobar cannot be shown | 610 // Do not attach to the target if for any reason the infobar cannot be shown |
601 // for this WebContents instance. | 611 // for this WebContents instance. |
602 infobar_delegate = ExtensionDevToolsInfoBarDelegate::Create( | 612 infobar_delegate = ExtensionDevToolsInfoBarDelegate::Create( |
603 contents_, GetExtension()->name()); | 613 agent_host_->GetRenderViewHost(), GetExtension()->name()); |
604 if (!infobar_delegate) { | 614 if (!infobar_delegate) { |
605 error_ = ErrorUtils::FormatErrorMessage( | 615 error_ = ErrorUtils::FormatErrorMessage( |
606 keys::kSilentDebuggingRequired, | 616 keys::kSilentDebuggingRequired, |
607 switches::kSilentDebuggerExtensionAPI); | 617 switches::kSilentDebuggerExtensionAPI); |
608 return false; | 618 return false; |
609 } | 619 } |
610 } | 620 } |
611 | 621 |
612 new ExtensionDevToolsClientHost(contents_, | 622 new ExtensionDevToolsClientHost(profile(), |
623 agent_host_, | |
613 GetExtension()->id(), | 624 GetExtension()->id(), |
614 GetExtension()->name(), | 625 GetExtension()->name(), |
615 debuggee_, | 626 debuggee_, |
616 infobar_delegate); | 627 infobar_delegate); |
617 SendResponse(true); | 628 SendResponse(true); |
618 return true; | 629 return true; |
619 } | 630 } |
620 | 631 |
621 DebuggerDetachFunction::DebuggerDetachFunction() {} | 632 DebuggerDetachFunction::DebuggerDetachFunction() {} |
622 | 633 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
668 | 679 |
669 results_ = SendCommand::Results::Create(result); | 680 results_ = SendCommand::Results::Create(result); |
670 SendResponse(true); | 681 SendResponse(true); |
671 } | 682 } |
672 | 683 |
673 DebuggerGetTargetsFunction::DebuggerGetTargetsFunction() {} | 684 DebuggerGetTargetsFunction::DebuggerGetTargetsFunction() {} |
674 | 685 |
675 DebuggerGetTargetsFunction::~DebuggerGetTargetsFunction() {} | 686 DebuggerGetTargetsFunction::~DebuggerGetTargetsFunction() {} |
676 | 687 |
677 bool DebuggerGetTargetsFunction::RunImpl() { | 688 bool DebuggerGetTargetsFunction::RunImpl() { |
678 base::ListValue* results_list = new ListValue(); | 689 base::ListValue* results_list = new base::ListValue(); |
679 | 690 |
680 std::vector<RenderViewHost*> rvh_list = | 691 std::vector<RenderViewHost*> rvh_list = |
681 DevToolsAgentHost::GetValidRenderViewHosts(); | 692 DevToolsAgentHost::GetValidRenderViewHosts(); |
682 for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin(); | 693 for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin(); |
683 it != rvh_list.end(); ++it) { | 694 it != rvh_list.end(); ++it) { |
684 base::Value* value = SerializePageInfo(*it); | 695 base::Value* value = SerializePageInfo(*it); |
685 if (value) | 696 if (value) |
686 results_list->Append(value); | 697 results_list->Append(value); |
687 } | 698 } |
688 | 699 |
689 SetResult(results_list); | 700 BrowserThread::PostTaskAndReply( |
690 SendResponse(true); | 701 BrowserThread::IO, |
702 FROM_HERE, | |
703 base::Bind(&DebuggerGetTargetsFunction::CollectWorkerInfo, | |
704 this, | |
705 results_list), | |
706 base::Bind(&DebuggerGetTargetsFunction::SendTargetList, | |
707 this, | |
708 results_list)); | |
691 return true; | 709 return true; |
692 } | 710 } |
711 | |
712 void DebuggerGetTargetsFunction::CollectWorkerInfo(base::ListValue* list) { | |
713 std::vector<WorkerService::WorkerInfo> worker_info = | |
714 WorkerService::GetInstance()->GetWorkers(); | |
715 | |
716 for (size_t i = 0; i < worker_info.size(); ++i) | |
717 list->Append(SerializeWorkerInfo(worker_info[i])); | |
718 } | |
719 | |
720 void DebuggerGetTargetsFunction::SendTargetList(base::ListValue* list) { | |
721 SetResult(list); | |
722 SendResponse(true); | |
723 } | |
OLD | NEW |