/*
 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "third_party/blink/renderer/core/exported/web_view_impl.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/memory/scoped_refptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "cc/layers/picture_layer.h"
#include "media/base/media_switches.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/common/input/web_menu_source_type.h"
#include "third_party/blink/public/common/page/page_zoom.h"
#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
#include "third_party/blink/public/common/switches.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h"
#include "third_party/blink/public/platform/interface_registry.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
#include "third_party/blink/public/platform/web_media_player.h"
#include "third_party/blink/public/platform/web_network_state_notifier.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
#include "third_party/blink/public/platform/web_text_input_info.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/web_autofill_client.h"
#include "third_party/blink/public/web/web_console_message.h"
#include "third_party/blink/public/web/web_element.h"
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_hit_test_result.h"
#include "third_party/blink/public/web/web_input_element.h"
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_meaningful_layout.h"
#include "third_party/blink/public/web/web_node.h"
#include "third_party/blink/public/web/web_plugin.h"
#include "third_party/blink/public/web/web_range.h"
#include "third_party/blink/public/web/web_render_theme.h"
#include "third_party/blink/public/web/web_view_client.h"
#include "third_party/blink/public/web/web_window_features.h"
#include "third_party/blink/renderer/core/clipboard/data_object.h"
#include "third_party/blink/renderer/core/content_capture/content_capture_manager.h"
#include "third_party/blink/renderer/core/core_initializer.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/dom/context_features_client_impl.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h"
#include "third_party/blink/renderer/core/dom/text.h"
#include "third_party/blink/renderer/core/editing/editing_utilities.h"
#include "third_party/blink/renderer/core/editing/editor.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/ime/input_method_controller.h"
#include "third_party/blink/renderer/core/editing/iterators/text_iterator.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/serializers/html_interchange.h"
#include "third_party/blink/renderer/core/editing/serializers/serialization.h"
#include "third_party/blink/renderer/core/events/current_input_event.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/events/ui_event_with_key_state.h"
#include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
#include "third_party/blink/renderer/core/events/wheel_event.h"
#include "third_party/blink/renderer/core/exported/web_dev_tools_agent_impl.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
#include "third_party/blink/renderer/core/exported/web_settings_impl.h"
#include "third_party/blink/renderer/core/frame/browser_controls.h"
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
#include "third_party/blink/renderer/core/frame/fullscreen_controller.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/page_scale_constraints_set.h"
#include "third_party/blink/renderer/core/frame/remote_frame.h"
#include "third_party/blink/renderer/core/frame/resize_viewport_anchor.h"
#include "third_party/blink/renderer/core/frame/rotation_viewport_anchor.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/viewport_data.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/frame/web_frame_widget_impl.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/frame/web_remote_frame_impl.h"
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/html/forms/html_text_area_element.h"
#include "third_party/blink/renderer/core/html/html_plugin_element.h"
#include "third_party/blink/renderer/core/html/plugin_document.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/input/context_menu_allowed_scope.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/input/touch_action_util.h"
#include "third_party/blink/renderer/core/inspector/dev_tools_emulator.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/text_autosizer.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/loader/frame_load_request.h"
#include "third_party/blink/renderer/core/loader/frame_loader.h"
#include "third_party/blink/renderer/core/loader/interactive_detector.h"
#include "third_party/blink/renderer/core/loader/no_state_prefetch_client.h"
#include "third_party/blink/renderer/core/page/chrome_client_impl.h"
#include "third_party/blink/renderer/core/page/context_menu_controller.h"
#include "third_party/blink/renderer/core/page/context_menu_provider.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/frame_tree.h"
#include "third_party/blink/renderer/core/page/link_highlight.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/page_popup_client.h"
#include "third_party/blink/renderer/core/page/pointer_lock_controller.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
#include "third_party/blink/renderer/core/page/scrolling/top_document_root_scroller_controller.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/paint/paint_timing.h"
#include "third_party/blink/renderer/core/paint/paint_timing_detector.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/window_performance.h"
#include "third_party/blink/renderer/platform/fonts/font_cache.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/keyboard_codes.h"
#include "third_party/blink/renderer/platform/loader/fetch/unique_identifier.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/page_lifecycle_state.h"
#include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h"
#include "third_party/blink/renderer/platform/widget/widget_base.h"
#include "third_party/icu/source/common/unicode/uscript.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/skia_util.h"

#if defined(OS_ANDROID)
#include "components/viz/common/features.h"
#endif

#if !defined(OS_MAC)
#include "skia/ext/legacy_display_globals.h"
#include "third_party/blink/public/platform/web_font_render_style.h"
#include "ui/gfx/font_render_params.h"
#endif

#if defined(OS_WIN)
#include "third_party/blink/public/web/win/web_font_rendering.h"
#endif

// Get rid of WTF's pow define so we can use std::pow.
#undef pow
#include <cmath>  // for std::pow

#include "build/chromeos_buildflags.h"

// The following constants control parameters for automated scaling of webpages
// (such as due to a double tap gesture or find in page etc.). These are
// experimentally determined.
static const int touchPointPadding = 32;
static const int nonUserInitiatedPointPadding = 11;
static const float minScaleDifference = 0.01f;
static const float doubleTapZoomContentDefaultMargin = 5;
static const float doubleTapZoomContentMinimumMargin = 2;
static constexpr base::TimeDelta kDoubleTapZoomAnimationDuration =
    base::TimeDelta::FromMilliseconds(250);
static const float doubleTapZoomAlreadyLegibleRatio = 1.2f;

static constexpr base::TimeDelta kFindInPageAnimationDuration;

// Constants for viewport anchoring on resize.
static const float viewportAnchorCoordX = 0.5f;
static const float viewportAnchorCoordY = 0;

// Constants for zooming in on a focused text field.
static constexpr base::TimeDelta kScrollAndScaleAnimationDuration =
    base::TimeDelta::FromMicroseconds(200);
static const int minReadableCaretHeight = 16;
static const int minReadableCaretHeightForTextArea = 13;
static const float minScaleChangeToTriggerZoom = 1.5f;
static const float leftBoxRatio = 0.3f;
static const int caretPadding = 10;

namespace blink {

using mojom::blink::EffectiveConnectionType;

// Historically, these values came from Webkit in
// WebKitLegacy/mac/WebView/WebView.mm (named MinimumZoomMultiplier and
// MaximumZoomMultiplier there).
const double WebView::kMinTextSizeMultiplier = 0.5;
const double WebView::kMaxTextSizeMultiplier = 3.0;

// static
HashSet<WebViewImpl*>& WebViewImpl::AllInstances() {
  DEFINE_STATIC_LOCAL(HashSet<WebViewImpl*>, all_instances, ());
  return all_instances;
}

static bool g_should_use_external_popup_menus = false;

void WebView::SetUseExternalPopupMenus(bool use_external_popup_menus) {
  g_should_use_external_popup_menus = use_external_popup_menus;
}

bool WebViewImpl::UseExternalPopupMenus() {
  return g_should_use_external_popup_menus;
}

namespace {

class EmptyEventListener final : public NativeEventListener {
 public:
  void Invoke(ExecutionContext* execution_context, Event*) override {}
};

typedef void (*SetFontFamilyWrapper)(blink::WebSettings*,
                                     const base::string16&,
                                     UScriptCode);

void SetStandardFontFamilyWrapper(WebSettings* settings,
                                  const base::string16& font,
                                  UScriptCode script) {
  settings->SetStandardFontFamily(WebString::FromUTF16(font), script);
}

void SetFixedFontFamilyWrapper(WebSettings* settings,
                               const base::string16& font,
                               UScriptCode script) {
  settings->SetFixedFontFamily(WebString::FromUTF16(font), script);
}

void SetSerifFontFamilyWrapper(WebSettings* settings,
                               const base::string16& font,
                               UScriptCode script) {
  settings->SetSerifFontFamily(WebString::FromUTF16(font), script);
}

void SetSansSerifFontFamilyWrapper(WebSettings* settings,
                                   const base::string16& font,
                                   UScriptCode script) {
  settings->SetSansSerifFontFamily(WebString::FromUTF16(font), script);
}

void SetCursiveFontFamilyWrapper(WebSettings* settings,
                                 const base::string16& font,
                                 UScriptCode script) {
  settings->SetCursiveFontFamily(WebString::FromUTF16(font), script);
}

void SetFantasyFontFamilyWrapper(WebSettings* settings,
                                 const base::string16& font,
                                 UScriptCode script) {
  settings->SetFantasyFontFamily(WebString::FromUTF16(font), script);
}

void SetPictographFontFamilyWrapper(WebSettings* settings,
                                    const base::string16& font,
                                    UScriptCode script) {
  settings->SetPictographFontFamily(WebString::FromUTF16(font), script);
}

// If |scriptCode| is a member of a family of "similar" script codes, returns
// the script code in that family that is used by WebKit for font selection
// purposes.  For example, USCRIPT_KATAKANA_OR_HIRAGANA and USCRIPT_JAPANESE are
// considered equivalent for the purposes of font selection.  WebKit uses the
// script code USCRIPT_KATAKANA_OR_HIRAGANA.  So, if |scriptCode| is
// USCRIPT_JAPANESE, the function returns USCRIPT_KATAKANA_OR_HIRAGANA.  WebKit
// uses different scripts than the ones in Chrome pref names because the version
// of ICU included on certain ports does not have some of the newer scripts.  If
// |scriptCode| is not a member of such a family, returns |scriptCode|.
UScriptCode GetScriptForWebSettings(UScriptCode scriptCode) {
  switch (scriptCode) {
    case USCRIPT_HIRAGANA:
    case USCRIPT_KATAKANA:
    case USCRIPT_JAPANESE:
      return USCRIPT_KATAKANA_OR_HIRAGANA;
    case USCRIPT_KOREAN:
      return USCRIPT_HANGUL;
    default:
      return scriptCode;
  }
}

void ApplyFontsFromMap(const web_pref::ScriptFontFamilyMap& map,
                       SetFontFamilyWrapper setter,
                       WebSettings* settings) {
  for (auto& it : map) {
    int32_t script = u_getPropertyValueEnum(UCHAR_SCRIPT, (it.first).c_str());
    if (script >= 0 && script < USCRIPT_CODE_LIMIT) {
      UScriptCode code = static_cast<UScriptCode>(script);
      (*setter)(settings, it.second, GetScriptForWebSettings(code));
    }
  }
}

void ApplyCommandLineToSettings(WebSettings* settings) {
  const base::CommandLine& command_line =
      *base::CommandLine::ForCurrentProcess();

  WebSettings::SelectionStrategyType selection_strategy;
  if (command_line.GetSwitchValueASCII(switches::kTouchTextSelectionStrategy) ==
      "direction")
    selection_strategy = WebSettings::SelectionStrategyType::kDirection;
  else
    selection_strategy = WebSettings::SelectionStrategyType::kCharacter;
  settings->SetSelectionStrategy(selection_strategy);

  WebString passive_listeners_default = WebString::FromUTF8(
      command_line.GetSwitchValueASCII(switches::kPassiveListenersDefault));
  if (!passive_listeners_default.IsEmpty()) {
    WebSettings::PassiveEventListenerDefault passive_default =
        WebSettings::PassiveEventListenerDefault::kFalse;
    if (passive_listeners_default == "true")
      passive_default = WebSettings::PassiveEventListenerDefault::kTrue;
    else if (passive_listeners_default == "forcealltrue")
      passive_default = WebSettings::PassiveEventListenerDefault::kForceAllTrue;
    settings->SetPassiveEventListenerDefault(passive_default);
  }

  WebString network_quiet_timeout = WebString::FromUTF8(
      command_line.GetSwitchValueASCII(switches::kNetworkQuietTimeout));
  if (!network_quiet_timeout.IsEmpty()) {
    bool ok;
    double network_quiet_timeout_seconds =
        String(network_quiet_timeout).ToDouble(&ok);
    if (ok)
      settings->SetNetworkQuietTimeout(network_quiet_timeout_seconds);
  }

  if (command_line.HasSwitch(switches::kBlinkSettings)) {
    Vector<String> blink_settings;
    String command_line_settings =
        command_line.GetSwitchValueASCII(switches::kBlinkSettings).c_str();
    command_line_settings.Split(",", blink_settings);
    for (const String& setting : blink_settings) {
      wtf_size_t pos = setting.find('=');
      settings->SetFromStrings(
          WebString(setting.Substring(0, pos)),
          WebString(pos == kNotFound ? "" : setting.Substring(pos + 1)));
    }
  }
}

WebMediaPlayer::SurfaceLayerMode GetVideoSurfaceLayerMode() {
#if defined(OS_ANDROID)
  if (base::FeatureList::IsEnabled(media::kDisableSurfaceLayerForVideo) &&
      !::features::IsUsingVizForWebView())
    return WebMediaPlayer::SurfaceLayerMode::kNever;
#endif  // OS_ANDROID

  return WebMediaPlayer::SurfaceLayerMode::kAlways;
}

ui::mojom::blink::WindowOpenDisposition NavigationPolicyToDisposition(
    NavigationPolicy policy) {
  switch (policy) {
    case kNavigationPolicyDownload:
      return ui::mojom::blink::WindowOpenDisposition::SAVE_TO_DISK;
    case kNavigationPolicyCurrentTab:
      return ui::mojom::blink::WindowOpenDisposition::CURRENT_TAB;
    case kNavigationPolicyNewBackgroundTab:
      return ui::mojom::blink::WindowOpenDisposition::NEW_BACKGROUND_TAB;
    case kNavigationPolicyNewForegroundTab:
      return ui::mojom::blink::WindowOpenDisposition::NEW_FOREGROUND_TAB;
    case kNavigationPolicyNewWindow:
      return ui::mojom::blink::WindowOpenDisposition::NEW_WINDOW;
    case kNavigationPolicyNewPopup:
      return ui::mojom::blink::WindowOpenDisposition::NEW_POPUP;
  }
  NOTREACHED() << "Unexpected NavigationPolicy";
  return ui::mojom::blink::WindowOpenDisposition::IGNORE_ACTION;
}

#if !defined(OS_MAC) && !defined(OS_WIN)
SkFontHinting RendererPreferencesToSkiaHinting(
    const blink::RendererPreferences& prefs) {
// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
// complete.
#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
  if (!prefs.should_antialias_text) {
    // When anti-aliasing is off, GTK maps all non-zero hinting settings to
    // 'Normal' hinting so we do the same. Otherwise, folks who have 'Slight'
    // hinting selected will see readable text in everything expect Chromium.
    switch (prefs.hinting) {
      case gfx::FontRenderParams::HINTING_NONE:
        return SkFontHinting::kNone;
      case gfx::FontRenderParams::HINTING_SLIGHT:
      case gfx::FontRenderParams::HINTING_MEDIUM:
      case gfx::FontRenderParams::HINTING_FULL:
        return SkFontHinting::kNormal;
      default:
        NOTREACHED();
        return SkFontHinting::kNormal;
    }
  }
#endif

  switch (prefs.hinting) {
    case gfx::FontRenderParams::HINTING_NONE:
      return SkFontHinting::kNone;
    case gfx::FontRenderParams::HINTING_SLIGHT:
      return SkFontHinting::kSlight;
    case gfx::FontRenderParams::HINTING_MEDIUM:
      return SkFontHinting::kNormal;
    case gfx::FontRenderParams::HINTING_FULL:
      return SkFontHinting::kFull;
    default:
      NOTREACHED();
      return SkFontHinting::kNormal;
  }
}
#endif  // OS_MAC

}  // namespace

// WebView ----------------------------------------------------------------

WebView* WebView::Create(
    WebViewClient* client,
    bool is_hidden,
    bool is_inside_portal,
    bool compositing_enabled,
    WebView* opener,
    CrossVariantMojoAssociatedReceiver<mojom::PageBroadcastInterfaceBase>
        page_handle,
    scheduler::WebAgentGroupScheduler& agent_group_scheduler) {
  return WebViewImpl::Create(
      client,
      is_hidden ? mojom::blink::PageVisibilityState::kHidden
                : mojom::blink::PageVisibilityState::kVisible,
      is_inside_portal, compositing_enabled, static_cast<WebViewImpl*>(opener),
      std::move(page_handle), agent_group_scheduler);
}

WebViewImpl* WebViewImpl::Create(
    WebViewClient* client,
    mojom::blink::PageVisibilityState visibility,
    bool is_inside_portal,
    bool compositing_enabled,
    WebViewImpl* opener,
    mojo::PendingAssociatedReceiver<mojom::blink::PageBroadcast> page_handle,
    blink::scheduler::WebAgentGroupScheduler& agent_group_scheduler) {
  // Take a self-reference for WebViewImpl that is released by calling Close(),
  // then return a raw pointer to the caller.
  auto web_view = base::AdoptRef(
      new WebViewImpl(client, visibility, is_inside_portal, compositing_enabled,
                      opener, std::move(page_handle), agent_group_scheduler));
  web_view->AddRef();
  return web_view.get();
}

void WebView::UpdateVisitedLinkState(uint64_t link_hash) {
  Page::VisitedStateChanged(link_hash);
}

void WebView::ResetVisitedLinkState(bool invalidate_visited_link_hashes) {
  Page::AllVisitedStateChanged(invalidate_visited_link_hashes);
}

void WebViewImpl::SetNoStatePrefetchClient(
    WebNoStatePrefetchClient* no_state_prefetch_client) {
  DCHECK(page_);
  ProvideNoStatePrefetchClientTo(*page_,
                                 MakeGarbageCollected<NoStatePrefetchClient>(
                                     *page_, no_state_prefetch_client));
}

void WebViewImpl::CloseWindowSoon() {
  // Ask the RenderViewHost with a local main frame to initiate close.  We
  // could be called from deep in Javascript.  If we ask the RenderViewHost to
  // close now, the window could be closed before the JS finishes executing,
  // thanks to nested message loops running and handling the resulting
  // DestroyView IPC. So instead, post a message back to the message loop, which
  // won't run until the JS is complete, and then the
  // RouteCloseEvent/RequestClose request can be sent.
  GetPage()
      ->GetPageScheduler()
      ->GetAgentGroupScheduler()
      .DefaultTaskRunner()
      ->PostTask(FROM_HERE, WTF::Bind(&WebViewImpl::DoDeferredCloseWindowSoon,
                                      weak_ptr_factory_.GetWeakPtr()));
}

void WebViewImpl::DoDeferredCloseWindowSoon() {
  // Have the browser process a close request. We should have either a
  // |local_main_frame_host_remote_| or |remote_main_frame_host_remote_|.
  // This method will not execute if Close has been called as WeakPtrs
  // will be invalidated in Close.
  if (GetPage()->MainFrame()->IsLocalFrame()) {
    DCHECK(local_main_frame_host_remote_);
    local_main_frame_host_remote_->RequestClose();
  } else {
    DCHECK(remote_main_frame_host_remote_);
    remote_main_frame_host_remote_->RouteCloseEvent();
  }
}

WebViewImpl::WebViewImpl(
    WebViewClient* client,
    mojom::blink::PageVisibilityState visibility,
    bool is_inside_portal,
    bool does_composite,
    WebViewImpl* opener,
    mojo::PendingAssociatedReceiver<mojom::blink::PageBroadcast> page_handle,
    blink::scheduler::WebAgentGroupScheduler& agent_group_scheduler)
    : web_view_client_(client),
      chrome_client_(MakeGarbageCollected<ChromeClientImpl>(this)),
      minimum_zoom_level_(PageZoomFactorToZoomLevel(kMinimumPageZoomFactor)),
      maximum_zoom_level_(PageZoomFactorToZoomLevel(kMaximumPageZoomFactor)),
      does_composite_(does_composite),
      fullscreen_controller_(std::make_unique<FullscreenController>(this)),
      receiver_(this,
                std::move(page_handle),
                agent_group_scheduler.DefaultTaskRunner()) {
  if (!web_view_client_)
    DCHECK(!does_composite_);
  Page::PageClients page_clients;
  page_clients.chrome_client = chrome_client_.Get();
  page_ =
      Page::CreateOrdinary(page_clients, opener ? opener->GetPage() : nullptr,
                           agent_group_scheduler);
  CoreInitializer::GetInstance().ProvideModulesToPage(*page_, web_view_client_);

  SetVisibilityState(visibility, /*is_initial_state=*/true);

  // We pass this state to Page, but it's only used by the main frame in the
  // page.
  SetInsidePortal(is_inside_portal);

  // When not compositing, keep the Page in the loop so that it will paint all
  // content into the root layer, as multiple layers can only be used when
  // compositing them together later.
  if (does_composite_)
    page_->GetSettings().SetAcceleratedCompositingEnabled(true);

  dev_tools_emulator_ = MakeGarbageCollected<DevToolsEmulator>(this);

  AllInstances().insert(this);

  resize_viewport_anchor_ = MakeGarbageCollected<ResizeViewportAnchor>(*page_);
}

WebViewImpl::~WebViewImpl() {
  DCHECK(!page_);
}

WebDevToolsAgentImpl* WebViewImpl::MainFrameDevToolsAgentImpl() {
  WebLocalFrameImpl* main_frame = MainFrameImpl();
  return main_frame ? main_frame->DevToolsAgentImpl() : nullptr;
}

void WebViewImpl::SetTabKeyCyclesThroughElements(bool value) {
  if (page_)
    page_->SetTabKeyCyclesThroughElements(value);
}

bool WebViewImpl::StartPageScaleAnimation(const IntPoint& target_position,
                                          bool use_anchor,
                                          float new_scale,
                                          base::TimeDelta duration) {
  // PageScaleFactor is a property of the main frame only, and only exists when
  // compositing.
  DCHECK(MainFrameImpl());
  DCHECK(does_composite_);

  VisualViewport& visual_viewport = GetPage()->GetVisualViewport();
  gfx::Point clamped_point = target_position;
  if (!use_anchor) {
    clamped_point =
        visual_viewport.ClampDocumentOffsetAtScale(target_position, new_scale);
    if (duration.is_zero()) {
      SetPageScaleFactor(new_scale);

      LocalFrameView* view = MainFrameImpl()->GetFrameView();
      if (view && view->GetScrollableArea()) {
        view->GetScrollableArea()->SetScrollOffset(
            ScrollOffset(clamped_point.x(), clamped_point.y()),
            mojom::blink::ScrollType::kProgrammatic);
      }

      return false;
    }
  }
  if (use_anchor && new_scale == PageScaleFactor())
    return false;

  if (enable_fake_page_scale_animation_for_testing_) {
    fake_page_scale_animation_target_position_ = target_position;
    fake_page_scale_animation_use_anchor_ = use_anchor;
    fake_page_scale_animation_page_scale_factor_ = new_scale;
  } else {
    MainFrameImpl()->FrameWidgetImpl()->StartPageScaleAnimation(
        static_cast<gfx::Vector2d>(target_position), use_anchor, new_scale,
        duration);
  }
  return true;
}

void WebViewImpl::EnableFakePageScaleAnimationForTesting(bool enable) {
  enable_fake_page_scale_animation_for_testing_ = enable;
  fake_page_scale_animation_target_position_ = IntPoint();
  fake_page_scale_animation_use_anchor_ = false;
  fake_page_scale_animation_page_scale_factor_ = 0;
}

void WebViewImpl::AcceptLanguagesChanged() {
  FontCache::AcceptLanguagesChanged(
      String::FromUTF8(renderer_preferences_.accept_languages));

  if (!GetPage())
    return;

  GetPage()->AcceptLanguagesChanged();
}

gfx::Rect WebViewImpl::WidenRectWithinPageBounds(const gfx::Rect& source,
                                                 int target_margin,
                                                 int minimum_margin) {
  // Caller should guarantee that the main frame exists and is local.
  DCHECK(MainFrame());
  DCHECK(MainFrame()->IsWebLocalFrame());
  WebSize max_size = MainFrame()->ToWebLocalFrame()->DocumentSize();
  IntSize scroll_offset = MainFrame()->ToWebLocalFrame()->GetScrollOffset();

  int left_margin = target_margin;
  int right_margin = target_margin;

  const int absolute_source_x = source.x() + scroll_offset.Width();
  if (left_margin > absolute_source_x) {
    left_margin = absolute_source_x;
    right_margin = std::max(left_margin, minimum_margin);
  }

  const int maximum_right_margin =
      max_size.width - (source.width() + absolute_source_x);
  if (right_margin > maximum_right_margin) {
    right_margin = maximum_right_margin;
    left_margin = std::min(left_margin, std::max(right_margin, minimum_margin));
  }

  const int new_width = source.width() + left_margin + right_margin;
  const int new_x = source.x() - left_margin;

  DCHECK_GE(new_width, 0);
  DCHECK_LE(scroll_offset.Width() + new_x + new_width, max_size.width);

  return gfx::Rect(new_x, source.y(), new_width, source.height());
}

float WebViewImpl::MaximumLegiblePageScale() const {
  // Pages should be as legible as on desktop when at dpi scale, so no
  // need to zoom in further when automatically determining zoom level
  // (after double tap, find in page, etc), though the user should still
  // be allowed to manually pinch zoom in further if they desire.
  if (GetPage()) {
    return maximum_legible_scale_ *
           GetPage()->GetSettings().GetAccessibilityFontScaleFactor();
  }
  return maximum_legible_scale_;
}

void WebViewImpl::ComputeScaleAndScrollForBlockRect(
    const gfx::Point& hit_point_in_root_frame,
    const gfx::Rect& block_rect_in_root_frame,
    float padding,
    float default_scale_when_already_legible,
    float& scale,
    IntPoint& scroll) {
  scale = PageScaleFactor();
  scroll = IntPoint();

  gfx::Rect rect = block_rect_in_root_frame;

  if (!rect.IsEmpty()) {
    float default_margin = doubleTapZoomContentDefaultMargin;
    float minimum_margin = doubleTapZoomContentMinimumMargin;
    // We want the margins to have the same physical size, which means we
    // need to express them in post-scale size. To do that we'd need to know
    // the scale we're scaling to, but that depends on the margins. Instead
    // we express them as a fraction of the target rectangle: this will be
    // correct if we end up fully zooming to it, and won't matter if we
    // don't.
    rect = WidenRectWithinPageBounds(
        rect, static_cast<int>(default_margin * rect.width() / size_.width()),
        static_cast<int>(minimum_margin * rect.width() / size_.width()));
    // Fit block to screen, respecting limits.
    scale = static_cast<float>(size_.width()) / rect.width();
    scale = std::min(scale, MaximumLegiblePageScale());
    if (PageScaleFactor() < default_scale_when_already_legible)
      scale = std::max(scale, default_scale_when_already_legible);
    scale = ClampPageScaleFactorToLimits(scale);
  }

  // FIXME: If this is being called for auto zoom during find in page,
  // then if the user manually zooms in it'd be nice to preserve the
  // relative increase in zoom they caused (if they zoom out then it's ok
  // to zoom them back in again). This isn't compatible with our current
  // double-tap zoom strategy (fitting the containing block to the screen)
  // though.

  float screen_width = size_.width() / scale;
  float screen_height = size_.height() / scale;

  // Scroll to vertically align the block.
  if (rect.height() < screen_height) {
    // Vertically center short blocks.
    rect.Offset(0, -0.5 * (screen_height - rect.height()));
  } else {
    // Ensure position we're zooming to (+ padding) isn't off the bottom of
    // the screen.
    rect.set_y(std::max<float>(
        rect.y(), hit_point_in_root_frame.y() + padding - screen_height));
  }  // Otherwise top align the block.

  // Do the same thing for horizontal alignment.
  if (rect.width() < screen_width) {
    rect.Offset(-0.5 * (screen_width - rect.width()), 0);
  } else {
    rect.set_x(std::max<float>(
        rect.x(), hit_point_in_root_frame.x() + padding - screen_width));
  }
  scroll.SetX(rect.x());
  scroll.SetY(rect.y());

  scale = ClampPageScaleFactorToLimits(scale);
  scroll = MainFrameImpl()->GetFrameView()->RootFrameToDocument(scroll);
  scroll =
      GetPage()->GetVisualViewport().ClampDocumentOffsetAtScale(scroll, scale);
}

static Node* FindCursorDefiningAncestor(Node* node, LocalFrame* frame) {
  // Go up the tree to find the node that defines a mouse cursor style
  while (node) {
    if (node->GetLayoutObject()) {
      ECursor cursor = node->GetLayoutObject()->Style()->Cursor();
      if (cursor != ECursor::kAuto ||
          frame->GetEventHandler().UseHandCursor(node, node->IsLink()))
        break;
    }
    node = LayoutTreeBuilderTraversal::Parent(*node);
  }

  return node;
}

static bool ShowsHandCursor(Node* node, LocalFrame* frame) {
  if (!node || !node->GetLayoutObject())
    return false;

  ECursor cursor = node->GetLayoutObject()->Style()->Cursor();
  return cursor == ECursor::kPointer ||
         (cursor == ECursor::kAuto &&
          frame->GetEventHandler().UseHandCursor(node, node->IsLink()));
}

// This is for tap (link) highlight and is tested in
// link_highlight_impl_test.cc.
Node* WebViewImpl::BestTapNode(
    const GestureEventWithHitTestResults& targeted_tap_event) {
  TRACE_EVENT0("input", "WebViewImpl::bestTapNode");

  Page* page = page_.Get();
  if (!page || !page->MainFrame())
    return nullptr;

  Node* best_touch_node = targeted_tap_event.GetHitTestResult().InnerNode();
  if (!best_touch_node)
    return nullptr;

  // We might hit something like an image map that has no layoutObject on it
  // Walk up the tree until we have a node with an attached layoutObject
  while (!best_touch_node->GetLayoutObject()) {
    best_touch_node = LayoutTreeBuilderTraversal::Parent(*best_touch_node);
    if (!best_touch_node)
      return nullptr;
  }

  // Editable nodes should not be highlighted (e.g., <input>)
  if (HasEditableStyle(*best_touch_node))
    return nullptr;

  Node* cursor_defining_ancestor = FindCursorDefiningAncestor(
      best_touch_node, page->DeprecatedLocalMainFrame());
  // We show a highlight on tap only when the current node shows a hand cursor
  if (!cursor_defining_ancestor ||
      !ShowsHandCursor(cursor_defining_ancestor,
                       page->DeprecatedLocalMainFrame())) {
    return nullptr;
  }

  // We should pick the largest enclosing node with hand cursor set. We do this
  // by first jumping up to cursorDefiningAncestor (which is already known to
  // have hand cursor set). Then we locate the next cursor-defining ancestor up
  // in the the tree and repeat the jumps as long as the node has hand cursor
  // set.
  do {
    best_touch_node = cursor_defining_ancestor;
    cursor_defining_ancestor = FindCursorDefiningAncestor(
        LayoutTreeBuilderTraversal::Parent(*best_touch_node),
        page->DeprecatedLocalMainFrame());
  } while (cursor_defining_ancestor &&
           ShowsHandCursor(cursor_defining_ancestor,
                           page->DeprecatedLocalMainFrame()));

  // This happens in cases like:
  // <div style="display: contents; cursor: pointer">Text</div>.
  // The text node inherits cursor: pointer and the div doesn't have a
  // LayoutObject, so |best_touch_node| is the text node here. We should not
  // return the text node because it can't have touch actions.
  if (best_touch_node->IsTextNode())
    return nullptr;

  return best_touch_node;
}

void WebViewImpl::EnableTapHighlightAtPoint(
    const GestureEventWithHitTestResults& targeted_tap_event) {
  DCHECK(MainFrameImpl());
  Node* touch_node = BestTapNode(targeted_tap_event);
  GetPage()->GetLinkHighlight().SetTapHighlight(touch_node);
  MainFrameWidget()->UpdateLifecycle(WebLifecycleUpdate::kAll,
                                     DocumentUpdateReason::kTapHighlight);
}

void WebViewImpl::AnimateDoubleTapZoom(const gfx::Point& point_in_root_frame,
                                       const gfx::Rect& rect_to_zoom) {
  DCHECK(MainFrameImpl());

  float scale;
  IntPoint scroll;

  ComputeScaleAndScrollForBlockRect(
      point_in_root_frame, rect_to_zoom, touchPointPadding,
      MinimumPageScaleFactor() * doubleTapZoomAlreadyLegibleRatio, scale,
      scroll);

  bool still_at_previous_double_tap_scale =
      (PageScaleFactor() == double_tap_zoom_page_scale_factor_ &&
       double_tap_zoom_page_scale_factor_ != MinimumPageScaleFactor()) ||
      double_tap_zoom_pending_;

  bool scale_unchanged = fabs(PageScaleFactor() - scale) < minScaleDifference;
  bool should_zoom_out = rect_to_zoom.IsEmpty() || scale_unchanged ||
                         still_at_previous_double_tap_scale;

  bool is_animating;

  if (should_zoom_out) {
    scale = MinimumPageScaleFactor();
    IntPoint target_position =
        MainFrameImpl()->GetFrameView()->RootFrameToDocument(
            IntPoint(point_in_root_frame.x(), point_in_root_frame.y()));
    is_animating = StartPageScaleAnimation(target_position, true, scale,
                                           kDoubleTapZoomAnimationDuration);
  } else {
    is_animating = StartPageScaleAnimation(scroll, false, scale,
                                           kDoubleTapZoomAnimationDuration);
  }

  // TODO(dglazkov): The only reason why we're using isAnimating and not just
  // checking for layer_tree_view_->HasPendingPageScaleAnimation() is because of
  // fake page scale animation plumbing for testing, which doesn't actually
  // initiate a page scale animation.
  if (is_animating) {
    double_tap_zoom_page_scale_factor_ = scale;
    double_tap_zoom_pending_ = true;
  }
}

void WebViewImpl::ZoomToFindInPageRect(const gfx::Rect& rect_in_root_frame) {
  DCHECK(MainFrameImpl());

  gfx::Rect block_bounds =
      MainFrameImpl()->FrameWidgetImpl()->ComputeBlockBound(
          gfx::Point(rect_in_root_frame.x() + rect_in_root_frame.width() / 2,
                     rect_in_root_frame.y() + rect_in_root_frame.height() / 2),
          true);

  if (block_bounds.IsEmpty()) {
    // Keep current scale (no need to scroll as x,y will normally already
    // be visible). FIXME: Revisit this if it isn't always true.
    return;
  }

  float scale;
  IntPoint scroll;

  ComputeScaleAndScrollForBlockRect(rect_in_root_frame.origin(), block_bounds,
                                    nonUserInitiatedPointPadding,
                                    MinimumPageScaleFactor(), scale, scroll);

  StartPageScaleAnimation(scroll, false, scale, kFindInPageAnimationDuration);
}

#if !defined(OS_MAC)
// Mac has no way to open a context menu based on a keyboard event.
WebInputEventResult WebViewImpl::SendContextMenuEvent() {
  // The contextMenuController() holds onto the last context menu that was
  // popped up on the page until a new one is created. We need to clear
  // this menu before propagating the event through the DOM so that we can
  // detect if we create a new menu for this event, since we won't create
  // a new menu if the DOM swallows the event and the defaultEventHandler does
  // not run.
  GetPage()->GetContextMenuController().ClearContextMenu();

  {
    ContextMenuAllowedScope scope;
    Frame* focused_frame = GetPage()->GetFocusController().FocusedOrMainFrame();
    auto* focused_local_frame = DynamicTo<LocalFrame>(focused_frame);
    if (!focused_local_frame)
      return WebInputEventResult::kNotHandled;
    // Firefox reveal focus based on "keydown" event but not "contextmenu"
    // event, we match FF.
    if (Element* focused_element =
            focused_local_frame->GetDocument()->FocusedElement())
      focused_element->scrollIntoViewIfNeeded();
    return focused_local_frame->GetEventHandler().ShowNonLocatedContextMenu(
        nullptr, kMenuSourceKeyboard);
  }
}
#else
WebInputEventResult WebViewImpl::SendContextMenuEvent() {
  return WebInputEventResult::kNotHandled;
}
#endif

WebPagePopupImpl* WebViewImpl::OpenPagePopup(PagePopupClient* client) {
  DCHECK(client);

  // This guarantees there is never more than 1 PagePopup active at a time.
  CancelPagePopup();
  DCHECK(!page_popup_);

  WebLocalFrameImpl* frame = WebLocalFrameImpl::FromFrame(
      client->OwnerElement().GetDocument().GetFrame()->LocalFrameRoot());
  WebPagePopup* popup_widget = web_view_client_->CreatePopup(frame);
  // CreatePopup returns nullptr if this renderer process is about to die.
  if (!popup_widget)
    return nullptr;
  page_popup_ = To<WebPagePopupImpl>(popup_widget);
  page_popup_->Initialize(this, client);
  EnablePopupMouseWheelEventListener(frame);
  return page_popup_.get();
}

void WebViewImpl::CancelPagePopup() {
  if (page_popup_)
    page_popup_->Cancel();
}

void WebViewImpl::ClosePagePopup(PagePopup* popup) {
  DCHECK(popup);
  auto* popup_impl = To<WebPagePopupImpl>(popup);
  DCHECK_EQ(page_popup_.get(), popup_impl);
  if (page_popup_.get() != popup_impl)
    return;
  page_popup_->ClosePopup();
}

void WebViewImpl::CleanupPagePopup() {
  page_popup_ = nullptr;
  DisablePopupMouseWheelEventListener();
}

void WebViewImpl::UpdatePagePopup() {
  if (page_popup_)
    page_popup_->Update();
}

void WebViewImpl::EnablePopupMouseWheelEventListener(
    WebLocalFrameImpl* local_root) {
  DCHECK(!popup_mouse_wheel_event_listener_);
  Document* document = local_root->GetDocument();
  DCHECK(document);
  // We register an empty event listener, EmptyEventListener, so that mouse
  // wheel events get sent to the WebView.
  popup_mouse_wheel_event_listener_ =
      MakeGarbageCollected<EmptyEventListener>();
  document->addEventListener(event_type_names::kMousewheel,
                             popup_mouse_wheel_event_listener_, false);
  local_root_with_empty_mouse_wheel_listener_ = local_root;
}

void WebViewImpl::DisablePopupMouseWheelEventListener() {
  // TODO(kenrb): Concerns the same as in enablePopupMouseWheelEventListener.
  // See https://crbug.com/566130
  DCHECK(popup_mouse_wheel_event_listener_);
  Document* document =
      local_root_with_empty_mouse_wheel_listener_->GetDocument();
  DCHECK(document);
  // Document may have already removed the event listener, for instance, due
  // to a navigation, but remove it anyway.
  document->removeEventListener(event_type_names::kMousewheel,
                                popup_mouse_wheel_event_listener_.Release(),
                                false);
  local_root_with_empty_mouse_wheel_listener_ = nullptr;
}

LocalDOMWindow* WebViewImpl::PagePopupWindow() const {
  return page_popup_ ? page_popup_->Window() : nullptr;
}

Frame* WebViewImpl::FocusedCoreFrame() const {
  Page* page = page_.Get();
  return page ? page->GetFocusController().FocusedOrMainFrame() : nullptr;
}

// WebWidget ------------------------------------------------------------------

void WebViewImpl::Close() {
  // Closership is a single relationship, so only 1 call to Close() should
  // occur.
  CHECK(page_);
  DCHECK(AllInstances().Contains(this));
  AllInstances().erase(this);

  // Invalidate any weak ptrs as we are starting to shutdown.
  weak_ptr_factory_.InvalidateWeakPtrs();

  // Initiate shutdown for the entire frameset.  This will cause a lot of
  // notifications to be sent. This will detach all frames in this WebView's
  // frame tree.
  page_->WillBeDestroyed();
  page_.Clear();

  // Reset the delegate to prevent notifications being sent as we're being
  // deleted.
  web_view_client_ = nullptr;

  for (auto& observer : observers_)
    observer.WebViewDestroyed();

  Release();  // Balances a reference acquired in WebView::Create
}

gfx::Size WebViewImpl::Size() {
  return size_;
}

void WebViewImpl::ResizeVisualViewport(const gfx::Size& new_size) {
  GetPage()->GetVisualViewport().SetSize(WebSize(new_size));
  GetPage()->GetVisualViewport().ClampToBoundaries();
}

void WebViewImpl::UpdateICBAndResizeViewport(
    const IntSize& visible_viewport_size) {
  // We'll keep the initial containing block size from changing when the top
  // controls hide so that the ICB will always be the same size as the
  // viewport with the browser controls shown.
  IntSize icb_size = IntSize(size_);
  if (GetBrowserControls().PermittedState() ==
          cc::BrowserControlsState::kBoth &&
      !GetBrowserControls().ShrinkViewport()) {
    icb_size.Expand(0, -(GetBrowserControls().TotalHeight() -
                         GetBrowserControls().TotalMinHeight()));
  }

  GetPageScaleConstraintsSet().DidChangeInitialContainingBlockSize(icb_size);

  UpdatePageDefinedViewportConstraints(MainFrameImpl()
                                           ->GetFrame()
                                           ->GetDocument()
                                           ->GetViewportData()
                                           .GetViewportDescription());
  UpdateMainFrameLayoutSize();

  GetPage()->GetVisualViewport().SetSize(visible_viewport_size);

  if (MainFrameImpl()->GetFrameView()) {
    MainFrameImpl()->GetFrameView()->SetInitialViewportSize(icb_size);
    if (!MainFrameImpl()->GetFrameView()->NeedsLayout())
      resize_viewport_anchor_->ResizeFrameView(MainFrameSize());
  }

  // The boundaries are not properly established until after the frame view is
  // also resized, as demonstrated by
  // VisualViewportTest.TestBrowserControlsAdjustmentAndResize.
  GetPage()->GetVisualViewport().ClampToBoundaries();
}

void WebViewImpl::UpdateBrowserControlsConstraint(
    cc::BrowserControlsState constraint) {
  cc::BrowserControlsState old_permitted_state =
      GetBrowserControls().PermittedState();

  GetBrowserControls().UpdateConstraintsAndState(
      constraint, cc::BrowserControlsState::kBoth);

  // If the controls are going from a locked hidden to unlocked state, or vice
  // versa, the ICB size needs to change but we can't rely on getting a
  // WebViewImpl::resize since the top controls shown state may not have
  // changed.
  if ((old_permitted_state == cc::BrowserControlsState::kHidden &&
       constraint == cc::BrowserControlsState::kBoth) ||
      (old_permitted_state == cc::BrowserControlsState::kBoth &&
       constraint == cc::BrowserControlsState::kHidden)) {
    UpdateICBAndResizeViewport(GetPage()->GetVisualViewport().Size());
  }
}

void WebViewImpl::DidUpdateBrowserControls() {
  // BrowserControls are a feature whereby the browser can introduce an
  // interactable element [e.g. search box] that grows/shrinks in height as the
  // user scrolls the web contents.
  //
  // This method is called by the BrowserControls class to let the compositor
  // know that the browser controls have been updated. This is only relevant if
  // the main frame is local because BrowserControls only affects the main
  // frame's viewport, and are only affected by main frame scrolling.
  //
  // The relevant state is stored on the BrowserControls object even if the main
  // frame is remote. If the main frame becomes local, the state will be
  // restored by the first commit, since the state is checked in every call to
  // ApplyScrollAndScale().
  WebLocalFrameImpl* main_frame = MainFrameImpl();
  if (!main_frame)
    return;

  WebFrameWidgetImpl* widget = main_frame->LocalRootFrameWidget();
  widget->SetBrowserControlsShownRatio(GetBrowserControls().TopShownRatio(),
                                       GetBrowserControls().BottomShownRatio());
  widget->SetBrowserControlsParams(GetBrowserControls().Params());

  VisualViewport& visual_viewport = GetPage()->GetVisualViewport();

  {
    // This object will save the current visual viewport offset w.r.t. the
    // document and restore it when the object goes out of scope. It's
    // needed since the browser controls adjustment will change the maximum
    // scroll offset and we may need to reposition them to keep the user's
    // apparent position unchanged.
    ResizeViewportAnchor::ResizeScope resize_scope(*resize_viewport_anchor_);

    visual_viewport.SetBrowserControlsAdjustment(
        GetBrowserControls().UnreportedSizeAdjustment());
  }
}

BrowserControls& WebViewImpl::GetBrowserControls() {
  return GetPage()->GetBrowserControls();
}

void WebViewImpl::ResizeViewWhileAnchored(
    cc::BrowserControlsParams params,
    const IntSize& visible_viewport_size) {
  DCHECK(MainFrameImpl());

  GetBrowserControls().SetParams(params);

  {
    // Avoids unnecessary invalidations while various bits of state in
    // TextAutosizer are updated.
    TextAutosizer::DeferUpdatePageInfo defer_update_page_info(GetPage());
    LocalFrameView* frame_view = MainFrameImpl()->GetFrameView();
    IntSize old_size = frame_view->Size();
    UpdateICBAndResizeViewport(visible_viewport_size);
    IntSize new_size = frame_view->Size();
    frame_view->MarkViewportConstrainedObjectsForLayout(
        old_size.Width() != new_size.Width(),
        old_size.Height() != new_size.Height());
  }

  fullscreen_controller_->UpdateSize();

  // Update lifecycle phases immediately to recalculate the minimum scale limit
  // for rotation anchoring, and to make sure that no lifecycle states are
  // stale if this WebView is embedded in another one.
  MainFrameWidget()->UpdateLifecycle(WebLifecycleUpdate::kAll,
                                     DocumentUpdateReason::kSizeChange);
}

void WebViewImpl::ResizeWithBrowserControls(
    const gfx::Size& new_size,
    float top_controls_height,
    float bottom_controls_height,
    bool browser_controls_shrink_layout) {
  ResizeWithBrowserControls(
      new_size, new_size,
      {top_controls_height, GetBrowserControls().TopMinHeight(),
       bottom_controls_height, GetBrowserControls().BottomMinHeight(),
       GetBrowserControls().AnimateHeightChanges(),
       browser_controls_shrink_layout});
}

void WebViewImpl::ResizeWithBrowserControls(
    const gfx::Size& main_frame_widget_size,
    const gfx::Size& visible_viewport_size,
    cc::BrowserControlsParams browser_controls_params) {
  if (should_auto_resize_) {
    // When auto-resizing only the viewport size comes from the browser, while
    // the widget size is determined in the renderer.
    ResizeVisualViewport(visible_viewport_size);
    return;
  }

  if (size_ == main_frame_widget_size &&
      GetPage()->GetVisualViewport().Size() == IntSize(visible_viewport_size) &&
      GetBrowserControls().Params() == browser_controls_params)
    return;

  if (GetPage()->MainFrame() && !GetPage()->MainFrame()->IsLocalFrame()) {
    // Viewport resize for a remote main frame does not require any
    // particular action, but the state needs to reflect the correct size
    // so that it can be used for initialization if the main frame gets
    // swapped to a LocalFrame at a later time.
    size_ = main_frame_widget_size;
    GetPageScaleConstraintsSet().DidChangeInitialContainingBlockSize(
        IntSize(size_));
    GetPage()->GetVisualViewport().SetSize(IntSize(size_));
    GetPage()->GetBrowserControls().SetParams(browser_controls_params);
    return;
  }

  WebLocalFrameImpl* main_frame = MainFrameImpl();
  if (!main_frame)
    return;

  LocalFrameView* view = main_frame->GetFrameView();
  if (!view)
    return;

  VisualViewport& visual_viewport = GetPage()->GetVisualViewport();

  bool is_rotation =
      GetPage()->GetSettings().GetMainFrameResizesAreOrientationChanges() &&
      size_.width() && ContentsSize().Width() &&
      main_frame_widget_size.width() != size_.width() &&
      !fullscreen_controller_->IsFullscreenOrTransitioning();
  size_ = main_frame_widget_size;

  FloatSize viewport_anchor_coords(viewportAnchorCoordX, viewportAnchorCoordY);
  if (is_rotation) {
    RotationViewportAnchor anchor(*view, visual_viewport,
                                  viewport_anchor_coords,
                                  GetPageScaleConstraintsSet());
    ResizeViewWhileAnchored(browser_controls_params,
                            IntSize(visible_viewport_size));
  } else {
    ResizeViewportAnchor::ResizeScope resize_scope(*resize_viewport_anchor_);
    ResizeViewWhileAnchored(browser_controls_params,
                            IntSize(visible_viewport_size));
  }
  SendResizeEventForMainFrame();
}

void WebViewImpl::Resize(const gfx::Size& new_size) {
  if (should_auto_resize_ || size_ == new_size)
    return;

  ResizeWithBrowserControls(new_size, GetBrowserControls().TopHeight(),
                            GetBrowserControls().BottomHeight(),
                            GetBrowserControls().ShrinkViewport());
}

void WebViewImpl::SetScreenOrientationOverrideForTesting(
    base::Optional<blink::mojom::ScreenOrientation> orientation) {
  screen_orientation_override_ = orientation;

  // Since we updated the override value, notify all widgets.
  for (WebFrame* frame = MainFrame(); frame; frame = frame->TraverseNext()) {
    if (frame->IsWebLocalFrame()) {
      if (WebFrameWidgetImpl* widget = static_cast<WebFrameWidgetImpl*>(
              frame->ToWebLocalFrame()->FrameWidget()))
        widget->UpdateScreenInfo(widget->GetScreenInfo());
    }
  }
}

void WebViewImpl::UseSynchronousResizeModeForTesting(bool enable) {
  web_widget_->UseSynchronousResizeModeForTesting(enable);
}

void WebViewImpl::SetWindowRectSynchronouslyForTesting(
    const gfx::Rect& new_window_rect) {
  web_widget_->SetWindowRectSynchronouslyForTesting(new_window_rect);
}

base::Optional<mojom::blink::ScreenOrientation>
WebViewImpl::ScreenOrientationOverride() {
  return screen_orientation_override_;
}

void WebViewImpl::DidEnterFullscreen() {
  fullscreen_controller_->DidEnterFullscreen();
}

void WebViewImpl::DidExitFullscreen() {
  fullscreen_controller_->DidExitFullscreen();
}

void WebViewImpl::SetMainFrameViewWidget(WebFrameWidgetImpl* widget) {
  DCHECK(!widget || widget->ForMainFrame());
  web_widget_ = widget;
}

void WebViewImpl::SetMouseOverURL(const KURL& url) {
  mouse_over_url_ = url;
  UpdateTargetURL(mouse_over_url_, focus_url_);
}

void WebViewImpl::SetKeyboardFocusURL(const KURL& url) {
  focus_url_ = url;
  UpdateTargetURL(focus_url_, mouse_over_url_);
}

WebFrameWidgetImpl* WebViewImpl::MainFrameViewWidget() {
  return web_widget_;
}

void WebViewImpl::PaintContent(cc::PaintCanvas* canvas, const gfx::Rect& rect) {
  // This should only be used when compositing is not being used for this
  // WebView, and it is painting into the recording of its parent.
  DCHECK(!does_composite_);
  // Non-composited WebViews always have a local main frame.
  DCHECK(MainFrameImpl());

  if (rect.IsEmpty())
    return;

  LocalFrameView& main_view = *MainFrameImpl()->GetFrame()->View();
  DCHECK(main_view.GetLayoutView()->GetDocument().Lifecycle().GetState() ==
         DocumentLifecycle::kPaintClean);

  PaintRecordBuilder builder;
  main_view.PaintOutsideOfLifecycle(builder.Context(), kGlobalPaintNormalPhase,
                                    CullRect(IntRect(rect)));
  // Don't bother to save/restore here as the caller is expecting the canvas
  // to be modified and take care of it.
  canvas->clipRect(gfx::RectToSkRect(rect));
  builder.EndRecording(*canvas, main_view.GetLayoutView()
                                    ->FirstFragment()
                                    .LocalBorderBoxProperties()
                                    .Unalias());
}

// static
void WebView::ApplyWebPreferences(const web_pref::WebPreferences& prefs,
                                  WebView* web_view) {
  WebViewImpl* web_view_impl = static_cast<WebViewImpl*>(web_view);
  WebSettings* settings = web_view->GetSettings();
  ApplyFontsFromMap(prefs.standard_font_family_map,
                    SetStandardFontFamilyWrapper, settings);
  ApplyFontsFromMap(prefs.fixed_font_family_map, SetFixedFontFamilyWrapper,
                    settings);
  ApplyFontsFromMap(prefs.serif_font_family_map, SetSerifFontFamilyWrapper,
                    settings);
  ApplyFontsFromMap(prefs.sans_serif_font_family_map,
                    SetSansSerifFontFamilyWrapper, settings);
  ApplyFontsFromMap(prefs.cursive_font_family_map, SetCursiveFontFamilyWrapper,
                    settings);
  ApplyFontsFromMap(prefs.fantasy_font_family_map, SetFantasyFontFamilyWrapper,
                    settings);
  ApplyFontsFromMap(prefs.pictograph_font_family_map,
                    SetPictographFontFamilyWrapper, settings);
  settings->SetDefaultFontSize(prefs.default_font_size);
  settings->SetDefaultFixedFontSize(prefs.default_fixed_font_size);
  settings->SetMinimumFontSize(prefs.minimum_font_size);
  settings->SetMinimumLogicalFontSize(prefs.minimum_logical_font_size);
  settings->SetDefaultTextEncodingName(
      WebString::FromASCII(prefs.default_encoding));
  settings->SetJavaScriptEnabled(prefs.javascript_enabled);
  settings->SetWebSecurityEnabled(prefs.web_security_enabled);
  settings->SetLoadsImagesAutomatically(prefs.loads_images_automatically);
  settings->SetImagesEnabled(prefs.images_enabled);
  settings->SetPluginsEnabled(prefs.plugins_enabled);
  settings->SetDOMPasteAllowed(prefs.dom_paste_enabled);
  settings->SetTextAreasAreResizable(prefs.text_areas_are_resizable);
  settings->SetAllowScriptsToCloseWindows(prefs.allow_scripts_to_close_windows);
  settings->SetDownloadableBinaryFontsEnabled(prefs.remote_fonts_enabled);
  settings->SetJavaScriptCanAccessClipboard(
      prefs.javascript_can_access_clipboard);
  RuntimeEnabledFeatures::SetXSLTEnabled(prefs.xslt_enabled);
  settings->SetDNSPrefetchingEnabled(prefs.dns_prefetching_enabled);
  blink::WebNetworkStateNotifier::SetSaveDataEnabled(prefs.data_saver_enabled);
  settings->SetLocalStorageEnabled(prefs.local_storage_enabled);
  settings->SetSyncXHRInDocumentsEnabled(prefs.sync_xhr_in_documents_enabled);
  settings->SetTargetBlankImpliesNoOpenerEnabledWillBeRemoved(
      prefs.target_blank_implies_no_opener_enabled_will_be_removed);
  settings->SetAllowNonEmptyNavigatorPlugins(
      prefs.allow_non_empty_navigator_plugins);
  RuntimeEnabledFeatures::SetDatabaseEnabled(prefs.databases_enabled);
  settings->SetOfflineWebApplicationCacheEnabled(
      prefs.application_cache_enabled);
  settings->SetShouldProtectAgainstIpcFlooding(
      !prefs.disable_ipc_flooding_protection);
  settings->SetHyperlinkAuditingEnabled(prefs.hyperlink_auditing_enabled);
  settings->SetCookieEnabled(prefs.cookie_enabled);
  settings->SetNavigateOnDragDrop(prefs.navigate_on_drag_drop);
  settings->SetThreadedScrollingEnabled(prefs.threaded_scrolling_enabled);

  // By default, allow_universal_access_from_file_urls is set to false and thus
  // we mitigate attacks from local HTML files by not granting file:// URLs
  // universal access. Only test shell will enable this.
  settings->SetAllowUniversalAccessFromFileURLs(
      prefs.allow_universal_access_from_file_urls);
  settings->SetAllowFileAccessFromFileURLs(
      prefs.allow_file_access_from_file_urls);

  settings->SetWebGL1Enabled(prefs.webgl1_enabled);
  settings->SetWebGL2Enabled(prefs.webgl2_enabled);

  // Enable WebGL errors to the JS console if requested.
  settings->SetWebGLErrorsToConsoleEnabled(
      prefs.webgl_errors_to_console_enabled);

  settings->SetHideScrollbars(prefs.hide_scrollbars);

  // Enable gpu-accelerated 2d canvas if requested on the command line.
  RuntimeEnabledFeatures::SetAccelerated2dCanvasEnabled(
      prefs.accelerated_2d_canvas_enabled);

  // Enable new canvas 2d api features
  RuntimeEnabledFeatures::SetNewCanvas2DAPIEnabled(
      prefs.new_canvas_2d_api_enabled);

  // Disable antialiasing for 2d canvas if requested on the command line.
  settings->SetAntialiased2dCanvasEnabled(
      !prefs.antialiased_2d_canvas_disabled);

  // Disable antialiasing of clips for 2d canvas if requested on the command
  // line.
  settings->SetAntialiasedClips2dCanvasEnabled(
      prefs.antialiased_clips_2d_canvas_enabled);

  // Tabs to link is not part of the settings. WebCore calls
  // ChromeClient::tabsToLinks which is part of the glue code.
  web_view_impl->SetTabsToLinks(prefs.tabs_to_links);

  settings->SetAllowRunningOfInsecureContent(
      prefs.allow_running_insecure_content);
  settings->SetDisableReadingFromCanvas(prefs.disable_reading_from_canvas);
  settings->SetStrictMixedContentChecking(prefs.strict_mixed_content_checking);

  settings->SetStrictlyBlockBlockableMixedContent(
      prefs.strictly_block_blockable_mixed_content);

  settings->SetStrictMixedContentCheckingForPlugin(
      prefs.block_mixed_plugin_content);

  settings->SetStrictPowerfulFeatureRestrictions(
      prefs.strict_powerful_feature_restrictions);
  settings->SetAllowGeolocationOnInsecureOrigins(
      prefs.allow_geolocation_on_insecure_origins);
  settings->SetPasswordEchoEnabled(prefs.password_echo_enabled);
  settings->SetShouldPrintBackgrounds(prefs.should_print_backgrounds);
  settings->SetShouldClearDocumentBackground(
      prefs.should_clear_document_background);
  settings->SetEnableScrollAnimator(prefs.enable_scroll_animator);
  settings->SetPrefersReducedMotion(prefs.prefers_reduced_motion);

  RuntimeEnabledFeatures::SetTouchEventFeatureDetectionEnabled(
      prefs.touch_event_feature_detection_enabled);
  settings->SetMaxTouchPoints(prefs.pointer_events_max_touch_points);
  settings->SetAvailablePointerTypes(prefs.available_pointer_types);
  settings->SetPrimaryPointerType(prefs.primary_pointer_type);
  settings->SetAvailableHoverTypes(prefs.available_hover_types);
  settings->SetPrimaryHoverType(prefs.primary_hover_type);
  settings->SetBarrelButtonForDragEnabled(prefs.barrel_button_for_drag_enabled);

  settings->SetEditingBehavior(prefs.editing_behavior);

  settings->SetSupportsMultipleWindows(prefs.supports_multiple_windows);

  settings->SetMainFrameClipsContent(!prefs.record_whole_document);

  settings->SetSmartInsertDeleteEnabled(prefs.smart_insert_delete_enabled);

  settings->SetSpatialNavigationEnabled(prefs.spatial_navigation_enabled);
  // Spatnav depends on KeyboardFocusableScrollers. The WebUI team has
  // disabled KFS because they need more time to update their custom elements,
  // crbug.com/907284. Meanwhile, we pre-ship KFS to spatnav users.
  if (prefs.spatial_navigation_enabled)
    RuntimeEnabledFeatures::SetKeyboardFocusableScrollersEnabled(true);

  settings->SetSelectionIncludesAltImageText(true);

  settings->SetV8CacheOptions(prefs.v8_cache_options);

  settings->SetImageAnimationPolicy(prefs.animation_policy);

  settings->SetPresentationRequiresUserGesture(
      prefs.user_gesture_required_for_presentation);

  if (prefs.text_tracks_enabled) {
    settings->SetTextTrackKindUserPreference(
        WebSettings::TextTrackKindUserPreference::kCaptions);
  } else {
    settings->SetTextTrackKindUserPreference(
        WebSettings::TextTrackKindUserPreference::kDefault);
  }
  settings->SetTextTrackBackgroundColor(
      WebString::FromASCII(prefs.text_track_background_color));
  settings->SetTextTrackTextColor(
      WebString::FromASCII(prefs.text_track_text_color));
  settings->SetTextTrackTextSize(
      WebString::FromASCII(prefs.text_track_text_size));
  settings->SetTextTrackTextShadow(
      WebString::FromASCII(prefs.text_track_text_shadow));
  settings->SetTextTrackFontFamily(
      WebString::FromASCII(prefs.text_track_font_family));
  settings->SetTextTrackFontStyle(
      WebString::FromASCII(prefs.text_track_font_style));
  settings->SetTextTrackFontVariant(
      WebString::FromASCII(prefs.text_track_font_variant));
  settings->SetTextTrackMarginPercentage(prefs.text_track_margin_percentage);
  settings->SetTextTrackWindowColor(
      WebString::FromASCII(prefs.text_track_window_color));
  settings->SetTextTrackWindowPadding(
      WebString::FromASCII(prefs.text_track_window_padding));
  settings->SetTextTrackWindowRadius(
      WebString::FromASCII(prefs.text_track_window_radius));

  // Needs to happen before SetDefaultPageScaleLimits below since that'll
  // recalculate the final page scale limits and that depends on this setting.
  settings->SetShrinksViewportContentToFit(
      prefs.shrinks_viewport_contents_to_fit);

  // Needs to happen before SetIgnoreViewportTagScaleLimits below.
  web_view->SetDefaultPageScaleLimits(prefs.default_minimum_page_scale_factor,
                                      prefs.default_maximum_page_scale_factor);

  settings->SetFullscreenSupported(prefs.fullscreen_supported);
  settings->SetTextAutosizingEnabled(prefs.text_autosizing_enabled);
  settings->SetDoubleTapToZoomEnabled(prefs.double_tap_to_zoom_enabled);
  blink::WebNetworkStateNotifier::SetNetworkQualityWebHoldback(
      static_cast<blink::WebEffectiveConnectionType>(
          prefs.network_quality_estimator_web_holdback));

  settings->SetDontSendKeyEventsToJavascript(
      prefs.dont_send_key_events_to_javascript);
  settings->SetWebAppScope(WebString::FromASCII(prefs.web_app_scope.spec()));

#if defined(OS_ANDROID)
  settings->SetAllowCustomScrollbarInMainFrame(false);
  settings->SetAccessibilityFontScaleFactor(prefs.font_scale_factor);
  settings->SetDeviceScaleAdjustment(prefs.device_scale_adjustment);
  web_view_impl->SetIgnoreViewportTagScaleLimits(prefs.force_enable_zoom);
  settings->SetAutoZoomFocusedNodeToLegibleScale(true);
  settings->SetDefaultVideoPosterURL(
      WebString::FromASCII(prefs.default_video_poster_url.spec()));
  settings->SetSupportDeprecatedTargetDensityDPI(
      prefs.support_deprecated_target_density_dpi);
  settings->SetUseLegacyBackgroundSizeShorthandBehavior(
      prefs.use_legacy_background_size_shorthand_behavior);
  settings->SetWideViewportQuirkEnabled(prefs.wide_viewport_quirk);
  settings->SetUseWideViewport(prefs.use_wide_viewport);
  settings->SetForceZeroLayoutHeight(prefs.force_zero_layout_height);
  settings->SetViewportMetaMergeContentQuirk(
      prefs.viewport_meta_merge_content_quirk);
  settings->SetViewportMetaNonUserScalableQuirk(
      prefs.viewport_meta_non_user_scalable_quirk);
  settings->SetViewportMetaZeroValuesQuirk(
      prefs.viewport_meta_zero_values_quirk);
  settings->SetClobberUserAgentInitialScaleQuirk(
      prefs.clobber_user_agent_initial_scale_quirk);
  settings->SetIgnoreMainFrameOverflowHiddenQuirk(
      prefs.ignore_main_frame_overflow_hidden_quirk);
  settings->SetReportScreenSizeInPhysicalPixelsQuirk(
      prefs.report_screen_size_in_physical_pixels_quirk);
  settings->SetShouldReuseGlobalForUnownedMainFrame(
      prefs.reuse_global_for_unowned_main_frame);
  settings->SetPreferHiddenVolumeControls(true);
  settings->SetSpellCheckEnabledByDefault(prefs.spellcheck_enabled_by_default);

  RuntimeEnabledFeatures::SetVideoFullscreenOrientationLockEnabled(
      prefs.video_fullscreen_orientation_lock_enabled);
  RuntimeEnabledFeatures::SetVideoRotateToFullscreenEnabled(
      prefs.video_rotate_to_fullscreen_enabled);
  settings->SetEmbeddedMediaExperienceEnabled(
      prefs.embedded_media_experience_enabled);
  settings->SetImmersiveModeEnabled(prefs.immersive_mode_enabled);
  settings->SetDoNotUpdateSelectionOnMutatingSelectionRange(
      prefs.do_not_update_selection_on_mutating_selection_range);
  RuntimeEnabledFeatures::SetCSSHexAlphaColorEnabled(
      prefs.css_hex_alpha_color_enabled);
  RuntimeEnabledFeatures::SetScrollTopLeftInteropEnabled(
      prefs.scroll_top_left_interop_enabled);
  RuntimeEnabledFeatures::SetSurfaceEmbeddingFeaturesEnabled(
      !prefs.disable_features_depending_on_viz);
  RuntimeEnabledFeatures::SetAcceleratedSmallCanvasesEnabled(
      !prefs.disable_accelerated_small_canvases);
#endif  // defined(OS_ANDROID)
  settings->SetForceDarkModeEnabled(prefs.force_dark_mode_enabled);

  settings->SetAccessibilityAlwaysShowFocus(prefs.always_show_focus);
  settings->SetAutoplayPolicy(prefs.autoplay_policy);
  settings->SetViewportEnabled(prefs.viewport_enabled);
  settings->SetViewportMetaEnabled(prefs.viewport_meta_enabled);
  settings->SetViewportStyle(prefs.viewport_style);

  settings->SetLoadWithOverviewMode(prefs.initialize_at_minimum_page_scale);
  settings->SetMainFrameResizesAreOrientationChanges(
      prefs.main_frame_resizes_are_orientation_changes);

  settings->SetShowContextMenuOnMouseUp(prefs.context_menu_on_mouse_up);
  settings->SetAlwaysShowContextMenuOnTouch(
      prefs.always_show_context_menu_on_touch);
  settings->SetSmoothScrollForFindEnabled(prefs.smooth_scroll_for_find_enabled);

  settings->SetHideDownloadUI(prefs.hide_download_ui);

  settings->SetPresentationReceiver(prefs.presentation_receiver);

  settings->SetMediaControlsEnabled(prefs.media_controls_enabled);

  settings->SetLowPriorityIframesThreshold(
      static_cast<blink::WebEffectiveConnectionType>(
          prefs.low_priority_iframes_threshold));

  settings->SetPictureInPictureEnabled(
      prefs.picture_in_picture_enabled &&
      GetVideoSurfaceLayerMode() !=
          blink::WebMediaPlayer::SurfaceLayerMode::kNever);

  settings->SetDataSaverHoldbackWebApi(
      prefs.data_saver_holdback_web_api_enabled);

  settings->SetLazyLoadEnabled(prefs.lazy_load_enabled);
  settings->SetPreferredColorScheme(prefs.preferred_color_scheme);
  settings->SetPreferredContrast(prefs.preferred_contrast);

  for (const auto& ect_distance_pair :
       prefs.lazy_frame_loading_distance_thresholds_px) {
    switch (ect_distance_pair.first) {
      case EffectiveConnectionType::kEffectiveConnectionUnknownType:
        settings->SetLazyFrameLoadingDistanceThresholdPxUnknown(
            ect_distance_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnectionOfflineType:
        settings->SetLazyFrameLoadingDistanceThresholdPxOffline(
            ect_distance_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnectionSlow2GType:
        settings->SetLazyFrameLoadingDistanceThresholdPxSlow2G(
            ect_distance_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnection2GType:
        settings->SetLazyFrameLoadingDistanceThresholdPx2G(
            ect_distance_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnection3GType:
        settings->SetLazyFrameLoadingDistanceThresholdPx3G(
            ect_distance_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnection4GType:
        settings->SetLazyFrameLoadingDistanceThresholdPx4G(
            ect_distance_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnectionTypeLast:
        continue;
    }
    NOTREACHED();
  }

  for (const auto& ect_distance_pair :
       prefs.lazy_image_loading_distance_thresholds_px) {
    switch (ect_distance_pair.first) {
      case EffectiveConnectionType::kEffectiveConnectionUnknownType:
        settings->SetLazyImageLoadingDistanceThresholdPxUnknown(
            ect_distance_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnectionOfflineType:
        settings->SetLazyImageLoadingDistanceThresholdPxOffline(
            ect_distance_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnectionSlow2GType:
        settings->SetLazyImageLoadingDistanceThresholdPxSlow2G(
            ect_distance_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnection2GType:
        settings->SetLazyImageLoadingDistanceThresholdPx2G(
            ect_distance_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnection3GType:
        settings->SetLazyImageLoadingDistanceThresholdPx3G(
            ect_distance_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnection4GType:
        settings->SetLazyImageLoadingDistanceThresholdPx4G(
            ect_distance_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnectionTypeLast:
        continue;
    }
    NOTREACHED();
  }

  for (const auto& fully_load_k_pair : prefs.lazy_image_first_k_fully_load) {
    switch (fully_load_k_pair.first) {
      case EffectiveConnectionType::kEffectiveConnectionOfflineType:
        continue;
      case EffectiveConnectionType::kEffectiveConnectionUnknownType:
        settings->SetLazyImageFirstKFullyLoadUnknown(fully_load_k_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnectionSlow2GType:
        settings->SetLazyImageFirstKFullyLoadSlow2G(fully_load_k_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnection2GType:
        settings->SetLazyImageFirstKFullyLoad2G(fully_load_k_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnection3GType:
        settings->SetLazyImageFirstKFullyLoad3G(fully_load_k_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnection4GType:
        settings->SetLazyImageFirstKFullyLoad4G(fully_load_k_pair.second);
        continue;
      case EffectiveConnectionType::kEffectiveConnectionTypeLast:
        continue;
    }
    NOTREACHED();
  }

  settings->SetTouchDragDropEnabled(prefs.touch_drag_drop_enabled);
  settings->SetTouchDragEndContextMenu(prefs.touch_dragend_context_menu);
  settings->SetWebXRImmersiveArAllowed(prefs.webxr_immersive_ar_allowed);

#if defined(OS_MAC)
  web_view_impl->SetMaximumLegibleScale(
      prefs.default_maximum_page_scale_factor);
#endif

#if defined(OS_WIN)
  RuntimeEnabledFeatures::SetMiddleClickAutoscrollEnabled(true);
#endif

  RuntimeEnabledFeatures::SetTranslateServiceEnabled(
      prefs.translate_service_available);
}

void WebViewImpl::ThemeChanged() {
  if (!GetPage())
    return;
  if (!GetPage()->MainFrame()->IsLocalFrame())
    return;
  LocalFrameView* view = GetPage()->DeprecatedLocalMainFrame()->View();

  IntRect damaged_rect(0, 0, size_.width(), size_.height());
  view->InvalidateRect(damaged_rect);
}

void WebViewImpl::EnterFullscreen(LocalFrame& frame,
                                  const FullscreenOptions* options,
                                  FullscreenRequestType request_type) {
  fullscreen_controller_->EnterFullscreen(frame, options, request_type);
}

void WebViewImpl::ExitFullscreen(LocalFrame& frame) {
  fullscreen_controller_->ExitFullscreen(frame);
}

void WebViewImpl::FullscreenElementChanged(Element* old_element,
                                           Element* new_element,
                                           const FullscreenOptions* options,
                                           FullscreenRequestType request_type) {
  fullscreen_controller_->FullscreenElementChanged(old_element, new_element,
                                                   options, request_type);
}

bool WebViewImpl::HasHorizontalScrollbar() {
  return MainFrameImpl()
      ->GetFrameView()
      ->LayoutViewport()
      ->HorizontalScrollbar();
}

bool WebViewImpl::HasVerticalScrollbar() {
  return MainFrameImpl()->GetFrameView()->LayoutViewport()->VerticalScrollbar();
}

void WebViewImpl::SetPageFocus(bool enable) {
  if (enable)
    page_->GetFocusController().SetActive(true);
  page_->GetFocusController().SetFocused(enable);
  if (enable) {
    LocalFrame* focused_frame = page_->GetFocusController().FocusedFrame();
    if (focused_frame) {
      Element* element = focused_frame->GetDocument()->FocusedElement();
      if (element && focused_frame->Selection()
                         .ComputeVisibleSelectionInDOMTreeDeprecated()
                         .IsNone()) {
        // If the selection was cleared while the WebView was not
        // focused, then the focus element shows with a focus ring but
        // no caret and does respond to keyboard inputs.
        focused_frame->GetDocument()->UpdateStyleAndLayoutTree();
        if (element->IsTextControl()) {
          element->UpdateFocusAppearance(SelectionBehaviorOnFocus::kRestore);
        } else if (HasEditableStyle(*element)) {
          // updateFocusAppearance() selects all the text of
          // contentseditable DIVs. So we set the selection explicitly
          // instead. Note that this has the side effect of moving the
          // caret back to the beginning of the text.
          Position position(element, 0);
          focused_frame->Selection().SetSelectionAndEndTyping(
              SelectionInDOMTree::Builder().Collapse(position).Build());
        }
      }
    }
  } else {
    CancelPagePopup();

    LocalFrame* focused_frame = page_->GetFocusController().FocusedFrame();
    if (focused_frame) {
      // Finish an ongoing composition to delete the composition node.
      if (focused_frame->GetInputMethodController().HasComposition()) {
        // TODO(editing-dev): The use of
        // UpdateStyleAndLayout needs to be audited.
        // See http://crbug.com/590369 for more details.
        focused_frame->GetDocument()->UpdateStyleAndLayout(
            DocumentUpdateReason::kFocus);

        focused_frame->GetInputMethodController().FinishComposingText(
            InputMethodController::kKeepSelection);
      }
    }
  }
}

// WebView --------------------------------------------------------------------

WebSettingsImpl* WebViewImpl::SettingsImpl() {
  if (!web_settings_) {
    web_settings_ = std::make_unique<WebSettingsImpl>(
        &page_->GetSettings(), dev_tools_emulator_.Get());
  }
  DCHECK(web_settings_);
  return web_settings_.get();
}

WebSettings* WebViewImpl::GetSettings() {
  return SettingsImpl();
}

WebString WebViewImpl::PageEncoding() const {
  if (!page_)
    return WebString();

  auto* main_frame = DynamicTo<LocalFrame>(page_->MainFrame());
  if (!main_frame)
    return WebString();

  // FIXME: Is this check needed?
  if (!main_frame->GetDocument()->Loader())
    return WebString();

  return main_frame->GetDocument()->EncodingName();
}

WebFrame* WebViewImpl::MainFrame() {
  Page* page = page_.Get();
  return WebFrame::FromCoreFrame(page ? page->MainFrame() : nullptr);
}

WebLocalFrameImpl* WebViewImpl::MainFrameImpl() const {
  Page* page = page_.Get();
  if (!page)
    return nullptr;
  return WebLocalFrameImpl::FromFrame(DynamicTo<LocalFrame>(page->MainFrame()));
}

std::string WebViewImpl::GetNullFrameReasonForBug1139104() const {
  Page* page = page_.Get();
  if (!page)
    return "WebViewImpl::page";
  if (!page->MainFrame())
    return "WebViewImpl::page->MainFrame";
  LocalFrame* local_frame = DynamicTo<LocalFrame>(page->MainFrame());
  if (!local_frame)
    return "WebViewImpl::local_frame";
  return WebLocalFrameImpl::GetNullFrameReasonForBug1139104(local_frame);
}

void WebViewImpl::DidAttachLocalMainFrame() {
  DCHECK(MainFrameImpl());

  LocalFrame* local_frame = MainFrameImpl()->GetFrame();
  local_frame->WasAttachedAsLocalMainFrame();

  local_frame->GetRemoteNavigationAssociatedInterfaces()->GetInterface(
      local_main_frame_host_remote_.BindNewEndpointAndPassReceiver(
          GetPage()
              ->GetPageScheduler()
              ->GetAgentGroupScheduler()
              .DefaultTaskRunner()));

  if (does_composite_) {
    // When attaching a local main frame, set up any state on the compositor.
    MainFrameImpl()->FrameWidgetImpl()->SetBackgroundColor(BackgroundColor());
    auto& viewport = GetPage()->GetVisualViewport();
    MainFrameImpl()->FrameWidgetImpl()->SetPageScaleStateAndLimits(
        viewport.Scale(), viewport.IsPinchGestureActive(),
        MinimumPageScaleFactor(), MaximumPageScaleFactor());
    // Prevent main frame updates while the main frame is loading until enough
    // progress is made and BeginMainFrames are explicitly asked for.
    scoped_defer_main_frame_update_ =
        MainFrameImpl()->FrameWidgetImpl()->DeferMainFrameUpdate();
  }
}

void WebViewImpl::DidAttachRemoteMainFrame() {
  DCHECK(!MainFrameImpl());

  RemoteFrame* remote_frame = DynamicTo<RemoteFrame>(GetPage()->MainFrame());
  remote_frame->WasAttachedAsRemoteMainFrame();

  remote_frame->GetRemoteAssociatedInterfaces()->GetInterface(
      remote_main_frame_host_remote_.BindNewEndpointAndPassReceiver(
          GetPage()
              ->GetPageScheduler()
              ->GetAgentGroupScheduler()
              .DefaultTaskRunner()));

  auto& viewport = GetPage()->GetVisualViewport();
  viewport.Reset();
}

void WebViewImpl::DidDetachLocalMainFrame() {
  // The WebFrameWidget that generated the |scoped_defer_main_frame_update_|
  // for a local main frame is going away.
  scoped_defer_main_frame_update_ = nullptr;
  local_main_frame_host_remote_.reset();
}

void WebViewImpl::DidDetachRemoteMainFrame() {
  remote_main_frame_host_remote_.reset();
}

WebLocalFrame* WebViewImpl::FocusedFrame() {
  Frame* frame = FocusedCoreFrame();
  // TODO(yabinh): focusedCoreFrame() should always return a local frame, and
  // the following check should be unnecessary.
  // See crbug.com/625068
  return WebLocalFrameImpl::FromFrame(DynamicTo<LocalFrame>(frame));
}

void WebViewImpl::SetFocusedFrame(WebFrame* frame) {
  if (!frame) {
    // Clears the focused frame if any.
    Frame* focused_frame = FocusedCoreFrame();
    if (auto* focused_local_frame = DynamicTo<LocalFrame>(focused_frame))
      focused_local_frame->Selection().SetFrameIsFocused(false);
    return;
  }
  LocalFrame* core_frame = To<WebLocalFrameImpl>(frame)->GetFrame();
  core_frame->GetPage()->GetFocusController().SetFocusedFrame(core_frame);
}

bool WebViewImpl::ShouldZoomToLegibleScale(const Element& element) {
  bool zoom_into_legible_scale =
      web_settings_->AutoZoomFocusedNodeToLegibleScale() &&
      !GetPage()->GetVisualViewport().ShouldDisableDesktopWorkarounds();

  if (zoom_into_legible_scale) {
    // When deciding whether to zoom in on a focused text box, we should
    // decide not to zoom in if the user won't be able to zoom out. e.g if the
    // textbox is within a touch-action: none container the user can't zoom
    // back out.
    TouchAction action =
        touch_action_util::ComputeEffectiveTouchAction(element);
    if (!(static_cast<int>(action) & static_cast<int>(TouchAction::kPinchZoom)))
      zoom_into_legible_scale = false;
  }

  return zoom_into_legible_scale;
}

void WebViewImpl::ZoomAndScrollToFocusedEditableElementRect(
    const IntRect& element_bounds_in_document,
    const IntRect& caret_bounds_in_document,
    bool zoom_into_legible_scale) {
  float scale;
  IntPoint scroll;
  bool need_animation = false;
  ComputeScaleAndScrollForEditableElementRects(
      element_bounds_in_document, caret_bounds_in_document,
      zoom_into_legible_scale, scale, scroll, need_animation);
  if (need_animation) {
    StartPageScaleAnimation(scroll, false, scale,
                            kScrollAndScaleAnimationDuration);
  }
}

void WebViewImpl::SmoothScroll(int target_x,
                               int target_y,
                               base::TimeDelta duration) {
  IntPoint target_position(target_x, target_y);
  StartPageScaleAnimation(target_position, false, PageScaleFactor(), duration);
}

void WebViewImpl::ComputeScaleAndScrollForEditableElementRects(
    const IntRect& element_bounds_in_document,
    const IntRect& caret_bounds_in_document,
    bool zoom_into_legible_scale,
    float& new_scale,
    IntPoint& new_scroll,
    bool& need_animation) {
  VisualViewport& visual_viewport = GetPage()->GetVisualViewport();

  TopDocumentRootScrollerController& controller =
      GetPage()->GlobalRootScrollerController();
  Node* root_scroller = controller.GlobalRootScroller();

  IntRect element_bounds_in_content = element_bounds_in_document;
  IntRect caret_bounds_in_content = caret_bounds_in_document;

  // If the page has a non-default root scroller then we need to scroll that
  // rather than the "real" viewport. However, the given coordinates are in the
  // real viewport's document space rather than the root scroller's so we
  // perform the conversion here.  TODO(bokan): Convert this function to take
  // coordinates in absolute/root-frame coordinates to make this more
  // consistent. https://crbug.com/931447.
  if (root_scroller != MainFrameImpl()->GetFrame()->GetDocument() &&
      controller.RootScrollerArea()) {
    ScrollOffset offset = controller.RootScrollerArea()->GetScrollOffset();
    element_bounds_in_content.Move(FlooredIntSize(offset));
    caret_bounds_in_content.Move(FlooredIntSize(offset));
  }

  if (!zoom_into_legible_scale) {
    new_scale = PageScaleFactor();
  } else {
    // Pick a scale which is reasonably readable. This is the scale at which
    // the caret height will become minReadableCaretHeightForNode (adjusted
    // for dpi and font scale factor).
    const int min_readable_caret_height_for_node =
        (element_bounds_in_content.Height() >=
                 2 * caret_bounds_in_content.Height()
             ? minReadableCaretHeightForTextArea
             : minReadableCaretHeight) *
        MainFrameImpl()->GetFrame()->PageZoomFactor();
    new_scale = ClampPageScaleFactorToLimits(
        MaximumLegiblePageScale() * min_readable_caret_height_for_node /
        caret_bounds_in_content.Height());
    new_scale = std::max(new_scale, PageScaleFactor());
  }
  const float delta_scale = new_scale / PageScaleFactor();

  need_animation = false;

  // If we are at less than the target zoom level, zoom in.
  if (delta_scale > minScaleChangeToTriggerZoom)
    need_animation = true;
  else
    new_scale = PageScaleFactor();

  ScrollableArea* root_viewport =
      MainFrameImpl()->GetFrame()->View()->GetScrollableArea();

  // If the caret is offscreen, then animate.
  if (!root_viewport->VisibleContentRect().Contains(caret_bounds_in_content))
    need_animation = true;

  // If the box is partially offscreen and it's possible to bring it fully
  // onscreen, then animate.
  if (visual_viewport.VisibleRect().Width() >=
          element_bounds_in_content.Width() &&
      visual_viewport.VisibleRect().Height() >=
          element_bounds_in_content.Height() &&
      !root_viewport->VisibleContentRect().Contains(element_bounds_in_content))
    need_animation = true;

  if (!need_animation)
    return;

  FloatSize target_viewport_size(visual_viewport.Size());
  target_viewport_size.Scale(1 / new_scale);

  if (element_bounds_in_content.Width() <= target_viewport_size.Width()) {
    // Field is narrower than screen. Try to leave padding on left so field's
    // label is visible, but it's more important to ensure entire field is
    // onscreen.
    int ideal_left_padding = target_viewport_size.Width() * leftBoxRatio;
    int max_left_padding_keeping_box_onscreen =
        target_viewport_size.Width() - element_bounds_in_content.Width();
    new_scroll.SetX(element_bounds_in_content.X() -
                    std::min<int>(ideal_left_padding,
                                  max_left_padding_keeping_box_onscreen));
  } else {
    // Field is wider than screen. Try to left-align field, unless caret would
    // be offscreen, in which case right-align the caret.
    new_scroll.SetX(std::max<int>(
        element_bounds_in_content.X(),
        caret_bounds_in_content.X() + caret_bounds_in_content.Width() +
            caretPadding - target_viewport_size.Width()));
  }
  if (element_bounds_in_content.Height() <= target_viewport_size.Height()) {
    // Field is shorter than screen. Vertically center it.
    new_scroll.SetY(
        element_bounds_in_content.Y() -
        (target_viewport_size.Height() - element_bounds_in_content.Height()) /
            2);
  } else {
    // Field is taller than screen. Try to top align field, unless caret would
    // be offscreen, in which case bottom-align the caret.
    new_scroll.SetY(std::max<int>(
        element_bounds_in_content.Y(),
        caret_bounds_in_content.Y() + caret_bounds_in_content.Height() +
            caretPadding - target_viewport_size.Height()));
  }
}

void WebViewImpl::AdvanceFocus(bool reverse) {
  GetPage()->GetFocusController().AdvanceFocus(
      reverse ? mojom::blink::FocusType::kBackward
              : mojom::blink::FocusType::kForward);
}

double WebViewImpl::ZoomLevel() {
  return zoom_level_;
}

void WebViewImpl::PropagateZoomFactorToLocalFrameRoots(Frame* frame,
                                                       float zoom_factor) {
  auto* local_frame = DynamicTo<LocalFrame>(frame);
  if (local_frame && local_frame->IsLocalRoot()) {
    if (Document* document = local_frame->GetDocument()) {
      auto* plugin_document = DynamicTo<PluginDocument>(document);
      if (!plugin_document || !plugin_document->GetPluginView()) {
        local_frame->SetPageZoomFactor(zoom_factor);
      }
    }
  }

  for (Frame* child = frame->Tree().FirstChild(); child;
       child = child->Tree().NextSibling())
    PropagateZoomFactorToLocalFrameRoots(child, zoom_factor);
}

double WebViewImpl::SetZoomLevel(double zoom_level) {
  double old_zoom_level = zoom_level_;
  if (zoom_level < minimum_zoom_level_)
    zoom_level_ = minimum_zoom_level_;
  else if (zoom_level > maximum_zoom_level_)
    zoom_level_ = maximum_zoom_level_;
  else
    zoom_level_ = zoom_level;

  float zoom_factor =
      zoom_factor_override_
          ? zoom_factor_override_
          : static_cast<float>(PageZoomLevelToZoomFactor(zoom_level_));
  if (zoom_factor_for_device_scale_factor_) {
    if (compositor_device_scale_factor_override_) {
      // Adjust the page's DSF so that DevicePixelRatio becomes
      // |zoom_factor_for_device_scale_factor_|.
      page_->SetDeviceScaleFactorDeprecated(
          zoom_factor_for_device_scale_factor_ /
          compositor_device_scale_factor_override_);
      zoom_factor *= compositor_device_scale_factor_override_;
    } else {
      page_->SetDeviceScaleFactorDeprecated(1.f);
      zoom_factor *= zoom_factor_for_device_scale_factor_;
    }
  }
  PropagateZoomFactorToLocalFrameRoots(page_->MainFrame(), zoom_factor);

  if (old_zoom_level != zoom_level_) {
    for (auto& observer : observers_)
      observer.OnZoomLevelChanged();
    CancelPagePopup();
  }

  return zoom_level_;
}

float WebViewImpl::PageScaleFactor() const {
  if (!GetPage())
    return 1;

  return GetPage()->GetVisualViewport().Scale();
}

float WebViewImpl::ClampPageScaleFactorToLimits(float scale_factor) const {
  return GetPageScaleConstraintsSet().FinalConstraints().ClampToConstraints(
      scale_factor);
}

void WebViewImpl::SetVisualViewportOffset(const gfx::PointF& offset) {
  DCHECK(GetPage());
  GetPage()->GetVisualViewport().SetLocation(FloatPoint(offset));
}

gfx::PointF WebViewImpl::VisualViewportOffset() const {
  DCHECK(GetPage());
  return GetPage()->GetVisualViewport().VisibleRect().Location();
}

gfx::SizeF WebViewImpl::VisualViewportSize() const {
  DCHECK(GetPage());
  return gfx::SizeF(GetPage()->GetVisualViewport().VisibleRect().Size());
}

void WebViewImpl::SetPageScaleFactorAndLocation(float scale_factor,
                                                bool is_pinch_gesture_active,
                                                const FloatPoint& location) {
  DCHECK(GetPage());

  GetPage()->GetVisualViewport().SetScaleAndLocation(
      ClampPageScaleFactorToLimits(scale_factor), is_pinch_gesture_active,
      location);
}

void WebViewImpl::SetPageScaleFactor(float scale_factor) {
  DCHECK(GetPage());
  DCHECK(MainFrameImpl());

  MainFrameImpl()->GetFrame()->SetScaleFactor(scale_factor);
}

void WebViewImpl::SetDeviceScaleFactor(float scale_factor) {
  if (!GetPage())
    return;

  if (GetPage()->DeviceScaleFactorDeprecated() == scale_factor)
    return;

  GetPage()->SetDeviceScaleFactorDeprecated(scale_factor);
}

void WebViewImpl::SetZoomFactorForDeviceScaleFactor(
    float zoom_factor_for_device_scale_factor) {
  DCHECK(does_composite_);
  // We can't early-return here if these are already equal, because we may
  // need to propagate the correct zoom factor to newly navigated frames.
  zoom_factor_for_device_scale_factor_ = zoom_factor_for_device_scale_factor;
  SetZoomLevel(zoom_level_);
}

void WebViewImpl::SetPageLifecycleStateFromNewPageCommit(
    mojom::blink::PageVisibilityState visibility,
    mojom::blink::PagehideDispatch pagehide_dispatch) {
  mojom::blink::PageLifecycleStatePtr state =
      GetPage()->GetPageLifecycleState().Clone();
  state->visibility = visibility;
  state->pagehide_dispatch = pagehide_dispatch;
  SetPageLifecycleStateInternal(std::move(state),
                                /*page_restore_params=*/nullptr);
}

void WebViewImpl::SetPageLifecycleState(
    mojom::blink::PageLifecycleStatePtr state,
    mojom::blink::PageRestoreParamsPtr page_restore_params,
    SetPageLifecycleStateCallback callback) {
  SetPageLifecycleStateInternal(std::move(state),
                                std::move(page_restore_params));
  // Tell the browser that the lifecycle update was successful.
  std::move(callback).Run();
}

void WebViewImpl::SetPageLifecycleStateInternal(
    mojom::blink::PageLifecycleStatePtr new_state,
    mojom::blink::PageRestoreParamsPtr page_restore_params) {
  Page* page = GetPage();
  if (!page)
    return;
  auto& old_state = page->GetPageLifecycleState();
  bool storing_in_bfcache = new_state->is_in_back_forward_cache &&
                            !old_state->is_in_back_forward_cache;
  bool restoring_from_bfcache = !new_state->is_in_back_forward_cache &&
                                old_state->is_in_back_forward_cache;
  bool hiding_page =
      (new_state->visibility != mojom::blink::PageVisibilityState::kVisible) &&
      (old_state->visibility == mojom::blink::PageVisibilityState::kVisible);
  bool showing_page =
      (new_state->visibility == mojom::blink::PageVisibilityState::kVisible) &&
      (old_state->visibility != mojom::blink::PageVisibilityState::kVisible);
  bool freezing_page = new_state->is_frozen && !old_state->is_frozen;
  bool resuming_page = !new_state->is_frozen && old_state->is_frozen;
  bool dispatching_pagehide =
      (new_state->pagehide_dispatch !=
       mojom::blink::PagehideDispatch::kNotDispatched) &&
      !GetPage()->DispatchedPagehideAndStillHidden();
  bool dispatching_pageshow =
      (new_state->pagehide_dispatch ==
       mojom::blink::PagehideDispatch::kNotDispatched) &&
      GetPage()->DispatchedPagehideAndStillHidden();
  bool eviction_changed =
      new_state->eviction_enabled != old_state->eviction_enabled;

  if (dispatching_pagehide) {
    RemoveFocusAndTextInputState();
  }
  if (dispatching_pagehide) {
    // Note that |dispatching_pagehide| is different than |hiding_page|.
    // |dispatching_pagehide| will only be true when we're navigating away from
    // a page, while |hiding_page| might be true in other cases too such as when
    // the tab containing a page is backgrounded, and might be false even when
    // we're navigating away from a page, if the page is already hidden.
    DispatchPagehide(new_state->pagehide_dispatch);
  }
  if (hiding_page) {
    SetVisibilityState(new_state->visibility, /*is_initial_state=*/false);
  }
  if (storing_in_bfcache) {
    Scheduler()->SetPageBackForwardCached(new_state->is_in_back_forward_cache);
  }
  if (freezing_page)
    SetPageFrozen(true);
  if (restoring_from_bfcache) {
    DCHECK(page_restore_params);
    // Update the history offset and length value saved in RenderViewImpl, as
    // pages that are kept in the back-forward cache do not get notified about
    // updates on these values, so the currently saved value might be stale.
    web_view_client_->OnSetHistoryOffsetAndLength(
        page_restore_params->pending_history_list_offset,
        page_restore_params->current_history_list_length);
  }
  if (eviction_changed)
    HookBackForwardCacheEviction(new_state->eviction_enabled);
  if (resuming_page)
    SetPageFrozen(false);
  if (showing_page) {
    SetVisibilityState(new_state->visibility, /*is_initial_state=*/false);
  }
  if (dispatching_pageshow) {
    DCHECK(restoring_from_bfcache);
    DispatchPageshow(page_restore_params->navigation_start);
  }
  if (restoring_from_bfcache) {
    DCHECK(dispatching_pageshow);
    DCHECK(page_restore_params);
    Scheduler()->SetPageBackForwardCached(new_state->is_in_back_forward_cache);
  }

  // Make sure no TrackedFeaturesUpdate message is sent after the ACK
  // TODO(carlscab): Do we really need to go through LocalFrame =>
  // platform/scheduler/ => LocalFrame to report the features? We can probably
  // move SchedulerTrackedFeatures to core/ and remove the back and forth.
  ReportActiveSchedulerTrackedFeatures();

  GetPage()->SetPageLifecycleState(std::move(new_state));

  // Notify all local frames that we've updated the page lifecycle state.
  for (WebFrame* frame = MainFrame(); frame; frame = frame->TraverseNext()) {
    if (frame->IsWebLocalFrame()) {
      frame->ToWebLocalFrame()->Client()->DidSetPageLifecycleState();
    }
  }
}

void WebViewImpl::ReportActiveSchedulerTrackedFeatures() {
  Page* page = GetPage();
  if (!page)
    return;

  for (Frame* frame = page->MainFrame(); frame;
       frame = frame->Tree().TraverseNext()) {
    if (!frame->IsLocalFrame())
      continue;
    auto* local_frame = DynamicTo<LocalFrame>(frame);
    if (!local_frame->GetFrameScheduler())
      continue;
    local_frame->GetFrameScheduler()->ReportActiveSchedulerTrackedFeatures();
  }
}

void WebViewImpl::AudioStateChanged(bool is_audio_playing) {
  GetPage()->GetPageScheduler()->AudioStateChanged(is_audio_playing);
}

void WebViewImpl::RemoveFocusAndTextInputState() {
  auto& focus_controller = GetPage()->GetFocusController();
  auto* focused_frame = focus_controller.FocusedFrame();
  if (!focused_frame)
    return;
  // Remove focus from the currently focused element and frame.
  focus_controller.SetFocusedElement(nullptr, nullptr);
  // Clear composing state, and make sure we send a TextInputState update.
  // Note that the TextInputState itself is cleared when we clear the focus,
  // but no updates to the browser will be triggered until the next animation
  // frame, which won't happen if we're freezing the page.
  if (auto* widget = static_cast<WebFrameWidgetImpl*>(
          focused_frame->GetWidgetForLocalRoot())) {
    widget->FinishComposingText(false /* keep_selection */);
    widget->UpdateTextInputState();
  }
}

void WebViewImpl::DispatchPagehide(
    mojom::blink::PagehideDispatch pagehide_dispatch) {
  DCHECK_NE(pagehide_dispatch, mojom::blink::PagehideDispatch::kNotDispatched);
  bool persisted = (pagehide_dispatch ==
                    mojom::blink::PagehideDispatch::kDispatchedPersisted);
  // Dispatch pagehide on all frames.
  for (Frame* frame = GetPage()->MainFrame(); frame;
       frame = frame->Tree().TraverseNext()) {
    if (frame->DomWindow() && frame->DomWindow()->IsLocalDOMWindow()) {
      frame->DomWindow()->ToLocalDOMWindow()->DispatchPagehideEvent(
          persisted
              ? PageTransitionEventPersistence::kPageTransitionEventPersisted
              : PageTransitionEventPersistence::
                    kPageTransitionEventNotPersisted);
    }
  }
}

void WebViewImpl::DispatchPageshow(base::TimeTicks navigation_start) {
  for (Frame* frame = GetPage()->MainFrame(); frame;
       frame = frame->Tree().TraverseNext()) {
    auto* local_frame = DynamicTo<LocalFrame>(frame);
    // Record the metics.
    if (local_frame && local_frame->View()) {
      Document* document = local_frame->GetDocument();
      if (document) {
        PaintTiming::From(*document).OnRestoredFromBackForwardCache();
        InteractiveDetector::From(*document)->OnRestoredFromBackForwardCache();
      }
      DocumentLoader* loader = local_frame->Loader().GetDocumentLoader();
      if (loader) {
        loader->GetTiming().MarkBackForwardCacheRestoreNavigationStart(
            navigation_start);
      }
    }
    if (frame->DomWindow() && frame->DomWindow()->IsLocalDOMWindow()) {
      frame->DomWindow()->ToLocalDOMWindow()->DispatchPersistedPageshowEvent(
          navigation_start);
      if (frame->IsMainFrame()) {
        UMA_HISTOGRAM_BOOLEAN(
            "BackForwardCache.MainFrameHasPageshowListenersOnRestore",
            frame->DomWindow()->ToLocalDOMWindow()->HasEventListeners(
                event_type_names::kPageshow));
      }
    }
  }
}

void WebViewImpl::HookBackForwardCacheEviction(bool hook) {
  DCHECK(GetPage());
  for (Frame* frame = GetPage()->MainFrame(); frame;
       frame = frame->Tree().TraverseNext()) {
    auto* local_frame = DynamicTo<LocalFrame>(frame);
    if (!local_frame)
      continue;
    if (hook)
      local_frame->HookBackForwardCacheEviction();
    else
      local_frame->RemoveBackForwardCacheEviction();
  }
}

void WebViewImpl::EnableAutoResizeMode(const gfx::Size& min_size,
                                       const gfx::Size& max_size) {
  should_auto_resize_ = true;
  min_auto_size_ = IntSize(min_size);
  max_auto_size_ = IntSize(max_size);
  ConfigureAutoResizeMode();
}

void WebViewImpl::DisableAutoResizeMode() {
  should_auto_resize_ = false;
  ConfigureAutoResizeMode();
}

bool WebViewImpl::AutoResizeMode() {
  return should_auto_resize_;
}

void WebViewImpl::EnableAutoResizeForTesting(const gfx::Size& min_window_size,
                                             const gfx::Size& max_window_size) {
  EnableAutoResizeMode(web_widget_->DIPsToCeiledBlinkSpace(min_window_size),
                       web_widget_->DIPsToCeiledBlinkSpace(max_window_size));
}

void WebViewImpl::DisableAutoResizeForTesting(
    const gfx::Size& new_window_size) {
  if (!should_auto_resize_)
    return;
  DisableAutoResizeMode();

  // The |new_size| is empty when resetting auto resize in between tests. In
  // this case the current size should just be preserved.
  if (!new_window_size.IsEmpty()) {
    web_widget_->Resize(web_widget_->DIPsToCeiledBlinkSpace(new_window_size));
  }
}

void WebViewImpl::SetDefaultPageScaleLimits(float min_scale, float max_scale) {
  dev_tools_emulator_->SetDefaultPageScaleLimits(min_scale, max_scale);
}

void WebViewImpl::SetInitialPageScaleOverride(
    float initial_page_scale_factor_override) {
  PageScaleConstraints constraints =
      GetPageScaleConstraintsSet().UserAgentConstraints();
  constraints.initial_scale = initial_page_scale_factor_override;

  if (constraints == GetPageScaleConstraintsSet().UserAgentConstraints())
    return;

  GetPageScaleConstraintsSet().SetNeedsReset(true);
  GetPage()->SetUserAgentPageScaleConstraints(constraints);
}

void WebViewImpl::SetMaximumLegibleScale(float maximum_legible_scale) {
  maximum_legible_scale_ = maximum_legible_scale;
}

void WebViewImpl::SetIgnoreViewportTagScaleLimits(bool ignore) {
  PageScaleConstraints constraints =
      GetPageScaleConstraintsSet().UserAgentConstraints();
  if (ignore) {
    // Don't ignore the minimum limits in touchless mode to prevent wide
    // loading elements from causing us to zoom pages out beyond their layout
    // which is fairly common.
    if (!RuntimeEnabledFeatures::FocuslessSpatialNavigationEnabled()) {
      constraints.minimum_scale =
          GetPageScaleConstraintsSet().DefaultConstraints().minimum_scale;
    }
    constraints.maximum_scale =
        GetPageScaleConstraintsSet().DefaultConstraints().maximum_scale;
  } else {
    if (!RuntimeEnabledFeatures::FocuslessSpatialNavigationEnabled()) {
      constraints.minimum_scale = -1;
    }
    constraints.maximum_scale = -1;
  }
  GetPage()->SetUserAgentPageScaleConstraints(constraints);
}

IntSize WebViewImpl::MainFrameSize() {
  // The frame size should match the viewport size at minimum scale, since the
  // viewport must always be contained by the frame.
  return IntSize(gfx::ScaleToCeiledSize(size_, 1 / MinimumPageScaleFactor()));
}

PageScaleConstraintsSet& WebViewImpl::GetPageScaleConstraintsSet() const {
  return GetPage()->GetPageScaleConstraintsSet();
}

void WebViewImpl::RefreshPageScaleFactor() {
  if (!MainFrame() || !GetPage() || !GetPage()->MainFrame() ||
      !GetPage()->MainFrame()->IsLocalFrame() ||
      !GetPage()->DeprecatedLocalMainFrame()->View())
    return;
  UpdatePageDefinedViewportConstraints(MainFrameImpl()
                                           ->GetFrame()
                                           ->GetDocument()
                                           ->GetViewportData()
                                           .GetViewportDescription());
  GetPageScaleConstraintsSet().ComputeFinalConstraints();

  float new_page_scale_factor = PageScaleFactor();
  if (GetPageScaleConstraintsSet().NeedsReset() &&
      GetPageScaleConstraintsSet().FinalConstraints().initial_scale != -1) {
    new_page_scale_factor =
        GetPageScaleConstraintsSet().FinalConstraints().initial_scale;
    GetPageScaleConstraintsSet().SetNeedsReset(false);
  }
  SetPageScaleFactor(new_page_scale_factor);

  // The constraints may have changed above which affects the page scale limits,
  // so we must update those even though SetPageScaleFactor() may do the same if
  // the scale factor is changed.
  if (does_composite_) {
    auto& viewport = GetPage()->GetVisualViewport();
    MainFrameImpl()->FrameWidgetImpl()->SetPageScaleStateAndLimits(
        viewport.Scale(), viewport.IsPinchGestureActive(),
        MinimumPageScaleFactor(), MaximumPageScaleFactor());
  }
}

void WebViewImpl::UpdatePageDefinedViewportConstraints(
    const ViewportDescription& description) {
  if (!GetPage() || (!size_.width() && !size_.height()))
    return;
  // The viewport is a property of the main frame and its widget, so ignore it
  // when the main frame is remote.
  // TODO(danakj): Remove calls to this method from ChromeClient and DCHECK this
  // instead.
  if (!GetPage()->MainFrame()->IsLocalFrame())
    return;

  if (!GetSettings()->ViewportEnabled()) {
    GetPageScaleConstraintsSet().ClearPageDefinedConstraints();
    UpdateMainFrameLayoutSize();
    return;
  }

  Document* document = GetPage()->DeprecatedLocalMainFrame()->GetDocument();

  Length default_min_width =
      document->GetViewportData().ViewportDefaultMinWidth();
  if (default_min_width.IsAuto())
    default_min_width = Length::ExtendToZoom();

  float old_initial_scale =
      GetPageScaleConstraintsSet().PageDefinedConstraints().initial_scale;
  GetPageScaleConstraintsSet().UpdatePageDefinedConstraints(description,
                                                            default_min_width);

  if (SettingsImpl()->ClobberUserAgentInitialScaleQuirk() &&
      GetPageScaleConstraintsSet().UserAgentConstraints().initial_scale != -1 &&
      GetPageScaleConstraintsSet().UserAgentConstraints().initial_scale *
              DeviceScaleFactor() <=
          1) {
    if (description.max_width == Length::DeviceWidth() ||
        (description.max_width.IsAuto() &&
         GetPageScaleConstraintsSet().PageDefinedConstraints().initial_scale ==
             1.0f))
      SetInitialPageScaleOverride(-1);
  }

  Settings& page_settings = GetPage()->GetSettings();
  GetPageScaleConstraintsSet().AdjustForAndroidWebViewQuirks(
      description, default_min_width.IntValue(), DeviceScaleFactor(),
      SettingsImpl()->SupportDeprecatedTargetDensityDPI(),
      page_settings.GetWideViewportQuirkEnabled(),
      page_settings.GetUseWideViewport(),
      page_settings.GetLoadWithOverviewMode(),
      SettingsImpl()->ViewportMetaNonUserScalableQuirk());
  float new_initial_scale =
      GetPageScaleConstraintsSet().PageDefinedConstraints().initial_scale;
  if (old_initial_scale != new_initial_scale && new_initial_scale != -1) {
    GetPageScaleConstraintsSet().SetNeedsReset(true);
    if (MainFrameImpl() && MainFrameImpl()->GetFrameView())
      MainFrameImpl()->GetFrameView()->SetNeedsLayout();
  }

  UpdateMainFrameLayoutSize();
}

void WebViewImpl::UpdateMainFrameLayoutSize() {
  if (should_auto_resize_ || !MainFrameImpl())
    return;

  LocalFrameView* view = MainFrameImpl()->GetFrameView();
  if (!view)
    return;

  gfx::Size layout_size = size_;

  if (GetSettings()->ViewportEnabled())
    layout_size = gfx::Size(GetPageScaleConstraintsSet().GetLayoutSize());

  if (GetPage()->GetSettings().GetForceZeroLayoutHeight())
    layout_size.set_height(0);

  view->SetLayoutSize(IntSize(layout_size));
}

IntSize WebViewImpl::ContentsSize() const {
  if (!GetPage()->MainFrame()->IsLocalFrame())
    return IntSize();
  auto* layout_view =
      GetPage()->DeprecatedLocalMainFrame()->ContentLayoutObject();
  if (!layout_view)
    return IntSize();
  return PixelSnappedIntRect(layout_view->DocumentRect()).Size();
}

gfx::Size WebViewImpl::ContentsPreferredMinimumSize() {
  DCHECK(page_->MainFrame()->IsLocalFrame());

  auto* main_local_frame = DynamicTo<LocalFrame>(page_->MainFrame());
  Document* document = main_local_frame->GetDocument();
  if (!document || !document->GetLayoutView() || !document->documentElement() ||
      !document->documentElement()->GetLayoutBox())
    return gfx::Size();

  // The preferred size requires an up-to-date layout tree.
  DCHECK(!document->NeedsLayoutTreeUpdate() &&
         !document->View()->NeedsLayout());

  // Needed for computing MinPreferredWidth.
  FontCachePurgePreventer fontCachePurgePreventer;
  int width_scaled = document->GetLayoutView()
                         ->PreferredLogicalWidths()
                         .min_size.Round();  // Already accounts for zoom.
  int height_scaled =
      document->documentElement()->GetLayoutBox()->ScrollHeight().Round();
  return gfx::Size(width_scaled, height_scaled);
}

void WebViewImpl::UpdatePreferredSize() {
  // We don't always want to send the change messages over IPC, only if we've
  // been put in that mode by getting a |ViewMsg_EnablePreferredSizeChangedMode|
  // message.
  if (!send_preferred_size_changes_ || !MainFrameImpl())
    return;

  if (!needs_preferred_size_update_)
    return;
  needs_preferred_size_update_ = false;

  gfx::Size size_in_dips =
      MainFrameImpl()->LocalRootFrameWidget()->BlinkSpaceToFlooredDIPs(
          gfx::Size(ContentsPreferredMinimumSize()));

  if (size_in_dips != preferred_size_in_dips_) {
    preferred_size_in_dips_ = size_in_dips;
    local_main_frame_host_remote_->ContentsPreferredSizeChanged(size_in_dips);
  }
}

void WebViewImpl::EnablePreferredSizeChangedMode() {
  if (send_preferred_size_changes_)
    return;
  send_preferred_size_changes_ = true;
  needs_preferred_size_update_ = true;

  // We need to ensure |UpdatePreferredSize| gets called. If a layout is needed,
  // force an update here which will call |DidUpdateMainFrameLayout|.
  if (MainFrameWidget()) {
    MainFrameWidget()->UpdateLifecycle(WebLifecycleUpdate::kLayout,
                                       DocumentUpdateReason::kSizeChange);
  }

  // If a layout was not needed, |DidUpdateMainFrameLayout| will not be called.
  // We explicitly update the preferred size here to ensure the preferred size
  // notification is sent.
  UpdatePreferredSize();
}

void WebViewImpl::Focus() {
  if (GetPage()->MainFrame()->IsLocalFrame()) {
    DCHECK(local_main_frame_host_remote_);
    local_main_frame_host_remote_->FocusPage();
  } else {
    DCHECK(remote_main_frame_host_remote_);
    remote_main_frame_host_remote_->FocusPage();
  }
}

void WebViewImpl::TakeFocus(bool reverse) {
  if (GetPage()->MainFrame()->IsLocalFrame()) {
    DCHECK(local_main_frame_host_remote_);
    local_main_frame_host_remote_->TakeFocus(reverse);
  } else {
    DCHECK(remote_main_frame_host_remote_);
    remote_main_frame_host_remote_->TakeFocus(reverse);
  }
}

void WebViewImpl::Show(const LocalFrameToken& opener_frame_token,
                       NavigationPolicy policy,
                       const gfx::Rect& rect,
                       bool opened_by_user_gesture) {
  // This is only called on local main frames.
  DCHECK(local_main_frame_host_remote_);
  DCHECK(web_widget_);
  web_widget_->SetPendingWindowRect(rect);
  local_main_frame_host_remote_->ShowCreatedWindow(
      opener_frame_token, NavigationPolicyToDisposition(policy), rect,
      opened_by_user_gesture,
      WTF::Bind(&WebViewImpl::DidShowCreatedWindow, WTF::Unretained(this)));

  MainFrameDevToolsAgentImpl()->DidShowNewWindow();
}

void WebViewImpl::DidShowCreatedWindow() {
  web_widget_->AckPendingWindowRect();
}

void WebViewImpl::SendWindowRectToMainFrameHost(
    const gfx::Rect& bounds,
    base::OnceClosure ack_callback) {
  DCHECK(local_main_frame_host_remote_);
  local_main_frame_host_remote_->SetWindowRect(bounds, std::move(ack_callback));
}

void WebViewImpl::UpdateTargetURL(const WebURL& url,
                                  const WebURL& fallback_url) {
  KURL latest_url = KURL(url.IsEmpty() ? fallback_url : url);
  if (latest_url == target_url_)
    return;

  // Tell the browser to display a destination link.
  if (target_url_status_ == TARGET_INFLIGHT ||
      target_url_status_ == TARGET_PENDING) {
    // If we have a request in-flight, save the URL to be sent when we
    // receive an ACK to the in-flight request. We can happily overwrite
    // any existing pending sends.
    pending_target_url_ = latest_url;
    target_url_status_ = TARGET_PENDING;
  } else {
    // URLs larger than |kMaxURLChars| cannot be sent through IPC -
    // see |ParamTraits<GURL>|.
    if (latest_url.GetString().length() > url::kMaxURLChars)
      latest_url = KURL();
    SendUpdatedTargetURLToBrowser(latest_url);
    target_url_ = latest_url;
    target_url_status_ = TARGET_INFLIGHT;
  }
}

void WebViewImpl::SendUpdatedTargetURLToBrowser(const KURL& target_url) {
  // Note: WTF::Unretained() usage below is safe, since `this` owns both
  // `mojo::Remote` objects.
  if (GetPage()->MainFrame()->IsLocalFrame()) {
    DCHECK(local_main_frame_host_remote_);
    local_main_frame_host_remote_->UpdateTargetURL(
        target_url, WTF::Bind(&WebViewImpl::TargetURLUpdatedInBrowser,
                              WTF::Unretained(this)));
  } else {
    DCHECK(remote_main_frame_host_remote_);
    remote_main_frame_host_remote_->UpdateTargetURL(
        target_url, WTF::Bind(&WebViewImpl::TargetURLUpdatedInBrowser,
                              WTF::Unretained(this)));
  }
}

void WebViewImpl::TargetURLUpdatedInBrowser() {
  // Check if there is a targeturl waiting to be sent.
  if (target_url_status_ == TARGET_PENDING)
    SendUpdatedTargetURLToBrowser(pending_target_url_);

  target_url_status_ = TARGET_NONE;
}

float WebViewImpl::DefaultMinimumPageScaleFactor() const {
  return GetPageScaleConstraintsSet().DefaultConstraints().minimum_scale;
}

float WebViewImpl::DefaultMaximumPageScaleFactor() const {
  return GetPageScaleConstraintsSet().DefaultConstraints().maximum_scale;
}

float WebViewImpl::MinimumPageScaleFactor() const {
  return GetPageScaleConstraintsSet().FinalConstraints().minimum_scale;
}

float WebViewImpl::MaximumPageScaleFactor() const {
  return GetPageScaleConstraintsSet().FinalConstraints().maximum_scale;
}

void WebViewImpl::ResetScaleStateImmediately() {
  GetPageScaleConstraintsSet().SetNeedsReset(true);
}

void WebViewImpl::ResetScrollAndScaleState() {
  GetPage()->GetVisualViewport().Reset();

  auto* main_local_frame = DynamicTo<LocalFrame>(GetPage()->MainFrame());
  if (!main_local_frame)
    return;

  if (LocalFrameView* frame_view = main_local_frame->View()) {
    ScrollableArea* scrollable_area = frame_view->LayoutViewport();

    if (!scrollable_area->GetScrollOffset().IsZero()) {
      scrollable_area->SetScrollOffset(ScrollOffset(),
                                       mojom::blink::ScrollType::kProgrammatic);
    }
  }

  if (Document* document = main_local_frame->GetDocument()) {
    if (DocumentLoader* loader = document->Loader()) {
      if (HistoryItem* item = loader->GetHistoryItem())
        item->ClearViewState();
    }
  }

  GetPageScaleConstraintsSet().SetNeedsReset(true);
}

void WebViewImpl::SendResizeEventForMainFrame() {
  // FIXME: This is wrong. The LocalFrameView is responsible sending a
  // resizeEvent as part of layout. Layout is also responsible for sending
  // invalidations to the embedder. This method and all callers may be wrong. --
  // eseidel.
  if (MainFrameImpl()->GetFrameView()) {
    // Enqueues the resize event.
    MainFrameImpl()->GetFrame()->GetDocument()->EnqueueResizeEvent();
  }

  // A resized main frame can change the page scale limits.
  if (does_composite_) {
    auto& viewport = GetPage()->GetVisualViewport();
    MainFrameImpl()->FrameWidgetImpl()->SetPageScaleStateAndLimits(
        viewport.Scale(), viewport.IsPinchGestureActive(),
        MinimumPageScaleFactor(), MaximumPageScaleFactor());
  }
}

void WebViewImpl::ConfigureAutoResizeMode() {
  if (!MainFrameImpl() || !MainFrameImpl()->GetFrame() ||
      !MainFrameImpl()->GetFrame()->View())
    return;

  if (should_auto_resize_) {
    MainFrameImpl()->GetFrame()->View()->EnableAutoSizeMode(min_auto_size_,
                                                            max_auto_size_);
  } else {
    MainFrameImpl()->GetFrame()->View()->DisableAutoSizeMode();
  }
}

void WebViewImpl::SetCompositorDeviceScaleFactorOverride(
    float device_scale_factor) {
  if (compositor_device_scale_factor_override_ == device_scale_factor)
    return;
  compositor_device_scale_factor_override_ = device_scale_factor;
  if (zoom_factor_for_device_scale_factor_) {
    SetZoomLevel(ZoomLevel());
    return;
  }
}

void WebViewImpl::SetDeviceEmulationTransform(
    const TransformationMatrix& transform) {
  if (transform == device_emulation_transform_)
    return;
  device_emulation_transform_ = transform;
  UpdateDeviceEmulationTransform();
}

TransformationMatrix WebViewImpl::GetDeviceEmulationTransform() const {
  return device_emulation_transform_;
}

void WebViewImpl::EnableDeviceEmulation(const DeviceEmulationParams& params) {
  web_widget_->EnableDeviceEmulation(params);
}

void WebViewImpl::ActivateDevToolsTransform(
    const DeviceEmulationParams& params) {
  TransformationMatrix device_emulation_transform =
      dev_tools_emulator_->EnableDeviceEmulation(params);
  SetDeviceEmulationTransform(device_emulation_transform);
}

void WebViewImpl::DisableDeviceEmulation() {
  web_widget_->DisableDeviceEmulation();
}

void WebViewImpl::DeactivateDevToolsTransform() {
  dev_tools_emulator_->DisableDeviceEmulation();
  SetDeviceEmulationTransform(TransformationMatrix());
}

void WebViewImpl::PerformCustomContextMenuAction(unsigned action) {
  if (page_) {
    page_->GetContextMenuController().CustomContextMenuItemSelected(action);
  }
}

void WebViewImpl::DidCloseContextMenu() {
  LocalFrame* frame = page_->GetFocusController().FocusedFrame();
  if (frame)
    frame->Selection().SetCaretBlinkingSuspended(false);
}

SkColor WebViewImpl::BackgroundColor() const {
  if (background_color_override_enabled_)
    return background_color_override_;
  Page* page = page_.Get();
  if (!page)
    return BaseBackgroundColor().Rgb();
  if (auto* main_local_frame = DynamicTo<LocalFrame>(page->MainFrame())) {
    LocalFrameView* view = main_local_frame->View();
    if (view)
      return view->DocumentBackgroundColor().Rgb();
  }
  return BaseBackgroundColor().Rgb();
}

Color WebViewImpl::BaseBackgroundColor() const {
  return base_background_color_override_enabled_
             ? base_background_color_override_
             : base_background_color_;
}

void WebViewImpl::SetBaseBackgroundColor(SkColor color) {
  if (base_background_color_ == color)
    return;

  base_background_color_ = color;
  UpdateBaseBackgroundColor();
}

void WebViewImpl::SetBaseBackgroundColorOverride(SkColor color) {
  if (base_background_color_override_enabled_ &&
      base_background_color_override_ == color) {
    return;
  }

  base_background_color_override_enabled_ = true;
  base_background_color_override_ = color;
  if (MainFrameImpl()) {
    // Force lifecycle update to ensure we're good to call
    // LocalFrameView::setBaseBackgroundColor().
    MainFrameImpl()
        ->GetFrame()
        ->View()
        ->UpdateLifecycleToCompositingCleanPlusScrolling(
            DocumentUpdateReason::kBaseColor);
  }
  UpdateBaseBackgroundColor();
}

void WebViewImpl::ClearBaseBackgroundColorOverride() {
  if (!base_background_color_override_enabled_)
    return;

  base_background_color_override_enabled_ = false;
  if (MainFrameImpl()) {
    // Force lifecycle update to ensure we're good to call
    // LocalFrameView::setBaseBackgroundColor().
    MainFrameImpl()
        ->GetFrame()
        ->View()
        ->UpdateLifecycleToCompositingCleanPlusScrolling(
            DocumentUpdateReason::kBaseColor);
  }
  UpdateBaseBackgroundColor();
}

void WebViewImpl::UpdateBaseBackgroundColor() {
  Color color = BaseBackgroundColor();
  if (auto* local_frame = DynamicTo<LocalFrame>(page_->MainFrame())) {
    LocalFrameView* view = local_frame->View();
    view->UpdateBaseBackgroundColorRecursively(color);
  }
}

void WebViewImpl::UpdateFontRenderingFromRendererPrefs() {
#if !defined(OS_MAC)
  skia::LegacyDisplayGlobals::SetCachedPixelGeometry(
      gfx::FontRenderParams::SubpixelRenderingToSkiaPixelGeometry(
          renderer_preferences_.subpixel_rendering));
#if defined(OS_WIN)
  // Cache the system font metrics in blink.
  WebFontRendering::SetMenuFontMetrics(
      WebString::FromUTF16(renderer_preferences_.menu_font_family_name),
      renderer_preferences_.menu_font_height);
  WebFontRendering::SetSmallCaptionFontMetrics(
      WebString::FromUTF16(
          renderer_preferences_.small_caption_font_family_name),
      renderer_preferences_.small_caption_font_height);
  WebFontRendering::SetStatusFontMetrics(
      WebString::FromUTF16(renderer_preferences_.status_font_family_name),
      renderer_preferences_.status_font_height);
  WebFontRendering::SetAntialiasedTextEnabled(
      renderer_preferences_.should_antialias_text);
  WebFontRendering::SetLCDTextEnabled(
      renderer_preferences_.subpixel_rendering !=
      gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE);
#else
  WebFontRenderStyle::SetHinting(
      RendererPreferencesToSkiaHinting(renderer_preferences_));
  WebFontRenderStyle::SetAutoHint(renderer_preferences_.use_autohinter);
  WebFontRenderStyle::SetUseBitmaps(renderer_preferences_.use_bitmaps);
  WebFontRenderStyle::SetAntiAlias(renderer_preferences_.should_antialias_text);
  WebFontRenderStyle::SetSubpixelRendering(
      renderer_preferences_.subpixel_rendering !=
      gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE);
  WebFontRenderStyle::SetSubpixelPositioning(
      renderer_preferences_.use_subpixel_positioning);
// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is
// complete.
#if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) && !defined(OS_ANDROID)
  if (!renderer_preferences_.system_font_family_name.empty()) {
    WebFontRenderStyle::SetSystemFontFamily(blink::WebString::FromUTF8(
        renderer_preferences_.system_font_family_name));
  }
#endif  // (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) &&
        // !defined(OS_ANDROID)
#endif  // defined(OS_WIN)
#endif  // !defined(OS_MAC)
}

void WebViewImpl::SetInsidePortal(bool inside_portal) {
  GetPage()->SetInsidePortal(inside_portal);

  // We may not have created the frame widget yet but that's ok because it'll
  // be created with this value correctly initialized. This can also be null if
  // the main frame is remote.
  if (web_widget_)
    web_widget_->SetIsNestedMainFrameWidget(inside_portal);
}

void WebViewImpl::RegisterRendererPreferenceWatcher(
    CrossVariantMojoRemote<mojom::RendererPreferenceWatcherInterfaceBase>
        watcher) {
  renderer_preference_watchers_.Add(std::move(watcher));
}

void WebViewImpl::SetRendererPreferences(
    const RendererPreferences& preferences) {
  UpdateRendererPreferences(preferences);
}

const RendererPreferences& WebViewImpl::GetRendererPreferences() {
  return renderer_preferences_;
}

void WebViewImpl::UpdateRendererPreferences(
    const RendererPreferences& preferences) {
  std::string old_accept_languages = renderer_preferences_.accept_languages;
  renderer_preferences_ = preferences;

  for (auto& watcher : renderer_preference_watchers_)
    watcher->NotifyUpdate(renderer_preferences_);

  // TODO(crbug.com/1102442): Remove once we no longer need to update theme
  // preferences on Windows via content::WebThemeEngineDefault.
  web_view_client_->DidUpdateRendererPreferences();
  UpdateFontRenderingFromRendererPrefs();

  blink::SetCaretBlinkInterval(
      renderer_preferences_.caret_blink_interval.has_value()
          ? renderer_preferences_.caret_blink_interval.value()
          : base::TimeDelta::FromMilliseconds(
                mojom::blink::kDefaultCaretBlinkIntervalInMilliseconds));

#if defined(USE_AURA)
  if (renderer_preferences_.use_custom_colors) {
    SetFocusRingColor(renderer_preferences_.focus_ring_color);
    SetSelectionColors(renderer_preferences_.active_selection_bg_color,
                       renderer_preferences_.active_selection_fg_color,
                       renderer_preferences_.inactive_selection_bg_color,
                       renderer_preferences_.inactive_selection_fg_color);
    ThemeChanged();
  }
#endif

  if (::features::IsFormControlsRefreshEnabled() &&
      renderer_preferences_.use_custom_colors) {
    SetFocusRingColor(renderer_preferences_.focus_ring_color);
  }

  if (old_accept_languages != renderer_preferences_.accept_languages)
    AcceptLanguagesChanged();

  GetSettings()->SetCaretBrowsingEnabled(
      renderer_preferences_.caret_browsing_enabled);

#if defined(USE_X11) || defined(USE_OZONE)
  GetSettings()->SetSelectionClipboardBufferAvailable(
      renderer_preferences_.selection_clipboard_buffer_available);
#endif  // defined(USE_X11) || defined(USE_OZONE)
}

void WebViewImpl::SetHistoryOffsetAndLength(int32_t history_offset,
                                            int32_t history_length) {
  DCHECK(web_view_client_);
  web_view_client_->OnSetHistoryOffsetAndLength(history_offset, history_length);
}

void WebViewImpl::SetWebPreferences(
    const web_pref::WebPreferences& preferences) {
  UpdateWebPreferences(preferences);
}

const web_pref::WebPreferences& WebViewImpl::GetWebPreferences() {
  return web_preferences_;
}

void WebViewImpl::UpdateWebPreferences(
    const blink::web_pref::WebPreferences& preferences) {
  web_preferences_ = preferences;
  ApplyWebPreferences(preferences, this);
  ApplyCommandLineToSettings(SettingsImpl());
}

void WebViewImpl::AddObserver(WebViewObserver* observer) {
  observers_.AddObserver(observer);
}

void WebViewImpl::RemoveObserver(WebViewObserver* observer) {
  observers_.RemoveObserver(observer);
}

void WebViewImpl::SetIsActive(bool active) {
  if (GetPage())
    GetPage()->GetFocusController().SetActive(active);
}

bool WebViewImpl::IsActive() const {
  return GetPage() ? GetPage()->GetFocusController().IsActive() : false;
}

void WebViewImpl::SetWindowFeatures(const WebWindowFeatures& features) {
  page_->SetWindowFeatures(features);
}

void WebViewImpl::SetOpenedByDOM() {
  page_->SetOpenedByDOM();
}

void WebViewImpl::DidCommitLoad(bool is_new_navigation,
                                bool is_navigation_within_page) {
  if (!is_navigation_within_page) {
    if (web_widget_)
      web_widget_->ResetMeaningfulLayoutStateForMainFrame();

    if (is_new_navigation)
      GetPageScaleConstraintsSet().SetNeedsReset(true);
  }

  // Give the visual viewport's scroll layer its initial size.
  GetPage()->GetVisualViewport().MainFrameDidChangeSize();
}

void WebViewImpl::DidCommitCompositorFrameForLocalMainFrame() {
  for (auto& observer : observers_)
    observer.DidCommitCompositorFrame();
}

void WebViewImpl::ResizeAfterLayout() {
  DCHECK(MainFrameImpl());

  if (!web_view_client_ || !web_view_client_->CanUpdateLayout())
    return;

  if (should_auto_resize_) {
    LocalFrameView* view = MainFrameImpl()->GetFrame()->View();
    gfx::Size frame_size = gfx::Size(view->Size());
    if (frame_size != size_) {
      size_ = frame_size;

      GetPage()->GetVisualViewport().SetSize(IntSize(size_));
      GetPageScaleConstraintsSet().DidChangeInitialContainingBlockSize(
          IntSize(size_));
      view->SetInitialViewportSize(IntSize(size_));

      web_view_client_->DidAutoResize(size_);
      web_widget_->DidAutoResize(size_);
      SendResizeEventForMainFrame();
    }
  }

  if (does_composite_ && GetPageScaleConstraintsSet().ConstraintsDirty())
    RefreshPageScaleFactor();

  resize_viewport_anchor_->ResizeFrameView(MainFrameSize());
}

void WebViewImpl::MainFrameLayoutUpdated() {
  DCHECK(MainFrameImpl());
  if (!web_view_client_)
    return;

  for (auto& observer : observers_)
    observer.DidUpdateMainFrameLayout();
  needs_preferred_size_update_ = true;
}

void WebViewImpl::DidChangeContentsSize() {
  auto* local_frame = DynamicTo<LocalFrame>(GetPage()->MainFrame());
  if (!local_frame)
    return;

  LocalFrameView* view = local_frame->View();

  int vertical_scrollbar_width = 0;
  if (view && view->LayoutViewport()) {
    Scrollbar* vertical_scrollbar = view->LayoutViewport()->VerticalScrollbar();
    if (vertical_scrollbar && !vertical_scrollbar->IsOverlayScrollbar())
      vertical_scrollbar_width = vertical_scrollbar->Width();
  }

  GetPageScaleConstraintsSet().DidChangeContentsSize(
      ContentsSize(), vertical_scrollbar_width, PageScaleFactor());
}

void WebViewImpl::PageScaleFactorChanged() {
  // This is called from the VisualViewport which only is used to control the
  // page scale/scroll viewport for a local main frame, and only when
  // compositing as PageScaleFactor doesn't exist otherwise.
  DCHECK(MainFrameImpl());
  DCHECK(does_composite_);

  GetPageScaleConstraintsSet().SetNeedsReset(false);
  // Set up the compositor and inform the browser of the PageScaleFactor,
  // which is tracked per-view.
  auto& viewport = GetPage()->GetVisualViewport();
  MainFrameImpl()->FrameWidgetImpl()->SetPageScaleStateAndLimits(
      viewport.Scale(), viewport.IsPinchGestureActive(),
      MinimumPageScaleFactor(), MaximumPageScaleFactor());

  local_main_frame_host_remote_->ScaleFactorChanged(viewport.Scale());

  if (dev_tools_emulator_->HasViewportOverride()) {
    TransformationMatrix device_emulation_transform =
        dev_tools_emulator_->MainFrameScrollOrScaleChanged();
    SetDeviceEmulationTransform(device_emulation_transform);
  }
}

void WebViewImpl::MainFrameScrollOffsetChanged() {
  DCHECK(MainFrameImpl());
  if (dev_tools_emulator_->HasViewportOverride()) {
    TransformationMatrix device_emulation_transform =
        dev_tools_emulator_->MainFrameScrollOrScaleChanged();
    SetDeviceEmulationTransform(device_emulation_transform);
  }
}

void WebViewImpl::TextAutosizerPageInfoChanged(
    const mojom::blink::TextAutosizerPageInfo& page_info) {
  DCHECK(MainFrameImpl());
  local_main_frame_host_remote_->TextAutosizerPageInfoChanged(
      page_info.Clone());
}

void WebViewImpl::SetBackgroundColorOverride(SkColor color) {
  DCHECK(does_composite_);

  background_color_override_enabled_ = true;
  background_color_override_ = color;
  if (MainFrameImpl()) {
    MainFrameImpl()->FrameWidgetImpl()->SetBackgroundColor(BackgroundColor());
  }
}

void WebViewImpl::ClearBackgroundColorOverride() {
  DCHECK(does_composite_);

  background_color_override_enabled_ = false;
  if (MainFrameImpl()) {
    MainFrameImpl()->FrameWidgetImpl()->SetBackgroundColor(BackgroundColor());
  }
}

void WebViewImpl::SetZoomFactorOverride(float zoom_factor) {
  zoom_factor_override_ = zoom_factor;
  SetZoomLevel(ZoomLevel());
}

Element* WebViewImpl::FocusedElement() const {
  LocalFrame* frame = page_->GetFocusController().FocusedFrame();
  if (!frame)
    return nullptr;

  Document* document = frame->GetDocument();
  if (!document)
    return nullptr;

  return document->FocusedElement();
}

WebHitTestResult WebViewImpl::HitTestResultForTap(
    const gfx::Point& tap_point_window_pos,
    const gfx::Size& tap_area) {
  auto* main_frame = DynamicTo<LocalFrame>(page_->MainFrame());
  if (!main_frame)
    return HitTestResult();

  WebGestureEvent tap_event(WebInputEvent::Type::kGestureTap,
                            WebInputEvent::kNoModifiers, base::TimeTicks::Now(),
                            WebGestureDevice::kTouchscreen);
  // GestureTap is only ever from a touchscreen.
  tap_event.SetPositionInWidget(FloatPoint(IntPoint(tap_point_window_pos)));
  tap_event.data.tap.tap_count = 1;
  tap_event.data.tap.width = tap_area.width();
  tap_event.data.tap.height = tap_area.height();

  WebGestureEvent scaled_event =
      TransformWebGestureEvent(MainFrameImpl()->GetFrameView(), tap_event);

  HitTestResult result =
      main_frame->GetEventHandler()
          .HitTestResultForGestureEvent(
              scaled_event, HitTestRequest::kReadOnly | HitTestRequest::kActive)
          .GetHitTestResult();

  result.SetToShadowHostIfInRestrictedShadowRoot();
  return result;
}

void WebViewImpl::SetTabsToLinks(bool enable) {
  tabs_to_links_ = enable;
}

bool WebViewImpl::TabsToLinks() const {
  return tabs_to_links_;
}

void WebViewImpl::DidChangeRootLayer(bool root_layer_exists) {
  // The Layer is removed when the main frame's `Document` changes. It also is
  // removed when the whole `LocalFrame` goes away, in which case we don't
  // need to DeferMainFrameUpdate() as we will do so if a local MainFrame is
  // attached in the future.
  if (!MainFrameImpl()) {
    DCHECK(!root_layer_exists);
    return;
  }
  if (root_layer_exists) {
    if (!device_emulation_transform_.IsIdentity())
      UpdateDeviceEmulationTransform();
  } else {
    // When the document in an already-attached main frame is being replaced by
    // a navigation then DidChangeRootLayer(false) will be called. Since we are
    // navigating, defer BeginMainFrames until the new document is ready for
    // them.
    //
    // TODO(crbug.com/936696): This should not be needed once we always swap
    // frames when swapping documents.
    scoped_defer_main_frame_update_ =
        MainFrameImpl()->FrameWidgetImpl()->DeferMainFrameUpdate();
  }
}

void WebViewImpl::InvalidateRect(const IntRect& rect) {
  // This is only for WebViewPlugin.
  if (!does_composite_ && web_view_client_)
    web_view_client_->DidInvalidateRect(rect);
}

void WebViewImpl::ApplyViewportChanges(const ApplyViewportChangesArgs& args) {
  // TODO(https://crbug.com/1160652): Figure out if Page is null.
  CHECK(page_);

  VisualViewport& visual_viewport = GetPage()->GetVisualViewport();

  // Store the desired offsets the visual viewport before setting the top
  // controls ratio since doing so will change the bounds and move the
  // viewports to keep the offsets valid. The compositor may have already
  // done that so we don't want to double apply the deltas here.
  FloatPoint visual_viewport_offset = visual_viewport.VisibleRect().Location();
  visual_viewport_offset.Move(args.inner_delta.x(), args.inner_delta.y());

  GetBrowserControls().SetShownRatio(
      GetBrowserControls().TopShownRatio() + args.top_controls_delta,
      GetBrowserControls().BottomShownRatio() + args.bottom_controls_delta);

  SetPageScaleFactorAndLocation(PageScaleFactor() * args.page_scale_delta,
                                args.is_pinch_gesture_active,
                                visual_viewport_offset);

  if (args.page_scale_delta != 1) {
    double_tap_zoom_pending_ = false;
    visual_viewport.UserDidChangeScale();
  }

  elastic_overscroll_ += FloatSize(args.elastic_overscroll_delta.x(),
                                   args.elastic_overscroll_delta.y());
  UpdateBrowserControlsConstraint(args.browser_controls_constraint);

  if (args.scroll_gesture_did_end) {
    // TODO(https://crbug.com/1160652): Figure out if MainFrameImpl is null.
    CHECK(MainFrameImpl());
    MainFrameImpl()->GetFrame()->GetEventHandler().MarkHoverStateDirty();
  }
}

Node* WebViewImpl::FindNodeFromScrollableCompositorElementId(
    cc::ElementId element_id) const {
  if (!GetPage())
    return nullptr;

  if (element_id == GetPage()->GetVisualViewport().GetScrollElementId()) {
    // Return the Document in this case since the window.visualViewport DOM
    // object is not a node.
    if (MainFrameImpl())
      return MainFrameImpl()->GetDocument();
  }

  if (!GetPage()->GetScrollingCoordinator())
    return nullptr;
  ScrollableArea* scrollable_area =
      GetPage()
          ->GetScrollingCoordinator()
          ->ScrollableAreaWithElementIdInAllLocalFrames(element_id);
  if (!scrollable_area || !scrollable_area->GetLayoutBox())
    return nullptr;

  return scrollable_area->GetLayoutBox()->GetNode();
}

void WebViewImpl::UpdateDeviceEmulationTransform() {
  GetPage()->GetVisualViewport().SetNeedsPaintPropertyUpdate();

  if (auto* main_frame = MainFrameImpl()) {
    // When the device emulation transform is updated, to avoid incorrect
    // scales and fuzzy raster from the compositor, force all content to
    // pick ideal raster scales.
    // TODO(wjmaclean): This is only done on the main frame's widget currently,
    // it should update all local frames.
    main_frame->FrameWidgetImpl()->SetNeedsRecalculateRasterScales();

    // Device emulation transform also affects the overriding visible rect
    // which is used as the overflow rect of the main frame layout view.
    if (auto* view = main_frame->GetFrameView())
      view->SetNeedsPaintPropertyUpdate();
  }
}

PageScheduler* WebViewImpl::Scheduler() const {
  DCHECK(GetPage());
  return GetPage()->GetPageScheduler();
}

void WebViewImpl::SetVisibilityState(
    mojom::blink::PageVisibilityState visibility_state,
    bool is_initial_state) {
  DCHECK(GetPage());
  if (!is_initial_state) {
    // Preserve the side effects of visibility change.
    web_view_client_->OnPageVisibilityChanged(visibility_state);
    for (auto& observer : observers_)
      observer.OnPageVisibilityChanged(visibility_state);
  }
  GetPage()->SetVisibilityState(visibility_state, is_initial_state);
  GetPage()->GetPageScheduler()->SetPageVisible(
      visibility_state == mojom::blink::PageVisibilityState::kVisible);
}

mojom::blink::PageVisibilityState WebViewImpl::GetVisibilityState() {
  DCHECK(GetPage());
  return GetPage()->GetVisibilityState();
}

float WebViewImpl::DeviceScaleFactor() const {
  // TODO(oshima): Investigate if this should return the ScreenInfo's scale
  // factor rather than page's scale factor, which can be 1 in use-zoom-for-dsf
  // mode.
  if (!GetPage())
    return 1;

  return GetPage()->DeviceScaleFactorDeprecated();
}

LocalFrame* WebViewImpl::FocusedLocalFrameInWidget() const {
  if (!MainFrameImpl())
    return nullptr;

  auto* focused_frame = To<LocalFrame>(FocusedCoreFrame());
  if (focused_frame->LocalFrameRoot() != MainFrameImpl()->GetFrame())
    return nullptr;
  return focused_frame;
}

void WebViewImpl::SetPageFrozen(bool frozen) {
  Scheduler()->SetPageFrozen(frozen);
  web_view_client_->OnPageFrozenChanged(frozen);
}

WebFrameWidget* WebViewImpl::MainFrameWidget() {
  return web_widget_;
}

void WebViewImpl::AddAutoplayFlags(int32_t value) {
  page_->AddAutoplayFlags(value);
}

void WebViewImpl::ClearAutoplayFlags() {
  page_->ClearAutoplayFlags();
}

int32_t WebViewImpl::AutoplayFlagsForTest() {
  return page_->AutoplayFlags();
}

gfx::Size WebViewImpl::GetPreferredSizeForTest() {
  return preferred_size_in_dips_;
}

void WebViewImpl::StopDeferringMainFrameUpdate() {
  DCHECK(MainFrameImpl());
  scoped_defer_main_frame_update_ = nullptr;
}

void WebViewImpl::SetDeviceColorSpaceForTesting(
    const gfx::ColorSpace& color_space) {
  web_widget_->SetDeviceColorSpaceForTesting(color_space);
}

}  // namespace blink
