Add abhijeet.k@samsung.com to AUTHORS list.
[chromium-blink-merge.git] / components / infobars / core / infobar_manager.cc
blobc93f05efacb446f8d33ca612cd416f8d79431af3
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/infobars/core/infobar_manager.h"
7 #include "base/command_line.h"
8 #include "components/infobars/core/infobar.h"
9 #include "components/infobars/core/infobars_switches.h"
11 namespace infobars {
14 // InfoBarManager::Observer ---------------------------------------------------
16 InfoBarManager::Observer::~Observer() {
19 void InfoBarManager::Observer::OnInfoBarAdded(InfoBar* infobar) {
22 void InfoBarManager::Observer::OnInfoBarRemoved(InfoBar* infobar,
23 bool animate) {
26 void InfoBarManager::Observer::OnInfoBarReplaced(InfoBar* old_infobar,
27 InfoBar* new_infobar) {
30 void InfoBarManager::Observer::OnManagerShuttingDown(InfoBarManager* manager) {
34 // InfoBarManager --------------------------------------------------------------
36 InfoBar* InfoBarManager::AddInfoBar(scoped_ptr<InfoBar> infobar) {
37 DCHECK(infobar);
38 if (!infobars_enabled_)
39 return NULL;
41 for (InfoBars::const_iterator i(infobars_.begin()); i != infobars_.end();
42 ++i) {
43 if ((*i)->delegate()->EqualsDelegate(infobar->delegate())) {
44 DCHECK_NE((*i)->delegate(), infobar->delegate());
45 return NULL;
49 InfoBar* infobar_ptr = infobar.release();
50 infobars_.push_back(infobar_ptr);
51 infobar_ptr->SetOwner(this);
53 NotifyInfoBarAdded(infobar_ptr);
55 return infobar_ptr;
58 void InfoBarManager::RemoveInfoBar(InfoBar* infobar) {
59 RemoveInfoBarInternal(infobar, true);
62 void InfoBarManager::RemoveAllInfoBars(bool animate) {
63 while (!infobars_.empty())
64 RemoveInfoBarInternal(infobars_.back(), animate);
67 InfoBar* InfoBarManager::ReplaceInfoBar(InfoBar* old_infobar,
68 scoped_ptr<InfoBar> new_infobar) {
69 DCHECK(old_infobar);
70 if (!infobars_enabled_)
71 return AddInfoBar(new_infobar.Pass()); // Deletes the infobar.
72 DCHECK(new_infobar);
74 InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(),
75 old_infobar));
76 DCHECK(i != infobars_.end());
78 InfoBar* new_infobar_ptr = new_infobar.release();
79 i = infobars_.insert(i, new_infobar_ptr);
80 new_infobar_ptr->SetOwner(this);
82 // Remove the old infobar before notifying, so that if any observers call back
83 // to AddInfoBar() or similar, we don't dupe-check against this infobar.
84 infobars_.erase(++i);
86 FOR_EACH_OBSERVER(Observer,
87 observer_list_,
88 OnInfoBarReplaced(old_infobar, new_infobar_ptr));
90 old_infobar->CloseSoon();
91 return new_infobar_ptr;
94 void InfoBarManager::AddObserver(Observer* obs) {
95 observer_list_.AddObserver(obs);
98 void InfoBarManager::RemoveObserver(Observer* obs) {
99 observer_list_.RemoveObserver(obs);
102 InfoBarManager::InfoBarManager()
103 : infobars_enabled_(true) {
104 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
105 switches::kDisableInfoBars))
106 infobars_enabled_ = false;
109 InfoBarManager::~InfoBarManager() {}
111 void InfoBarManager::ShutDown() {
112 // Destroy all remaining InfoBars. It's important to not animate here so that
113 // we guarantee that we'll delete all delegates before we do anything else.
114 RemoveAllInfoBars(false);
115 FOR_EACH_OBSERVER(Observer, observer_list_, OnManagerShuttingDown(this));
118 void InfoBarManager::OnNavigation(
119 const InfoBarDelegate::NavigationDetails& details) {
120 // NOTE: It is not safe to change the following code to count upwards or
121 // use iterators, as the RemoveInfoBar() call synchronously modifies our
122 // delegate list.
123 for (size_t i = infobars_.size(); i > 0; --i) {
124 InfoBar* infobar = infobars_[i - 1];
125 if (infobar->delegate()->ShouldExpire(details))
126 RemoveInfoBar(infobar);
130 void InfoBarManager::NotifyInfoBarAdded(InfoBar* infobar) {
131 FOR_EACH_OBSERVER(Observer, observer_list_, OnInfoBarAdded(infobar));
134 void InfoBarManager::NotifyInfoBarRemoved(InfoBar* infobar, bool animate) {
135 FOR_EACH_OBSERVER(Observer, observer_list_,
136 OnInfoBarRemoved(infobar, animate));
139 void InfoBarManager::RemoveInfoBarInternal(InfoBar* infobar, bool animate) {
140 DCHECK(infobar);
141 if (!infobars_enabled_) {
142 DCHECK(infobars_.empty());
143 return;
146 InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar));
147 DCHECK(i != infobars_.end());
149 // Remove the infobar before notifying, so that if any observers call back to
150 // AddInfoBar() or similar, we don't dupe-check against this infobar.
151 infobars_.erase(i);
153 // This notification must happen before the call to CloseSoon() below, since
154 // observers may want to access |infobar| and that call can delete it.
155 NotifyInfoBarRemoved(infobar, animate);
157 infobar->CloseSoon();
160 } // namespace infobars