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 const std::string& extension_id() { return extension_id_; } |
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 |
226 dictionary->SetString(kTargetIdField, agent_host->GetId()); | 230 dictionary->SetString(kTargetIdField, agent_host->GetId()); |
227 dictionary->SetBoolean(kTargetAttachedField, agent_host->IsAttached()); | 231 dictionary->SetBoolean(kTargetAttachedField, agent_host->IsAttached()); |
228 dictionary->SetString(kTargetUrlField, web_contents->GetURL().spec()); | 232 dictionary->SetString(kTargetUrlField, web_contents->GetURL().spec()); |
229 | 233 |
230 extensions::ExtensionHost* extension_host = | 234 extensions::ExtensionHost* extension_host = |
231 GetExtensionBackgroundHost(web_contents); | 235 GetExtensionBackgroundHost(web_contents); |
232 if (extension_host) { | 236 if (extension_host) { |
233 // This RenderViewHost belongs to a background page. | 237 // This RenderViewHost belongs to a background page. |
234 dictionary->SetString(kTargetTypeField, kTargetTypeBackgroundPage); | 238 dictionary->SetString(kTargetTypeField, kTargetTypeBackgroundPage); |
235 dictionary->SetString(kTargetTitleField, | 239 dictionary->SetString(kTargetTitleField, |
236 extension_host->extension()->name()); | 240 extension_host->extension()->name()); |
237 } else { | 241 } else { |
238 // This RenderViewHost belongs to a regular page. | 242 // This RenderViewHost belongs to a regular page. |
239 dictionary->SetString(kTargetTypeField, kTargetTypePage); | 243 dictionary->SetString(kTargetTypeField, kTargetTypePage); |
240 dictionary->SetString(kTargetTitleField, | 244 dictionary->SetString(kTargetTitleField, web_contents->GetTitle()); |
241 UTF16ToUTF8(net::EscapeForHTML(web_contents->GetTitle()))); | |
242 | 245 |
243 content::NavigationController& controller = web_contents->GetController(); | 246 content::NavigationController& controller = web_contents->GetController(); |
244 content::NavigationEntry* entry = controller.GetActiveEntry(); | 247 content::NavigationEntry* entry = controller.GetActiveEntry(); |
245 if (entry != NULL && entry->GetURL().is_valid()) { | 248 if (entry != NULL && entry->GetURL().is_valid()) { |
246 dictionary->SetString(kTargetFaviconUrlField, | 249 dictionary->SetString(kTargetFaviconUrlField, |
247 entry->GetFavicon().url.spec()); | 250 entry->GetFavicon().url.spec()); |
248 } | 251 } |
249 } | 252 } |
250 | 253 |
251 return dictionary; | 254 return dictionary; |
252 } | 255 } |
253 | 256 |
| 257 static base::Value* SerializeWorkerInfo( |
| 258 const WorkerService::WorkerInfo& worker) { |
| 259 base::DictionaryValue* dictionary = new base::DictionaryValue; |
| 260 |
| 261 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetForWorker( |
| 262 worker.process_id, worker.route_id)); |
| 263 dictionary->SetString(kTargetIdField, agent->GetId()); |
| 264 dictionary->SetString(kTargetTypeField, kTargetTypeWorker); |
| 265 dictionary->SetString(kTargetTitleField, worker.name); |
| 266 dictionary->SetString(kTargetUrlField, worker.url.spec()); |
| 267 dictionary->SetBoolean(kTargetAttachedField, agent->IsAttached()); |
| 268 |
| 269 return dictionary; |
| 270 } |
| 271 |
254 } // namespace | 272 } // namespace |
255 | 273 |
256 static void CopyDebuggee(Debuggee & dst, const Debuggee& src) { | 274 static void CopyDebuggee(Debuggee & dst, const Debuggee& src) { |
257 if (src.tab_id) | 275 if (src.tab_id) |
258 dst.tab_id.reset(new int(*src.tab_id)); | 276 dst.tab_id.reset(new int(*src.tab_id)); |
259 if (src.extension_id) | 277 if (src.extension_id) |
260 dst.extension_id.reset(new std::string(*src.extension_id)); | 278 dst.extension_id.reset(new std::string(*src.extension_id)); |
261 if (src.target_id) | 279 if (src.target_id) |
262 dst.target_id.reset(new std::string(*src.target_id)); | 280 dst.target_id.reset(new std::string(*src.target_id)); |
263 } | 281 } |
264 | 282 |
265 ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( | 283 ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( |
266 WebContents* web_contents, | 284 Profile* profile, |
| 285 DevToolsAgentHost* agent_host, |
267 const std::string& extension_id, | 286 const std::string& extension_id, |
268 const std::string& extension_name, | 287 const std::string& extension_name, |
269 const Debuggee& debuggee, | 288 const Debuggee& debuggee, |
270 ExtensionDevToolsInfoBarDelegate* infobar_delegate) | 289 ExtensionDevToolsInfoBarDelegate* infobar_delegate) |
271 : web_contents_(web_contents), | 290 : profile_(profile), |
| 291 agent_host_(agent_host), |
272 extension_id_(extension_id), | 292 extension_id_(extension_id), |
273 last_request_id_(0), | 293 last_request_id_(0), |
274 infobar_delegate_(infobar_delegate), | 294 infobar_delegate_(infobar_delegate), |
275 detach_reason_(OnDetach::REASON_TARGET_CLOSED) { | 295 detach_reason_(OnDetach::REASON_TARGET_CLOSED) { |
276 CopyDebuggee(debuggee_, debuggee); | 296 CopyDebuggee(debuggee_, debuggee); |
277 | 297 |
278 AttachedClientHosts::GetInstance()->Add(this); | 298 AttachedClientHosts::GetInstance()->Add(this); |
279 | 299 |
280 // Detach from debugger when extension unloads. | 300 // Detach from debugger when extension unloads. |
281 Profile* profile = | |
282 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); | |
283 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 301 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
284 content::Source<Profile>(profile)); | 302 content::Source<Profile>(profile_)); |
285 | 303 |
286 // Attach to debugger and tell it we are ready. | 304 // Attach to debugger and tell it we are ready. |
287 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor( | 305 DevToolsManager::GetInstance()-> |
288 web_contents_->GetRenderViewHost())); | 306 RegisterDevToolsClientHostFor(agent_host_, this); |
289 DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(agent, this); | |
290 | 307 |
291 if (infobar_delegate_) { | 308 if (infobar_delegate_) { |
292 infobar_delegate_->AttachClientHost(this); | 309 infobar_delegate_->AttachClientHost(this); |
293 registrar_.Add(this, | 310 registrar_.Add(this, |
294 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, | 311 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, |
295 content::Source<InfoBarService>(infobar_delegate_->owner())); | 312 content::Source<InfoBarService>(infobar_delegate_->owner())); |
296 } | 313 } |
297 } | 314 } |
298 | 315 |
299 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { | 316 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { |
300 // Ensure calling RemoveInfoBar() below won't result in Observe() trying to | 317 // Ensure calling RemoveInfoBar() below won't result in Observe() trying to |
301 // Close() us. | 318 // Close() us. |
302 registrar_.RemoveAll(); | 319 registrar_.RemoveAll(); |
303 | 320 |
304 if (infobar_delegate_) { | 321 if (infobar_delegate_) { |
305 infobar_delegate_->DiscardClientHost(); | 322 infobar_delegate_->DiscardClientHost(); |
306 if (infobar_delegate_->owner()) | 323 if (infobar_delegate_->owner()) |
307 infobar_delegate_->owner()->RemoveInfoBar(infobar_delegate_); | 324 infobar_delegate_->owner()->RemoveInfoBar(infobar_delegate_); |
308 } | 325 } |
309 AttachedClientHosts::GetInstance()->Remove(this); | 326 AttachedClientHosts::GetInstance()->Remove(this); |
310 } | 327 } |
311 | 328 |
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 | 329 // DevToolsClientHost interface |
319 void ExtensionDevToolsClientHost::InspectedContentsClosing() { | 330 void ExtensionDevToolsClientHost::InspectedContentsClosing() { |
320 SendDetachedEvent(); | 331 SendDetachedEvent(); |
321 delete this; | 332 delete this; |
322 } | 333 } |
323 | 334 |
324 void ExtensionDevToolsClientHost::ReplacedWithAnotherClient() { | 335 void ExtensionDevToolsClientHost::ReplacedWithAnotherClient() { |
325 detach_reason_ = OnDetach::REASON_REPLACED_WITH_DEVTOOLS; | 336 detach_reason_ = OnDetach::REASON_REPLACED_WITH_DEVTOOLS; |
326 } | 337 } |
327 | 338 |
(...skipping 19 matching lines...) Expand all Loading... |
347 std::string json_args; | 358 std::string json_args; |
348 base::JSONWriter::Write(&protocol_request, &json_args); | 359 base::JSONWriter::Write(&protocol_request, &json_args); |
349 DevToolsManager::GetInstance()->DispatchOnInspectorBackend(this, json_args); | 360 DevToolsManager::GetInstance()->DispatchOnInspectorBackend(this, json_args); |
350 } | 361 } |
351 | 362 |
352 void ExtensionDevToolsClientHost::MarkAsDismissed() { | 363 void ExtensionDevToolsClientHost::MarkAsDismissed() { |
353 detach_reason_ = OnDetach::REASON_CANCELED_BY_USER; | 364 detach_reason_ = OnDetach::REASON_CANCELED_BY_USER; |
354 } | 365 } |
355 | 366 |
356 void ExtensionDevToolsClientHost::SendDetachedEvent() { | 367 void ExtensionDevToolsClientHost::SendDetachedEvent() { |
357 Profile* profile = | 368 if (!extensions::ExtensionSystem::Get(profile_)->event_router()) |
358 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); | 369 return; |
359 if (profile != NULL && | 370 |
360 extensions::ExtensionSystem::Get(profile)->event_router()) { | 371 scoped_ptr<base::ListValue> args(OnDetach::Create(debuggee_, |
361 scoped_ptr<base::ListValue> args(OnDetach::Create(debuggee_, | 372 detach_reason_)); |
362 detach_reason_)); | 373 scoped_ptr<extensions::Event> event(new extensions::Event( |
363 scoped_ptr<extensions::Event> event(new extensions::Event( | 374 keys::kOnDetach, args.Pass())); |
364 keys::kOnDetach, args.Pass())); | 375 event->restrict_to_profile = profile_; |
365 event->restrict_to_profile = profile; | 376 extensions::ExtensionSystem::Get(profile_)->event_router()-> |
366 extensions::ExtensionSystem::Get(profile)->event_router()-> | 377 DispatchEventToExtension(extension_id_, event.Pass()); |
367 DispatchEventToExtension(extension_id_, event.Pass()); | |
368 } | |
369 } | 378 } |
370 | 379 |
371 void ExtensionDevToolsClientHost::Observe( | 380 void ExtensionDevToolsClientHost::Observe( |
372 int type, | 381 int type, |
373 const content::NotificationSource& source, | 382 const content::NotificationSource& source, |
374 const content::NotificationDetails& details) { | 383 const content::NotificationDetails& details) { |
375 if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { | 384 if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { |
376 std::string id = | 385 std::string id = |
377 content::Details<extensions::UnloadedExtensionInfo>(details)-> | 386 content::Details<extensions::UnloadedExtensionInfo>(details)-> |
378 extension->id(); | 387 extension->id(); |
379 if (id == extension_id_) | 388 if (id == extension_id_) |
380 Close(); | 389 Close(); |
381 } else { | 390 } else { |
382 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type); | 391 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type); |
383 if (content::Details<InfoBarRemovedDetails>(details)->first == | 392 if (content::Details<InfoBarRemovedDetails>(details)->first == |
384 infobar_delegate_) { | 393 infobar_delegate_) { |
385 infobar_delegate_ = NULL; | 394 infobar_delegate_ = NULL; |
386 SendDetachedEvent(); | 395 SendDetachedEvent(); |
387 Close(); | 396 Close(); |
388 } | 397 } |
389 } | 398 } |
390 } | 399 } |
391 | 400 |
392 void ExtensionDevToolsClientHost::DispatchOnInspectorFrontend( | 401 void ExtensionDevToolsClientHost::DispatchOnInspectorFrontend( |
393 const std::string& message) { | 402 const std::string& message) { |
394 Profile* profile = | 403 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; | 404 return; |
399 | 405 |
400 scoped_ptr<Value> result(base::JSONReader::Read(message)); | 406 scoped_ptr<Value> result(base::JSONReader::Read(message)); |
401 if (!result->IsType(Value::TYPE_DICTIONARY)) | 407 if (!result->IsType(Value::TYPE_DICTIONARY)) |
402 return; | 408 return; |
403 DictionaryValue* dictionary = static_cast<DictionaryValue*>(result.get()); | 409 DictionaryValue* dictionary = static_cast<DictionaryValue*>(result.get()); |
404 | 410 |
405 int id; | 411 int id; |
406 if (!dictionary->GetInteger("id", &id)) { | 412 if (!dictionary->GetInteger("id", &id)) { |
407 std::string method_name; | 413 std::string method_name; |
408 if (!dictionary->GetString("method", &method_name)) | 414 if (!dictionary->GetString("method", &method_name)) |
409 return; | 415 return; |
410 | 416 |
411 OnEvent::Params params; | 417 OnEvent::Params params; |
412 DictionaryValue* params_value; | 418 DictionaryValue* params_value; |
413 if (dictionary->GetDictionary("params", ¶ms_value)) | 419 if (dictionary->GetDictionary("params", ¶ms_value)) |
414 params.additional_properties.Swap(params_value); | 420 params.additional_properties.Swap(params_value); |
415 | 421 |
416 scoped_ptr<ListValue> args(OnEvent::Create(debuggee_, method_name, params)); | 422 scoped_ptr<ListValue> args(OnEvent::Create(debuggee_, method_name, params)); |
417 scoped_ptr<extensions::Event> event(new extensions::Event( | 423 scoped_ptr<extensions::Event> event(new extensions::Event( |
418 keys::kOnEvent, args.Pass())); | 424 keys::kOnEvent, args.Pass())); |
419 event->restrict_to_profile = profile; | 425 event->restrict_to_profile = profile_; |
420 extensions::ExtensionSystem::Get(profile)->event_router()-> | 426 extensions::ExtensionSystem::Get(profile_)->event_router()-> |
421 DispatchEventToExtension(extension_id_, event.Pass()); | 427 DispatchEventToExtension(extension_id_, event.Pass()); |
422 } else { | 428 } else { |
423 DebuggerSendCommandFunction* function = pending_requests_[id]; | 429 DebuggerSendCommandFunction* function = pending_requests_[id]; |
424 if (!function) | 430 if (!function) |
425 return; | 431 return; |
426 | 432 |
427 function->SendResponseBody(dictionary); | 433 function->SendResponseBody(dictionary); |
428 pending_requests_.erase(id); | 434 pending_requests_.erase(id); |
429 } | 435 } |
430 } | 436 } |
431 | 437 |
432 // static | 438 // static |
433 ExtensionDevToolsInfoBarDelegate* ExtensionDevToolsInfoBarDelegate::Create( | 439 ExtensionDevToolsInfoBarDelegate* ExtensionDevToolsInfoBarDelegate::Create( |
434 WebContents* web_contents, | 440 RenderViewHost* rvh, |
435 const std::string& client_name) { | 441 const std::string& client_name) { |
| 442 if (!rvh) |
| 443 return NULL; |
| 444 |
| 445 WebContents* web_contents = WebContents::FromRenderViewHost(rvh); |
| 446 if (!web_contents) |
| 447 return NULL; |
| 448 |
436 InfoBarService* infobar_service = | 449 InfoBarService* infobar_service = |
437 InfoBarService::FromWebContents(web_contents); | 450 InfoBarService::FromWebContents(web_contents); |
438 if (!infobar_service) | 451 if (!infobar_service) |
439 return NULL; | 452 return NULL; |
| 453 |
440 return static_cast<ExtensionDevToolsInfoBarDelegate*>( | 454 return static_cast<ExtensionDevToolsInfoBarDelegate*>( |
441 infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>( | 455 infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>( |
442 new ExtensionDevToolsInfoBarDelegate(infobar_service, client_name)))); | 456 new ExtensionDevToolsInfoBarDelegate(infobar_service, client_name)))); |
443 } | 457 } |
444 | 458 |
445 void ExtensionDevToolsInfoBarDelegate::AttachClientHost( | 459 void ExtensionDevToolsInfoBarDelegate::AttachClientHost( |
446 ExtensionDevToolsClientHost* client_host) { | 460 ExtensionDevToolsClientHost* client_host) { |
447 client_host_ = client_host; | 461 client_host_ = client_host; |
448 } | 462 } |
449 | 463 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 client_host_->MarkAsDismissed(); | 499 client_host_->MarkAsDismissed(); |
486 } | 500 } |
487 | 501 |
488 bool ExtensionDevToolsInfoBarDelegate::Cancel() { | 502 bool ExtensionDevToolsInfoBarDelegate::Cancel() { |
489 if (client_host_) | 503 if (client_host_) |
490 client_host_->MarkAsDismissed(); | 504 client_host_->MarkAsDismissed(); |
491 return true; | 505 return true; |
492 } | 506 } |
493 | 507 |
494 DebuggerFunction::DebuggerFunction() | 508 DebuggerFunction::DebuggerFunction() |
495 : contents_(0), | 509 : client_host_(0) { |
496 client_host_(0) { | 510 } |
| 511 |
| 512 DebuggerFunction::~DebuggerFunction() { |
497 } | 513 } |
498 | 514 |
499 void DebuggerFunction::FormatErrorMessage(const std::string& format) { | 515 void DebuggerFunction::FormatErrorMessage(const std::string& format) { |
500 if (debuggee_.tab_id) | 516 if (debuggee_.tab_id) |
501 error_ = ErrorUtils::FormatErrorMessage( | 517 error_ = ErrorUtils::FormatErrorMessage( |
502 format, keys::kTabTargetType, base::IntToString(*debuggee_.tab_id)); | 518 format, keys::kTabTargetType, base::IntToString(*debuggee_.tab_id)); |
503 else if (debuggee_.extension_id) | 519 else if (debuggee_.extension_id) |
504 error_ = ErrorUtils::FormatErrorMessage( | 520 error_ = ErrorUtils::FormatErrorMessage( |
505 format, keys::kBackgroundPageTargetType, *debuggee_.extension_id); | 521 format, keys::kBackgroundPageTargetType, *debuggee_.extension_id); |
506 else | 522 else |
507 error_ = ErrorUtils::FormatErrorMessage( | 523 error_ = ErrorUtils::FormatErrorMessage( |
508 format, keys::kOpaqueTargetType, *debuggee_.target_id); | 524 format, keys::kOpaqueTargetType, *debuggee_.target_id); |
509 } | 525 } |
510 | 526 |
511 bool DebuggerFunction::InitWebContents() { | 527 bool DebuggerFunction::InitAgentHost() { |
512 if (debuggee_.tab_id) { | 528 if (debuggee_.tab_id) { |
513 WebContents* web_contents = NULL; | 529 WebContents* web_contents = NULL; |
514 bool result = ExtensionTabUtil::GetTabById( | 530 bool result = ExtensionTabUtil::GetTabById( |
515 *debuggee_.tab_id, profile(), include_incognito(), NULL, NULL, | 531 *debuggee_.tab_id, profile(), include_incognito(), NULL, NULL, |
516 &web_contents, NULL); | 532 &web_contents, NULL); |
517 if (result && web_contents) { | 533 if (result && web_contents) { |
518 if (content::HasWebUIScheme(web_contents->GetURL())) { | 534 if (content::HasWebUIScheme(web_contents->GetURL())) { |
519 error_ = ErrorUtils::FormatErrorMessage( | 535 error_ = ErrorUtils::FormatErrorMessage( |
520 keys::kAttachToWebUIError, | 536 keys::kAttachToWebUIError, |
521 web_contents->GetURL().scheme()); | 537 web_contents->GetURL().scheme()); |
522 return false; | 538 return false; |
523 } | 539 } |
524 contents_ = web_contents; | 540 agent_host_ = DevToolsAgentHost::GetOrCreateFor( |
| 541 web_contents->GetRenderViewHost()); |
525 } | 542 } |
526 } else if (debuggee_.extension_id) { | 543 } else if (debuggee_.extension_id) { |
527 extensions::ExtensionHost* extension_host = | 544 extensions::ExtensionHost* extension_host = |
528 extensions::ExtensionSystem::Get(profile())->process_manager()-> | 545 extensions::ExtensionSystem::Get(profile())->process_manager()-> |
529 GetBackgroundHostForExtension(*debuggee_.extension_id); | 546 GetBackgroundHostForExtension(*debuggee_.extension_id); |
530 if (extension_host) { | 547 if (extension_host) { |
531 contents_ = WebContents::FromRenderViewHost( | 548 agent_host_ = DevToolsAgentHost::GetOrCreateFor( |
532 extension_host->render_view_host()); | 549 extension_host->render_view_host()); |
533 } | 550 } |
534 } else if (debuggee_.target_id) { | 551 } else if (debuggee_.target_id) { |
535 DevToolsAgentHost* agent_host = | 552 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 { | 553 } else { |
542 error_ = keys::kInvalidTargetError; | 554 error_ = keys::kInvalidTargetError; |
543 return false; | 555 return false; |
544 } | 556 } |
545 | 557 |
546 if (!contents_) { | 558 if (!agent_host_) { |
547 FormatErrorMessage(keys::kNoTargetError); | 559 FormatErrorMessage(keys::kNoTargetError); |
548 return false; | 560 return false; |
549 } | 561 } |
550 return true; | 562 return true; |
551 } | 563 } |
552 | 564 |
553 bool DebuggerFunction::InitClientHost() { | 565 bool DebuggerFunction::InitClientHost() { |
554 if (!InitWebContents()) | 566 if (!InitAgentHost()) |
555 return false; | 567 return false; |
556 | 568 |
557 // Don't fetch rvh from the contents since it'll be wrong upon navigation. | 569 client_host_ = AttachedClientHosts::GetInstance()-> |
558 client_host_ = AttachedClientHosts::GetInstance()->Lookup(contents_); | 570 Lookup(agent_host_, GetExtension()->id()); |
559 | 571 |
560 if (!client_host_ || | 572 if (!client_host_) { |
561 !client_host_->MatchesContentsAndExtensionId(contents_, | |
562 GetExtension()->id())) { | |
563 FormatErrorMessage(keys::kNotAttachedError); | 573 FormatErrorMessage(keys::kNotAttachedError); |
564 return false; | 574 return false; |
565 } | 575 } |
566 return true; | 576 return true; |
567 } | 577 } |
568 | 578 |
569 DebuggerAttachFunction::DebuggerAttachFunction() {} | 579 DebuggerAttachFunction::DebuggerAttachFunction() {} |
570 | 580 |
571 DebuggerAttachFunction::~DebuggerAttachFunction() {} | 581 DebuggerAttachFunction::~DebuggerAttachFunction() {} |
572 | 582 |
573 bool DebuggerAttachFunction::RunImpl() { | 583 bool DebuggerAttachFunction::RunImpl() { |
574 scoped_ptr<Attach::Params> params(Attach::Params::Create(*args_)); | 584 scoped_ptr<Attach::Params> params(Attach::Params::Create(*args_)); |
575 EXTENSION_FUNCTION_VALIDATE(params.get()); | 585 EXTENSION_FUNCTION_VALIDATE(params.get()); |
576 | 586 |
577 CopyDebuggee(debuggee_, params->target); | 587 CopyDebuggee(debuggee_, params->target); |
578 if (!InitWebContents()) | 588 if (!InitAgentHost()) |
579 return false; | 589 return false; |
580 | 590 |
581 if (!webkit_glue::IsInspectorProtocolVersionSupported( | 591 if (!webkit_glue::IsInspectorProtocolVersionSupported( |
582 params->required_version)) { | 592 params->required_version)) { |
583 error_ = ErrorUtils::FormatErrorMessage( | 593 error_ = ErrorUtils::FormatErrorMessage( |
584 keys::kProtocolVersionNotSupportedError, | 594 keys::kProtocolVersionNotSupportedError, |
585 params->required_version); | 595 params->required_version); |
586 return false; | 596 return false; |
587 } | 597 } |
588 | 598 |
589 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor( | 599 if (agent_host_->IsAttached()) { |
590 contents_->GetRenderViewHost())); | |
591 if (agent->IsAttached()) { | |
592 FormatErrorMessage(keys::kAlreadyAttachedError); | 600 FormatErrorMessage(keys::kAlreadyAttachedError); |
593 return false; | 601 return false; |
594 } | 602 } |
595 | 603 |
596 ExtensionDevToolsInfoBarDelegate* infobar_delegate = NULL; | 604 ExtensionDevToolsInfoBarDelegate* infobar_delegate = NULL; |
597 | 605 |
598 if (!CommandLine::ForCurrentProcess()-> | 606 if (!CommandLine::ForCurrentProcess()-> |
599 HasSwitch(switches::kSilentDebuggerExtensionAPI)) { | 607 HasSwitch(switches::kSilentDebuggerExtensionAPI)) { |
600 // Do not attach to the target if for any reason the infobar cannot be shown | 608 // Do not attach to the target if for any reason the infobar cannot be shown |
601 // for this WebContents instance. | 609 // for this WebContents instance. |
602 infobar_delegate = ExtensionDevToolsInfoBarDelegate::Create( | 610 infobar_delegate = ExtensionDevToolsInfoBarDelegate::Create( |
603 contents_, GetExtension()->name()); | 611 agent_host_->GetRenderViewHost(), GetExtension()->name()); |
604 if (!infobar_delegate) { | 612 if (!infobar_delegate) { |
605 error_ = ErrorUtils::FormatErrorMessage( | 613 error_ = ErrorUtils::FormatErrorMessage( |
606 keys::kSilentDebuggingRequired, | 614 keys::kSilentDebuggingRequired, |
607 switches::kSilentDebuggerExtensionAPI); | 615 switches::kSilentDebuggerExtensionAPI); |
608 return false; | 616 return false; |
609 } | 617 } |
610 } | 618 } |
611 | 619 |
612 new ExtensionDevToolsClientHost(contents_, | 620 new ExtensionDevToolsClientHost(profile(), |
| 621 agent_host_, |
613 GetExtension()->id(), | 622 GetExtension()->id(), |
614 GetExtension()->name(), | 623 GetExtension()->name(), |
615 debuggee_, | 624 debuggee_, |
616 infobar_delegate); | 625 infobar_delegate); |
617 SendResponse(true); | 626 SendResponse(true); |
618 return true; | 627 return true; |
619 } | 628 } |
620 | 629 |
621 DebuggerDetachFunction::DebuggerDetachFunction() {} | 630 DebuggerDetachFunction::DebuggerDetachFunction() {} |
622 | 631 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 | 677 |
669 results_ = SendCommand::Results::Create(result); | 678 results_ = SendCommand::Results::Create(result); |
670 SendResponse(true); | 679 SendResponse(true); |
671 } | 680 } |
672 | 681 |
673 DebuggerGetTargetsFunction::DebuggerGetTargetsFunction() {} | 682 DebuggerGetTargetsFunction::DebuggerGetTargetsFunction() {} |
674 | 683 |
675 DebuggerGetTargetsFunction::~DebuggerGetTargetsFunction() {} | 684 DebuggerGetTargetsFunction::~DebuggerGetTargetsFunction() {} |
676 | 685 |
677 bool DebuggerGetTargetsFunction::RunImpl() { | 686 bool DebuggerGetTargetsFunction::RunImpl() { |
678 base::ListValue* results_list = new ListValue(); | 687 base::ListValue* results_list = new base::ListValue(); |
679 | 688 |
680 std::vector<RenderViewHost*> rvh_list = | 689 std::vector<RenderViewHost*> rvh_list = |
681 DevToolsAgentHost::GetValidRenderViewHosts(); | 690 DevToolsAgentHost::GetValidRenderViewHosts(); |
682 for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin(); | 691 for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin(); |
683 it != rvh_list.end(); ++it) { | 692 it != rvh_list.end(); ++it) { |
684 base::Value* value = SerializePageInfo(*it); | 693 base::Value* value = SerializePageInfo(*it); |
685 if (value) | 694 if (value) |
686 results_list->Append(value); | 695 results_list->Append(value); |
687 } | 696 } |
688 | 697 |
689 SetResult(results_list); | 698 BrowserThread::PostTaskAndReply( |
690 SendResponse(true); | 699 BrowserThread::IO, |
| 700 FROM_HERE, |
| 701 base::Bind(&DebuggerGetTargetsFunction::CollectWorkerInfo, |
| 702 this, |
| 703 results_list), |
| 704 base::Bind(&DebuggerGetTargetsFunction::SendTargetList, |
| 705 this, |
| 706 results_list)); |
691 return true; | 707 return true; |
692 } | 708 } |
| 709 |
| 710 void DebuggerGetTargetsFunction::CollectWorkerInfo(base::ListValue* list) { |
| 711 std::vector<WorkerService::WorkerInfo> worker_info = |
| 712 WorkerService::GetInstance()->GetWorkers(); |
| 713 |
| 714 for (size_t i = 0; i < worker_info.size(); ++i) |
| 715 list->Append(SerializeWorkerInfo(worker_info[i])); |
| 716 } |
| 717 |
| 718 void DebuggerGetTargetsFunction::SendTargetList(base::ListValue* list) { |
| 719 SetResult(list); |
| 720 SendResponse(true); |
| 721 } |
OLD | NEW |