Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / components / infobars / core / infobar_manager.cc
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
16 InfoBarManager::Observer::~Observer() {
17 }
18
19 void InfoBarManager::Observer::OnInfoBarAdded(InfoBar* infobar) {
20 }
21
22 void InfoBarManager::Observer::OnInfoBarRemoved(InfoBar* infobar,
23                                                 bool animate) {
24 }
25
26 void InfoBarManager::Observer::OnInfoBarReplaced(InfoBar* old_infobar,
27                                                  InfoBar* new_infobar) {
28 }
29
30 void InfoBarManager::Observer::OnManagerShuttingDown(InfoBarManager* manager) {
31 }
32
33
34 // InfoBarManager --------------------------------------------------------------
35
36 InfoBar* InfoBarManager::AddInfoBar(scoped_ptr<InfoBar> infobar) {
37   DCHECK(infobar);
38   if (!infobars_enabled_)
39     return NULL;
40
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;
46     }
47   }
48
49   InfoBar* infobar_ptr = infobar.release();
50   infobars_.push_back(infobar_ptr);
51   infobar_ptr->SetOwner(this);
52
53   NotifyInfoBarAdded(infobar_ptr);
54
55   return infobar_ptr;
56 }
57
58 void InfoBarManager::RemoveInfoBar(InfoBar* infobar) {
59   RemoveInfoBarInternal(infobar, true);
60 }
61
62 void InfoBarManager::RemoveAllInfoBars(bool animate) {
63   while (!infobars_.empty())
64     RemoveInfoBarInternal(infobars_.back(), animate);
65 }
66
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);
73
74   InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(),
75                                  old_infobar));
76   DCHECK(i != infobars_.end());
77
78   InfoBar* new_infobar_ptr = new_infobar.release();
79   i = infobars_.insert(i, new_infobar_ptr);
80   new_infobar_ptr->SetOwner(this);
81
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);
85
86   FOR_EACH_OBSERVER(Observer,
87                     observer_list_,
88                     OnInfoBarReplaced(old_infobar, new_infobar_ptr));
89
90   old_infobar->CloseSoon();
91   return new_infobar_ptr;
92 }
93
94 void InfoBarManager::AddObserver(Observer* obs) {
95   observer_list_.AddObserver(obs);
96 }
97
98 void InfoBarManager::RemoveObserver(Observer* obs) {
99   observer_list_.RemoveObserver(obs);
100 }
101
102 InfoBarManager::InfoBarManager()
103     : infobars_enabled_(true) {
104   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableInfoBars))
105     infobars_enabled_ = false;
106 }
107
108 InfoBarManager::~InfoBarManager() {}
109
110 void InfoBarManager::ShutDown() {
111   // Destroy all remaining InfoBars.  It's important to not animate here so that
112   // we guarantee that we'll delete all delegates before we do anything else.
113   RemoveAllInfoBars(false);
114   FOR_EACH_OBSERVER(Observer, observer_list_, OnManagerShuttingDown(this));
115 }
116
117 void InfoBarManager::OnNavigation(
118     const InfoBarDelegate::NavigationDetails& details) {
119   // NOTE: It is not safe to change the following code to count upwards or
120   // use iterators, as the RemoveInfoBar() call synchronously modifies our
121   // delegate list.
122   for (size_t i = infobars_.size(); i > 0; --i) {
123     InfoBar* infobar = infobars_[i - 1];
124     if (infobar->delegate()->ShouldExpire(details))
125       RemoveInfoBar(infobar);
126   }
127 }
128
129 void InfoBarManager::NotifyInfoBarAdded(InfoBar* infobar) {
130   FOR_EACH_OBSERVER(Observer, observer_list_, OnInfoBarAdded(infobar));
131 }
132
133 void InfoBarManager::NotifyInfoBarRemoved(InfoBar* infobar, bool animate) {
134   FOR_EACH_OBSERVER(Observer, observer_list_,
135                     OnInfoBarRemoved(infobar, animate));
136 }
137
138 void InfoBarManager::RemoveInfoBarInternal(InfoBar* infobar, bool animate) {
139   DCHECK(infobar);
140   if (!infobars_enabled_) {
141     DCHECK(infobars_.empty());
142     return;
143   }
144
145   InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar));
146   DCHECK(i != infobars_.end());
147
148   // Remove the infobar before notifying, so that if any observers call back to
149   // AddInfoBar() or similar, we don't dupe-check against this infobar.
150   infobars_.erase(i);
151
152   // This notification must happen before the call to CloseSoon() below, since
153   // observers may want to access |infobar| and that call can delete it.
154   NotifyInfoBarRemoved(infobar, animate);
155
156   infobar->CloseSoon();
157 }
158
159 }  // namespace infobars