| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/extension_debugger_api.h" | 7 #include "chrome/browser/extensions/extension_debugger_api.h" |
| 8 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "chrome/browser/profiles/profile.h" | 22 #include "chrome/browser/profiles/profile.h" |
| 23 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h" | 23 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h" |
| 24 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 24 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
| 25 #include "chrome/browser/ui/webui/chrome_web_ui_factory.h" | 25 #include "chrome/browser/ui/webui/chrome_web_ui_factory.h" |
| 26 #include "chrome/common/chrome_notification_types.h" | 26 #include "chrome/common/chrome_notification_types.h" |
| 27 #include "chrome/common/extensions/extension.h" | 27 #include "chrome/common/extensions/extension.h" |
| 28 #include "chrome/common/extensions/extension_error_utils.h" | 28 #include "chrome/common/extensions/extension_error_utils.h" |
| 29 #include "content/public/browser/devtools_agent_host_registry.h" | 29 #include "content/public/browser/devtools_agent_host_registry.h" |
| 30 #include "content/public/browser/devtools_client_host.h" | 30 #include "content/public/browser/devtools_client_host.h" |
| 31 #include "content/public/browser/devtools_manager.h" | 31 #include "content/public/browser/devtools_manager.h" |
| 32 #include "content/browser/tab_contents/tab_contents.h" | |
| 33 #include "content/public/browser/notification_service.h" | 32 #include "content/public/browser/notification_service.h" |
| 34 #include "content/public/browser/notification_source.h" | 33 #include "content/public/browser/notification_source.h" |
| 34 #include "content/public/browser/web_contents.h" |
| 35 #include "grit/generated_resources.h" | 35 #include "grit/generated_resources.h" |
| 36 #include "webkit/glue/webkit_glue.h" | 36 #include "webkit/glue/webkit_glue.h" |
| 37 #include "ui/base/l10n/l10n_util.h" | 37 #include "ui/base/l10n/l10n_util.h" |
| 38 | 38 |
| 39 using content::DevToolsAgentHost; | 39 using content::DevToolsAgentHost; |
| 40 using content::DevToolsAgentHostRegistry; | 40 using content::DevToolsAgentHostRegistry; |
| 41 using content::DevToolsClientHost; | 41 using content::DevToolsClientHost; |
| 42 using content::DevToolsManager; | 42 using content::DevToolsManager; |
| 43 | 43 |
| 44 namespace keys = extension_debugger_api_constants; | 44 namespace keys = extension_debugger_api_constants; |
| 45 | 45 |
| 46 using content::WebContents; |
| 47 |
| 46 class ExtensionDevToolsInfoBarDelegate : public ConfirmInfoBarDelegate { | 48 class ExtensionDevToolsInfoBarDelegate : public ConfirmInfoBarDelegate { |
| 47 public: | 49 public: |
| 48 ExtensionDevToolsInfoBarDelegate( | 50 ExtensionDevToolsInfoBarDelegate( |
| 49 InfoBarTabHelper* infobar_helper, | 51 InfoBarTabHelper* infobar_helper, |
| 50 const std::string& client_name, | 52 const std::string& client_name, |
| 51 ExtensionDevToolsClientHost* client_host); | 53 ExtensionDevToolsClientHost* client_host); |
| 52 virtual ~ExtensionDevToolsInfoBarDelegate(); | 54 virtual ~ExtensionDevToolsInfoBarDelegate(); |
| 53 | 55 |
| 54 void ClearClientHost(); | 56 void ClearClientHost(); |
| 55 | 57 |
| 56 private: | 58 private: |
| 57 // ConfirmInfoBarDelegate: | 59 // ConfirmInfoBarDelegate: |
| 58 virtual bool ShouldExpire( | 60 virtual bool ShouldExpire( |
| 59 const content::LoadCommittedDetails& details) const OVERRIDE; | 61 const content::LoadCommittedDetails& details) const OVERRIDE; |
| 60 virtual int GetButtons() const OVERRIDE; | 62 virtual int GetButtons() const OVERRIDE; |
| 61 virtual Type GetInfoBarType() const OVERRIDE; | 63 virtual Type GetInfoBarType() const OVERRIDE; |
| 62 virtual string16 GetMessageText() const OVERRIDE; | 64 virtual string16 GetMessageText() const OVERRIDE; |
| 63 | 65 |
| 64 std::string client_name_; | 66 std::string client_name_; |
| 65 ExtensionDevToolsClientHost* client_host_; | 67 ExtensionDevToolsClientHost* client_host_; |
| 66 DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsInfoBarDelegate); | 68 DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsInfoBarDelegate); |
| 67 }; | 69 }; |
| 68 | 70 |
| 69 class ExtensionDevToolsClientHost : public DevToolsClientHost, | 71 class ExtensionDevToolsClientHost : public DevToolsClientHost, |
| 70 public content::NotificationObserver { | 72 public content::NotificationObserver { |
| 71 public: | 73 public: |
| 72 ExtensionDevToolsClientHost(TabContents* tab_contents, | 74 ExtensionDevToolsClientHost(WebContents* web_contents, |
| 73 const std::string& extension_id, | 75 const std::string& extension_id, |
| 74 const std::string& extension_name, | 76 const std::string& extension_name, |
| 75 int tab_id); | 77 int tab_id); |
| 76 | 78 |
| 77 ~ExtensionDevToolsClientHost(); | 79 ~ExtensionDevToolsClientHost(); |
| 78 | 80 |
| 79 bool MatchesContentsAndExtensionId(TabContents* tab_contents, | 81 bool MatchesContentsAndExtensionId(WebContents* web_contents, |
| 80 const std::string& extension_id); | 82 const std::string& extension_id); |
| 81 void Close(); | 83 void Close(); |
| 82 void InfoBarDestroyed(); | 84 void InfoBarDestroyed(); |
| 83 void SendMessageToBackend(SendCommandDebuggerFunction* function, | 85 void SendMessageToBackend(SendCommandDebuggerFunction* function, |
| 84 const std::string& method, | 86 const std::string& method, |
| 85 Value* params); | 87 Value* params); |
| 86 | 88 |
| 87 // DevToolsClientHost interface | 89 // DevToolsClientHost interface |
| 88 virtual void InspectedTabClosing(); | 90 virtual void InspectedTabClosing(); |
| 89 virtual void DispatchOnInspectorFrontend(const std::string& message); | 91 virtual void DispatchOnInspectorFrontend(const std::string& message); |
| 90 virtual void TabReplaced(TabContents* tab_contents); | 92 virtual void TabReplaced(WebContents* web_contents); |
| 91 virtual void FrameNavigating(const std::string& url) {} | 93 virtual void FrameNavigating(const std::string& url) {} |
| 92 | 94 |
| 93 private: | 95 private: |
| 94 void SendDetachedEvent(); | 96 void SendDetachedEvent(); |
| 95 | 97 |
| 96 // content::NotificationObserver implementation. | 98 // content::NotificationObserver implementation. |
| 97 virtual void Observe(int type, | 99 virtual void Observe(int type, |
| 98 const content::NotificationSource& source, | 100 const content::NotificationSource& source, |
| 99 const content::NotificationDetails& details); | 101 const content::NotificationDetails& details); |
| 100 | 102 |
| 101 TabContents* tab_contents_; | 103 WebContents* web_contents_; |
| 102 std::string extension_id_; | 104 std::string extension_id_; |
| 103 int tab_id_; | 105 int tab_id_; |
| 104 content::NotificationRegistrar registrar_; | 106 content::NotificationRegistrar registrar_; |
| 105 int last_request_id_; | 107 int last_request_id_; |
| 106 typedef std::map<int, scoped_refptr<SendCommandDebuggerFunction> > | 108 typedef std::map<int, scoped_refptr<SendCommandDebuggerFunction> > |
| 107 PendingRequests; | 109 PendingRequests; |
| 108 PendingRequests pending_requests_; | 110 PendingRequests pending_requests_; |
| 109 ExtensionDevToolsInfoBarDelegate* infobar_delegate_; | 111 ExtensionDevToolsInfoBarDelegate* infobar_delegate_; |
| 110 | 112 |
| 111 DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsClientHost); | 113 DISALLOW_COPY_AND_ASSIGN(ExtensionDevToolsClientHost); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 return static_cast<ExtensionDevToolsClientHost*>(client_host); | 152 return static_cast<ExtensionDevToolsClientHost*>(client_host); |
| 151 } | 153 } |
| 152 | 154 |
| 153 private: | 155 private: |
| 154 std::set<DevToolsClientHost*> client_hosts_; | 156 std::set<DevToolsClientHost*> client_hosts_; |
| 155 }; | 157 }; |
| 156 | 158 |
| 157 } // namespace | 159 } // namespace |
| 158 | 160 |
| 159 ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( | 161 ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( |
| 160 TabContents* tab_contents, | 162 WebContents* web_contents, |
| 161 const std::string& extension_id, | 163 const std::string& extension_id, |
| 162 const std::string& extension_name, | 164 const std::string& extension_name, |
| 163 int tab_id) | 165 int tab_id) |
| 164 : tab_contents_(tab_contents), | 166 : web_contents_(web_contents), |
| 165 extension_id_(extension_id), | 167 extension_id_(extension_id), |
| 166 tab_id_(tab_id), | 168 tab_id_(tab_id), |
| 167 last_request_id_(0), | 169 last_request_id_(0), |
| 168 infobar_delegate_(NULL) { | 170 infobar_delegate_(NULL) { |
| 169 AttachedClientHosts::GetInstance()->Add(this); | 171 AttachedClientHosts::GetInstance()->Add(this); |
| 170 | 172 |
| 171 // Detach from debugger when extension unloads. | 173 // Detach from debugger when extension unloads. |
| 172 Profile* profile = | 174 Profile* profile = |
| 173 Profile::FromBrowserContext(tab_contents_->GetBrowserContext()); | 175 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); |
| 174 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 176 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
| 175 content::Source<Profile>(profile)); | 177 content::Source<Profile>(profile)); |
| 176 | 178 |
| 177 // Attach to debugger and tell it we are ready. | 179 // Attach to debugger and tell it we are ready. |
| 178 DevToolsAgentHost* agent = DevToolsAgentHostRegistry::GetDevToolsAgentHost( | 180 DevToolsAgentHost* agent = DevToolsAgentHostRegistry::GetDevToolsAgentHost( |
| 179 tab_contents_->GetRenderViewHost()); | 181 web_contents_->GetRenderViewHost()); |
| 180 DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(agent, this); | 182 DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(agent, this); |
| 181 | 183 |
| 182 TabContentsWrapper* wrapper = | 184 TabContentsWrapper* wrapper = |
| 183 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents_); | 185 TabContentsWrapper::GetCurrentWrapperForContents(web_contents_); |
| 184 infobar_delegate_ = new ExtensionDevToolsInfoBarDelegate( | 186 infobar_delegate_ = new ExtensionDevToolsInfoBarDelegate( |
| 185 wrapper->infobar_tab_helper(), extension_name, this); | 187 wrapper->infobar_tab_helper(), extension_name, this); |
| 186 wrapper->infobar_tab_helper()->AddInfoBar(infobar_delegate_); | 188 wrapper->infobar_tab_helper()->AddInfoBar(infobar_delegate_); |
| 187 } | 189 } |
| 188 | 190 |
| 189 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { | 191 ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { |
| 190 if (infobar_delegate_) { | 192 if (infobar_delegate_) { |
| 191 infobar_delegate_->ClearClientHost(); | 193 infobar_delegate_->ClearClientHost(); |
| 192 TabContentsWrapper* wrapper = | 194 TabContentsWrapper* wrapper = |
| 193 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents_); | 195 TabContentsWrapper::GetCurrentWrapperForContents(web_contents_); |
| 194 InfoBarTabHelper* helper = wrapper->infobar_tab_helper(); | 196 InfoBarTabHelper* helper = wrapper->infobar_tab_helper(); |
| 195 if(helper) | 197 if(helper) |
| 196 helper->RemoveInfoBar(infobar_delegate_); | 198 helper->RemoveInfoBar(infobar_delegate_); |
| 197 } | 199 } |
| 198 AttachedClientHosts::GetInstance()->Remove(this); | 200 AttachedClientHosts::GetInstance()->Remove(this); |
| 199 } | 201 } |
| 200 | 202 |
| 201 bool ExtensionDevToolsClientHost::MatchesContentsAndExtensionId( | 203 bool ExtensionDevToolsClientHost::MatchesContentsAndExtensionId( |
| 202 TabContents* tab_contents, | 204 WebContents* web_contents, |
| 203 const std::string& extension_id) { | 205 const std::string& extension_id) { |
| 204 return tab_contents == tab_contents_ && extension_id_ == extension_id; | 206 return web_contents == web_contents_ && extension_id_ == extension_id; |
| 205 } | 207 } |
| 206 | 208 |
| 207 // DevToolsClientHost interface | 209 // DevToolsClientHost interface |
| 208 void ExtensionDevToolsClientHost::InspectedTabClosing() { | 210 void ExtensionDevToolsClientHost::InspectedTabClosing() { |
| 209 SendDetachedEvent(); | 211 SendDetachedEvent(); |
| 210 delete this; | 212 delete this; |
| 211 } | 213 } |
| 212 | 214 |
| 213 void ExtensionDevToolsClientHost::TabReplaced( | 215 void ExtensionDevToolsClientHost::TabReplaced( |
| 214 TabContents* tab_contents) { | 216 WebContents* web_contents) { |
| 215 tab_contents_ = tab_contents; | 217 web_contents_ = web_contents; |
| 216 } | 218 } |
| 217 | 219 |
| 218 void ExtensionDevToolsClientHost::Close() { | 220 void ExtensionDevToolsClientHost::Close() { |
| 219 DevToolsManager::GetInstance()->ClientHostClosing(this); | 221 DevToolsManager::GetInstance()->ClientHostClosing(this); |
| 220 delete this; | 222 delete this; |
| 221 } | 223 } |
| 222 | 224 |
| 223 void ExtensionDevToolsClientHost::InfoBarDestroyed() { | 225 void ExtensionDevToolsClientHost::InfoBarDestroyed() { |
| 224 infobar_delegate_ = NULL; | 226 infobar_delegate_ = NULL; |
| 225 SendDetachedEvent(); | 227 SendDetachedEvent(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 238 if (params) | 240 if (params) |
| 239 protocol_request.Set("params", params->DeepCopy()); | 241 protocol_request.Set("params", params->DeepCopy()); |
| 240 | 242 |
| 241 std::string json_args; | 243 std::string json_args; |
| 242 base::JSONWriter::Write(&protocol_request, false, &json_args); | 244 base::JSONWriter::Write(&protocol_request, false, &json_args); |
| 243 DevToolsManager::GetInstance()->DispatchOnInspectorBackend(this, json_args); | 245 DevToolsManager::GetInstance()->DispatchOnInspectorBackend(this, json_args); |
| 244 } | 246 } |
| 245 | 247 |
| 246 void ExtensionDevToolsClientHost::SendDetachedEvent() { | 248 void ExtensionDevToolsClientHost::SendDetachedEvent() { |
| 247 Profile* profile = | 249 Profile* profile = |
| 248 Profile::FromBrowserContext(tab_contents_->GetBrowserContext()); | 250 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); |
| 249 if (profile != NULL && profile->GetExtensionEventRouter()) { | 251 if (profile != NULL && profile->GetExtensionEventRouter()) { |
| 250 ListValue args; | 252 ListValue args; |
| 251 args.Append(CreateDebuggeeId(tab_id_)); | 253 args.Append(CreateDebuggeeId(tab_id_)); |
| 252 | 254 |
| 253 std::string json_args; | 255 std::string json_args; |
| 254 base::JSONWriter::Write(&args, false, &json_args); | 256 base::JSONWriter::Write(&args, false, &json_args); |
| 255 | 257 |
| 256 profile->GetExtensionEventRouter()->DispatchEventToExtension( | 258 profile->GetExtensionEventRouter()->DispatchEventToExtension( |
| 257 extension_id_, keys::kOnDetach, json_args, profile, GURL()); | 259 extension_id_, keys::kOnDetach, json_args, profile, GURL()); |
| 258 } | 260 } |
| 259 } | 261 } |
| 260 | 262 |
| 261 void ExtensionDevToolsClientHost::Observe( | 263 void ExtensionDevToolsClientHost::Observe( |
| 262 int type, | 264 int type, |
| 263 const content::NotificationSource& source, | 265 const content::NotificationSource& source, |
| 264 const content::NotificationDetails& details) { | 266 const content::NotificationDetails& details) { |
| 265 DCHECK(type == chrome::NOTIFICATION_EXTENSION_UNLOADED); | 267 DCHECK(type == chrome::NOTIFICATION_EXTENSION_UNLOADED); |
| 266 std::string id = | 268 std::string id = |
| 267 content::Details<UnloadedExtensionInfo>(details)->extension->id(); | 269 content::Details<UnloadedExtensionInfo>(details)->extension->id(); |
| 268 if (id == extension_id_) | 270 if (id == extension_id_) |
| 269 Close(); | 271 Close(); |
| 270 } | 272 } |
| 271 | 273 |
| 272 void ExtensionDevToolsClientHost::DispatchOnInspectorFrontend( | 274 void ExtensionDevToolsClientHost::DispatchOnInspectorFrontend( |
| 273 const std::string& message) { | 275 const std::string& message) { |
| 274 Profile* profile = | 276 Profile* profile = |
| 275 Profile::FromBrowserContext(tab_contents_->GetBrowserContext()); | 277 Profile::FromBrowserContext(web_contents_->GetBrowserContext()); |
| 276 if (profile == NULL || !profile->GetExtensionEventRouter()) | 278 if (profile == NULL || !profile->GetExtensionEventRouter()) |
| 277 return; | 279 return; |
| 278 | 280 |
| 279 scoped_ptr<Value> result(base::JSONReader::Read(message, false)); | 281 scoped_ptr<Value> result(base::JSONReader::Read(message, false)); |
| 280 if (!result->IsType(Value::TYPE_DICTIONARY)) | 282 if (!result->IsType(Value::TYPE_DICTIONARY)) |
| 281 return; | 283 return; |
| 282 DictionaryValue* dictionary = static_cast<DictionaryValue*>(result.get()); | 284 DictionaryValue* dictionary = static_cast<DictionaryValue*>(result.get()); |
| 283 | 285 |
| 284 int id; | 286 int id; |
| 285 if (!dictionary->GetInteger("id", &id)) { | 287 if (!dictionary->GetInteger("id", &id)) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 contents_ = NULL; | 364 contents_ = NULL; |
| 363 TabContentsWrapper* wrapper = NULL; | 365 TabContentsWrapper* wrapper = NULL; |
| 364 bool result = ExtensionTabUtil::GetTabById( | 366 bool result = ExtensionTabUtil::GetTabById( |
| 365 tab_id_, profile(), include_incognito(), NULL, NULL, &wrapper, NULL); | 367 tab_id_, profile(), include_incognito(), NULL, NULL, &wrapper, NULL); |
| 366 if (!result || !wrapper) { | 368 if (!result || !wrapper) { |
| 367 error_ = ExtensionErrorUtils::FormatErrorMessage( | 369 error_ = ExtensionErrorUtils::FormatErrorMessage( |
| 368 keys::kNoTabError, | 370 keys::kNoTabError, |
| 369 base::IntToString(tab_id_)); | 371 base::IntToString(tab_id_)); |
| 370 return false; | 372 return false; |
| 371 } | 373 } |
| 372 contents_ = wrapper->tab_contents(); | 374 contents_ = wrapper->web_contents(); |
| 373 | 375 |
| 374 if (ChromeWebUIFactory::GetInstance()->HasWebUIScheme(contents_->GetURL())) { | 376 if (ChromeWebUIFactory::GetInstance()->HasWebUIScheme(contents_->GetURL())) { |
| 375 error_ = ExtensionErrorUtils::FormatErrorMessage( | 377 error_ = ExtensionErrorUtils::FormatErrorMessage( |
| 376 keys::kAttachToWebUIError, | 378 keys::kAttachToWebUIError, |
| 377 contents_->GetURL().scheme()); | 379 contents_->GetURL().scheme()); |
| 378 return false; | 380 return false; |
| 379 } | 381 } |
| 380 | 382 |
| 381 return true; | 383 return true; |
| 382 } | 384 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 return; | 481 return; |
| 480 } | 482 } |
| 481 | 483 |
| 482 Value* result_body; | 484 Value* result_body; |
| 483 if (dictionary->Get("result", &result_body)) | 485 if (dictionary->Get("result", &result_body)) |
| 484 result_.reset(result_body->DeepCopy()); | 486 result_.reset(result_body->DeepCopy()); |
| 485 else | 487 else |
| 486 result_.reset(new DictionaryValue()); | 488 result_.reset(new DictionaryValue()); |
| 487 SendResponse(true); | 489 SendResponse(true); |
| 488 } | 490 } |
| OLD | NEW |