blob: bbbdc6dfcb86916ed7b96844f8cbc35998b52df0 [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.h"
#include "base/logging.h"
#import "ios/chrome/browser/ui/overlays/overlay_coordinator+internal.h"
#include "ios/chrome/browser/ui/overlays/overlay_coordinator.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
OverlayQueue::OverlayQueue()
: overlays_([[NSMutableArray<OverlayCoordinator*> alloc] init]),
showing_overlay_(false) {}
OverlayQueue::~OverlayQueue() {
CancelOverlays();
}
void OverlayQueue::AddObserver(OverlayQueueObserver* observer) {
observers_.AddObserver(observer);
}
void OverlayQueue::RemoveObserver(OverlayQueueObserver* observer) {
observers_.RemoveObserver(observer);
}
void OverlayQueue::OverlayWasStopped(OverlayCoordinator* overlay_coordinator) {
DCHECK(overlay_coordinator);
DCHECK_EQ(GetFirstOverlay(), overlay_coordinator);
DCHECK(IsShowingOverlay());
[overlays_ removeObjectAtIndex:0];
showing_overlay_ = false;
for (auto& observer : observers_) {
observer.OverlayQueueDidStopVisibleOverlay(this);
}
}
void OverlayQueue::ReplaceVisibleOverlay(
OverlayCoordinator* overlay_coordinator) {
DCHECK(overlay_coordinator);
DCHECK(IsShowingOverlay());
DCHECK_GE([overlays_ count], 1U);
// Add the overlay after the currently displayed overlay and notify observers
// before stopping the current overlay.
for (auto& observer : observers_) {
observer.OverlayQueueWillReplaceVisibleOverlay(this);
}
[overlays_ insertObject:overlay_coordinator atIndex:1];
[overlay_coordinator wasAddedToQueue:this];
OverlayCoordinator* visible_overlay = GetFirstOverlay();
[visible_overlay cancelOverlay];
[visible_overlay stop];
}
bool OverlayQueue::HasQueuedOverlays() const {
return GetCount() > 0U;
}
bool OverlayQueue::IsShowingOverlay() const {
return showing_overlay_;
}
void OverlayQueue::CancelOverlays() {
// Cancel all overlays in the queue.
for (OverlayCoordinator* overlay_coordinator in overlays_) {
[overlay_coordinator cancelOverlay];
}
for (auto& observer : observers_) {
observer.OverlayQueueDidCancelOverlays(this);
}
// Stop the visible overlay before emptying the queue.
if (IsShowingOverlay())
[GetFirstOverlay() stop];
[overlays_ removeAllObjects];
}
web::WebState* OverlayQueue::GetWebState() const {
return nullptr;
}
void OverlayQueue::AddOverlay(OverlayCoordinator* overlay_coordinator) {
// Add the overlay coordinator to the queue, then notify observers.
DCHECK(overlay_coordinator);
[overlays_ addObject:overlay_coordinator];
[overlay_coordinator wasAddedToQueue:this];
for (auto& observer : observers_) {
observer.OverlayQueueDidAddOverlay(this);
}
}
NSUInteger OverlayQueue::GetCount() const {
return [overlays_ count];
}
OverlayCoordinator* OverlayQueue::GetFirstOverlay() {
return [overlays_ firstObject];
}
void OverlayQueue::OverlayWasStarted() {
showing_overlay_ = true;
}