Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(808)

Side by Side Diff: chrome/browser/extensions/api/debugger/debugger_api.cc

Issue 13517002: Support shared workers as debug targets for chrome.debugger API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moved flaky tests to a separate patch Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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", &params_value)) 419 if (dictionary->GetDictionary("params", &params_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
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
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 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/debugger/debugger_api.h ('k') | chrome/common/extensions/api/debugger.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698