Commit 798856d7 authored by dgozman's avatar dgozman Committed by Commit bot

[DevTools] One infobar per extension.

BUG=555939

Review URL: https://codereview.chromium.org/1448903004

Cr-Commit-Position: refs/heads/master@{#360492}
parent c661e6bb
......@@ -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);
}
......
......@@ -193,6 +193,8 @@ IN_PROC_BROWSER_TEST_F(DebuggerApiTest, InfoBar) {
new Browser(Browser::CreateParams(profile(), chrome::GetActiveDesktop()));
AddBlankTabAndShow(another_browser);
AddBlankTabAndShow(another_browser);
int tab_id2 = SessionTabHelper::IdForTab(
another_browser->tab_strip_model()->GetActiveWebContents());
InfoBarService* service1 = InfoBarService::FromWebContents(
browser()->tab_strip_model()->GetActiveWebContents());
......@@ -212,6 +214,27 @@ IN_PROC_BROWSER_TEST_F(DebuggerApiTest, InfoBar) {
EXPECT_EQ(1u, service2->infobar_count());
EXPECT_EQ(1u, service3->infobar_count());
// Second attach should not create infobars.
attach_function = new DebuggerAttachFunction();
attach_function->set_extension(extension());
ASSERT_TRUE(
RunFunction(attach_function.get(),
base::StringPrintf("[{\"tabId\": %d}, \"1.1\"]", tab_id2),
browser(), extension_function_test_utils::NONE));
EXPECT_EQ(1u, service1->infobar_count());
EXPECT_EQ(1u, service2->infobar_count());
EXPECT_EQ(1u, service3->infobar_count());
// Detach from one of the tabs should not remove infobars.
detach_function = new DebuggerDetachFunction();
detach_function->set_extension(extension());
ASSERT_TRUE(RunFunction(detach_function.get(),
base::StringPrintf("[{\"tabId\": %d}]", tab_id2),
browser(), extension_function_test_utils::NONE));
EXPECT_EQ(1u, service1->infobar_count());
EXPECT_EQ(1u, service2->infobar_count());
EXPECT_EQ(1u, service3->infobar_count());
// Detach should remove all infobars.
detach_function = new DebuggerDetachFunction();
detach_function->set_extension(extension());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment