blob: 98309bec075cb91973e8dc184bec5345b122529a [file] [log] [blame]
// Copyright 2018 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/infobars/infobar_container_coordinator.h"
#include <memory>
#include "ios/chrome/browser/experimental_flags.h"
#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
#import "ios/chrome/browser/ui/commands/application_commands.h"
#import "ios/chrome/browser/ui/fullscreen/fullscreen_controller_factory.h"
#include "ios/chrome/browser/ui/infobars/infobar_container_mediator.h"
#include "ios/chrome/browser/ui/infobars/infobar_container_view_controller.h"
#import "ios/chrome/browser/ui/infobars/infobar_positioner.h"
#include "ios/chrome/browser/ui/infobars/legacy_infobar_container_view_controller.h"
#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_animator.h"
#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_presentation_controller.h"
#import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h"
#include "ios/chrome/browser/upgrade/upgrade_center.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface InfobarContainerCoordinator () <
InfobarContainerPresenter,
UIViewControllerTransitioningDelegate,
SigninPresenter>
@property(nonatomic, assign) TabModel* tabModel;
// UIViewController that contains Infobars.
@property(nonatomic, strong)
UIViewController<InfobarContainerConsumer>* containerViewController;
// The mediator for this Coordinator.
@property(nonatomic, strong) InfobarContainerMediator* mediator;
@end
@implementation InfobarContainerCoordinator
- (instancetype)initWithBaseViewController:(UIViewController*)viewController
browserState:
(ios::ChromeBrowserState*)browserState
tabModel:(TabModel*)tabModel {
self = [super initWithBaseViewController:viewController
browserState:browserState];
if (self) {
_tabModel = tabModel;
}
return self;
}
- (void)start {
DCHECK(self.positioner);
DCHECK(self.dispatcher);
// Create and setup the ViewController.
if (experimental_flags::IsInfobarUIRebootEnabled()) {
InfobarContainerViewController* container =
[[InfobarContainerViewController alloc] init];
container.presenter = self;
self.containerViewController = container;
} else {
LegacyInfobarContainerViewController* legacyContainer =
[[LegacyInfobarContainerViewController alloc]
initWithFullscreenController:
FullscreenControllerFactory::GetInstance()->GetForBrowserState(
self.browserState)];
[self.baseViewController addChildViewController:legacyContainer];
// TODO(crbug.com/892376): We shouldn't modify the BaseVC hierarchy, BVC
// needs to handle this.
[self.baseViewController.view insertSubview:legacyContainer.view
aboveSubview:self.positioner.parentView];
[legacyContainer didMoveToParentViewController:self.baseViewController];
legacyContainer.positioner = self.positioner;
self.containerViewController = legacyContainer;
}
// Create the mediator once the VC has been added to the View hierarchy.
self.mediator = [[InfobarContainerMediator alloc]
initWithConsumer:self.containerViewController
browserState:self.browserState
tabModel:self.tabModel];
self.mediator.syncPresenter = self.syncPresenter;
self.mediator.signinPresenter = self;
[[UpgradeCenter sharedInstance] registerClient:self.mediator
withDispatcher:self.dispatcher];
}
- (void)stop {
[[UpgradeCenter sharedInstance] unregisterClient:self.mediator];
self.mediator = nil;
}
#pragma mark - Public Interface
- (UIView*)view {
return self.containerViewController.view;
}
- (void)updateInfobarContainer {
[self.containerViewController updateLayoutAnimated:NO];
}
- (BOOL)isInfobarPresentingForWebState:(web::WebState*)webState {
infobars::InfoBarManager* infoBarManager =
InfoBarManagerImpl::FromWebState(webState);
if (infoBarManager->infobar_count() > 0) {
return YES;
}
return NO;
}
#pragma mark - InfobarContainerPresenter
- (void)presentInfobarContainer {
// Should only be called in the new UI implementation.
DCHECK(experimental_flags::IsInfobarUIRebootEnabled());
self.containerViewController.transitioningDelegate = self;
[self.containerViewController
setModalPresentationStyle:UIModalPresentationCustom];
[self.baseViewController presentViewController:self.containerViewController
animated:YES
completion:nil];
}
#pragma mark - UIViewControllerTransitioningDelegate
- (UIPresentationController*)
presentationControllerForPresentedViewController:
(UIViewController*)presented
presentingViewController:
(UIViewController*)presenting
sourceViewController:(UIViewController*)source {
InfobarBannerPresentationController* presentationController =
[[InfobarBannerPresentationController alloc]
initWithPresentedViewController:presented
presentingViewController:presenting];
return presentationController;
}
- (id<UIViewControllerAnimatedTransitioning>)
animationControllerForPresentedController:(UIViewController*)presented
presentingController:(UIViewController*)presenting
sourceController:(UIViewController*)source {
InfobarBannerAnimator* animator = [[InfobarBannerAnimator alloc] init];
animator.presenting = YES;
return animator;
}
- (id<UIViewControllerAnimatedTransitioning>)
animationControllerForDismissedController:(UIViewController*)dismissed {
InfobarBannerAnimator* animator = [[InfobarBannerAnimator alloc] init];
animator.presenting = NO;
return animator;
}
#pragma mark - SigninPresenter
- (void)showSignin:(ShowSigninCommand*)command {
[self.dispatcher showSignin:command
baseViewController:self.baseViewController];
}
@end