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