1e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// found in the LICENSE file.
4e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/infobars/core/infobar_manager.h"
6e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
7e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/command_line.h"
80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/infobars/core/infobar.h"
90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/infobars/core/infobars_switches.h"
100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace infobars {
120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// InfoBarManager::Observer ---------------------------------------------------
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid InfoBarManager::Observer::OnInfoBarAdded(InfoBar* infobar) {
170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid InfoBarManager::Observer::OnInfoBarRemoved(InfoBar* infobar,
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                                bool animate) {
210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid InfoBarManager::Observer::OnInfoBarReplaced(InfoBar* old_infobar,
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                                 InfoBar* new_infobar) {
250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid InfoBarManager::Observer::OnManagerShuttingDown(InfoBarManager* manager) {
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// InfoBarManager --------------------------------------------------------------
32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
33e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochInfoBar* InfoBarManager::AddInfoBar(scoped_ptr<InfoBar> infobar) {
34e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK(infobar);
35e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (!infobars_enabled_)
36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return NULL;
37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
38e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  for (InfoBars::const_iterator i(infobars_.begin()); i != infobars_.end();
39e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch       ++i) {
40e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if ((*i)->delegate()->EqualsDelegate(infobar->delegate())) {
41e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      DCHECK_NE((*i)->delegate(), infobar->delegate());
42e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      return NULL;
43e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
44e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
45e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
46e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  InfoBar* infobar_ptr = infobar.release();
47e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  infobars_.push_back(infobar_ptr);
48e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  infobar_ptr->SetOwner(this);
49e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
50a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  NotifyInfoBarAdded(infobar_ptr);
51e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
52e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  return infobar_ptr;
53e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
54e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
55e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid InfoBarManager::RemoveInfoBar(InfoBar* infobar) {
56e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  RemoveInfoBarInternal(infobar, true);
57e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid InfoBarManager::RemoveAllInfoBars(bool animate) {
60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  while (!infobars_.empty())
61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    RemoveInfoBarInternal(infobars_.back(), animate);
62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
63e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochInfoBar* InfoBarManager::ReplaceInfoBar(InfoBar* old_infobar,
65e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                        scoped_ptr<InfoBar> new_infobar) {
66e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK(old_infobar);
67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (!infobars_enabled_)
68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return AddInfoBar(new_infobar.Pass());  // Deletes the infobar.
69e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK(new_infobar);
70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
71e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(),
72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                                 old_infobar));
73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK(i != infobars_.end());
74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  InfoBar* new_infobar_ptr = new_infobar.release();
76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  i = infobars_.insert(i, new_infobar_ptr);
77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  new_infobar_ptr->SetOwner(this);
78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
79e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Remove the old infobar before notifying, so that if any observers call back
80e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // to AddInfoBar() or similar, we don't dupe-check against this infobar.
81e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  infobars_.erase(++i);
82e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FOR_EACH_OBSERVER(Observer,
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    observer_list_,
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    OnInfoBarReplaced(old_infobar, new_infobar_ptr));
86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
87e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  old_infobar->CloseSoon();
88e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  return new_infobar_ptr;
89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid InfoBarManager::AddObserver(Observer* obs) {
92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  observer_list_.AddObserver(obs);
93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid InfoBarManager::RemoveObserver(Observer* obs) {
96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  observer_list_.RemoveObserver(obs);
97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
99a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochInfoBarManager::InfoBarManager()
100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    : infobars_enabled_(true) {
101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableInfoBars))
102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    infobars_enabled_ = false;
103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
105a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochInfoBarManager::~InfoBarManager() {}
106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid InfoBarManager::ShutDown() {
108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Destroy all remaining InfoBars.  It's important to not animate here so that
109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // we guarantee that we'll delete all delegates before we do anything else.
110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  RemoveAllInfoBars(false);
111e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  FOR_EACH_OBSERVER(Observer, observer_list_, OnManagerShuttingDown(this));
112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
114e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid InfoBarManager::OnNavigation(
115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const InfoBarDelegate::NavigationDetails& details) {
116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // NOTE: It is not safe to change the following code to count upwards or
117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // use iterators, as the RemoveInfoBar() call synchronously modifies our
118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // delegate list.
119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  for (size_t i = infobars_.size(); i > 0; --i) {
120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    InfoBar* infobar = infobars_[i - 1];
121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (infobar->delegate()->ShouldExpire(details))
122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      RemoveInfoBar(infobar);
123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
124e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid InfoBarManager::NotifyInfoBarAdded(InfoBar* infobar) {
127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  FOR_EACH_OBSERVER(Observer, observer_list_, OnInfoBarAdded(infobar));
128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid InfoBarManager::NotifyInfoBarRemoved(InfoBar* infobar, bool animate) {
131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  FOR_EACH_OBSERVER(Observer, observer_list_,
132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                    OnInfoBarRemoved(infobar, animate));
133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid InfoBarManager::RemoveInfoBarInternal(InfoBar* infobar, bool animate) {
136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK(infobar);
137e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (!infobars_enabled_) {
138e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    DCHECK(infobars_.empty());
139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return;
140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
141e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar));
143e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DCHECK(i != infobars_.end());
144e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Remove the infobar before notifying, so that if any observers call back to
146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // AddInfoBar() or similar, we don't dupe-check against this infobar.
147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  infobars_.erase(i);
148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // This notification must happen before the call to CloseSoon() below, since
150e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // observers may want to access |infobar| and that call can delete it.
151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  NotifyInfoBarRemoved(infobar, animate);
152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
153e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  infobar->CloseSoon();
154e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
1550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace infobars
157