Index: chrome/browser/extensions/api/debugger/debugger_api.cc |
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc |
index e01e3a911d21adfddb20e787245d5a795276aa60..bfa4cdcbcef91a257235281b417bf933cbe88e9a 100644 |
--- a/chrome/browser/extensions/api/debugger/debugger_api.cc |
+++ b/chrome/browser/extensions/api/debugger/debugger_api.cc |
@@ -151,6 +151,85 @@ bool ExtensionDevToolsInfoBarDelegate::Cancel() { |
return false; |
} |
+// ExtensionDevToolsInfoBar --------------------------------------------------- |
+ |
+class ExtensionDevToolsInfoBar; |
+using ExtensionInfoBars = |
+ std::map<std::string, ExtensionDevToolsInfoBar*>; |
+base::LazyInstance<ExtensionInfoBars>::Leaky g_extension_info_bars = |
+ LAZY_INSTANCE_INITIALIZER; |
+ |
+class ExtensionDevToolsInfoBar { |
+ public: |
+ static ExtensionDevToolsInfoBar* Create( |
+ const std::string& extension_id, |
+ const std::string& extension_name, |
+ ExtensionDevToolsClientHost* client_host, |
+ const base::Closure& dismissed_callback); |
+ void Remove(ExtensionDevToolsClientHost* client_host); |
+ |
+ private: |
+ ExtensionDevToolsInfoBar(const std::string& extension_id, |
+ const std::string& extension_name); |
+ ~ExtensionDevToolsInfoBar(); |
+ void InfoBarDismissed(); |
+ |
+ std::string extension_id_; |
+ std::map<ExtensionDevToolsClientHost*, base::Closure> callbacks_; |
+ base::WeakPtr<GlobalConfirmInfoBar> infobar_; |
+}; |
+ |
+// static |
+ExtensionDevToolsInfoBar* ExtensionDevToolsInfoBar::Create( |
+ const std::string& extension_id, |
+ const std::string& extension_name, |
+ ExtensionDevToolsClientHost* client_host, |
+ const base::Closure& dismissed_callback) { |
+ ExtensionInfoBars::iterator it = |
+ g_extension_info_bars.Get().find(extension_id); |
+ ExtensionDevToolsInfoBar* infobar = nullptr; |
+ if (it != g_extension_info_bars.Get().end()) |
+ infobar = it->second; |
+ else |
+ infobar = new ExtensionDevToolsInfoBar(extension_id, extension_name); |
+ infobar->callbacks_[client_host] = dismissed_callback; |
+ return infobar; |
+} |
+ |
+ExtensionDevToolsInfoBar::ExtensionDevToolsInfoBar( |
+ const std::string& extension_id, |
+ const std::string& extension_name) |
+ : extension_id_(extension_id) { |
+ g_extension_info_bars.Get()[extension_id] = this; |
+ |
+ // This class closes the |infobar_|, so it's safe to pass Unretained(this). |
+ scoped_ptr<ExtensionDevToolsInfoBarDelegate> delegate( |
+ new ExtensionDevToolsInfoBarDelegate( |
+ base::Bind(&ExtensionDevToolsInfoBar::InfoBarDismissed, |
+ base::Unretained(this)), |
+ extension_name)); |
+ infobar_ = GlobalConfirmInfoBar::Show(delegate.Pass()); |
+} |
+ |
+ExtensionDevToolsInfoBar::~ExtensionDevToolsInfoBar() { |
+ g_extension_info_bars.Get().erase(extension_id_); |
+ if (infobar_) |
+ infobar_->Close(); |
+} |
+ |
+void ExtensionDevToolsInfoBar::Remove( |
+ ExtensionDevToolsClientHost* client_host) { |
+ callbacks_.erase(client_host); |
+ if (!callbacks_.size()) |
+ delete this; |
+} |
+ |
+void ExtensionDevToolsInfoBar::InfoBarDismissed() { |
+ std::map<ExtensionDevToolsClientHost*, base::Closure> copy = callbacks_; |
+ for (const auto& pair: copy) |
+ pair.second.Run(); |
+} |
+ |
} // namespace |
// ExtensionDevToolsClientHost ------------------------------------------------ |
@@ -210,7 +289,7 @@ class ExtensionDevToolsClientHost : public content::DevToolsAgentHostClient, |
content::NotificationRegistrar registrar_; |
int last_request_id_; |
PendingRequests pending_requests_; |
- base::WeakPtr<GlobalConfirmInfoBar> infobar_; |
+ ExtensionDevToolsInfoBar* infobar_; |
api::debugger::DetachReason detach_reason_; |
// Listen to extension unloaded notification. |
@@ -232,6 +311,7 @@ ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( |
agent_host_(agent_host), |
extension_id_(extension_id), |
last_request_id_(0), |
+ infobar_(nullptr), |
detach_reason_(api::debugger::DETACH_REASON_TARGET_CLOSED), |
extension_registry_observer_(this) { |
CopyDebuggee(&debuggee_, debuggee); |
@@ -253,19 +333,16 @@ ExtensionDevToolsClientHost::ExtensionDevToolsClientHost( |
if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
::switches::kSilentDebuggerExtensionAPI)) { |
- // This class closes the |infobar_|, so it's safe to pass Unretained(this). |
- scoped_ptr<ExtensionDevToolsInfoBarDelegate> delegate( |
- new ExtensionDevToolsInfoBarDelegate( |
- base::Bind(&ExtensionDevToolsClientHost::InfoBarDismissed, |
- base::Unretained(this)), |
- extension_name)); |
- infobar_ = GlobalConfirmInfoBar::Show(delegate.Pass()); |
+ infobar_ = ExtensionDevToolsInfoBar::Create( |
+ extension_id, extension_name, this, |
+ base::Bind(&ExtensionDevToolsClientHost::InfoBarDismissed, |
+ base::Unretained(this))); |
} |
} |
ExtensionDevToolsClientHost::~ExtensionDevToolsClientHost() { |
if (infobar_) |
- infobar_->Close(); |
+ infobar_->Remove(this); |
g_attached_client_hosts.Get().erase(this); |
} |