Roll DEPS for libelf clang compilation fix.
[chromium-blink-merge.git] / components / infobars / core / infobar_manager.cc
blobd2c699fe3e1ef26e811a05f6f4c0cb9a199ed103
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 void InfoBarManager::Observer::OnInfoBarAdded(InfoBar* infobar) {
19 void InfoBarManager::Observer::OnInfoBarRemoved(InfoBar* infobar,
20 bool animate) {
23 void InfoBarManager::Observer::OnInfoBarReplaced(InfoBar* old_infobar,
24 InfoBar* new_infobar) {
27 void InfoBarManager::Observer::OnManagerShuttingDown(InfoBarManager* manager) {
31 // InfoBarManager --------------------------------------------------------------
33 InfoBar* InfoBarManager::AddInfoBar(scoped_ptr<InfoBar> infobar) {
34 DCHECK(infobar);
35 if (!infobars_enabled_)
36 return NULL;
38 for (InfoBars::const_iterator i(infobars_.begin()); i != infobars_.end();
39 ++i) {
40 if ((*i)->delegate()->EqualsDelegate(infobar->delegate())) {
41 DCHECK_NE((*i)->delegate(), infobar->delegate());
42 return NULL;
46 InfoBar* infobar_ptr = infobar.release();
47 infobars_.push_back(infobar_ptr);
48 infobar_ptr->SetOwner(this);
50 NotifyInfoBarAdded(infobar_ptr);
52 return infobar_ptr;
55 void InfoBarManager::RemoveInfoBar(InfoBar* infobar) {
56 RemoveInfoBarInternal(infobar, true);
59 void InfoBarManager::RemoveAllInfoBars(bool animate) {
60 while (!infobars_.empty())
61 RemoveInfoBarInternal(infobars_.back(), animate);
64 InfoBar* InfoBarManager::ReplaceInfoBar(InfoBar* old_infobar,
65 scoped_ptr<InfoBar> new_infobar) {
66 DCHECK(old_infobar);
67 if (!infobars_enabled_)
68 return AddInfoBar(new_infobar.Pass()); // Deletes the infobar.
69 DCHECK(new_infobar);
71 InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(),
72 old_infobar));
73 DCHECK(i != infobars_.end());
75 InfoBar* new_infobar_ptr = new_infobar.release();
76 i = infobars_.insert(i, new_infobar_ptr);
77 new_infobar_ptr->SetOwner(this);
79 // Remove the old infobar before notifying, so that if any observers call back
80 // to AddInfoBar() or similar, we don't dupe-check against this infobar.
81 infobars_.erase(++i);
83 FOR_EACH_OBSERVER(Observer,
84 observer_list_,
85 OnInfoBarReplaced(old_infobar, new_infobar_ptr));
87 old_infobar->CloseSoon();
88 return new_infobar_ptr;
91 void InfoBarManager::AddObserver(Observer* obs) {
92 observer_list_.AddObserver(obs);
95 void InfoBarManager::RemoveObserver(Observer* obs) {
96 observer_list_.RemoveObserver(obs);
99 InfoBarManager::InfoBarManager()
100 : infobars_enabled_(true) {
101 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableInfoBars))
102 infobars_enabled_ = false;
105 InfoBarManager::~InfoBarManager() {}
107 void InfoBarManager::ShutDown() {
108 // Destroy all remaining InfoBars. It's important to not animate here so that
109 // we guarantee that we'll delete all delegates before we do anything else.
110 RemoveAllInfoBars(false);
111 FOR_EACH_OBSERVER(Observer, observer_list_, OnManagerShuttingDown(this));
114 void InfoBarManager::OnNavigation(
115 const InfoBarDelegate::NavigationDetails& details) {
116 // NOTE: It is not safe to change the following code to count upwards or
117 // use iterators, as the RemoveInfoBar() call synchronously modifies our
118 // delegate list.
119 for (size_t i = infobars_.size(); i > 0; --i) {
120 InfoBar* infobar = infobars_[i - 1];
121 if (infobar->delegate()->ShouldExpire(details))
122 RemoveInfoBar(infobar);
126 void InfoBarManager::NotifyInfoBarAdded(InfoBar* infobar) {
127 FOR_EACH_OBSERVER(Observer, observer_list_, OnInfoBarAdded(infobar));
130 void InfoBarManager::NotifyInfoBarRemoved(InfoBar* infobar, bool animate) {
131 FOR_EACH_OBSERVER(Observer, observer_list_,
132 OnInfoBarRemoved(infobar, animate));
135 void InfoBarManager::RemoveInfoBarInternal(InfoBar* infobar, bool animate) {
136 DCHECK(infobar);
137 if (!infobars_enabled_) {
138 DCHECK(infobars_.empty());
139 return;
142 InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar));
143 DCHECK(i != infobars_.end());
145 // Remove the infobar before notifying, so that if any observers call back to
146 // AddInfoBar() or similar, we don't dupe-check against this infobar.
147 infobars_.erase(i);
149 // This notification must happen before the call to CloseSoon() below, since
150 // observers may want to access |infobar| and that call can delete it.
151 NotifyInfoBarRemoved(infobar, animate);
153 infobar->CloseSoon();
156 } // namespace infobars