// Copyright 2013 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/fullscreen_controller.h"

#include <cmath>

#include "base/logging.h"

#import "ios/chrome/browser/ui/browser_view_controller.h"
#import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h"
#import "ios/chrome/browser/ui/tabs/tab_strip_controller.h"
#import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
#import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h"
#import "ios/chrome/browser/ui/voice/voice_search_notification_names.h"
#include "ios/web/public/navigation_item.h"
#import "ios/web/public/navigation_manager.h"
#include "ios/web/public/ssl_status.h"
#import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
#import "ios/web/web_state/ui/crw_web_controller.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

NSString* const kSetupForTestingWillCloseAllTabsNotification =
    @"kSetupForTestingWillCloseAllTabsNotification";

using web::NavigationManager;

namespace {

class ScopedIncrementer {
 public:
  explicit ScopedIncrementer(int* value) : value_(value) { ++(*value_); }
  ~ScopedIncrementer() { --(*value_); }

 private:
  int* value_;
};

CGFloat kPrecision = 0.00001;

// Duration for the delay before showing the omnibox.
const double kShowOmniboxDelaySeconds = 0.5;
// Indicates if the FullScreenController returns nil from |init|. Used for
// testing purposes.
BOOL gEnabledForTests = YES;

// Compares that two CGFloat a and b are within a range of kPrecision of each
// other.
BOOL CGFloatEquals(CGFloat a, CGFloat b) {
  CGFloat delta = std::abs(a - b);

  return delta < kPrecision;
}

}  // anonymous namespace.

@interface FullScreenController ()<UIGestureRecognizerDelegate> {
  // Used to detect movement in the scrollview produced by this class.
  int selfTriggered_;
  // Used to detect if the keyboard is visible.
  BOOL keyboardIsVisible_;
  // Used to detect that the OverscrollActionsController is displaying its UI.
  // The FullScreenController is disabled when the OverscrollActionsController's
  // UI is displayed.
  BOOL overscrollActionsInProgress_;
  // Counter used to keep track of the number of actions currently disabling
  // full screen.
  uint fullScreenLock_;
  // CRWWebViewProxy object allows web view manipulations.
  id<CRWWebViewProxy> webViewProxy_;
}

// Access to the UIWebView's UIScrollView.
@property(weak, nonatomic, readonly) CRWWebViewScrollViewProxy* scrollViewProxy;
// The navigation controller of the page.
@property(nonatomic, readonly, assign) NavigationManager* navigationManager;
// The gesture recognizer set on the scrollview to detect tap. Must be readwrite
// for property releaser to work.
@property(nonatomic, readwrite, strong)
    UITapGestureRecognizer* userInteractionGestureRecognizer;
// The delegate responsible for providing the header height and moving the
// header.
@property(weak, nonatomic, readonly) id<FullScreenControllerDelegate> delegate;
// Current height of the header, in points. This is a pass-through method that
// fetches the header height from the FullScreenControllerDelegate.
@property(nonatomic, readonly) CGFloat headerHeight;
// |top| field of UIScrollView.contentInset value caused by header.
// Always 0 for WKWebView, as it does not support contentInset.
@property(nonatomic, readonly) CGFloat topContentInsetCausedByHeader;
// Last known y offset of the content in the scroll view during a scroll. Used
// to infer the direction of the current scroll.
@property(nonatomic, assign) CGFloat previousContentOffset;
// Last known y offset requested on the scroll view. In general the same value
// as previous content offset unless the offset was corrected by the controller
// to slide from under the toolbar.
@property(nonatomic, assign) CGFloat previousRequestedContentOffset;
// Whether or not the content of the scroll view fits entirely on screen when
// the toolbar is visible.
@property(nonatomic, readonly) BOOL contentFitsWithToolbarVisible;
// During a drag operation stores and remember the length of the latest scroll
// down operation. If a scroll up move happens later during the same gesture
// this will be used to delay the apparition of the header.
@property(nonatomic, assign) CGFloat lastScrollDownDistance;
// Tracks whether the current scrollview movements are triggered by the user or
// programmatically.
@property(nonatomic, assign) BOOL isUserTriggered;
// Tracks if fullscreen is currently disabled because of page load.
@property(nonatomic, assign) BOOL isFullScreenDisabledForLoading;
// Tracks if fullscreen is currently disabled because of unsecured page.
@property(nonatomic, readonly, assign) BOOL isFullScreenDisabledForSSLStatus;
// Tracks if fullscreen is currently disabled.
@property(nonatomic, readonly, assign) BOOL isFullScreenDisabled;
// Tracks if fullscreen is temporarily disabled for the current page.
@property(nonatomic, readonly, assign) BOOL isFullScreenDisabledTemporarily;
// Tracks if fullscreen is permanently disabled for the current page.
@property(nonatomic, readonly, assign) BOOL isFullScreenDisabledPermanently;
// Skip next attempt to correct the scroll offset for the toolbar height. This
// is necessary when programatically scrolling down the y offset.
@property(nonatomic, assign) BOOL skipNextScrollOffsetForHeader;
// Incremented each time a timed request to remove the header is sent,
// decremented when the timer fires. When it reach zero, the header is moved.
@property(nonatomic, assign) unsigned int delayedHideHeaderCount;
// ID of the session (each Tab represents a session).
@property(nonatomic, copy) NSString* sessionID;

// Returns if the given entry will be displayed with an error padlock. If this
// is the case, the toolbar should never be hidden on this entry.
- (BOOL)isEntryBrokenSSL:(web::NavigationItem*)item;
// Called at the start of a user scroll.
- (void)webViewScrollViewWillStartScrolling:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy;
// Called at the end of a scroll.
- (void)webViewScrollViewDidStopScrolling:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy;
// Called before and after the keyboard is appearing. Used to allow scroll
// events triggered by the keyboard appearing to go through.
- (void)keyboardStart:(NSNotification*)notification;
- (void)keyboardEnd:(NSNotification*)notification;
// Called before and after an action that disables full screen. The version
// resetting the timer will ensure that the header stay on screen for a little
// while.
- (void)incrementFullScreenLock;
- (void)decrementFullScreenLock;
// Called when the application is about to be the foreground application.
- (void)applicationWillEnterForeground:(NSNotification*)notification;
// Called from -webViewScrollViewDidScroll: Returns YES if the scroll should be
// ignored.
- (BOOL)shouldIgnoreScroll:(CRWWebViewScrollViewProxy*)webViewScrollViewProxy;
// Processes a scroll event triggered by a user action.
- (void)userTriggeredWebViewScrollViewDidScroll:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy;
// Processes a scroll event triggered by code (these could be initiated via
// Javascript, find in page or simply the keyboard sliding in and out).
- (void)codeTriggeredWebViewScrollViewDidScroll:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy;
// Returns YES if |scrollView_| is for the current tab.
- (BOOL)isScrollViewForCurrentTab;
// Shows the header. The header is hidden after kHideOmniboxDelaySeconds if the
// page requested fullscreen explicitly.
- (void)triggerHeader;
// Sets top inset to content view, and updates scroll view content offset to
// counteract the change in the content's view frame.
- (void)setContentViewTopContentPadding:(CGFloat)newTopInset;
// Hide the header if it is possible to do so.
- (void)hideHeaderIfPossible;
// Shows or hides the header as directed by |visible|. If necessary the delegate
// will be called synchronously with the desired offset and |animate| value.
// This method can be called when it is desirable to show or hide the header
// programmatically. It must be called when the header size changes.
- (void)moveHeaderToRestingPosition:(BOOL)visible animate:(BOOL)animate;
@end

@implementation FullScreenController

@synthesize delegate = delegate_;
@synthesize navigationManager = navigationManager_;
@synthesize previousContentOffset = previousContentOffset_;
@synthesize previousRequestedContentOffset = previousRequestedContentOffset_;
@synthesize lastScrollDownDistance = lastScrollDownDistance_;
@synthesize immediateDragDown = immediateDragDown_;
@synthesize isUserTriggered = userTriggered_;
@synthesize isFullScreenDisabledForLoading = isFullScreenDisabledForLoading_;
@synthesize skipNextScrollOffsetForHeader = skipNextScrollOffsetForHeader_;
@synthesize delayedHideHeaderCount = delayedHideHeaderCount_;
@synthesize sessionID = sessionID_;
@synthesize userInteractionGestureRecognizer =
    userInteractionGestureRecognizer_;

- (id)initWithDelegate:(id<FullScreenControllerDelegate>)delegate
     navigationManager:(NavigationManager*)navigationManager
             sessionID:(NSString*)sessionID {
  if (!gEnabledForTests)
    return nil;
  if ((self = [super init])) {
    DCHECK(sessionID);
    DCHECK(delegate);
    delegate_ = delegate;
    sessionID_ = [sessionID copy];
    navigationManager_ = navigationManager;

    NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
    [center addObserver:self
               selector:@selector(keyboardStart:)
                   name:UIKeyboardWillShowNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(keyboardEnd:)
                   name:UIKeyboardWillHideNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(incrementFullScreenLock)
                   name:kMenuWillShowNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(decrementFullScreenLock)
                   name:kMenuWillHideNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(triggerHeader)
                   name:kWillStartTabStripTabAnimation
                 object:nil];
    [center addObserver:self
               selector:@selector(incrementFullScreenLock)
                   name:kTabHistoryPopupWillShowNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(decrementFullScreenLock)
                   name:kTabHistoryPopupWillHideNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(incrementFullScreenLock)
                   name:kVoiceSearchWillShowNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(decrementFullScreenLock)
                   name:kVoiceSearchWillHideNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(incrementFullScreenLock)
                   name:kVoiceSearchBarViewButtonSelectedNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(decrementFullScreenLock)
                   name:kVoiceSearchBarViewButtonDeselectedNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(applicationWillEnterForeground:)
                   name:UIApplicationWillEnterForegroundNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(triggerHeader)
                   name:kSetupForTestingWillCloseAllTabsNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(incrementFullScreenLock)
                   name:ios_internal::kPageInfoWillShowNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(decrementFullScreenLock)
                   name:ios_internal::kPageInfoWillHideNotification
                 object:nil];
    [center
        addObserver:self
           selector:@selector(incrementFullScreenLock)
               name:ios_internal::kLocationBarBecomesFirstResponderNotification
             object:nil];
    [center
        addObserver:self
           selector:@selector(decrementFullScreenLock)
               name:ios_internal::kLocationBarResignsFirstResponderNotification
             object:nil];
    [center addObserver:self
               selector:@selector(incrementFullScreenLock)
                   name:kTabStripDragStarted
                 object:nil];
    [center addObserver:self
               selector:@selector(decrementFullScreenLock)
                   name:kTabStripDragEnded
                 object:nil];
    [center addObserver:self
               selector:@selector(incrementFullScreenLock)
                   name:ios_internal::kSideSwipeWillStartNotification
                 object:nil];
    [center addObserver:self
               selector:@selector(decrementFullScreenLock)
                   name:ios_internal::kSideSwipeDidStopNotification
                 object:nil];
    // TODO(crbug.com/451373): Evaluate using listeners instead of
    // notifications.
    [center addObserver:self
               selector:@selector(overscrollActionsWillStart)
                   name:kOverscrollActionsWillStart
                 object:nil];
    [center addObserver:self
               selector:@selector(overscrollActionsDidEnd)
                   name:kOverscrollActionsDidEnd
                 object:nil];
    [self moveHeaderToRestingPosition:YES];
  }
  return self;
}

- (void)invalidate {
  delegate_ = nil;
  navigationManager_ = NULL;
  [self.scrollViewProxy removeObserver:self];
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)dealloc {
  [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (CRWWebViewScrollViewProxy*)scrollViewProxy {
  return [webViewProxy_ scrollViewProxy];
}

- (CGFloat)headerHeight {
  return [self.delegate headerHeight];
}

- (CGFloat)topContentInsetCausedByHeader {
  if ([webViewProxy_ shouldUseInsetForTopPadding]) {
    // If the web view's |shouldUseInsetForTopPadding| is YES, fullscreen
    // header insets the content by modifying content inset.
    return self.headerHeight;
  }
  return 0.0f;
}

- (void)moveHeaderToRestingPosition:(BOOL)visible {
  [self moveHeaderToRestingPosition:visible animate:YES];
}

- (void)moveHeaderToRestingPosition:(BOOL)visible animate:(BOOL)animate {
  // If there is no delegate there is no need to do anything as the headerHeight
  // cannot be obtained.
  if (!self.delegate)
    return;
  DCHECK(visible || !self.isFullScreenDisabled);

  // The desired final position of the header.
  CGFloat headerPosition = visible ? 0.0 : self.headerHeight;

  // Check if there is anything to do.
  CGFloat delta = self.delegate.currentHeaderOffset - headerPosition;
  if (CGFloatEquals(delta, 0.0))
    return;

  // Do not further act on scrollview changes.
  ScopedIncrementer stack(&(self->selfTriggered_));

  // If the scrollview is not the current scrollview, don't update the UI.
  if (![self isScrollViewForCurrentTab])
    return;

  if (self.scrollViewProxy.contentOffset.y < 0.0 && delta < 0.0) {
    // If the delta is negative this means the header must be hidden more. Check
    // if the scrollview extents to the right place, there may be a need to
    // scroll it up.
    [self.delegate fullScreenController:self
               drawHeaderViewFromOffset:headerPosition
                         onWebViewProxy:webViewProxy_
                changeTopContentPadding:NO
                      scrollingToOffset:0.0f];
  } else {
    if (!visible && ![webViewProxy_ shouldUseInsetForTopPadding]) {
      // The header will be hidden, so if the content view is not using the
      // content inset, it is necessary to decrease the top padding, so more
      // content is visible to the user.
      CGFloat newTopContentPadding = self.headerHeight - headerPosition;
      CGFloat topContentPaddingChange =
          [webViewProxy_ topContentPadding] - newTopContentPadding;
      if (topContentPaddingChange <= self.scrollViewProxy.contentOffset.y) {
        // Padding can be decreased immediately and without animation as there
        // is enough content present behind the header.
        [self setContentViewTopContentPadding:newTopContentPadding];
      } else {
        // Header is taller that amount of hidden content, hence animated hide
        // is required.
        [self.delegate fullScreenController:self
                   drawHeaderViewFromOffset:headerPosition
                             onWebViewProxy:webViewProxy_
                    changeTopContentPadding:YES
                          scrollingToOffset:0.0f];
        return;
      }
    }
    // Only move the header, the content doesn't need to move.
    [self.delegate fullScreenController:self
               drawHeaderViewFromOffset:headerPosition
                                animate:animate];
  }
}

- (void)disableFullScreen {
  [self moveHeaderToRestingPosition:YES];
  self.isFullScreenDisabledForLoading = YES;
}

- (void)enableFullScreen {
  self.isFullScreenDisabledForLoading = NO;
}

- (void)shouldSkipNextScrollOffsetForHeader {
  self.skipNextScrollOffsetForHeader = YES;
}

- (void)moveContentBelowHeader {
  DCHECK(delegate_);
  DCHECK(webViewProxy_);
  [self moveHeaderToRestingPosition:YES animate:NO];
  CGPoint contentOffset = self.scrollViewProxy.contentOffset;
  contentOffset.y = 0;
  self.scrollViewProxy.contentOffset = contentOffset;
}

#pragma mark - private methods

- (BOOL)isEntryBrokenSSL:(web::NavigationItem*)item {
  if (!item)
    return NO;
  // Only BROKEN results in an error (vs. a warning); see toolbar_model_impl.cc.
  // TODO(qsr): Find a way to share this logic with the omnibox.
  const web::SSLStatus& ssl = item->GetSSL();
  switch (ssl.security_style) {
    case web::SECURITY_STYLE_UNKNOWN:
    case web::SECURITY_STYLE_UNAUTHENTICATED:
    case web::SECURITY_STYLE_AUTHENTICATED:
      return NO;
    case web::SECURITY_STYLE_AUTHENTICATION_BROKEN:
      return YES;
    default:
      NOTREACHED();
      return YES;
  }
}

- (BOOL)isFullScreenDisabled {
  return self.isFullScreenDisabledTemporarily ||
         self.isFullScreenDisabledPermanently;
}

- (BOOL)isFullScreenDisabledTemporarily {
  return fullScreenLock_ > 0 || self.isFullScreenDisabledForLoading;
}

- (BOOL)isFullScreenDisabledForSSLStatus {
  return self.navigationManager &&
         [self isEntryBrokenSSL:self.navigationManager->GetVisibleItem()];
}

- (BOOL)isFullScreenDisabledPermanently {
  return UIAccessibilityIsVoiceOverRunning() ||
         self.isFullScreenDisabledForSSLStatus ||
         CGRectIsEmpty(self.scrollViewProxy.frame);
}

- (void)hideHeaderIfPossible {
  // Covers a number of conditions, like a menu being up.
  if (self.isFullScreenDisabled)
    return;

  // Another FullScreenController is in control.
  if (![self isScrollViewForCurrentTab])
    return;

  // No autohide if the content needs to move.
  if (self.scrollViewProxy.contentOffset.y < 0.0)
    return;

  // It is quite safe to move the toolbar away.
  [self moveHeaderToRestingPosition:NO];
}

- (void)incrementFullScreenLock {
  // This method may be called late enough that it is unsafe to access the
  // delegate.
  fullScreenLock_++;
}

- (void)decrementFullScreenLock {
  // The corresponding notification for incrementing the lock may have been
  // posted before the FullScreenController was initialized. This can occur
  // when entering a URL or search query from the NTP since the CRWWebController
  // begins loading the page before the keyboard is dismissed.
  if (fullScreenLock_ > 0)
    fullScreenLock_--;
}

- (void)keyboardStart:(NSNotification*)notification {
  if (!keyboardIsVisible_) {
    keyboardIsVisible_ = YES;
    [self incrementFullScreenLock];
  }
  [self moveHeaderToRestingPosition:YES];
}

- (void)keyboardEnd:(NSNotification*)notification {
  if (keyboardIsVisible_) {
    keyboardIsVisible_ = NO;
    [self decrementFullScreenLock];
  }
}

- (void)applicationWillEnterForeground:(NSNotification*)notification {
  if (!self.isFullScreenDisabled && [self isScrollViewForCurrentTab]) {
    dispatch_time_t popTime = dispatch_time(
        DISPATCH_TIME_NOW, (int64_t)(kShowOmniboxDelaySeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^{
      [self triggerHeader];
    });
  }
}

- (void)webViewScrollViewWillStartScrolling:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
  self.isUserTriggered = YES;
  self.lastScrollDownDistance = 0.0;
}

- (void)webViewScrollViewDidStopScrolling:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
  self.isUserTriggered = NO;
  // If an overscroll action is in progress, it means the header is already
  // shown, trying to reset its position would interfere with the
  // OverscrollActionsController.
  if (!overscrollActionsInProgress_) {
    CGFloat threshold = self.headerHeight / 2.0;

    BOOL visible = self.delegate.currentHeaderOffset < threshold ||
                   self.isFullScreenDisabled;
    [self moveHeaderToRestingPosition:visible];
  }
}

- (BOOL)shouldIgnoreScroll:(CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
  if (overscrollActionsInProgress_)
    return YES;

  if (![self isScrollViewForCurrentTab])
    return YES;

  BOOL shouldIgnore = selfTriggered_ || webViewScrollViewProxy.isZooming ||
                      self.headerHeight == 0.0 || !self.delegate;

  if (self.isUserTriggered)
    return shouldIgnore;

  // Ignore simple realignment moves by 1 one pixel on retina display, called
  // sometimes at the end of an animation.
  CGFloat moveMagnitude = std::abs(self.previousContentOffset -
                                   webViewScrollViewProxy.contentOffset.y);
  shouldIgnore = shouldIgnore || moveMagnitude <= 0.5;

  // Never let the background show. The keyboard may sometimes center the
  // input fields in such a way that the inset of the scrollview is showing.
  // In those cases the header must be popped up unconditionally.
  CGFloat headerOffset = self.headerHeight - self.delegate.currentHeaderOffset;
  if (webViewScrollViewProxy.contentOffset.y + headerOffset < 0.0)
    shouldIgnore = NO;

  return shouldIgnore;
}

- (BOOL)contentFitsWithToolbarVisible {
  CGFloat viewportHeight = CGRectGetHeight(self.scrollViewProxy.frame) -
                           self.topContentInsetCausedByHeader;
  return self.scrollViewProxy.contentSize.height <= viewportHeight;
}

- (void)userTriggeredWebViewScrollViewDidScroll:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
  // Calculate the relative move compared to the last checked position: positive
  // values are scroll up, negative are scroll down.
  CGFloat verticalDelta =
      webViewScrollViewProxy.contentOffset.y - self.previousContentOffset;

  // Scroll view is scrolled all the way to the top. Ignore the bouce up.
  BOOL isContentAtTop = webViewScrollViewProxy.contentOffset.y <=
                        -self.topContentInsetCausedByHeader;
  BOOL ignoreScrollAtContentTop = isContentAtTop && (0.0f < verticalDelta);

  // Scroll view is scrolled all the way to the bottom. Ignore the bounce down.
  // Also ignore the scroll up if the page is visible with the toolbar on-screen
  // as the toolbar should not be hidden in that case.
  BOOL ignoreScrollAtContentBottom =
      (webViewScrollViewProxy.contentOffset.y +
           webViewScrollViewProxy.frame.size.height >=
       webViewScrollViewProxy.contentSize.height) &&
      (verticalDelta < 0.0 || [self contentFitsWithToolbarVisible]);

  if (ignoreScrollAtContentTop || ignoreScrollAtContentBottom)
    verticalDelta = 0.0;

  if (!self.immediateDragDown) {
    // Accumulate or reset the lastScrollDownDistance. Scrolling up consumes
    // twice as fast as scrolling down accumulates.
    if (verticalDelta > 0.0)
      self.lastScrollDownDistance += verticalDelta;
    else
      self.lastScrollDownDistance += verticalDelta * 2.0;

    if (self.lastScrollDownDistance < 0.0)
      self.lastScrollDownDistance = 0.0;
  }

  // Changes the header offset and informs the delegate to perform the move.
  CGFloat newHeaderOffset = self.delegate.currentHeaderOffset;
  if (verticalDelta > 0.0 || webViewScrollViewProxy.contentOffset.y <= 0.0 ||
      self.lastScrollDownDistance <= 0.0) {
    newHeaderOffset += verticalDelta;
  }
  if (newHeaderOffset < 0.0)
    newHeaderOffset = 0.0;
  else if (newHeaderOffset > self.headerHeight)
    newHeaderOffset = self.headerHeight;

  [self.delegate fullScreenController:self
             drawHeaderViewFromOffset:newHeaderOffset
                              animate:NO];
}

- (void)codeTriggeredWebViewScrollViewDidScroll:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
  if (webViewScrollViewProxy.contentOffset.y >= 0.0 && !keyboardIsVisible_)
    return;

  BOOL isFullyVisible = CGFloatEquals(self.delegate.currentHeaderOffset, 0.0);
  if (keyboardIsVisible_) {
    DCHECK(isFullyVisible);
    return;
  }

  CGFloat newOffset;
  if ([self contentFitsWithToolbarVisible] && !keyboardIsVisible_) {
    // Align the content just below the header if the scroll view's content fits
    // entirely on screen when the toolbar visible and if the keyboard is not
    // visible.
    // Note: The keyboard is visible when the user is editing a text field
    // at the bottom of the page and the page is scrolled to make it visible
    // for the user. Avoid changing the offset in this case.
    newOffset = -self.headerHeight;
  } else {
    newOffset = webViewScrollViewProxy.contentOffset.y;
    // Correct the offset to take into account the fact that the header is
    // obscuring the top of the view when scrolling down.
    if ((webViewScrollViewProxy.contentOffset.y <=
             self.previousRequestedContentOffset ||
         keyboardIsVisible_) &&
        !self.skipNextScrollOffsetForHeader)
      newOffset -= self.headerHeight;

    // Make sure the content is not too low.
    if (newOffset < -self.headerHeight)
      newOffset = -self.headerHeight;
  }

  if (isFullyVisible) {
    // As the header is already visible, just move the scrollview.
    webViewScrollViewProxy.contentOffset =
        CGPointMake(webViewScrollViewProxy.contentOffset.x, newOffset);
  }
}

- (BOOL)isScrollViewForCurrentTab {
  return [self.delegate isTabWithIDCurrent:self.sessionID];
}

- (void)triggerHeader {
  if (self.isFullScreenDisabled || ![self isScrollViewForCurrentTab])
    return;
  [self moveHeaderToRestingPosition:YES];
}

- (void)setContentViewTopContentPadding:(CGFloat)newTopPadding {
  [webViewProxy_ setTopContentPadding:newTopPadding];
}

- (void)setToolbarInsetsForHeaderOffset:(CGFloat)headerOffset {
  // Make space for the header in the scroll view.
  CGFloat topInset = self.headerHeight - headerOffset;
  UIEdgeInsets insets = self.scrollViewProxy.contentInset;
  insets.top = topInset;

  [self setContentViewTopContentPadding:topInset];
}

#pragma mark -
#pragma mark CRWWebControllerObserver methods

- (void)setWebViewProxy:(id<CRWWebViewProxy>)webViewProxy
             controller:(CRWWebController*)webController {
  DCHECK([webViewProxy scrollViewProxy]);
  webViewProxy_ = webViewProxy;
  [[webViewProxy scrollViewProxy] addObserver:self];
}

- (void)pageLoaded:(CRWWebController*)webController {
  [self enableFullScreen];
  web::WebState* webState = webController.webState;
  if (webState) {
    BOOL MIMETypeIsPDF = webState->GetContentsMimeType() == "application/pdf";
    [webViewProxy_ setShouldUseInsetForTopPadding:MIMETypeIsPDF];
  }
}

#pragma mark -
#pragma mark CRWWebViewScrollViewObserver

- (void)webViewScrollViewDidScroll:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
  CGFloat previousRequestedContentOffset =
      webViewScrollViewProxy.contentOffset.y;
  if ([self shouldIgnoreScroll:webViewScrollViewProxy]) {
    // Do not act on those events, just record the eventual move.
    self.previousContentOffset = previousRequestedContentOffset;
    self.previousRequestedContentOffset = previousRequestedContentOffset;
    return;
  }

  // Ignore any scroll moves called recursively.
  ScopedIncrementer stack(&(self->selfTriggered_));

  if (self.isUserTriggered) {
    if (!self.isFullScreenDisabled)
      [self userTriggeredWebViewScrollViewDidScroll:webViewScrollViewProxy];
  } else {
    [self codeTriggeredWebViewScrollViewDidScroll:webViewScrollViewProxy];
  }
  self.previousContentOffset = webViewScrollViewProxy.contentOffset.y;
  self.previousRequestedContentOffset = previousRequestedContentOffset;
}
- (void)webViewScrollViewWillBeginDragging:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
  [self webViewScrollViewWillStartScrolling:webViewScrollViewProxy];
}

- (void)webViewScrollViewDidEndDragging:
            (CRWWebViewScrollViewProxy*)webViewScrollViewProxy
                         willDecelerate:(BOOL)decelerate {
  DCHECK(self.delegate);
  if (!decelerate)
    [self webViewScrollViewDidStopScrolling:webViewScrollViewProxy];
}

- (void)webViewScrollViewDidEndScrollingAnimation:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
  self.skipNextScrollOffsetForHeader = NO;
}

- (void)webViewScrollViewDidEndDecelerating:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
  DCHECK(self.delegate);
  [self webViewScrollViewDidStopScrolling:webViewScrollViewProxy];
}

- (BOOL)webViewScrollViewShouldScrollToTop:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
  if (webViewScrollViewProxy.contentInset.top != self.headerHeight) {
    // Move the toolbar first so the origin of the page moves down.
    [self moveHeaderToRestingPosition:YES];
  }
  return YES;
}

#pragma mark -
#pragma mark CRWWebViewScrollViewProxyObserver

- (void)webViewScrollViewProxyDidSetScrollView:
    (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
  webViewScrollViewProxy.contentOffset = CGPointMake(0.0, -self.headerHeight);
  [self setToolbarInsetsForHeaderOffset:0.0];
}

#pragma mark - UIGestureRecognizerDelegate

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer {
  return YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
    shouldRecognizeSimultaneouslyWithGestureRecognizer:
        (UIGestureRecognizer*)otherGestureRecognizer {
  // This is necessary for the gesture recognizer to receive all the touches.
  // If the default value of NO is returned the default recognizers on the
  // webview do take precedence.
  return YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
       shouldReceiveTouch:(UITouch*)touch {
  return YES;
}

#pragma mark - Overscroll actions notifications handling

- (void)overscrollActionsWillStart {
  [self incrementFullScreenLock];
  overscrollActionsInProgress_ = YES;
}

- (void)overscrollActionsDidEnd {
  [self decrementFullScreenLock];
  overscrollActionsInProgress_ = NO;
}

#pragma mark - Used for testing

+ (void)setEnabledForTests:(BOOL)enabled {
  gEnabledForTests = enabled;
}

@end
