blob: 8ef6809dfc55336ea0a3253f9f0e52a9a0a21300 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/devtools/global_confirm_info_bar.h"
#include <utility>
#include "base/macros.h"
#include "base/stl_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "components/infobars/core/infobar.h"
#include "ui/gfx/image/image.h"
// InfoBarDelegateProxy -------------------------------------------------------
class GlobalConfirmInfoBar::DelegateProxy : public ConfirmInfoBarDelegate {
public:
explicit DelegateProxy(base::WeakPtr<GlobalConfirmInfoBar> global_info_bar);
~DelegateProxy() override;
void Detach();
private:
friend class GlobalConfirmInfoBar;
// ConfirmInfoBarDelegate overrides
infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override;
base::string16 GetMessageText() const override;
int GetButtons() const override;
base::string16 GetButtonLabel(InfoBarButton button) const override;
bool Accept() override;
bool Cancel() override;
base::string16 GetLinkText() const override;
GURL GetLinkURL() const override;
bool LinkClicked(WindowOpenDisposition disposition) override;
bool EqualsDelegate(infobars::InfoBarDelegate* delegate) const override;
void InfoBarDismissed() override;
infobars::InfoBar* info_bar_;
base::WeakPtr<GlobalConfirmInfoBar> global_info_bar_;
DISALLOW_COPY_AND_ASSIGN(DelegateProxy);
};
GlobalConfirmInfoBar::DelegateProxy::DelegateProxy(
base::WeakPtr<GlobalConfirmInfoBar> global_info_bar)
: info_bar_(nullptr),
global_info_bar_(global_info_bar) {
}
GlobalConfirmInfoBar::DelegateProxy::~DelegateProxy() {
}
infobars::InfoBarDelegate::InfoBarIdentifier
GlobalConfirmInfoBar::DelegateProxy::GetIdentifier() const {
return global_info_bar_ ? global_info_bar_->delegate_->GetIdentifier()
: INVALID;
}
base::string16 GlobalConfirmInfoBar::DelegateProxy::GetMessageText() const {
return global_info_bar_ ? global_info_bar_->delegate_->GetMessageText()
: base::string16();
}
int GlobalConfirmInfoBar::DelegateProxy::GetButtons() const {
return global_info_bar_ ? global_info_bar_->delegate_->GetButtons()
: 0;
}
base::string16 GlobalConfirmInfoBar::DelegateProxy::GetButtonLabel(
InfoBarButton button) const {
return global_info_bar_ ? global_info_bar_->delegate_->GetButtonLabel(button)
: base::string16();
}
bool GlobalConfirmInfoBar::DelegateProxy::Accept() {
base::WeakPtr<GlobalConfirmInfoBar> info_bar = global_info_bar_;
if (info_bar)
info_bar->delegate_->Accept();
// Could be destroyed after this point.
if (info_bar)
info_bar->Close();
return true;
}
bool GlobalConfirmInfoBar::DelegateProxy::Cancel() {
base::WeakPtr<GlobalConfirmInfoBar> info_bar = global_info_bar_;
if (info_bar)
info_bar->delegate_->Cancel();
// Could be destroyed after this point.
if (info_bar)
info_bar->Close();
return true;
}
base::string16 GlobalConfirmInfoBar::DelegateProxy::GetLinkText() const {
return global_info_bar_ ? global_info_bar_->delegate_->GetLinkText()
: base::string16();
}
GURL GlobalConfirmInfoBar::DelegateProxy::GetLinkURL() const {
return global_info_bar_ ? global_info_bar_->delegate_->GetLinkURL()
: GURL();
}
bool GlobalConfirmInfoBar::DelegateProxy::LinkClicked(
WindowOpenDisposition disposition) {
return global_info_bar_ ?
global_info_bar_->delegate_->LinkClicked(disposition) : false;
}
bool GlobalConfirmInfoBar::DelegateProxy::EqualsDelegate(
infobars::InfoBarDelegate* delegate) const {
return delegate == this;
}
void GlobalConfirmInfoBar::DelegateProxy::InfoBarDismissed() {
base::WeakPtr<GlobalConfirmInfoBar> info_bar = global_info_bar_;
if (info_bar)
info_bar->delegate_->InfoBarDismissed();
// Could be destroyed after this point.
if (info_bar)
info_bar->Close();
}
void GlobalConfirmInfoBar::DelegateProxy::Detach() {
global_info_bar_.reset();
}
// GlobalConfirmInfoBar -------------------------------------------------------
// static
base::WeakPtr<GlobalConfirmInfoBar> GlobalConfirmInfoBar::Show(
std::unique_ptr<ConfirmInfoBarDelegate> delegate) {
GlobalConfirmInfoBar* info_bar =
new GlobalConfirmInfoBar(std::move(delegate));
return info_bar->weak_factory_.GetWeakPtr();
}
void GlobalConfirmInfoBar::Close() {
delete this;
}
GlobalConfirmInfoBar::GlobalConfirmInfoBar(
std::unique_ptr<ConfirmInfoBarDelegate> delegate)
: delegate_(std::move(delegate)),
browser_tab_strip_tracker_(this, nullptr, nullptr),
weak_factory_(this) {
browser_tab_strip_tracker_.Init(
BrowserTabStripTracker::InitWith::BROWSERS_IN_ACTIVE_DESKTOP);
}
GlobalConfirmInfoBar::~GlobalConfirmInfoBar() {
while (!proxies_.empty()) {
auto it = proxies_.begin();
it->second->Detach();
it->first->RemoveObserver(this);
it->first->RemoveInfoBar(it->second->info_bar_);
proxies_.erase(it);
}
}
void GlobalConfirmInfoBar::TabInsertedAt(TabStripModel* tab_strip_model,
content::WebContents* web_contents,
int index,
bool foreground) {
MaybeAddInfoBar(web_contents);
}
void GlobalConfirmInfoBar::TabChangedAt(content::WebContents* web_contents,
int index,
TabChangeType change_type) {
MaybeAddInfoBar(web_contents);
}
void GlobalConfirmInfoBar::OnInfoBarRemoved(infobars::InfoBar* info_bar,
bool animate) {
// Do not process alien infobars.
for (auto it : proxies_) {
if (it.second->info_bar_ == info_bar) {
OnManagerShuttingDown(info_bar->owner());
break;
}
}
}
void GlobalConfirmInfoBar::OnManagerShuttingDown(
infobars::InfoBarManager* manager) {
manager->RemoveObserver(this);
proxies_.erase(manager);
}
void GlobalConfirmInfoBar::MaybeAddInfoBar(content::WebContents* web_contents) {
InfoBarService* infobar_service =
InfoBarService::FromWebContents(web_contents);
// WebContents from the tab strip must have the infobar service.
DCHECK(infobar_service);
if (ContainsKey(proxies_, infobar_service))
return;
std::unique_ptr<GlobalConfirmInfoBar::DelegateProxy> proxy(
new GlobalConfirmInfoBar::DelegateProxy(weak_factory_.GetWeakPtr()));
GlobalConfirmInfoBar::DelegateProxy* proxy_ptr = proxy.get();
infobars::InfoBar* added_bar = infobar_service->AddInfoBar(
infobar_service->CreateConfirmInfoBar(std::move(proxy)));
proxy_ptr->info_bar_ = added_bar;
DCHECK(added_bar);
proxies_[infobar_service] = proxy_ptr;
infobar_service->AddObserver(this);
}