blob: f0197ce1e52eae19c2efbba0efaf415c6f55f63e [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/overlays/overlay_queue_manager.h"
#import "ios/chrome/browser/ui/browser_list/browser_list.h"
#import "ios/chrome/browser/ui/overlays/browser_overlay_queue.h"
#import "ios/chrome/browser/ui/overlays/overlay_queue_manager_observer.h"
#import "ios/chrome/browser/ui/overlays/web_state_overlay_queue.h"
#import "ios/chrome/browser/web_state_list/web_state_list.h"
#import "ios/web/public/web_state/web_state.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
DEFINE_BROWSER_USER_DATA_KEY(OverlayQueueManager);
OverlayQueueManager::OverlayQueueManager(Browser* browser)
: web_state_list_(&browser->web_state_list()) {
// Create the BrowserOverlayQueue and add it to |queues_|.
BrowserOverlayQueue::CreateForBrowser(browser);
queues_.insert(BrowserOverlayQueue::FromBrowser(browser));
// Add queues for each WebState in |web_state_list_|.
for (int i = 0; i < web_state_list_->count(); ++i) {
AddQueueForWebState(web_state_list_->GetWebStateAt(i));
}
// Add as an observer for |web_state_list_|. This allows the manager to
// create OverlayQueues for newly added WebStates.
web_state_list_->AddObserver(this);
}
OverlayQueueManager::~OverlayQueueManager() {
// Disconnect() removes the manager as an observer for |web_state_list_|, nils
// out |web_state_list_|, and removes the OverlayQueues from |queues_|. It is
// expected to be called before deallocation.
DCHECK(queues_.empty());
DCHECK(!web_state_list_);
}
#pragma mark - Public
void OverlayQueueManager::AddObserver(OverlayQueueManagerObserver* observer) {
observers_.AddObserver(observer);
}
void OverlayQueueManager::RemoveObserver(
OverlayQueueManagerObserver* observer) {
observers_.RemoveObserver(observer);
}
void OverlayQueueManager::Disconnect() {
for (auto& observer : observers_) {
for (OverlayQueue* queue : queues_) {
observer.OverlayQueueManagerWillRemoveQueue(this, queue);
}
}
queues_.clear();
web_state_list_->RemoveObserver(this);
web_state_list_ = nullptr;
}
#pragma mark - WebStateListObserver
void OverlayQueueManager::WebStateInsertedAt(WebStateList* web_state_list,
web::WebState* web_state,
int index,
bool activating) {
AddQueueForWebState(web_state);
}
void OverlayQueueManager::WebStateReplacedAt(WebStateList* web_state_list,
web::WebState* old_web_state,
web::WebState* new_web_state,
int index) {
RemoveQueueForWebState(old_web_state);
AddQueueForWebState(new_web_state);
}
void OverlayQueueManager::WebStateDetachedAt(WebStateList* web_state_list,
web::WebState* web_state,
int index) {
RemoveQueueForWebState(web_state);
}
#pragma mark -
void OverlayQueueManager::AddQueueForWebState(web::WebState* web_state) {
WebStateOverlayQueue::CreateForWebState(web_state);
OverlayQueue* queue = WebStateOverlayQueue::FromWebState(web_state);
if (queues_.insert(queue).second) {
for (auto& observer : observers_) {
observer.OverlayQueueManagerDidAddQueue(this, queue);
}
}
}
void OverlayQueueManager::RemoveQueueForWebState(web::WebState* web_state) {
OverlayQueue* queue = WebStateOverlayQueue::FromWebState(web_state);
auto queue_iter = queues_.find(queue);
DCHECK(queue_iter != queues_.end());
for (auto& observer : observers_) {
observer.OverlayQueueManagerWillRemoveQueue(this, queue);
}
queues_.erase(queue_iter);
}