| Index: ios/clean/chrome/browser/ui/overlays/overlay_queue.mm
|
| diff --git a/ios/clean/chrome/browser/ui/overlays/overlay_queue.mm b/ios/clean/chrome/browser/ui/overlays/overlay_queue.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c22b96fb3dfa2bafec0948761b92ab360461bdbe
|
| --- /dev/null
|
| +++ b/ios/clean/chrome/browser/ui/overlays/overlay_queue.mm
|
| @@ -0,0 +1,102 @@
|
| +// 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/clean/chrome/browser/ui/overlays/overlay_queue.h"
|
| +
|
| +#include "base/logging.h"
|
| +#import "ios/clean/chrome/browser/ui/commands/overlay_commands.h"
|
| +#import "ios/shared/chrome/browser/ui/coordinators/browser_coordinator.h"
|
| +
|
| +#if !defined(__has_feature) || !__has_feature(objc_arc)
|
| +#error "This file requires ARC support."
|
| +#endif
|
| +
|
| +DEFINE_WEB_STATE_USER_DATA_KEY(OverlayQueue);
|
| +
|
| +// static
|
| +void OverlayQueue::CreateForWebState(web::WebState* web_state,
|
| + id<OverlaySchedulerCommands> dispatcher) {
|
| + DCHECK(web_state);
|
| + DCHECK(dispatcher);
|
| + if (!FromWebState(web_state)) {
|
| + std::unique_ptr<OverlayQueue> queue =
|
| + base::WrapUnique(new OverlayQueue(web_state, dispatcher));
|
| + web_state->SetUserData(UserDataKey(), std::move(queue));
|
| + }
|
| +}
|
| +
|
| +OverlayQueue::OverlayQueue(web::WebState* web_state,
|
| + id<OverlaySchedulerCommands> dispatcher)
|
| + : web_state_(web_state),
|
| + dispatcher_(dispatcher),
|
| + overlays_([[NSMutableArray alloc] init]),
|
| + showing_overlay_(false) {
|
| + DCHECK(web_state);
|
| + DCHECK(dispatcher);
|
| +}
|
| +
|
| +OverlayQueue::~OverlayQueue() {
|
| + [dispatcher_ cancelOverlaysForWebState:web_state_];
|
| +}
|
| +
|
| +void OverlayQueue::AddOverlay(OverlayCoordinator* overlay_coordinator) {
|
| + // Add the overlay coordinator to the queue, then notify the scheduler.
|
| + DCHECK(overlay_coordinator);
|
| + [overlays_ addObject:overlay_coordinator];
|
| + [dispatcher_ scheduleOverlayForWebState:web_state_];
|
| +}
|
| +
|
| +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 the
|
| + // scheduler that the overlay was replaced. Stopping the front overlay below
|
| + // will cause |overlay_cordinator| to start.
|
| + [overlays_ insertObject:overlay_coordinator atIndex:1];
|
| + [dispatcher_ visibleOverlayWasReplacedForWebState:web_state_];
|
| + OverlayCoordinator* visible_overlay = [overlays_ firstObject];
|
| + [visible_overlay cancelOverlay];
|
| + [visible_overlay stop];
|
| +}
|
| +
|
| +bool OverlayQueue::HasQueuedOverlays() const {
|
| + return [overlays_ count] > 0U;
|
| +}
|
| +
|
| +void OverlayQueue::StartNextOverlay(BrowserCoordinator* web_coordinator) {
|
| + DCHECK(web_coordinator);
|
| + DCHECK(HasQueuedOverlays());
|
| + DCHECK(!IsShowingOverlay());
|
| + [[overlays_ firstObject] startOverlayingCoordinator:web_coordinator];
|
| + showing_overlay_ = true;
|
| +}
|
| +
|
| +bool OverlayQueue::IsShowingOverlay() const {
|
| + return showing_overlay_;
|
| +}
|
| +
|
| +void OverlayQueue::OverlayWasStopped(OverlayCoordinator* overlay_coordinator) {
|
| + DCHECK(overlay_coordinator);
|
| + DCHECK_EQ([overlays_ firstObject], overlay_coordinator);
|
| + DCHECK(showing_overlay_);
|
| + [overlays_ removeObjectAtIndex:0];
|
| + showing_overlay_ = false;
|
| + [dispatcher_ overlayWasStoppedForWebState:web_state_];
|
| +}
|
| +
|
| +void OverlayQueue::CancelOverlays() {
|
| + // Call the WebKit completion blocks for all queued overlays.
|
| + for (OverlayCoordinator* overlay_coordinator in overlays_) {
|
| + [overlay_coordinator cancelOverlay];
|
| + }
|
| + // Remove the queued overlays and stop the visible overlay if one is
|
| + // presented. Stopping the visible overlay will trigger the next scheduled
|
| + // overlay, so the queue should be emptied before calling |-stop|.
|
| + OverlayCoordinator* visible_overlay =
|
| + showing_overlay_ ? [overlays_ firstObject] : nil;
|
| + [overlays_ removeAllObjects];
|
| + [visible_overlay stop];
|
| +}
|
|
|