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

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

Issue 10947037: DevTools: provide the debugger detach reason in chrome.debugger.onDetach extension API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Lint Created 8 years, 3 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 using content::WebContents; 48 using content::WebContents;
49 using extensions::api::debugger::Debuggee; 49 using extensions::api::debugger::Debuggee;
50 50
51 namespace keys = debugger_api_constants; 51 namespace keys = debugger_api_constants;
52 namespace Attach = extensions::api::debugger::Attach; 52 namespace Attach = extensions::api::debugger::Attach;
53 namespace Detach = extensions::api::debugger::Detach; 53 namespace Detach = extensions::api::debugger::Detach;
54 namespace OnDetach = extensions::api::debugger::OnDetach; 54 namespace OnDetach = extensions::api::debugger::OnDetach;
55 namespace OnEvent = extensions::api::debugger::OnEvent; 55 namespace OnEvent = extensions::api::debugger::OnEvent;
56 namespace SendCommand = extensions::api::debugger::SendCommand; 56 namespace SendCommand = extensions::api::debugger::SendCommand;
57 57
58 class ExtensionDevToolsClientHost;
59
58 class ExtensionDevToolsInfoBarDelegate : public ConfirmInfoBarDelegate { 60 class ExtensionDevToolsInfoBarDelegate : public ConfirmInfoBarDelegate {
59 public: 61 public:
60 ExtensionDevToolsInfoBarDelegate( 62 ExtensionDevToolsInfoBarDelegate(
61 InfoBarTabHelper* infobar_helper, 63 InfoBarTabHelper* infobar_helper,
62 const std::string& client_name); 64 const std::string& client_name,
65 ExtensionDevToolsClientHost* client_host);
63 virtual ~ExtensionDevToolsInfoBarDelegate(); 66 virtual ~ExtensionDevToolsInfoBarDelegate();
64 67
68 void DiscardClientHost();
Matt Perry 2012/09/19 19:14:13 Please comment this method.
69
65 private: 70 private:
66 // ConfirmInfoBarDelegate: 71 // ConfirmInfoBarDelegate:
67 virtual bool ShouldExpire( 72 virtual bool ShouldExpire(
68 const content::LoadCommittedDetails& details) const OVERRIDE; 73 const content::LoadCommittedDetails& details) const OVERRIDE;
69 virtual int GetButtons() const OVERRIDE; 74 virtual int GetButtons() const OVERRIDE;
70 virtual Type GetInfoBarType() const OVERRIDE; 75 virtual Type GetInfoBarType() const OVERRIDE;
71 virtual string16 GetMessageText() const OVERRIDE; 76 virtual string16 GetMessageText() const OVERRIDE;
77 virtual void InfoBarDismissed() OVERRIDE;
78 virtual bool Cancel() OVERRIDE;
72 79
73 std::string client_name_; 80 std::string client_name_;
81 ExtensionDevToolsClientHost* client_host_;
74 DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsInfoBarDelegate); 82 DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsInfoBarDelegate);
75 }; 83 };
76 84
77 class ExtensionDevToolsClientHost : public DevToolsClientHost, 85 class ExtensionDevToolsClientHost : public DevToolsClientHost,
78 public content::NotificationObserver { 86 public content::NotificationObserver {
79 public: 87 public:
80 ExtensionDevToolsClientHost(WebContents* web_contents, 88 ExtensionDevToolsClientHost(WebContents* web_contents,
81 const std::string& extension_id, 89 const std::string& extension_id,
82 const std::string& extension_name, 90 const std::string& extension_name,
83 int tab_id); 91 int tab_id);
84 92
85 ~ExtensionDevToolsClientHost(); 93 ~ExtensionDevToolsClientHost();
86 94
87 bool MatchesContentsAndExtensionId(WebContents* web_contents, 95 bool MatchesContentsAndExtensionId(WebContents* web_contents,
88 const std::string& extension_id); 96 const std::string& extension_id);
89 void Close(); 97 void Close();
90 void SendMessageToBackend(SendCommandDebuggerFunction* function, 98 void SendMessageToBackend(SendCommandDebuggerFunction* function,
91 const std::string& method, 99 const std::string& method,
92 SendCommand::Params::CommandParams* command_params); 100 SendCommand::Params::CommandParams* command_params);
101 void MarkAsReplaced();
102 void MarkAsDismissed();
Matt Perry 2012/09/19 19:14:13 All the methods above could use comments.
93 103
94 // DevToolsClientHost interface 104 // DevToolsClientHost interface
95 virtual void InspectedContentsClosing() OVERRIDE; 105 virtual void InspectedContentsClosing() OVERRIDE;
96 virtual void DispatchOnInspectorFrontend(const std::string& message) OVERRIDE; 106 virtual void DispatchOnInspectorFrontend(const std::string& message) OVERRIDE;
97 virtual void ContentsReplaced(WebContents* web_contents) OVERRIDE; 107 virtual void ContentsReplaced(WebContents* web_contents) OVERRIDE;
98 virtual void FrameNavigating(const std::string& url) OVERRIDE {} 108 virtual void FrameNavigating(const std::string& url) OVERRIDE {}
99 109
100 private: 110 private:
101 void SendDetachedEvent(); 111 void SendDetachedEvent();
102 112
103 // content::NotificationObserver implementation. 113 // content::NotificationObserver implementation.
104 virtual void Observe(int type, 114 virtual void Observe(int type,
105 const content::NotificationSource& source, 115 const content::NotificationSource& source,
106 const content::NotificationDetails& details); 116 const content::NotificationDetails& details);
107 117
108 WebContents* web_contents_; 118 WebContents* web_contents_;
109 std::string extension_id_; 119 std::string extension_id_;
110 int tab_id_; 120 int tab_id_;
111 content::NotificationRegistrar registrar_; 121 content::NotificationRegistrar registrar_;
112 int last_request_id_; 122 int last_request_id_;
113 typedef std::map<int, scoped_refptr<SendCommandDebuggerFunction> > 123 typedef std::map<int, scoped_refptr<SendCommandDebuggerFunction> >
114 PendingRequests; 124 PendingRequests;
115 PendingRequests pending_requests_; 125 PendingRequests pending_requests_;
116 ExtensionDevToolsInfoBarDelegate* infobar_delegate_; 126 ExtensionDevToolsInfoBarDelegate* infobar_delegate_;
127 OnDetach::Reason detach_reason_;
117 128
118 DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsClientHost); 129 DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsClientHost);
119 }; 130 };
120 131
121 namespace { 132 namespace {
122 133
123 class AttachedClientHosts { 134 class AttachedClientHosts {
124 public: 135 public:
125 AttachedClientHosts() {} 136 AttachedClientHosts() {}
126 137
127 // Returns the singleton instance of this class 138 // Returns the singleton instance of this class
128 static AttachedClientHosts* GetInstance() { 139 static AttachedClientHosts* GetInstance() {
129 return Singleton<AttachedClientHosts>::get(); 140 return Singleton<AttachedClientHosts>::get();
130 } 141 }
131 142
132 void Add(ExtensionDevToolsClientHost* client_host) { 143 void Add(ExtensionDevToolsClientHost* client_host) {
133 client_hosts_.insert(client_host); 144 client_hosts_.insert(client_host);
134 } 145 }
135 146
136 void Remove(ExtensionDevToolsClientHost* client_host) { 147 void Remove(ExtensionDevToolsClientHost* client_host) {
137 client_hosts_.erase(client_host); 148 client_hosts_.erase(client_host);
138 } 149 }
139 150
151 ExtensionDevToolsClientHost* AsExtensionDevToolsClientHost(
152 DevToolsClientHost* client_host) {
153 for (std::set<DevToolsClientHost*>::iterator it = client_hosts_.begin();
154 it != client_hosts_.end(); ++it) {
155 if (client_host == *it)
156 return static_cast<ExtensionDevToolsClientHost*>(*it);
157 }
158 return NULL;
159 }
160
140 ExtensionDevToolsClientHost* Lookup(WebContents* contents) { 161 ExtensionDevToolsClientHost* Lookup(WebContents* contents) {
141 for (std::set<DevToolsClientHost*>::iterator it = client_hosts_.begin(); 162 for (std::set<DevToolsClientHost*>::iterator it = client_hosts_.begin();
142 it != client_hosts_.end(); ++it) { 163 it != client_hosts_.end(); ++it) {
143 DevToolsAgentHost* agent_host = 164 DevToolsAgentHost* agent_host =
144 DevToolsManager::GetInstance()->GetDevToolsAgentHostFor(*it); 165 DevToolsManager::GetInstance()->GetDevToolsAgentHostFor(*it);
145 if (!agent_host) 166 if (!agent_host)
146 continue; 167 continue;
147 content::RenderViewHost* rvh = 168 content::RenderViewHost* rvh =
148 DevToolsAgentHostRegistry::GetRenderViewHost(agent_host); 169 DevToolsAgentHostRegistry::GetRenderViewHost(agent_host);
149 if (rvh && WebContents::FromRenderViewHost(rvh) == contents) 170 if (rvh && WebContents::FromRenderViewHost(rvh) == contents)
(...skipping 10 matching lines...) Expand all
160 181
161 ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( 182 ExtensionDevToolsClientHost::ExtensionDevToolsClientHost(
162 WebContents* web_contents, 183 WebContents* web_contents,
163 const std::string& extension_id, 184 const std::string& extension_id,
164 const std::string& extension_name, 185 const std::string& extension_name,
165 int tab_id) 186 int tab_id)
166 : web_contents_(web_contents), 187 : web_contents_(web_contents),
167 extension_id_(extension_id), 188 extension_id_(extension_id),
168 tab_id_(tab_id), 189 tab_id_(tab_id),
169 last_request_id_(0), 190 last_request_id_(0),
170 infobar_delegate_(NULL) { 191 infobar_delegate_(NULL),
192 detach_reason_(OnDetach::REASON_TARGET_CLOSED) {
171 AttachedClientHosts::GetInstance()->Add(this); 193 AttachedClientHosts::GetInstance()->Add(this);
172 194
173 // Detach from debugger when extension unloads. 195 // Detach from debugger when extension unloads.
174 Profile* profile = 196 Profile* profile =
175 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); 197 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
176 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 198 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
177 content::Source<Profile>(profile)); 199 content::Source<Profile>(profile));
178 200
179 // Attach to debugger and tell it we are ready. 201 // Attach to debugger and tell it we are ready.
180 DevToolsAgentHost* agent = DevToolsAgentHostRegistry::GetDevToolsAgentHost( 202 DevToolsAgentHost* agent = DevToolsAgentHostRegistry::GetDevToolsAgentHost(
181 web_contents_->GetRenderViewHost()); 203 web_contents_->GetRenderViewHost());
182 DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(agent, this); 204 DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(agent, this);
183 205
184 InfoBarTabHelper* infobar_helper = 206 InfoBarTabHelper* infobar_helper =
185 TabContents::FromWebContents(web_contents_)->infobar_tab_helper(); 207 TabContents::FromWebContents(web_contents_)->infobar_tab_helper();
186 infobar_delegate_ = 208 infobar_delegate_ = new ExtensionDevToolsInfoBarDelegate(infobar_helper,
187 new ExtensionDevToolsInfoBarDelegate(infobar_helper, extension_name); 209 extension_name,
210 this);
188 if (infobar_helper->AddInfoBar(infobar_delegate_)) { 211 if (infobar_helper->AddInfoBar(infobar_delegate_)) {
189 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 212 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
190 content::Source<InfoBarTabHelper>(infobar_helper)); 213 content::Source<InfoBarTabHelper>(infobar_helper));
191 } else { 214 } else {
192 infobar_delegate_ = NULL; 215 infobar_delegate_ = NULL;
193 } 216 }
194 } 217 }
195 218
196 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { 219 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() {
197 // Ensure calling RemoveInfoBar() below won't result in Observe() trying to 220 // Ensure calling RemoveInfoBar() below won't result in Observe() trying to
198 // Close() us. 221 // Close() us.
199 registrar_.RemoveAll(); 222 registrar_.RemoveAll();
200 223
201 if (infobar_delegate_) { 224 if (infobar_delegate_) {
225 infobar_delegate_->DiscardClientHost();
202 TabContents* tab_contents = TabContents::FromWebContents(web_contents_); 226 TabContents* tab_contents = TabContents::FromWebContents(web_contents_);
203 InfoBarTabHelper* helper = tab_contents->infobar_tab_helper(); 227 InfoBarTabHelper* helper = tab_contents->infobar_tab_helper();
204 if (helper) 228 if (helper)
205 helper->RemoveInfoBar(infobar_delegate_); 229 helper->RemoveInfoBar(infobar_delegate_);
206 } 230 }
207 AttachedClientHosts::GetInstance()->Remove(this); 231 AttachedClientHosts::GetInstance()->Remove(this);
208 } 232 }
209 233
210 bool ExtensionDevToolsClientHost::MatchesContentsAndExtensionId( 234 bool ExtensionDevToolsClientHost::MatchesContentsAndExtensionId(
211 WebContents* web_contents, 235 WebContents* web_contents,
(...skipping 28 matching lines...) Expand all
240 if (command_params) { 264 if (command_params) {
241 protocol_request.Set("params", 265 protocol_request.Set("params",
242 command_params->additional_properties.DeepCopy()); 266 command_params->additional_properties.DeepCopy());
243 } 267 }
244 268
245 std::string json_args; 269 std::string json_args;
246 base::JSONWriter::Write(&protocol_request, &json_args); 270 base::JSONWriter::Write(&protocol_request, &json_args);
247 DevToolsManager::GetInstance()->DispatchOnInspectorBackend(this, json_args); 271 DevToolsManager::GetInstance()->DispatchOnInspectorBackend(this, json_args);
248 } 272 }
249 273
274 void ExtensionDevToolsClientHost::MarkAsReplaced() {
275 detach_reason_ = OnDetach::REASON_REPLACED_WITH_DEVTOOLS;
276 }
277
278 void ExtensionDevToolsClientHost::MarkAsDismissed() {
279 detach_reason_ = OnDetach::REASON_CANCELED_BY_USER;
280 }
281
250 void ExtensionDevToolsClientHost::SendDetachedEvent() { 282 void ExtensionDevToolsClientHost::SendDetachedEvent() {
251 Profile* profile = 283 Profile* profile =
252 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); 284 Profile::FromBrowserContext(web_contents_->GetBrowserContext());
253 if (profile != NULL && profile->GetExtensionEventRouter()) { 285 if (profile != NULL && profile->GetExtensionEventRouter()) {
254 Debuggee debuggee; 286 Debuggee debuggee;
255 debuggee.tab_id = tab_id_; 287 debuggee.tab_id = tab_id_;
256 288 scoped_ptr<base::ListValue> args(OnDetach::Create(debuggee,
257 scoped_ptr<base::ListValue> args(OnDetach::Create(debuggee)); 289 detach_reason_));
258 profile->GetExtensionEventRouter()->DispatchEventToExtension( 290 profile->GetExtensionEventRouter()->DispatchEventToExtension(
259 extension_id_, keys::kOnDetach, args.Pass(), profile, GURL()); 291 extension_id_, keys::kOnDetach, args.Pass(), profile, GURL());
260 } 292 }
261 } 293 }
262 294
263 void ExtensionDevToolsClientHost::Observe( 295 void ExtensionDevToolsClientHost::Observe(
264 int type, 296 int type,
265 const content::NotificationSource& source, 297 const content::NotificationSource& source,
266 const content::NotificationDetails& details) { 298 const content::NotificationDetails& details) {
267 if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { 299 if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 if (!function) 347 if (!function)
316 return; 348 return;
317 349
318 function->SendResponseBody(dictionary); 350 function->SendResponseBody(dictionary);
319 pending_requests_.erase(id); 351 pending_requests_.erase(id);
320 } 352 }
321 } 353 }
322 354
323 ExtensionDevToolsInfoBarDelegate::ExtensionDevToolsInfoBarDelegate( 355 ExtensionDevToolsInfoBarDelegate::ExtensionDevToolsInfoBarDelegate(
324 InfoBarTabHelper* infobar_helper, 356 InfoBarTabHelper* infobar_helper,
325 const std::string& client_name) 357 const std::string& client_name,
358 ExtensionDevToolsClientHost* client_host)
326 : ConfirmInfoBarDelegate(infobar_helper), 359 : ConfirmInfoBarDelegate(infobar_helper),
327 client_name_(client_name) { 360 client_name_(client_name),
361 client_host_(client_host) {
328 } 362 }
329 363
330 ExtensionDevToolsInfoBarDelegate::~ExtensionDevToolsInfoBarDelegate() { 364 ExtensionDevToolsInfoBarDelegate::~ExtensionDevToolsInfoBarDelegate() {
331 } 365 }
332 366
367 void ExtensionDevToolsInfoBarDelegate::DiscardClientHost() {
368 client_host_ = NULL;
369 }
370
333 bool ExtensionDevToolsInfoBarDelegate::ShouldExpire( 371 bool ExtensionDevToolsInfoBarDelegate::ShouldExpire(
334 const content::LoadCommittedDetails& details) const { 372 const content::LoadCommittedDetails& details) const {
335 return false; 373 return false;
336 } 374 }
337 375
338 int ExtensionDevToolsInfoBarDelegate::GetButtons() const { 376 int ExtensionDevToolsInfoBarDelegate::GetButtons() const {
339 return BUTTON_CANCEL; 377 return BUTTON_CANCEL;
340 } 378 }
341 379
342 InfoBarDelegate::Type ExtensionDevToolsInfoBarDelegate::GetInfoBarType() const { 380 InfoBarDelegate::Type ExtensionDevToolsInfoBarDelegate::GetInfoBarType() const {
343 return WARNING_TYPE; 381 return WARNING_TYPE;
344 } 382 }
345 383
346 string16 ExtensionDevToolsInfoBarDelegate::GetMessageText() const { 384 string16 ExtensionDevToolsInfoBarDelegate::GetMessageText() const {
347 return l10n_util::GetStringFUTF16(IDS_DEV_TOOLS_INFOBAR_LABEL, 385 return l10n_util::GetStringFUTF16(IDS_DEV_TOOLS_INFOBAR_LABEL,
348 UTF8ToUTF16(client_name_)); 386 UTF8ToUTF16(client_name_));
349 } 387 }
350 388
389 void ExtensionDevToolsInfoBarDelegate::InfoBarDismissed() {
390 if (client_host_)
391 client_host_->MarkAsDismissed();
392 }
393
394 bool ExtensionDevToolsInfoBarDelegate::Cancel() {
395 if (client_host_)
396 client_host_->MarkAsDismissed();
397 return true;
398 }
399
351 DebuggerFunction::DebuggerFunction() 400 DebuggerFunction::DebuggerFunction()
352 : contents_(0), 401 : contents_(0),
353 tab_id_(0), 402 tab_id_(0),
354 client_host_(0) { 403 client_host_(0) {
355 } 404 }
356 405
357 bool DebuggerFunction::InitTabContents() { 406 bool DebuggerFunction::InitTabContents() {
358 // Find the TabContents that contains this tab id. 407 // Find the TabContents that contains this tab id.
359 contents_ = NULL; 408 contents_ = NULL;
360 TabContents* tab_contents = NULL; 409 TabContents* tab_contents = NULL;
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 } 530 }
482 531
483 DictionaryValue* result_body; 532 DictionaryValue* result_body;
484 SendCommand::Results::Result result; 533 SendCommand::Results::Result result;
485 if (response->GetDictionary("result", &result_body)) 534 if (response->GetDictionary("result", &result_body))
486 result.additional_properties.Swap(result_body); 535 result.additional_properties.Swap(result_body);
487 536
488 results_ = SendCommand::Results::Create(result); 537 results_ = SendCommand::Results::Create(result);
489 SendResponse(true); 538 SendResponse(true);
490 } 539 }
540
541 // static
542 void DebuggerApi::MarkDevToolsClientHostAsReplaced(
543 DevToolsClientHost* client_host) {
544 ExtensionDevToolsClientHost* host = AttachedClientHosts::GetInstance()->
545 AsExtensionDevToolsClientHost(client_host);
546 if (host)
547 host->MarkAsReplaced();
548 }
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