• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "components/infobars/core/infobar_manager.h"
6 
7 #include "base/command_line.h"
8 #include "components/infobars/core/infobar.h"
9 #include "components/infobars/core/infobars_switches.h"
10 
11 namespace infobars {
12 
13 
14 // InfoBarManager::Observer ---------------------------------------------------
15 
OnInfoBarAdded(InfoBar * infobar)16 void InfoBarManager::Observer::OnInfoBarAdded(InfoBar* infobar) {
17 }
18 
OnInfoBarRemoved(InfoBar * infobar,bool animate)19 void InfoBarManager::Observer::OnInfoBarRemoved(InfoBar* infobar,
20                                                 bool animate) {
21 }
22 
OnInfoBarReplaced(InfoBar * old_infobar,InfoBar * new_infobar)23 void InfoBarManager::Observer::OnInfoBarReplaced(InfoBar* old_infobar,
24                                                  InfoBar* new_infobar) {
25 }
26 
OnManagerShuttingDown(InfoBarManager * manager)27 void InfoBarManager::Observer::OnManagerShuttingDown(InfoBarManager* manager) {
28 }
29 
30 
31 // InfoBarManager --------------------------------------------------------------
32 
AddInfoBar(scoped_ptr<InfoBar> infobar)33 InfoBar* InfoBarManager::AddInfoBar(scoped_ptr<InfoBar> infobar) {
34   DCHECK(infobar);
35   if (!infobars_enabled_)
36     return NULL;
37 
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;
43     }
44   }
45 
46   InfoBar* infobar_ptr = infobar.release();
47   infobars_.push_back(infobar_ptr);
48   infobar_ptr->SetOwner(this);
49 
50   NotifyInfoBarAdded(infobar_ptr);
51 
52   return infobar_ptr;
53 }
54 
RemoveInfoBar(InfoBar * infobar)55 void InfoBarManager::RemoveInfoBar(InfoBar* infobar) {
56   RemoveInfoBarInternal(infobar, true);
57 }
58 
RemoveAllInfoBars(bool animate)59 void InfoBarManager::RemoveAllInfoBars(bool animate) {
60   while (!infobars_.empty())
61     RemoveInfoBarInternal(infobars_.back(), animate);
62 }
63 
ReplaceInfoBar(InfoBar * old_infobar,scoped_ptr<InfoBar> new_infobar)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);
70 
71   InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(),
72                                  old_infobar));
73   DCHECK(i != infobars_.end());
74 
75   InfoBar* new_infobar_ptr = new_infobar.release();
76   i = infobars_.insert(i, new_infobar_ptr);
77   new_infobar_ptr->SetOwner(this);
78 
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);
82 
83   FOR_EACH_OBSERVER(Observer,
84                     observer_list_,
85                     OnInfoBarReplaced(old_infobar, new_infobar_ptr));
86 
87   old_infobar->CloseSoon();
88   return new_infobar_ptr;
89 }
90 
AddObserver(Observer * obs)91 void InfoBarManager::AddObserver(Observer* obs) {
92   observer_list_.AddObserver(obs);
93 }
94 
RemoveObserver(Observer * obs)95 void InfoBarManager::RemoveObserver(Observer* obs) {
96   observer_list_.RemoveObserver(obs);
97 }
98 
InfoBarManager()99 InfoBarManager::InfoBarManager()
100     : infobars_enabled_(true) {
101   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableInfoBars))
102     infobars_enabled_ = false;
103 }
104 
~InfoBarManager()105 InfoBarManager::~InfoBarManager() {}
106 
ShutDown()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));
112 }
113 
OnNavigation(const InfoBarDelegate::NavigationDetails & details)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);
123   }
124 }
125 
NotifyInfoBarAdded(InfoBar * infobar)126 void InfoBarManager::NotifyInfoBarAdded(InfoBar* infobar) {
127   FOR_EACH_OBSERVER(Observer, observer_list_, OnInfoBarAdded(infobar));
128 }
129 
NotifyInfoBarRemoved(InfoBar * infobar,bool animate)130 void InfoBarManager::NotifyInfoBarRemoved(InfoBar* infobar, bool animate) {
131   FOR_EACH_OBSERVER(Observer, observer_list_,
132                     OnInfoBarRemoved(infobar, animate));
133 }
134 
RemoveInfoBarInternal(InfoBar * infobar,bool animate)135 void InfoBarManager::RemoveInfoBarInternal(InfoBar* infobar, bool animate) {
136   DCHECK(infobar);
137   if (!infobars_enabled_) {
138     DCHECK(infobars_.empty());
139     return;
140   }
141 
142   InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar));
143   DCHECK(i != infobars_.end());
144 
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);
148 
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);
152 
153   infobar->CloseSoon();
154 }
155 
156 }  // namespace infobars
157