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

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