// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/browser/web_module.h"

#include <memory>
#include <sstream>
#include <string>

#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/optional.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_checker.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/c_val.h"
#include "cobalt/base/debugger_hooks.h"
#include "cobalt/base/language.h"
#include "cobalt/base/tokens.h"
#include "cobalt/base/type_id.h"
#include "cobalt/browser/splash_screen_cache.h"
#include "cobalt/browser/stack_size_constants.h"
#include "cobalt/browser/switches.h"
#include "cobalt/browser/web_module_stat_tracker.h"
#include "cobalt/configuration/configuration.h"
#include "cobalt/css_parser/parser.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/global_stats.h"
#include "cobalt/dom/html_script_element.h"
#include "cobalt/dom/input_event.h"
#include "cobalt/dom/input_event_init.h"
#include "cobalt/dom/keyboard_event.h"
#include "cobalt/dom/keyboard_event_init.h"
#include "cobalt/dom/local_storage_database.h"
#include "cobalt/dom/mutation_observer_task_manager.h"
#include "cobalt/dom/navigation_type.h"
#include "cobalt/dom/navigator.h"
#include "cobalt/dom/pointer_event.h"
#include "cobalt/dom/storage.h"
#include "cobalt/dom/ui_event.h"
#include "cobalt/dom/visibility_state.h"
#include "cobalt/dom/wheel_event.h"
#include "cobalt/dom/window.h"
#include "cobalt/dom_parser/parser.h"
#include "cobalt/layout/topmost_event_target.h"
#include "cobalt/loader/image/animated_image_tracker.h"
#include "cobalt/loader/loader_factory.h"
#include "cobalt/loader/switches.h"
#include "cobalt/media/decoder_buffer_allocator.h"
#include "cobalt/media/media_module.h"
#include "cobalt/media_session/media_session_client.h"
#include "cobalt/storage/storage_manager.h"
#include "cobalt/ui_navigation/scroll_engine/scroll_engine.h"
#include "cobalt/web/blob.h"
#include "cobalt/web/context.h"
#include "cobalt/web/csp_delegate_factory.h"
#include "cobalt/web/environment_settings.h"
#include "cobalt/web/event.h"
#include "cobalt/web/url.h"
#include "starboard/accessibility.h"
#include "starboard/common/log.h"
#include "starboard/gles.h"

#if defined(ENABLE_DEBUGGER)
#include "cobalt/debug/backend/debug_module.h"  // nogncheck
#endif                                          // defined(ENABLE_DEBUGGER)

namespace cobalt {
namespace browser {

using cobalt::cssom::ViewportSize;

namespace {

// The maximum number of element depth in the DOM tree. Elements at a level
// deeper than this could be discarded, and will not be rendered.
const int kDOMMaxElementDepth = 32;

void CacheUrlContent(SplashScreenCache* splash_screen_cache,
                     const std::string& content,
                     const base::Optional<std::string>& topic) {
  splash_screen_cache->SplashScreenCache::CacheSplashScreen(content, topic);
}

base::Callback<void(const std::string&, const base::Optional<std::string>&)>
CacheUrlContentCallback(SplashScreenCache* splash_screen_cache) {
  // This callback takes in first the url, then the content string.
  if (splash_screen_cache) {
    return base::Bind(CacheUrlContent, base::Unretained(splash_screen_cache));
  } else {
    return base::Callback<void(const std::string&,
                               const base::Optional<std::string>&)>();
  }
}

void CancelScroll(ui_navigation::scroll_engine::ScrollEngine* scroll_engine,
                  const scoped_refptr<ui_navigation::NavItem>& nav_item) {
  auto nav_items = std::vector<scoped_refptr<ui_navigation::NavItem>>{nav_item};
  scroll_engine->thread()->message_loop()->task_runner()->PostTask(
      FROM_HERE, base::Bind(&ui_navigation::scroll_engine::ScrollEngine::
                                CancelActiveScrollsForNavItems,
                            base::Unretained(scroll_engine), nav_items));
}

dom::Window::NavItemCallback CancelScrollCallback(
    ui_navigation::scroll_engine::ScrollEngine* scroll_engine) {
  if (scroll_engine) {
    return base::Bind(CancelScroll, base::Unretained(scroll_engine));
  } else {
    return base::Callback<void(
        const scoped_refptr<cobalt::ui_navigation::NavItem>& nav_item)>();
  }
}

}  // namespace

// Private WebModule implementation. Each WebModule owns a single instance of
// this class, which performs all the actual work. All functions of this class
// must be called on the message loop of the WebModule thread, so they
// execute synchronously with respect to one another.
class WebModule::Impl {
 public:
  Impl(web::Context* web_context, const ConstructionData& data);
  ~Impl();

#if defined(ENABLE_DEBUGGER)
  debug::backend::DebugDispatcher* debug_dispatcher() {
    DCHECK(debug_module_);
    return debug_module_->debug_dispatcher();
  }
#endif  // ENABLE_DEBUGGER

  // Injects an on screen keyboard input event into the web module. Event is
  // directed at a specific element if the element is non-null. Otherwise, the
  // currently focused element receives the event. If element is specified, we
  // must be on the WebModule's message loop.
  void InjectOnScreenKeyboardInputEvent(
      base::Token type, const dom::InputEventInit& event,
      scoped_refptr<dom::Element> element = scoped_refptr<dom::Element>());
  // Injects an on screen keyboard shown event into the web module. Event is
  // directed at the on screen keyboard element.
  void InjectOnScreenKeyboardShownEvent(int ticket);
  // Injects an on screen keyboard hidden event into the web module. Event is
  // directed at the on screen keyboard element.
  void InjectOnScreenKeyboardHiddenEvent(int ticket);
  // Injects an on screen keyboard focused event into the web module. Event is
  // directed at the on screen keyboard element.
  void InjectOnScreenKeyboardFocusedEvent(int ticket);
  // Injects an on screen keyboard blurred event into the web module. Event is
  // directed at the on screen keyboard element.
  void InjectOnScreenKeyboardBlurredEvent(int ticket);
  // Injects an on screen keyboard suggestions updated event into the web
  // module. Event is directed at the on screen keyboard element.
  void InjectOnScreenKeyboardSuggestionsUpdatedEvent(int ticket);

  // Injects a keyboard event into the web module. Event is directed at a
  // specific element if the element is non-null. Otherwise, the currently
  // focused element receives the event. If element is specified, we must be
  // on the WebModule's message loop
  void InjectKeyboardEvent(
      base::Token type, const dom::KeyboardEventInit& event,
      scoped_refptr<dom::Element> element = scoped_refptr<dom::Element>());

  // Injects a pointer event into the web module. Event is directed at a
  // specific element if the element is non-null. Otherwise, the currently
  // focused element receives the event. If element is specified, we must be
  // on the WebModule's message loop
  void InjectPointerEvent(
      base::Token type, const dom::PointerEventInit& event,
      scoped_refptr<dom::Element> element = scoped_refptr<dom::Element>());

  // Injects a wheel event into the web module. Event is directed at a
  // specific element if the element is non-null. Otherwise, the currently
  // focused element receives the event. If element is specified, we must be
  // on the WebModule's message loop
  void InjectWheelEvent(
      base::Token type, const dom::WheelEventInit& event,
      scoped_refptr<dom::Element> element = scoped_refptr<dom::Element>());

  // Injects a beforeunload event into the web module. If this event is not
  // handled by the web application, |on_before_unload_fired_but_not_handled_|
  // will be called. The event is not directed at a specific element.
  void InjectBeforeUnloadEvent();

  void InjectCaptionSettingsChangedEvent();

  void InjectWindowOnOnlineEvent();
  void InjectWindowOnOfflineEvent();

  void UpdateDateTimeConfiguration();

  // Executes JavaScript in this WebModule. Sets the |result| output parameter
  // and signals |got_result|.
  void ExecuteJavascript(const std::string& script_utf8,
                         const base::SourceLocation& script_location,
                         std::string* result, bool* out_succeeded);

  // Clears disables timer related objects
  // so that the message loop can easily exit
  void ClearAllIntervalsAndTimeouts();

#if defined(ENABLE_WEBDRIVER)
  // Creates a new webdriver::WindowDriver that interacts with the Window that
  // is owned by this WebModule instance.
  void CreateWindowDriver(
      const webdriver::protocol::WindowId& window_id,
      std::unique_ptr<webdriver::WindowDriver>* window_driver_out);
#endif  // defined(ENABLE_WEBDRIVER)

#if defined(ENABLE_DEBUGGER)
  void WaitForWebDebugger();

  void FreezeDebugger(
      std::unique_ptr<debug::backend::DebuggerState>* debugger_state) {
    if (debugger_state) *debugger_state = debug_module_->Freeze();
  }
#endif  // defined(ENABLE_DEBUGGER)

  void SetSize(cssom::ViewportSize viewport_size);
  void UpdateCamera3D(const scoped_refptr<input::Camera3D>& camera_3d);
  void SetMediaModule(media::MediaModule* media_module);
  void SetImageCacheCapacity(int64_t bytes);
  void SetRemoteTypefaceCacheCapacity(int64_t bytes);

  // Sets the application state, asserts preconditions to transition to that
  // state, and dispatches any precipitate web events.
  void SetApplicationState(base::ApplicationState state,
                           SbTimeMonotonic timestamp);

  // See LifecycleObserver. These functions do not implement the interface, but
  // have the same basic function.
  void Blur(SbTimeMonotonic timestamp);
  void Conceal(render_tree::ResourceProvider* resource_provider,
               SbTimeMonotonic timestamp);
  void Freeze(SbTimeMonotonic timestamp);
  void Unfreeze(render_tree::ResourceProvider* resource_provider,
                SbTimeMonotonic timestamp);
  void Reveal(render_tree::ResourceProvider* resource_provider,
              SbTimeMonotonic timestamp);
  void Focus(SbTimeMonotonic timestamp);

  void ReduceMemory();

  void IsReadyToFreeze(volatile bool* is_ready_to_freeze) {
    if (window_->media_session()->media_session_client() == NULL) {
      *is_ready_to_freeze = true;
      return;
    }

    *is_ready_to_freeze =
        !window_->media_session()->media_session_client()->is_active();
  }

  void DoSynchronousLayoutAndGetRenderTree(
      scoped_refptr<render_tree::Node>* render_tree);

  void SetApplicationStartOrPreloadTimestamp(bool is_preload,
                                             SbTimeMonotonic timestamp);
  void SetDeepLinkTimestamp(SbTimeMonotonic timestamp);

  void SetUnloadEventTimingInfo(base::TimeTicks start_time,
                                base::TimeTicks end_time);

 private:
  class DocumentLoadedObserver;

  // Purge all resource caches owned by the WebModule.
  void PurgeResourceCaches(bool should_retain_remote_typeface_cache);

  // Disable callbacks in all resource caches owned by the WebModule.
  void DisableCallbacksInResourceCaches();

  // Called by |layout_manager_| after it runs the animation frame callbacks.
  void OnRanAnimationFrameCallbacks();

  // Called by |layout_manager_| when it produces a render tree. May modify
  // the render tree (e.g. to add a debug overlay), then runs the callback
  // specified in the constructor, |render_tree_produced_callback_|.
  void OnRenderTreeProduced(const LayoutResults& layout_results);

  // Called by the Renderer on the Renderer thread when it rasterizes a render
  // tree with this callback attached. It includes the time the render tree was
  // produced.
  void OnRenderTreeRasterized(
      scoped_refptr<base::SingleThreadTaskRunner> web_module_message_loop,
      const base::TimeTicks& produced_time);

  // WebModule thread handling of the OnRenderTreeRasterized() callback. It
  // includes the time that the render tree was produced and the time that the
  // render tree was rasterized.
  void ProcessOnRenderTreeRasterized(const base::TimeTicks& produced_time,
                                     const base::TimeTicks& rasterized_time);

  scoped_refptr<script::GlobalEnvironment> global_environment() {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    return web_context_->global_environment();
  }

  void OnLoadComplete(const base::Optional<std::string>& error) {
    if (error) error_callback_.Run(window_->location()->url(), *error);

    // Create Performance navigation timing info after document loading
    // completed.
    DCHECK(window_);
    DCHECK(window_->performance());
    if (window_->GetDocumentLoader()) {
      net::LoadTimingInfo load_timing_info =
          window_->GetDocumentLoader()->get_load_timing_info();
      // Check if the load happens through net mdoule.
      bool is_load_timing_info_valid =
          !load_timing_info.request_start.is_null();
      if (is_load_timing_info_valid) {
        window_->document()->CreatePerformanceNavigationTiming(
            window_->performance(), load_timing_info);
      }
    }
  }

  // Inject the DOM event object into the window or the element.
  void InjectInputEvent(scoped_refptr<dom::Element> element,
                        const scoped_refptr<web::Event>& event);

  // Handle queued pointer events. Called by LayoutManager on_layout callback.
  void HandlePointerEvents();

  // Initializes the ResourceProvider and dependent resources.
  void SetResourceProvider(render_tree::ResourceProvider* resource_provider);

  void OnStartDispatchEvent(const scoped_refptr<web::Event>& event);
  void OnStopDispatchEvent(const scoped_refptr<web::Event>& event);

  // Thread checker ensures all calls to the WebModule are made from the same
  // thread that it is created in.
  THREAD_CHECKER(thread_checker_);

  web::Context* web_context_;

  ui_navigation::scroll_engine::ScrollEngine* scroll_engine_;

  // Simple flag used for basic error checking.
  bool is_running_;

  // The most recent time that a new render tree was produced.
  base::TimeTicks last_render_tree_produced_time_;

  // Whether or not a render tree has been produced but not yet rasterized.
  base::CVal<bool, base::CValPublic> is_render_tree_rasterization_pending_;

  // Object that provides renderer resources like images and fonts.
  render_tree::ResourceProvider* resource_provider_;
  // The type id of resource provider being used by the WebModule. Whenever this
  // changes, the caches may have obsolete data and must be blown away.
  base::TypeId resource_provider_type_id_;

  // CSS parser.
  std::unique_ptr<css_parser::Parser> css_parser_;

  // DOM (HTML / XML) parser.
  std::unique_ptr<dom_parser::Parser> dom_parser_;

  // LoaderFactory that is used to acquire references to resources from a
  // URL.
  std::unique_ptr<loader::LoaderFactory> loader_factory_;

  std::unique_ptr<loader::image::AnimatedImageTracker> animated_image_tracker_;

  // ImageCache that is used to manage image cache logic.
  std::unique_ptr<loader::image::ImageCache> image_cache_;

  // The reduced cache capacity manager can be used to force a reduced image
  // cache over periods of time where memory is known to be restricted, such
  // as when a video is playing.
  std::unique_ptr<loader::image::ReducedCacheCapacityManager>
      reduced_image_cache_capacity_manager_;

  // RemoteTypefaceCache that is used to manage loading and caching typefaces
  // from URLs.
  std::unique_ptr<loader::font::RemoteTypefaceCache> remote_typeface_cache_;

  // MeshCache that is used to manage mesh cache logic.
  std::unique_ptr<loader::mesh::MeshCache> mesh_cache_;

  // Interface between LocalStorage and the Storage Manager.
  std::unique_ptr<dom::LocalStorageDatabase> local_storage_database_;

  // Stats for the web module. Both the dom stat tracker and layout stat
  // tracker are contained within it.
  std::unique_ptr<browser::WebModuleStatTracker> web_module_stat_tracker_;

  // Post and run tasks to notify MutationObservers.
  dom::MutationObserverTaskManager mutation_observer_task_manager_;

  // Object to register and retrieve MediaSource object with a string key.
  std::unique_ptr<dom::MediaSource::Registry> media_source_registry_;

  // The Window object wraps all DOM-related components.
  scoped_refptr<dom::Window> window_;

  // Cache a WeakPtr in the WebModule that is bound to the Window's message loop
  // so we can ensure that all subsequently created WeakPtr's are also bound to
  // the same loop.
  // See the documentation in base/memory/weak_ptr.h for details.
  base::WeakPtr<dom::Window> window_weak_;

  // Used only when MediaModule is null
  std::unique_ptr<media::DecoderBufferMemoryInfo>
      stub_decoder_buffer_memory_info_;

  // Called by |OnRenderTreeProduced|.
  OnRenderTreeProducedCallback render_tree_produced_callback_;

  // Called by |OnError|.
  OnErrorCallback error_callback_;

  // Triggers layout whenever the document changes.
  std::unique_ptr<layout::LayoutManager> layout_manager_;

#if defined(ENABLE_DEBUGGER)
  // Allows the debugger to add render components to the web module.
  // Used for DOM node highlighting and overlay messages.
  std::unique_ptr<debug::backend::RenderOverlay> debug_overlay_;

  // The core of the debugging system.
  std::unique_ptr<debug::backend::DebugModule> debug_module_;

  // Used to avoid a deadlock when running |Impl::Pause| while waiting for the
  // web debugger to connect.
  starboard::atomic_bool* waiting_for_web_debugger_;

  // Interface to report behaviour relevant to the web debugger.
  debug::backend::DebuggerHooksImpl debugger_hooks_;
#else
  // Null implementation used in gold builds without checking ENABLE_DEBUGGER.
  base::NullDebuggerHooks debugger_hooks_;
#endif  // ENABLE_DEBUGGER

  // DocumentObserver that observes the loading document.
  std::unique_ptr<DocumentLoadedObserver> document_load_observer_;

  std::unique_ptr<layout::TopmostEventTarget> topmost_event_target_;

  base::Closure on_before_unload_fired_but_not_handled_;

  bool should_retain_remote_typeface_cache_on_freeze_;

  scoped_refptr<cobalt::dom::captions::SystemCaptionSettings>
      system_caption_settings_;

  // This event is used to interrupt the loader when JavaScript is loaded
  // synchronously.  It is manually reset so that events like Freeze can be
  // correctly execute, even if there are multiple synchronous loads in queue
  // before the freeze (or other) event handlers.
  base::WaitableEvent* synchronous_loader_interrupt_;

  base::Callback<void(base::TimeTicks, base::TimeTicks)>
      report_unload_timing_info_callback_;
};

void WebModule::WillDestroyCurrentMessageLoop() { impl_.reset(); }

class WebModule::Impl::DocumentLoadedObserver : public dom::DocumentObserver {
 public:
  typedef std::vector<base::Closure> ClosureVector;
  explicit DocumentLoadedObserver(const ClosureVector& loaded_callbacks)
      : loaded_callbacks_(loaded_callbacks) {}
  // Called at most once, when document and all referred resources are loaded.
  void OnLoad() override {
    for (size_t i = 0; i < loaded_callbacks_.size(); ++i) {
      loaded_callbacks_[i].Run();
    }
  }

  void OnMutation() override {}
  void OnFocusChanged() override {}

 private:
  ClosureVector loaded_callbacks_;
};

WebModule::Impl::Impl(web::Context* web_context, const ConstructionData& data)
    : web_context_(web_context),
      scroll_engine_(data.scroll_engine),
      is_running_(false),
      is_render_tree_rasterization_pending_(
          base::StringPrintf("%s.IsRenderTreeRasterizationPending",
                             web_context_->name().c_str()),
          false, "True when a render tree is produced but not yet rasterized."),
      resource_provider_(data.resource_provider),
      resource_provider_type_id_(data.resource_provider->GetTypeId()),
#if defined(ENABLE_DEBUGGER)
      waiting_for_web_debugger_(data.waiting_for_web_debugger),
#endif  // defined(ENABLE_DEBUGGER)
      synchronous_loader_interrupt_(data.synchronous_loader_interrupt) {
  DCHECK(web_context_);
  css_parser::Parser::SupportsMapToMeshFlag supports_map_to_mesh =
      data.options.enable_map_to_mesh
          ? css_parser::Parser::kSupportsMapToMesh
          : css_parser::Parser::kDoesNotSupportMapToMesh;
  css_parser_ =
      css_parser::Parser::Create(debugger_hooks_, supports_map_to_mesh);
  DCHECK(css_parser_);

  dom_parser_.reset(new dom_parser::Parser(
      kDOMMaxElementDepth,
      base::Bind(&WebModule::Impl::OnLoadComplete, base::Unretained(this)),
      data.options.csp_header_policy));
  DCHECK(dom_parser_);

  on_before_unload_fired_but_not_handled_ =
      data.options.on_before_unload_fired_but_not_handled;

  should_retain_remote_typeface_cache_on_freeze_ =
      data.options.should_retain_remote_typeface_cache_on_freeze;

  DCHECK_LE(0, data.options.encoded_image_cache_capacity);
  loader_factory_.reset(new loader::LoaderFactory(
      web_context_->name().c_str(), web_context_->fetcher_factory(),
      resource_provider_, debugger_hooks_,
      data.options.encoded_image_cache_capacity,
      data.options.loader_thread_priority));

  animated_image_tracker_.reset(new loader::image::AnimatedImageTracker(
      data.options.animated_image_decode_thread_priority));

  DCHECK_LE(0, data.options.image_cache_capacity);
  image_cache_ = loader::image::CreateImageCache(
      base::StringPrintf("%s.ImageCache", web_context_->name().c_str()),
      debugger_hooks_, static_cast<uint32>(data.options.image_cache_capacity),
      loader_factory_.get());
  DCHECK(image_cache_);

  reduced_image_cache_capacity_manager_.reset(
      new loader::image::ReducedCacheCapacityManager(
          image_cache_.get(),
          data.options.image_cache_capacity_multiplier_when_playing_video));

  DCHECK_LE(0, data.options.remote_typeface_cache_capacity);
  remote_typeface_cache_ = loader::font::CreateRemoteTypefaceCache(
      base::StringPrintf("%s.RemoteTypefaceCache",
                         web_context_->name().c_str()),
      debugger_hooks_,
      static_cast<uint32>(data.options.remote_typeface_cache_capacity),
      loader_factory_.get());
  DCHECK(remote_typeface_cache_);

  DCHECK_LE(0, data.options.mesh_cache_capacity);
  mesh_cache_ = loader::mesh::CreateMeshCache(
      base::StringPrintf("%s.MeshCache", web_context_->name().c_str()),
      debugger_hooks_, static_cast<uint32>(data.options.mesh_cache_capacity),
      loader_factory_.get());
  DCHECK(mesh_cache_);

  local_storage_database_.reset(new dom::LocalStorageDatabase(
      web_context_->network_module()->storage_manager()));
  DCHECK(local_storage_database_);

  web_module_stat_tracker_.reset(new browser::WebModuleStatTracker(
      web_context_->name(), data.options.track_event_stats));
  DCHECK(web_module_stat_tracker_);

  media_source_registry_.reset(new dom::MediaSource::Registry);

  const media::DecoderBufferMemoryInfo* memory_info = nullptr;

  if (data.media_module) {
    memory_info = data.media_module->GetDecoderBufferAllocator();
  } else {
    stub_decoder_buffer_memory_info_.reset(
        new media::StubDecoderBufferMemoryInfo);
    memory_info = stub_decoder_buffer_memory_info_.get();
  }

  web_context_->SetupEnvironmentSettings(new dom::DOMSettings(
      debugger_hooks_, kDOMMaxElementDepth, media_source_registry_.get(),
      data.can_play_type_handler, memory_info, &mutation_observer_task_manager_,
      data.options.dom_settings_options));
  DCHECK(web_context_->environment_settings());
  // From algorithm to setup up a window environment settings object:
  //   https://html.spec.whatwg.org/commit-snapshots/465a6b672c703054de278b0f8133eb3ad33d93f4/#set-up-a-window-environment-settings-object
  // 6. Set settings object's creation URL to creationURL.
  web_context_->environment_settings()->set_creation_url(data.initial_url);

  system_caption_settings_ = new cobalt::dom::captions::SystemCaptionSettings(
      web_context_->environment_settings());

  dom::Window::CacheCallback splash_screen_cache_callback =
      CacheUrlContentCallback(data.options.splash_screen_cache);

  dom::Window::NavItemCallback cancel_scroll_callback =
      CancelScrollCallback(data.scroll_engine);

  // These members will reference other |Traceable|s, however are not
  // accessible from |Window|, so we must explicitly add them as roots.
  web_context_->global_environment()->AddRoot(&mutation_observer_task_manager_);
  web_context_->global_environment()->AddRoot(media_source_registry_.get());

#if defined(ENABLE_DEBUGGER)
  if (data.options.wait_for_web_debugger) {
    // Post a task that blocks the message loop and waits for the web debugger.
    // This must be posted before the the window's task to load the document.
    waiting_for_web_debugger_->store(true);
    base::MessageLoop::current()->task_runner()->PostTask(
        FROM_HERE, base::Bind(&WebModule::Impl::WaitForWebDebugger,
                              base::Unretained(this)));
  }
#endif  // defined(ENABLE_DEBUGGER)

  bool log_tts = false;
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  log_tts =
      base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseTTS);
#endif

  DCHECK(web_context_->network_module());
  window_ = new dom::Window(
      web_context_->environment_settings(), data.window_dimensions,
      data.initial_application_state, css_parser_.get(), dom_parser_.get(),
      web_context_->fetcher_factory(), loader_factory_.get(),
      &resource_provider_, animated_image_tracker_.get(), image_cache_.get(),
      reduced_image_cache_capacity_manager_.get(), remote_typeface_cache_.get(),
      mesh_cache_.get(), local_storage_database_.get(),
      data.can_play_type_handler, data.media_module,
      web_context_->execution_state(), web_context_->script_runner(),
      web_context_->global_environment()->script_value_factory(),
      media_source_registry_.get(),
      web_module_stat_tracker_->dom_stat_tracker(),
      base::GetSystemLanguageScript(), data.options.navigation_callback,
      base::Bind(&WebModule::Impl::OnLoadComplete, base::Unretained(this)),
      web_context_->network_module()->cookie_jar(),
      web::CspDelegate::Options(web_context_->network_module()->GetPostSender(),
                                data.options.csp_header_policy,
                                data.options.csp_enforcement_type,
                                data.options.csp_insecure_allowed_token),
      base::Bind(&WebModule::Impl::OnRanAnimationFrameCallbacks,
                 base::Unretained(this)),
      data.window_close_callback, data.window_minimize_callback,
      data.options.on_screen_keyboard_bridge, data.options.camera_3d,
      base::Bind(&WebModule::Impl::OnStartDispatchEvent,
                 base::Unretained(this)),
      base::Bind(&WebModule::Impl::OnStopDispatchEvent, base::Unretained(this)),
      data.options.provide_screenshot_function, cancel_scroll_callback,
      synchronous_loader_interrupt_, data.options.enable_inline_script_warnings,
      data.ui_nav_root, data.options.enable_map_to_mesh,
      data.options.csp_insecure_allowed_token, data.dom_max_element_depth,
      data.options.video_playback_rate_multiplier,
#if defined(ENABLE_TEST_RUNNER)
      data.options.layout_trigger == layout::LayoutManager::kTestRunnerMode
          ? dom::Window::kClockTypeTestRunner
          : (data.options.limit_performance_timer_resolution
                 ? dom::Window::kClockTypeResolutionLimitedSystemTime
                 : dom::Window::kClockTypeSystemTime),
#else
      dom::Window::kClockTypeSystemTime,
#endif
      splash_screen_cache_callback, system_caption_settings_, log_tts);
  DCHECK(window_);

  window_weak_ = base::AsWeakPtr(window_.get());
  DCHECK(window_weak_);

  web_context_->global_environment()->CreateGlobalObject(
      window_, web_context_->environment_settings());
  DCHECK(web_context_->GetWindowOrWorkerGlobalScope()->IsWindow());
  DCHECK(!web_context_->GetWindowOrWorkerGlobalScope()->IsDedicatedWorker());
  DCHECK(!web_context_->GetWindowOrWorkerGlobalScope()->IsServiceWorker());
  DCHECK(web_context_->GetWindowOrWorkerGlobalScope()->GetWrappableType() ==
         base::GetTypeId<dom::Window>());
  DCHECK_EQ(window_, base::polymorphic_downcast<dom::Window*>(
                         web_context_->GetWindowOrWorkerGlobalScope()));

  render_tree_produced_callback_ = data.render_tree_produced_callback;
  DCHECK(!render_tree_produced_callback_.is_null());

  error_callback_ = data.error_callback;
  DCHECK(!error_callback_.is_null());

  window_->navigator()->set_maybefreeze_callback(
      data.options.maybe_freeze_callback);
  window_->navigator()->set_media_player_factory(data.media_module);

  bool is_concealed =
      (data.initial_application_state == base::kApplicationStateConcealed);
  layout_manager_.reset(new layout::LayoutManager(
      is_concealed, web_context_->name(), window_.get(),
      base::Bind(&WebModule::Impl::OnRenderTreeProduced,
                 base::Unretained(this)),
      base::Bind(&WebModule::Impl::HandlePointerEvents, base::Unretained(this)),
      data.options.layout_trigger, data.dom_max_element_depth,
      data.layout_refresh_rate,
      web_context_->network_module()->preferred_language(),
      data.options.enable_image_animations,
      web_module_stat_tracker_->layout_stat_tracker(),
      data.options.clear_window_with_background_color));
  DCHECK(layout_manager_);

  if (!data.options.loaded_callbacks.empty()) {
    document_load_observer_.reset(
        new DocumentLoadedObserver(data.options.loaded_callbacks));
    window_->document()->AddObserver(document_load_observer_.get());
  }

#if defined(ENABLE_DEBUGGER)
  debug_overlay_.reset(
      new debug::backend::RenderOverlay(render_tree_produced_callback_));

  debug_module_.reset(new debug::backend::DebugModule(
      &debugger_hooks_, web_context_->global_environment(),
      debug_overlay_.get(), resource_provider_, window_,
      data.options.debugger_state));
#endif  // ENABLE_DEBUGGER

  report_unload_timing_info_callback_ =
      data.options.collect_unload_event_time_callback;

  web_context_->SetupFinished();
  is_running_ = true;
}

WebModule::Impl::~Impl() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);
  is_running_ = false;

  // Collect document's unload event start time.
  base::TimeTicks unload_event_start_time = base::TimeTicks::Now();

  window_->DispatchEvent(new web::Event(base::Tokens::unload()));

  // Collect document's unload event end time.
  base::TimeTicks unload_event_end_time = base::TimeTicks::Now();

  // Send the unload event start/end time back to application.
  if (!report_unload_timing_info_callback_.is_null()) {
    report_unload_timing_info_callback_.Run(unload_event_start_time,
                                            unload_event_end_time);
  }

  document_load_observer_.reset();

#if defined(ENABLE_DEBUGGER)
  debug_module_.reset();
  debug_overlay_.reset();
#endif  // ENABLE_DEBUGGER

  // Disable callbacks for the resource caches. Otherwise, it is possible for a
  // callback to occur into a DOM object that is being kept alive by a JS engine
  // reference even after the DOM tree has been destroyed. This can result in a
  // crash when the callback attempts to access a stale Document pointer.
  DisableCallbacksInResourceCaches();

  topmost_event_target_.reset();
  layout_manager_.reset();
  stub_decoder_buffer_memory_info_.reset();
  window_weak_.reset();
  window_->ClearPointerStateForShutdown();
  window_ = NULL;
  media_source_registry_.reset();
  web_context_->ShutDownJavaScriptEngine();
  local_storage_database_.reset();
  mesh_cache_.reset();
  remote_typeface_cache_.reset();
  // Warning: The image cache may contain animated images that rely on the
  // thread in AnimatedImageTracker, so it's important to destroy the image
  // cache before the animated image tracker object.
  image_cache_.reset();
  animated_image_tracker_.reset();
  dom_parser_.reset();
  css_parser_.reset();
  web_module_stat_tracker_.reset();
}

void WebModule::Impl::InjectInputEvent(scoped_refptr<dom::Element> element,
                                       const scoped_refptr<web::Event>& event) {
  TRACE_EVENT1("cobalt::browser", "WebModule::Impl::InjectInputEvent()",
               "event", TRACE_STR_COPY(event->type().c_str()));
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);
  DCHECK(window_);

  if (element) {
    element->DispatchEvent(event);
  } else {
    if (dom::PointerState::CanQueueEvent(event)) {
      // As an optimization we batch together pointer/mouse events for as long
      // as we can get away with it (e.g. until a non-pointer event is received
      // or whenever the next layout occurs).
      window_->document()->pointer_state()->QueuePointerEvent(event);
    } else {
      // In order to maintain the correct input event ordering, we first
      // dispatch any queued pending pointer events.
      HandlePointerEvents();
      window_->InjectEvent(event);
    }
  }
}

void WebModule::Impl::InjectOnScreenKeyboardInputEvent(
    base::Token type, const dom::InputEventInit& event,
    scoped_refptr<dom::Element> element) {
  scoped_refptr<dom::InputEvent> input_event(
      new dom::InputEvent(type, window_, event));
  InjectInputEvent(element, input_event);
}

void WebModule::Impl::InjectOnScreenKeyboardShownEvent(int ticket) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);
  DCHECK(window_);
  DCHECK(window_->on_screen_keyboard());

  window_->on_screen_keyboard()->DispatchShowEvent(ticket);
}

void WebModule::Impl::InjectOnScreenKeyboardHiddenEvent(int ticket) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);
  DCHECK(window_);
  DCHECK(window_->on_screen_keyboard());

  window_->on_screen_keyboard()->DispatchHideEvent(ticket);
}

void WebModule::Impl::InjectOnScreenKeyboardFocusedEvent(int ticket) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);
  DCHECK(window_);
  DCHECK(window_->on_screen_keyboard());

  window_->on_screen_keyboard()->DispatchFocusEvent(ticket);
}

void WebModule::Impl::InjectOnScreenKeyboardBlurredEvent(int ticket) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);
  DCHECK(window_);
  DCHECK(window_->on_screen_keyboard());

  window_->on_screen_keyboard()->DispatchBlurEvent(ticket);
}

void WebModule::Impl::InjectOnScreenKeyboardSuggestionsUpdatedEvent(
    int ticket) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);
  DCHECK(window_);
  DCHECK(window_->on_screen_keyboard());

  window_->on_screen_keyboard()->DispatchSuggestionsUpdatedEvent(ticket);
}


void WebModule::Impl::InjectKeyboardEvent(base::Token type,
                                          const dom::KeyboardEventInit& event,
                                          scoped_refptr<dom::Element> element) {
  scoped_refptr<dom::KeyboardEvent> keyboard_event(
      new dom::KeyboardEvent(type, window_, event));
  InjectInputEvent(element, keyboard_event);
}

void WebModule::Impl::InjectPointerEvent(base::Token type,
                                         const dom::PointerEventInit& event,
                                         scoped_refptr<dom::Element> element) {
  scoped_refptr<dom::PointerEvent> pointer_event(
      new dom::PointerEvent(type, window_, event));
  InjectInputEvent(element, pointer_event);
}

void WebModule::Impl::InjectWheelEvent(base::Token type,
                                       const dom::WheelEventInit& event,
                                       scoped_refptr<dom::Element> element) {
  scoped_refptr<dom::WheelEvent> wheel_event(
      new dom::WheelEvent(type, window_, event));
  InjectInputEvent(element, wheel_event);
}

void WebModule::Impl::UpdateDateTimeConfiguration() {
  if (web_context_ && web_context_->javascript_engine()) {
    web_context_->javascript_engine()->UpdateDateTimeConfiguration();
  }
}

void WebModule::Impl::ExecuteJavascript(
    const std::string& script_utf8, const base::SourceLocation& script_location,
    std::string* result, bool* out_succeeded) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);
  DCHECK(web_context_->script_runner());

  // JavaScript is being run. Track it in the global stats.
  dom::GlobalStats::GetInstance()->StartJavaScriptEvent();

  // This should only be called for Cobalt JavaScript, error reports are
  // allowed.
  if (result) {
    *result = web_context_->script_runner()->Execute(
        script_utf8, script_location, false /*mute_errors*/, out_succeeded);
  } else {
    web_context_->script_runner()->Execute(
        script_utf8, script_location, false /*mute_errors*/, out_succeeded);
  }


  // JavaScript is done running. Stop tracking it in the global stats.
  dom::GlobalStats::GetInstance()->StopJavaScriptEvent();
}

void WebModule::Impl::ClearAllIntervalsAndTimeouts() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(window_);
  window_->DestroyTimers();
}

void WebModule::Impl::OnRanAnimationFrameCallbacks() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);
  // Notify the stat tracker that the animation frame callbacks have finished.
  // This may end the current event being tracked.
  web_module_stat_tracker_->OnRanAnimationFrameCallbacks(
      layout_manager_->IsRenderTreePending());
}

void WebModule::Impl::OnRenderTreeProduced(
    const LayoutResults& layout_results) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);

  last_render_tree_produced_time_ = base::TimeTicks::Now();
  is_render_tree_rasterization_pending_ = true;

  web_module_stat_tracker_->OnRenderTreeProduced(
      last_render_tree_produced_time_);

  LayoutResults layout_results_with_callback(
      layout_results.render_tree, layout_results.layout_time,
      base::Bind(&WebModule::Impl::OnRenderTreeRasterized,
                 base::Unretained(this),
                 base::MessageLoop::current()->task_runner(),
                 last_render_tree_produced_time_));

#if defined(ENABLE_DEBUGGER)
  debug_overlay_->OnRenderTreeProduced(layout_results_with_callback);
#else   // ENABLE_DEBUGGER
  render_tree_produced_callback_.Run(layout_results_with_callback);
#endif  // ENABLE_DEBUGGER
}

void WebModule::Impl::OnRenderTreeRasterized(
    scoped_refptr<base::SingleThreadTaskRunner> web_module_message_loop,
    const base::TimeTicks& produced_time) {
  web_module_message_loop->PostTask(
      FROM_HERE, base::Bind(&WebModule::Impl::ProcessOnRenderTreeRasterized,
                            base::Unretained(this), produced_time,
                            base::TimeTicks::Now()));
}

void WebModule::Impl::ProcessOnRenderTreeRasterized(
    const base::TimeTicks& produced_time,
    const base::TimeTicks& rasterized_time) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  web_module_stat_tracker_->OnRenderTreeRasterized(produced_time,
                                                   rasterized_time);
  if (produced_time >= last_render_tree_produced_time_) {
    is_render_tree_rasterization_pending_ = false;
  }
}

void WebModule::Impl::DoSynchronousLayoutAndGetRenderTree(
    scoped_refptr<render_tree::Node>* render_tree) {
  TRACE_EVENT0("cobalt::browser",
               "WebModule::Impl::DoSynchronousLayoutAndGetRenderTree()");
  DCHECK(render_tree);
  scoped_refptr<render_tree::Node> tree =
      window_->document()->DoSynchronousLayoutAndGetRenderTree();
  if (render_tree) *render_tree = tree;
}

void WebModule::Impl::SetApplicationStartOrPreloadTimestamp(
    bool is_preload, SbTimeMonotonic timestamp) {
  DCHECK(window_);
  DCHECK(window_->performance());
  window_->performance()->SetApplicationStartOrPreloadTimestamp(is_preload,
                                                                timestamp);
}

void WebModule::Impl::SetDeepLinkTimestamp(SbTimeMonotonic timestamp) {
  DCHECK(window_);
  window_->performance()->SetDeepLinkTimestamp(timestamp);
}

void WebModule::Impl::SetUnloadEventTimingInfo(base::TimeTicks start_time,
                                               base::TimeTicks end_time) {
  DCHECK(window_);
  if (window_->document()) {
    window_->document()->SetUnloadEventTimingInfo(start_time, end_time);
  }
}

#if defined(ENABLE_WEBDRIVER)
void WebModule::Impl::CreateWindowDriver(
    const webdriver::protocol::WindowId& window_id,
    std::unique_ptr<webdriver::WindowDriver>* window_driver_out) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);
  DCHECK(window_);
  DCHECK(window_weak_);
  DCHECK(window_->document());
  DCHECK(web_context_->global_environment());

  window_driver_out->reset(new webdriver::WindowDriver(
      window_id, window_weak_,
      base::Bind(&WebModule::Impl::global_environment, base::Unretained(this)),
      base::Bind(&WebModule::Impl::InjectKeyboardEvent, base::Unretained(this)),
      base::Bind(&WebModule::Impl::InjectPointerEvent, base::Unretained(this)),
      base::MessageLoop::current()->task_runner()));
}
#endif  // defined(ENABLE_WEBDRIVER)

#if defined(ENABLE_DEBUGGER)
void WebModule::Impl::WaitForWebDebugger() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(debug_module_);
  LOG(WARNING) << "\n-------------------------------------"
                  "\n Waiting for web debugger to connect "
                  "\n-------------------------------------";
  // This blocks until the web debugger connects.
  debug_module_->debug_dispatcher()->SetPaused(true);
  waiting_for_web_debugger_->store(false);
}
#endif  // defined(ENABLE_DEBUGGER)

void WebModule::Impl::SetImageCacheCapacity(int64_t bytes) {
  image_cache_->SetCapacity(static_cast<uint32>(bytes));
}

void WebModule::Impl::SetRemoteTypefaceCacheCapacity(int64_t bytes) {
  remote_typeface_cache_->SetCapacity(static_cast<uint32>(bytes));
}

void WebModule::Impl::SetSize(cssom::ViewportSize viewport_size) {
  window_->SetSize(viewport_size);
}

void WebModule::Impl::UpdateCamera3D(
    const scoped_refptr<input::Camera3D>& camera_3d) {
  window_->UpdateCamera3D(camera_3d);
}

void WebModule::Impl::SetMediaModule(media::MediaModule* media_module) {
  SB_DCHECK(media_module);

  dom::DOMSettings* dom_settings =
      base::polymorphic_downcast<dom::DOMSettings*>(
          web_context_->environment_settings());

  dom_settings->set_decoder_buffer_memory_info(
      media_module->GetDecoderBufferAllocator());
  window_->set_web_media_player_factory(media_module);
}

void WebModule::Impl::SetApplicationState(base::ApplicationState state,
                                          SbTimeMonotonic timestamp) {
  window_->SetApplicationState(state, timestamp);
}

void WebModule::Impl::SetResourceProvider(
    render_tree::ResourceProvider* resource_provider) {
  resource_provider_ = resource_provider;
  if (resource_provider_) {
    base::TypeId resource_provider_type_id = resource_provider_->GetTypeId();
    // Check for if the resource provider type id has changed. If it has, then
    // anything contained within the caches is invalid and must be purged.
    if (resource_provider_type_id_ != resource_provider_type_id) {
      PurgeResourceCaches(should_retain_remote_typeface_cache_on_freeze_);
    }
    resource_provider_type_id_ = resource_provider_type_id;
  }
}

void WebModule::Impl::OnStartDispatchEvent(
    const scoped_refptr<web::Event>& event) {
  web_module_stat_tracker_->OnStartDispatchEvent(event);
}

void WebModule::Impl::OnStopDispatchEvent(
    const scoped_refptr<web::Event>& event) {
  web_module_stat_tracker_->OnStopDispatchEvent(
      event, window_->HasPendingAnimationFrameCallbacks(),
      layout_manager_->IsRenderTreePending());
}

void WebModule::Impl::Blur(SbTimeMonotonic timestamp) {
  TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Blur()");
  SetApplicationState(base::kApplicationStateBlurred, timestamp);
}

void WebModule::Impl::Conceal(render_tree::ResourceProvider* resource_provider,
                              SbTimeMonotonic timestamp) {
  TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Conceal()");
  SetResourceProvider(resource_provider);

  SetApplicationState(base::kApplicationStateConcealed, timestamp);
  layout_manager_->Suspend();
  // Purge the cached resources prior to the freeze. That may cancel pending
  // loads, allowing the freeze to occur faster and preventing unnecessary
  // callbacks.
  window_->document()->PurgeCachedResources();

  // Clear out any currently tracked animating images.
  animated_image_tracker_->Reset();

  // Purge the resource caches before running any freeze logic. This will force
  // any pending callbacks that the caches are batching to run.
  PurgeResourceCaches(should_retain_remote_typeface_cache_on_freeze_);

#if defined(ENABLE_DEBUGGER)
  // The debug overlay may be holding onto a render tree, clear that out.
  debug_overlay_->ClearInput();
#endif

  // Force garbage collection in |javascript_engine|.
  if (web_context_ && web_context_->javascript_engine()) {
    web_context_->javascript_engine()->CollectGarbage();
  }

  loader_factory_->UpdateResourceProvider(resource_provider_);

  if (window_->media_session()->media_session_client() != NULL) {
    window_->media_session()
        ->media_session_client()
        ->PostDelayedTaskForMaybeFreezeCallback();
  }
}

void WebModule::Impl::Freeze(SbTimeMonotonic timestamp) {
  TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Freeze()");
  SetApplicationState(base::kApplicationStateFrozen, timestamp);

  // Clear out the loader factory's resource provider, possibly aborting any
  // in-progress loads.
  loader_factory_->Suspend();
}

void WebModule::Impl::Unfreeze(render_tree::ResourceProvider* resource_provider,
                               SbTimeMonotonic timestamp) {
  TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Unfreeze()");
  synchronous_loader_interrupt_->Reset();
  DCHECK(resource_provider);

  loader_factory_->Resume(resource_provider);
  SetApplicationState(base::kApplicationStateConcealed, timestamp);
}

void WebModule::Impl::Reveal(render_tree::ResourceProvider* resource_provider,
                             SbTimeMonotonic timestamp) {
  TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Reveal()");
  synchronous_loader_interrupt_->Reset();
  DCHECK(resource_provider);
  SetResourceProvider(resource_provider);

  window_->document()->PurgeCachedResources();
  PurgeResourceCaches(should_retain_remote_typeface_cache_on_freeze_);

  loader_factory_->UpdateResourceProvider(resource_provider_);
  layout_manager_->Resume();

  SetApplicationState(base::kApplicationStateBlurred, timestamp);
}

void WebModule::Impl::Focus(SbTimeMonotonic timestamp) {
  TRACE_EVENT0("cobalt::browser", "WebModule::Impl::Focus()");
  synchronous_loader_interrupt_->Reset();
  SetApplicationState(base::kApplicationStateStarted, timestamp);
}

void WebModule::Impl::ReduceMemory() {
  TRACE_EVENT0("cobalt::browser", "WebModule::Impl::ReduceMemory()");
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (!is_running_) {
    return;
  }
  synchronous_loader_interrupt_->Reset();

  layout_manager_->Purge();

  // Retain the remote typeface cache when reducing memory.
  PurgeResourceCaches(true /*should_retain_remote_typeface_cache*/);
  window_->document()->PurgeCachedResources();

  // Force garbage collection in |javascript_engine|.
  if (web_context_ && web_context_->javascript_engine()) {
    web_context_->javascript_engine()->CollectGarbage();
  }
}

void WebModule::Impl::InjectBeforeUnloadEvent() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  if (window_ && window_->HasEventListener(base::Tokens::beforeunload())) {
    window_->DispatchEvent(new web::Event(base::Tokens::beforeunload()));
  } else if (!on_before_unload_fired_but_not_handled_.is_null()) {
    on_before_unload_fired_but_not_handled_.Run();
  }
}

void WebModule::Impl::InjectCaptionSettingsChangedEvent() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  system_caption_settings_->OnCaptionSettingsChanged();
}

void WebModule::Impl::InjectWindowOnOnlineEvent() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  window_->OnWindowOnOnlineEvent();
}

void WebModule::Impl::InjectWindowOnOfflineEvent() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  window_->OnWindowOnOfflineEvent();
}

void WebModule::Impl::PurgeResourceCaches(
    bool should_retain_remote_typeface_cache) {
  image_cache_->Purge();
  if (should_retain_remote_typeface_cache) {
    remote_typeface_cache_->ProcessPendingCallbacks();
  } else {
    remote_typeface_cache_->Purge();
  }
  mesh_cache_->Purge();
}

void WebModule::Impl::DisableCallbacksInResourceCaches() {
  image_cache_->DisableCallbacks();
  remote_typeface_cache_->DisableCallbacks();
  mesh_cache_->DisableCallbacks();
}

void WebModule::Impl::HandlePointerEvents() {
  TRACE_EVENT0("cobalt::browser", "WebModule::Impl::HandlePointerEvents");
  const scoped_refptr<dom::Document>& document = window_->document();
  scoped_refptr<web::Event> event;
  do {
    event = document->pointer_state()->GetNextQueuedPointerEvent();
    if (event) {
      SB_DCHECK(
          window_ ==
          base::polymorphic_downcast<const dom::UIEvent* const>(event.get())
              ->view());
      if (!topmost_event_target_) {
        topmost_event_target_.reset(
            new layout::TopmostEventTarget(scroll_engine_));
      }
      topmost_event_target_->MaybeSendPointerEvents(event);
    }
  } while (event && !layout_manager_->IsRenderTreePending());
}

WebModule::Options::Options()
    : layout_trigger(layout::LayoutManager::kOnDocumentMutation),
      mesh_cache_capacity(configuration::Configuration::GetInstance()
                              ->CobaltMeshCacheSizeInBytes()) {
  web_options.stack_size = cobalt::browser::kWebModuleStackSize;
}

WebModule::WebModule(const std::string& name)
    : ui_nav_root_(new ui_navigation::NavItem(
          ui_navigation::kNativeItemTypeContainer,
          // Currently, events do not need to be processed for the root item.
          base::Closure(), base::Closure(), base::Closure())) {
  web_agent_.reset(new web::Agent(name));
}

WebModule::~WebModule() {
  DCHECK(message_loop());
  DCHECK(web_agent_);
  // This will cancel the timers for tasks, which help the thread exit
  ClearAllIntervalsAndTimeouts();
  web_agent_->WaitUntilDone();
  web_agent_->Stop();
  web_agent_.reset();
}

void WebModule::Run(
    const GURL& initial_url, base::ApplicationState initial_application_state,
    ui_navigation::scroll_engine::ScrollEngine* scroll_engine,
    const OnRenderTreeProducedCallback& render_tree_produced_callback,
    OnErrorCallback error_callback, const CloseCallback& window_close_callback,
    const base::Closure& window_minimize_callback,
    media::CanPlayTypeHandler* can_play_type_handler,
    media::MediaModule* media_module, const ViewportSize& window_dimensions,
    render_tree::ResourceProvider* resource_provider, float layout_refresh_rate,
    const Options& options) {
  ConstructionData construction_data(
      initial_url, initial_application_state, scroll_engine,
      render_tree_produced_callback, error_callback, window_close_callback,
      window_minimize_callback, can_play_type_handler, media_module,
      window_dimensions, resource_provider, kDOMMaxElementDepth,
      layout_refresh_rate, ui_nav_root_,
#if defined(ENABLE_DEBUGGER)
      &waiting_for_web_debugger_,
#endif  // defined(ENABLE_DEBUGGER)
      &synchronous_loader_interrupt_, options);

  web::Agent::Options web_options(options.web_options);
  if (!options.injected_global_object_attributes.empty()) {
    for (Options::InjectedGlobalObjectAttributes::const_iterator iter =
             options.injected_global_object_attributes.begin();
         iter != options.injected_global_object_attributes.end(); ++iter) {
      DCHECK(!ContainsKey(web_options.injected_global_object_attributes,
                          iter->first));
      // Trampoline to the given callback, adding a pointer to this WebModule.
      web_options.injected_global_object_attributes[iter->first] =
          base::Bind(iter->second, base::Unretained(this));
    }
  }

  web_agent_->Run(web_options,
                  base::Bind(&WebModule::InitializeTaskInThread,
                             base::Unretained(this), construction_data),
                  this);
}

void WebModule::InitializeTaskInThread(const ConstructionData& data,
                                       web::Context* context) {
  DCHECK_EQ(base::MessageLoop::current(), message_loop());
  impl_.reset(new Impl(context, data));
}

// These are helper macros for jumping to the Impl thread without referencing
// impl_ outside of the thread.

// Ensure that we are on the WebModule thread where we can dereference impl_.
// Post a task to the given function if we are not.
#define TASK_TO_ENSURE_IMPL_ON_THREAD0(task_function, function)               \
  DCHECK(message_loop());                                                     \
  if (base::MessageLoop::current() != message_loop()) {                       \
    message_loop()->task_runner()->task_function(                             \
        FROM_HERE, base::Bind(&WebModule::function, base::Unretained(this))); \
    return;                                                                   \
  } else {                                                                    \
    DCHECK(impl_);                                                            \
  }

// Ensure that we are on the WebModule thread where we can dereference impl_.
// Post a task to the given function if we are not.
#define TASK_TO_ENSURE_IMPL_ON_THREAD(task_function, function, ...)         \
  DCHECK(message_loop());                                                   \
  if (base::MessageLoop::current() != message_loop()) {                     \
    message_loop()->task_runner()->task_function(                           \
        FROM_HERE, base::Bind(&WebModule::function, base::Unretained(this), \
                              ##__VA_ARGS__));                              \
    return;                                                                 \
  } else {                                                                  \
    DCHECK(impl_);                                                          \
  }

// Ensure that we are on the WebModule thread where we can dereference impl_.
// Post a task to the given function if we are not.
#define POST_TO_ENSURE_IMPL_ON_THREAD0(function) \
  TASK_TO_ENSURE_IMPL_ON_THREAD0(PostTask, function)

// Ensure that we are on the WebModule thread where we can dereference impl_.
// Post a task to the given function if we are not.
#define POST_TO_ENSURE_IMPL_ON_THREAD(function, ...) \
  TASK_TO_ENSURE_IMPL_ON_THREAD(PostTask, function, ##__VA_ARGS__)

// Ensure that we are on the WebModule thread where we can dereference impl_.
// Post a blocking task to the given function if we are not.
#define POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD0(function) \
  TASK_TO_ENSURE_IMPL_ON_THREAD0(PostBlockingTask, function)

// Ensure that we are on the WebModule thread where we can dereference impl_.
// Post a blocking task to the given function if we are not.
#define POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(function, ...) \
  TASK_TO_ENSURE_IMPL_ON_THREAD(PostBlockingTask, function, ##__VA_ARGS__)

void WebModule::InjectOnScreenKeyboardInputEvent(
    base::Token type, const dom::InputEventInit& event) {
  TRACE_EVENT1("cobalt::browser",
               "WebModule::InjectOnScreenKeyboardInputEvent()", "type",
               TRACE_STR_COPY(type.c_str()));
  POST_TO_ENSURE_IMPL_ON_THREAD(InjectOnScreenKeyboardInputEvent, type, event);
  impl_->InjectOnScreenKeyboardInputEvent(type, event);
}

void WebModule::InjectOnScreenKeyboardShownEvent(int ticket) {
  TRACE_EVENT1("cobalt::browser",
               "WebModule::InjectOnScreenKeyboardShownEvent()", "ticket",
               ticket);
  POST_TO_ENSURE_IMPL_ON_THREAD(InjectOnScreenKeyboardShownEvent, ticket);
  impl_->InjectOnScreenKeyboardShownEvent(ticket);
}

void WebModule::InjectOnScreenKeyboardHiddenEvent(int ticket) {
  TRACE_EVENT1("cobalt::browser",
               "WebModule::InjectOnScreenKeyboardHiddenEvent()", "ticket",
               ticket);
  POST_TO_ENSURE_IMPL_ON_THREAD(InjectOnScreenKeyboardHiddenEvent, ticket);
  impl_->InjectOnScreenKeyboardHiddenEvent(ticket);
}

void WebModule::InjectOnScreenKeyboardFocusedEvent(int ticket) {
  TRACE_EVENT1("cobalt::browser",
               "WebModule::InjectOnScreenKeyboardFocusedEvent()", "ticket",
               ticket);
  POST_TO_ENSURE_IMPL_ON_THREAD(InjectOnScreenKeyboardFocusedEvent, ticket);
  impl_->InjectOnScreenKeyboardFocusedEvent(ticket);
}

void WebModule::InjectOnScreenKeyboardBlurredEvent(int ticket) {
  TRACE_EVENT1("cobalt::browser",
               "WebModule::InjectOnScreenKeyboardBlurredEvent()", "ticket",
               ticket);
  POST_TO_ENSURE_IMPL_ON_THREAD(InjectOnScreenKeyboardBlurredEvent, ticket);
  impl_->InjectOnScreenKeyboardBlurredEvent(ticket);
}

void WebModule::InjectOnScreenKeyboardSuggestionsUpdatedEvent(int ticket) {
  TRACE_EVENT1("cobalt::browser",
               "WebModule::InjectOnScreenKeyboardSuggestionsUpdatedEvent()",
               "ticket", ticket);
  POST_TO_ENSURE_IMPL_ON_THREAD(InjectOnScreenKeyboardSuggestionsUpdatedEvent,
                                ticket);
  impl_->InjectOnScreenKeyboardSuggestionsUpdatedEvent(ticket);
}


void WebModule::InjectKeyboardEvent(base::Token type,
                                    const dom::KeyboardEventInit& event) {
  TRACE_EVENT1("cobalt::browser", "WebModule::InjectKeyboardEvent()", "type",
               TRACE_STR_COPY(type.c_str()));
  POST_TO_ENSURE_IMPL_ON_THREAD(InjectKeyboardEvent, type, event);
  impl_->InjectKeyboardEvent(type, event);
}

void WebModule::InjectPointerEvent(base::Token type,
                                   const dom::PointerEventInit& event) {
  TRACE_EVENT1("cobalt::browser", "WebModule::InjectPointerEvent()", "type",
               TRACE_STR_COPY(type.c_str()));
  POST_TO_ENSURE_IMPL_ON_THREAD(InjectPointerEvent, type, event);
  impl_->InjectPointerEvent(type, event);
}

void WebModule::InjectWheelEvent(base::Token type,
                                 const dom::WheelEventInit& event) {
  TRACE_EVENT1("cobalt::browser", "WebModule::InjectWheelEvent()", "type",
               TRACE_STR_COPY(type.c_str()));
  POST_TO_ENSURE_IMPL_ON_THREAD(InjectWheelEvent, type, event);
  impl_->InjectWheelEvent(type, event);
}

void WebModule::InjectBeforeUnloadEvent() {
  TRACE_EVENT0("cobalt::browser", "WebModule::InjectBeforeUnloadEvent()");
  POST_TO_ENSURE_IMPL_ON_THREAD0(InjectBeforeUnloadEvent);
  impl_->InjectBeforeUnloadEvent();
}

void WebModule::InjectCaptionSettingsChangedEvent() {
  TRACE_EVENT0("cobalt::browser",
               "WebModule::InjectCaptionSettingsChangedEvent()");
  POST_TO_ENSURE_IMPL_ON_THREAD0(InjectCaptionSettingsChangedEvent);
  impl_->InjectCaptionSettingsChangedEvent();
}

void WebModule::InjectWindowOnOnlineEvent(const base::Event* event) {
  TRACE_EVENT0("cobalt::browser", "WebModule::InjectWindowOnOnlineEvent()");
  POST_TO_ENSURE_IMPL_ON_THREAD(InjectWindowOnOnlineEvent, event);
  impl_->InjectWindowOnOnlineEvent();
}

void WebModule::InjectWindowOnOfflineEvent(const base::Event* event) {
  TRACE_EVENT0("cobalt::browser", "WebModule::InjectWindowOnOfflineEvent()");
  POST_TO_ENSURE_IMPL_ON_THREAD(InjectWindowOnOfflineEvent, event);
  impl_->InjectWindowOnOfflineEvent();
}

void WebModule::UpdateDateTimeConfiguration() {
  TRACE_EVENT0("cobalt::browser", "WebModule::UpdateDateTimeConfiguration()");
  POST_TO_ENSURE_IMPL_ON_THREAD0(UpdateDateTimeConfiguration);
  impl_->UpdateDateTimeConfiguration();
}

void WebModule::ExecuteJavascript(const std::string& script_utf8,
                                  const base::SourceLocation& script_location,
                                  std::string* out_result,
                                  bool* out_succeeded) {
  TRACE_EVENT0("cobalt::browser", "WebModule::ExecuteJavascript()");
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(ExecuteJavascript, script_utf8,
                                          script_location, out_result,
                                          out_succeeded);
  impl_->ExecuteJavascript(script_utf8, script_location, out_result,
                           out_succeeded);
}

void WebModule::ClearAllIntervalsAndTimeouts() {
  TRACE_EVENT0("cobalt::browser", "WebModule::ClearAllIntervalsAndTimeouts()");
  POST_TO_ENSURE_IMPL_ON_THREAD0(ClearAllIntervalsAndTimeouts);
  impl_->ClearAllIntervalsAndTimeouts();
}

#if defined(ENABLE_WEBDRIVER)
void WebModule::CreateWindowDriver(
    const webdriver::protocol::WindowId& window_id,
    std::unique_ptr<webdriver::WindowDriver>* window_driver_out) {
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(CreateWindowDriver, window_id,
                                          window_driver_out);
  impl_->CreateWindowDriver(window_id, window_driver_out);
}
#endif  // defined(ENABLE_WEBDRIVER)

#if defined(ENABLE_DEBUGGER)
// May be called from any thread.
void WebModule::GetDebugDispatcher(
    debug::backend::DebugDispatcher** dispatcher) {
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(GetDebugDispatcher, dispatcher);
  if (dispatcher) *dispatcher = impl_->debug_dispatcher();
}

void WebModule::FreezeDebugger(
    std::unique_ptr<debug::backend::DebuggerState>* debugger_state) {
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(FreezeDebugger, debugger_state);
  impl_->FreezeDebugger(debugger_state);
}
#endif  // defined(ENABLE_DEBUGGER)

void WebModule::SetSize(const ViewportSize& viewport_size) {
  POST_TO_ENSURE_IMPL_ON_THREAD(SetSize, viewport_size);
  impl_->SetSize(viewport_size);
}

void WebModule::UpdateCamera3D(
    const scoped_refptr<input::Camera3D>& camera_3d) {
  POST_TO_ENSURE_IMPL_ON_THREAD(UpdateCamera3D, camera_3d);
  impl_->UpdateCamera3D(camera_3d);
}

void WebModule::SetMediaModule(media::MediaModule* media_module) {
  POST_TO_ENSURE_IMPL_ON_THREAD(SetMediaModule, media_module);
  impl_->SetMediaModule(media_module);
}

void WebModule::SetImageCacheCapacity(int64_t bytes) {
  POST_TO_ENSURE_IMPL_ON_THREAD(SetImageCacheCapacity, bytes);
  impl_->SetImageCacheCapacity(bytes);
}

void WebModule::SetRemoteTypefaceCacheCapacity(int64_t bytes) {
  POST_TO_ENSURE_IMPL_ON_THREAD(SetRemoteTypefaceCacheCapacity, bytes);
  impl_->SetRemoteTypefaceCacheCapacity(bytes);
}

void WebModule::Blur(SbTimeMonotonic timestamp) {
  synchronous_loader_interrupt_.Signal();
#if defined(ENABLE_DEBUGGER)
  // We normally need to block here so that the call doesn't return until the
  // web application has had a chance to process the whole event. However, our
  // message loop is blocked while waiting for the web debugger to connect, so
  // we would deadlock here if the user switches to Chrome to run devtools on
  // the same machine where Cobalt is running. Therefore, while we're still
  // waiting for the debugger we post the pause task without blocking on it,
  // letting it eventually run when the debugger connects and the message loop
  // is unblocked again.
  if (waiting_for_web_debugger_.load()) {
    POST_TO_ENSURE_IMPL_ON_THREAD(Blur, timestamp);
    impl_->Blur(timestamp);
    return;
  }
#endif  // defined(ENABLE_DEBUGGER)

  // We must block here so that the call doesn't return until the web
  // application has had a chance to process the whole event.
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(Blur, timestamp);
  impl_->Blur(timestamp);
}

void WebModule::Conceal(render_tree::ResourceProvider* resource_provider,
                        SbTimeMonotonic timestamp) {
  synchronous_loader_interrupt_.Signal();
  // We must block here so that the call doesn't return until the web
  // application has had a chance to process the whole event.
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(Conceal, resource_provider,
                                          timestamp);
  impl_->Conceal(resource_provider, timestamp);
}

void WebModule::Freeze(SbTimeMonotonic timestamp) {
  // We must block here so that the call doesn't return until the web
  // application has had a chance to process the whole event.
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(Freeze, timestamp);
  impl_->Freeze(timestamp);
}

void WebModule::Unfreeze(render_tree::ResourceProvider* resource_provider,
                         SbTimeMonotonic timestamp) {
  // We must block here so that the call doesn't return until the web
  // application has had a chance to process the whole event.
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(Unfreeze, resource_provider,
                                          timestamp);
  impl_->Unfreeze(resource_provider, timestamp);
}

void WebModule::Reveal(render_tree::ResourceProvider* resource_provider,
                       SbTimeMonotonic timestamp) {
  // We must block here so that the call doesn't return until the web
  // application has had a chance to process the whole event.
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(Reveal, resource_provider, timestamp);
  impl_->Reveal(resource_provider, timestamp);
}

void WebModule::Focus(SbTimeMonotonic timestamp) {
  // We must block here so that the call doesn't return until the web
  // application has had a chance to process the whole event.
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(Focus, timestamp);
  impl_->Focus(timestamp);
}

void WebModule::ReduceMemory() {
  synchronous_loader_interrupt_.Signal();
  // We must block here so that the call doesn't return until the web
  // application has had a chance to process the whole event.
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD0(ReduceMemory);
  impl_->ReduceMemory();
}

void WebModule::RequestJavaScriptHeapStatistics(
    const web::Agent::JavaScriptHeapStatisticsCallback& callback) {
  web_agent_->RequestJavaScriptHeapStatistics(callback);
}

void WebModule::GetIsReadyToFreeze(volatile bool* is_ready_to_freeze) {
  // We must block here so that the call doesn't return until the thread
  // has had a chance to fill in the return value.
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(GetIsReadyToFreeze,
                                          is_ready_to_freeze);
  impl_->IsReadyToFreeze(is_ready_to_freeze);
}

bool WebModule::IsReadyToFreeze() {
  volatile bool is_ready_to_freeze = false;
  GetIsReadyToFreeze(&is_ready_to_freeze);
  return is_ready_to_freeze;
}

void WebModule::DoSynchronousLayoutAndGetRenderTree(
    scoped_refptr<render_tree::Node>* render_tree) {
  TRACE_EVENT0("cobalt::browser",
               "WebModule::DoSynchronousLayoutAndGetRenderTree()");
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(DoSynchronousLayoutAndGetRenderTree,
                                          render_tree);
  impl_->DoSynchronousLayoutAndGetRenderTree(render_tree);
}

void WebModule::SetApplicationStartOrPreloadTimestamp(
    bool is_preload, SbTimeMonotonic timestamp) {
  TRACE_EVENT0("cobalt::browser",
               "WebModule::SetApplicationStartOrPreloadTimestamp()");
  POST_TO_ENSURE_IMPL_ON_THREAD(SetApplicationStartOrPreloadTimestamp,
                                is_preload, timestamp);
  impl_->SetApplicationStartOrPreloadTimestamp(is_preload, timestamp);
}

void WebModule::SetDeepLinkTimestamp(SbTimeMonotonic timestamp) {
  TRACE_EVENT0("cobalt::browser", "WebModule::SetDeepLinkTimestamp()");
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(SetDeepLinkTimestamp, timestamp);
  impl_->SetDeepLinkTimestamp(timestamp);
}

void WebModule::SetUnloadEventTimingInfo(base::TimeTicks start_time,
                                         base::TimeTicks end_time) {
  TRACE_EVENT0("cobalt::browser", "WebModule::SetUnloadEventTimingInfo()");
  POST_TO_ENSURE_IMPL_ON_THREAD(SetUnloadEventTimingInfo, start_time, end_time);
  impl_->SetUnloadEventTimingInfo(start_time, end_time);
}

}  // namespace browser
}  // namespace cobalt
