// 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/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/startup_timer.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/media_source_settings.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/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>&)>();
  }
}

}  // 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 SetMediaSourceSetting(const std::string& name, int value,
                             bool* succeeded);
  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 LogScriptError(const base::SourceLocation& source_location,
                      const std::string& error_message);

  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);

  void OnCspPolicyChanged();

  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);
      }
    }
  }

  // Report an error encountered while running JS.
  // Returns whether or not the error was handled.
  bool ReportScriptError(const script::ErrorReport& error_report);

  // 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_;

  // 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_;

  // Object to hold WebModule wide settings for MediaSource related objects.
  dom::MediaSourceSettingsImpl media_source_settings_;

  // 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),
      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_);
#if defined(COBALT_ENABLE_JAVASCRIPT_ERROR_LOGGING)
  script::JavaScriptEngine::ErrorHandler error_handler =
      base::Bind(&WebModule::Impl::LogScriptError, base::Unretained(this));
  web_context_->javascript_engine()->RegisterErrorHandler(error_handler);
#endif

  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.require_csp));
  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_->setup_environment_settings(new dom::DOMSettings(
      debugger_hooks_, kDOMMaxElementDepth, media_source_registry_.get(),
      &media_source_settings_, 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);

  // 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_context_->network_module()->GetPostSender(), data.options.require_csp,
      data.options.csp_enforcement_mode,
      base::Bind(&WebModule::Impl::OnCspPolicyChanged, base::Unretained(this)),
      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, 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 !defined(COBALT_FORCE_CSP)
  if (data.options.csp_enforcement_mode == web::kCspEnforcementDisable) {
    // If CSP is disabled, enable eval(). Otherwise, it will be enabled by
    // a CSP directive.
    web_context_->global_environment()->EnableEval();
  }
#endif

  web_context_->global_environment()->SetReportEvalCallback(
      base::Bind(&web::CspDelegate::ReportEval,
                 base::Unretained(window_->csp_delegate())));

  web_context_->global_environment()->SetReportErrorCallback(
      base::Bind(&WebModule::Impl::ReportScriptError, base::Unretained(this)));

  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;

  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();
  animated_image_tracker_.reset();
  dom_parser_.reset();
  css_parser_.reset();
  image_cache_.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);
  }
}

void WebModule::Impl::OnCspPolicyChanged() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);
  DCHECK(window_);
  DCHECK(window_->csp_delegate());

  std::string eval_disabled_message;
  bool allow_eval = window_->csp_delegate()->AllowEval(&eval_disabled_message);
  if (allow_eval) {
    web_context_->global_environment()->EnableEval();
  } else {
    web_context_->global_environment()->DisableEval(eval_disabled_message);
  }
}

bool WebModule::Impl::ReportScriptError(
    const script::ErrorReport& error_report) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(is_running_);
  DCHECK(window_);
  return window_->ReportScriptError(error_report);
}

#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::SetMediaSourceSetting(const std::string& name, int value,
                                            bool* succeeded) {
  DCHECK(succeeded);
  *succeeded = media_source_settings_.Set(name, value);
}

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::LogScriptError(
    const base::SourceLocation& source_location,
    const std::string& error_message) {
  std::string file_name =
      base::FilePath(source_location.file_path).BaseName().value();

  std::stringstream ss;
  base::TimeDelta dt = base::StartupTimer::TimeElapsed();

  // Create the error output.
  // Example:
  //   JS:50250:file.js(29,80): ka(...) is not iterable
  //   JS:<time millis><js-file-name>(<line>,<column>):<message>
  ss << "JS:" << dt.InMilliseconds() << ":" << file_name << "("
     << source_location.line_number << "," << source_location.column_number
     << "): " << error_message << "\n";
  SbLogRaw(ss.str().c_str());
}

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());
      }
      topmost_event_target_->MaybeSendPointerEvents(event);
    }
  } while (event && !layout_manager_->IsRenderTreePending());
}

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

WebModule::WebModule(
    const GURL& initial_url, base::ApplicationState initial_application_state,
    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)
    : 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())) {
  ConstructionData construction_data(
      initial_url, initial_application_state, 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_.reset(
      new web::Agent(options.web_options,
                     base::Bind(&WebModule::Initialize, base::Unretained(this),
                                construction_data),
                     this));
}

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_.reset();
}

void WebModule::Initialize(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);
}

bool WebModule::SetMediaSourceSetting(const std::string& name, int value) {
  bool succeeded = false;
  SetMediaSourceSettingInternal(name, value, &succeeded);
  return succeeded;
}

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);
}

void WebModule::SetMediaSourceSettingInternal(const std::string& name,
                                              int value, bool* succeeded) {
  POST_AND_BLOCK_TO_ENSURE_IMPL_ON_THREAD(SetMediaSourceSettingInternal, name,
                                          value, succeeded);
  impl_->SetMediaSourceSetting(name, value, succeeded);
}

}  // namespace browser
}  // namespace cobalt
