blob: 0ca9808f01395ecf5f762ce7d47cab71a6ffdc20 [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/fullscreen/ui_bundled/fullscreen_controller_impl.h"
#import "base/memory/ptr_util.h"
#import "ios/chrome/browser/broadcaster/ui_bundled/chrome_broadcast_observer_bridge.h"
#import "ios/chrome/browser/broadcaster/ui_bundled/chrome_broadcaster.h"
#import "ios/chrome/browser/fullscreen/ui_bundled/fullscreen_system_notification_observer.h"
#import "ios/chrome/browser/shared/model/browser/browser.h"
#import "ios/chrome/browser/toolbar/ui_bundled/fullscreen/toolbars_size.h"
#import "ios/web/common/features.h"
// static
std::unique_ptr<FullscreenController> FullscreenController::Create(
Browser* browser) {
return base::WrapUnique(new FullscreenControllerImpl(browser));
}
FullscreenControllerImpl::FullscreenControllerImpl(Browser* browser)
: FullscreenController(browser),
broadcaster_([[ChromeBroadcaster alloc] init]),
model_(std::make_unique<FullscreenModel>()),
mediator_(this, model_.get()),
web_state_list_observer_(this, model_.get(), &mediator_),
fullscreen_browser_observer_(&web_state_list_observer_, browser),
bridge_(
[[ChromeBroadcastOberverBridge alloc] initWithObserver:model_.get()]),
notification_observer_([[FullscreenSystemNotificationObserver alloc]
initWithController:this
mediator:&mediator_]) {
DCHECK(broadcaster_);
[broadcaster_ addObserver:bridge_
forSelector:@selector(broadcastScrollViewContentSize:)];
if (base::FeatureList::IsEnabled(web::features::kSmoothScrollingDefault)) {
[broadcaster_ addObserver:bridge_
forSelector:@selector(broadcastScrollViewSize:)];
[broadcaster_ addObserver:bridge_
forSelector:@selector(broadcastScrollViewIsScrolling:)];
[broadcaster_ addObserver:bridge_
forSelector:@selector(broadcastScrollViewIsDragging:)];
[broadcaster_ addObserver:bridge_
forSelector:@selector(broadcastScrollViewIsZooming:)];
[broadcaster_ addObserver:bridge_
forSelector:@selector(broadcastScrollViewContentInset:)];
[broadcaster_ addObserver:bridge_
forSelector:@selector(broadcastContentScrollOffset:)];
}
if (!IsRefactorToolbarsSize()) {
[broadcaster_ addObserver:bridge_
forSelector:@selector(broadcastCollapsedTopToolbarHeight:)];
[broadcaster_ addObserver:bridge_
forSelector:@selector(broadcastExpandedTopToolbarHeight:)];
[broadcaster_
addObserver:bridge_
forSelector:@selector(broadcastCollapsedBottomToolbarHeight:)];
[broadcaster_ addObserver:bridge_
forSelector:@selector(broadcastExpandedBottomToolbarHeight:)];
}
}
FullscreenControllerImpl::~FullscreenControllerImpl() {
mediator_.Disconnect();
web_state_list_observer_.Disconnect();
[notification_observer_ disconnect];
[broadcaster_ removeObserver:bridge_
forSelector:@selector(broadcastScrollViewContentSize:)];
if (base::FeatureList::IsEnabled(web::features::kSmoothScrollingDefault)) {
[broadcaster_ removeObserver:bridge_
forSelector:@selector(broadcastScrollViewSize:)];
[broadcaster_ removeObserver:bridge_
forSelector:@selector(broadcastScrollViewIsScrolling:)];
[broadcaster_ removeObserver:bridge_
forSelector:@selector(broadcastScrollViewIsDragging:)];
[broadcaster_ removeObserver:bridge_
forSelector:@selector(broadcastScrollViewIsZooming:)];
[broadcaster_ removeObserver:bridge_
forSelector:@selector(broadcastScrollViewContentInset:)];
[broadcaster_ removeObserver:bridge_
forSelector:@selector(broadcastContentScrollOffset:)];
}
if (!IsRefactorToolbarsSize()) {
[broadcaster_
removeObserver:bridge_
forSelector:@selector(broadcastCollapsedTopToolbarHeight:)];
[broadcaster_ removeObserver:bridge_
forSelector:@selector(broadcastExpandedTopToolbarHeight:)];
[broadcaster_
removeObserver:bridge_
forSelector:@selector(broadcastExpandedBottomToolbarHeight:)];
[broadcaster_
removeObserver:bridge_
forSelector:@selector(broadcastCollapsedBottomToolbarHeight:)];
}
}
ChromeBroadcaster* FullscreenControllerImpl::broadcaster() {
return broadcaster_;
}
void FullscreenControllerImpl::AddObserver(
FullscreenControllerObserver* observer) {
mediator_.AddObserver(observer);
}
void FullscreenControllerImpl::RemoveObserver(
FullscreenControllerObserver* observer) {
mediator_.RemoveObserver(observer);
}
bool FullscreenControllerImpl::IsEnabled() const {
return model_->enabled();
}
void FullscreenControllerImpl::IncrementDisabledCounter() {
model_->IncrementDisabledCounter();
}
void FullscreenControllerImpl::DecrementDisabledCounter() {
model_->DecrementDisabledCounter();
}
bool FullscreenControllerImpl::ResizesScrollView() const {
return model_->ResizesScrollView();
}
void FullscreenControllerImpl::BrowserTraitCollectionChangedBegin() {
mediator_.SetIsBrowserTraitCollectionUpdating(true);
}
void FullscreenControllerImpl::BrowserTraitCollectionChangedEnd() {
mediator_.SetIsBrowserTraitCollectionUpdating(false);
}
CGFloat FullscreenControllerImpl::GetProgress() const {
return model_->progress();
}
UIEdgeInsets FullscreenControllerImpl::GetMinViewportInsets() const {
return model_->min_toolbar_insets();
}
UIEdgeInsets FullscreenControllerImpl::GetMaxViewportInsets() const {
return model_->max_toolbar_insets();
}
UIEdgeInsets FullscreenControllerImpl::GetCurrentViewportInsets() const {
return model_->current_toolbar_insets();
}
void FullscreenControllerImpl::EnterFullscreen() {
mediator_.EnterFullscreen();
}
// Needs to be cleanup.
void FullscreenControllerImpl::ExitFullscreen() {
mediator_.ExitFullscreen(FullscreenExitReason::kForcedByCode);
}
void FullscreenControllerImpl::ExitFullscreen(
FullscreenExitReason fullscreen_exit_reason) {
mediator_.ExitFullscreen(fullscreen_exit_reason);
}
void FullscreenControllerImpl::ExitFullscreenWithoutAnimation() {
mediator_.ExitFullscreenWithoutAnimation();
}
bool FullscreenControllerImpl::IsForceFullscreenMode() const {
return model_->IsForceFullscreenMode();
}
void FullscreenControllerImpl::EnterForceFullscreenMode(
bool insets_update_enabled) {
model_->SetForceFullscreenMode(true);
model_->SetInsetsUpdateEnabled(insets_update_enabled);
// Disable fullscreen because:
// - It interfers with the animation when moving the secondary toolbar above
// the keyboard.
// - Fullscreen should not resize the toolbar it's above the keyboard.
IncrementDisabledCounter();
mediator_.ForceEnterFullscreen();
}
void FullscreenControllerImpl::ExitForceFullscreenMode() {
if (!IsForceFullscreenMode()) {
return;
}
DecrementDisabledCounter();
model_->SetForceFullscreenMode(false);
model_->SetInsetsUpdateEnabled(true);
mediator_.ExitFullscreenWithoutAnimation();
}
void FullscreenControllerImpl::ResizeHorizontalViewport() {
// TODO(crbug.com/40143738) this hack temporarily force change webview's
// width insets to trigger a width recomputation of its content. It will cause
// two relayouts.
mediator_.ResizeHorizontalInsets();
}
void FullscreenControllerImpl::SetToolbarsSize(ToolbarsSize* toolbars_size) {
toolbars_size_ = toolbars_size;
model_->SetToolbarsSize(toolbars_size);
}
ToolbarsSize* FullscreenControllerImpl::GetToolbarsSize() const {
return toolbars_size_;
}