// Copyright 2014 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/browser_module.h"

#include <algorithm>
#include <memory>
#include <vector>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/optional.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/cobalt_paths.h"
#include "cobalt/base/source_location.h"
#include "cobalt/base/tokens.h"
#include "cobalt/browser/on_screen_keyboard_starboard_bridge.h"
#include "cobalt/browser/screen_shot_writer.h"
#include "cobalt/browser/storage_upgrade_handler.h"
#include "cobalt/browser/switches.h"
#include "cobalt/browser/user_agent_string.h"
#include "cobalt/browser/webapi_extension.h"
#include "cobalt/cssom/viewport_size.h"
#include "cobalt/dom/csp_delegate_factory.h"
#include "cobalt/dom/input_event_init.h"
#include "cobalt/dom/keyboard_event_init.h"
#include "cobalt/dom/keycode.h"
#include "cobalt/dom/mutation_observer_task_manager.h"
#include "cobalt/dom/window.h"
#include "cobalt/h5vcc/h5vcc.h"
#include "cobalt/input/input_device_manager_fuzzer.h"
#include "cobalt/overlay_info/overlay_info_registry.h"
#include "nb/memory_scope.h"
#include "starboard/atomic.h"
#include "starboard/common/string.h"
#include "starboard/configuration.h"
#include "starboard/system.h"
#include "starboard/time.h"

#if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
#include "base/memory/ptr_util.h"
#include "starboard/ps4/core_dump_handler.h"
#endif  // SB_HAS(CORE_DUMP_HANDLER_SUPPORT)

using cobalt::cssom::ViewportSize;

namespace cobalt {

#if defined(COBALT_CHECK_RENDER_TIMEOUT)
namespace timestamp {
// This is a temporary workaround.
extern SbAtomic64 g_last_render_timestamp;
}  // namespace timestamp

namespace {
struct NonTrivialGlobalVariables {
  NonTrivialGlobalVariables();

  SbAtomic64* last_render_timestamp;
};

NonTrivialGlobalVariables::NonTrivialGlobalVariables() {
  last_render_timestamp = &cobalt::timestamp::g_last_render_timestamp;
  SbAtomicNoBarrier_Exchange64(last_render_timestamp,
                               static_cast<SbAtomic64>(SbTimeGetNow()));
}

base::LazyInstance<NonTrivialGlobalVariables>::DestructorAtExit
    non_trivial_global_variables = LAZY_INSTANCE_INITIALIZER;
}  // namespace
#endif  // defined(COBALT_CHECK_RENDER_TIMEOUT)

namespace browser {
namespace {

#if defined(COBALT_CHECK_RENDER_TIMEOUT)
// Timeout for last render.
const int kLastRenderTimeoutSeconds = 15;

// Polling interval for timeout_polling_thread_.
const int kRenderTimeOutPollingDelaySeconds = 1;

// Minimum number of continuous times the timeout expirations. This is used to
// prevent unintended behavior in situations such as when returning from
// suspended state. Note that the timeout response trigger will be delayed
// after the actual timeout expiration by this value times the polling delay.
const int kMinimumContinuousRenderTimeoutExpirations = 2;

// Name for timeout_polling_thread_.
const char* kTimeoutPollingThreadName = "TimeoutPolling";

// This specifies the percentage of calls to OnRenderTimeout() that result in a
// call to OnError().
const int kRenderTimeoutErrorPercentage = 99;

#endif

// This constant defines the maximum rate at which the layout engine will
// refresh over time.  Since there is little benefit in performing a layout
// faster than the display's refresh rate, we set this to 60Hz.
const float kLayoutMaxRefreshFrequencyInHz = 60.0f;

// TODO: Subscribe to viewport size changes.

const int kMainWebModuleZIndex = 1;
const int kSplashScreenZIndex = 2;
#if defined(ENABLE_DEBUGGER)
const int kDebugConsoleZIndex = 3;
#endif  // defined(ENABLE_DEBUGGER)
const int kOverlayInfoZIndex = 4;

#if defined(ENABLE_DEBUGGER)

const char kFuzzerToggleCommand[] = "fuzzer_toggle";
const char kFuzzerToggleCommandShortHelp[] = "Toggles the input fuzzer on/off.";
const char kFuzzerToggleCommandLongHelp[] =
    "Each time this is called, it will toggle whether the input fuzzer is "
    "activated or not.  While activated, input will constantly and randomly be "
    "generated and passed directly into the main web module.";

const char kSetMediaConfigCommand[] = "set_media_config";
const char kSetMediaConfigCommandShortHelp[] =
    "Sets media module configuration.";
const char kSetMediaConfigCommandLongHelp[] =
    "This can be called in the form of set_media_config('name=value'), where "
    "name is a string and value is an int.  Refer to the implementation of "
    "MediaModule::SetConfiguration() on individual platform for settings "
    "supported on the particular platform.";

const char kScreenshotCommand[] = "screenshot";
const char kScreenshotCommandShortHelp[] = "Takes a screenshot.";
const char kScreenshotCommandLongHelp[] =
    "Creates a screenshot of the most recent layout tree and writes it "
    "to disk. Logs the filename of the screenshot to the console when done.";

// Debug console command `disable_media_codecs` for disabling a list of codecs
// by treating them as unsupported
const char kDisableMediaCodecsCommand[] = "disable_media_codecs";
const char kDisableMediaCodecsCommandShortHelp[] =
    "Specify a semicolon-seperated list of disabled media codecs.";
const char kDisableMediaCodecsCommandLongHelp[] =
    "Disabling Media Codecs will force the app to claim they are not "
    "supported. This "
    "is useful when trying to target testing to certain codecs, since other "
    "codecs will get picked as a fallback as a result.";

void ScreenshotCompleteCallback(const base::FilePath& output_path) {
  DLOG(INFO) << "Screenshot written to " << output_path.value();
}

void OnScreenshotMessage(BrowserModule* browser_module,
                         const std::string& message) {
  SB_UNREFERENCED_PARAMETER(message);
  base::FilePath dir;
  if (!base::PathService::Get(cobalt::paths::DIR_COBALT_DEBUG_OUT, &dir)) {
    NOTREACHED() << "Failed to get debug out directory.";
  }

  base::Time::Exploded exploded;
  base::Time::Now().LocalExplode(&exploded);
  DCHECK(exploded.HasValidValues());
  std::string screenshot_file_name =
      base::StringPrintf("screenshot-%04d-%02d-%02d_%02d-%02d-%02d.png",
                         exploded.year, exploded.month, exploded.day_of_month,
                         exploded.hour, exploded.minute, exploded.second);

  base::FilePath output_path = dir.Append(screenshot_file_name);
  browser_module->RequestScreenshotToFile(
      output_path, loader::image::EncodedStaticImage::ImageFormat::kPNG,
      /*clip_rect=*/base::nullopt,
      base::Bind(&ScreenshotCompleteCallback, output_path));
}

#endif  // defined(ENABLE_DEBUGGER)

scoped_refptr<script::Wrappable> CreateH5VCC(
    const h5vcc::H5vcc::Settings& settings,
    const scoped_refptr<dom::Window>& window,
    dom::MutationObserverTaskManager* mutation_observer_task_manager,
    script::GlobalEnvironment* global_environment) {
  SB_UNREFERENCED_PARAMETER(global_environment);
  return scoped_refptr<script::Wrappable>(
      new h5vcc::H5vcc(settings, window, mutation_observer_task_manager));
}

scoped_refptr<script::Wrappable> CreateExtensionInterface(
    const scoped_refptr<dom::Window>& window,
    dom::MutationObserverTaskManager* mutation_observer_task_manager,
    script::GlobalEnvironment* global_environment) {
  SB_UNREFERENCED_PARAMETER(mutation_observer_task_manager);
  return CreateWebAPIExtensionObject(window, global_environment);
}

renderer::RendererModule::Options RendererModuleWithCameraOptions(
    renderer::RendererModule::Options options,
    scoped_refptr<input::Camera3D> camera_3d) {
  options.get_camera_transform = base::Bind(
      &input::Camera3D::GetCameraTransformAndUpdateOrientation, camera_3d);
  return options;  // Copy.
}

renderer::Submission CreateSubmissionFromLayoutResults(
    const browser::WebModule::LayoutResults& layout_results) {
  renderer::Submission renderer_submission(layout_results.render_tree,
                                           layout_results.layout_time);
  if (!layout_results.on_rasterized_callback.is_null()) {
    renderer_submission.on_rasterized_callbacks.push_back(
        layout_results.on_rasterized_callback);
  }
  return renderer_submission;
}

}  // namespace

BrowserModule::BrowserModule(const GURL& url,
                             base::ApplicationState initial_application_state,
                             base::EventDispatcher* event_dispatcher,
                             account::AccountManager* account_manager,
                             const Options& options)
    : ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          weak_this_(weak_ptr_factory_.GetWeakPtr())),
      options_(options),
      self_message_loop_(base::MessageLoop::current()),
      event_dispatcher_(event_dispatcher),
      storage_manager_(std::unique_ptr<storage::StorageManager::UpgradeHandler>(
                           new StorageUpgradeHandler(url)),
                       options_.storage_manager_options),
      is_rendered_(false),
      can_play_type_handler_(media::MediaModule::CreateCanPlayTypeHandler()),
      network_module_(
          CreateUserAgentString(GetUserAgentPlatformInfoFromSystem()),
          &storage_manager_, event_dispatcher_,
          options_.network_module_options),
      splash_screen_cache_(new SplashScreenCache()),
#if SB_HAS(ON_SCREEN_KEYBOARD)
      on_screen_keyboard_bridge_(
          options.enable_on_screen_keyboard
              ? new OnScreenKeyboardStarboardBridge(base::Bind(
                    &BrowserModule::GetSbWindow, base::Unretained(this)))
              : NULL),
#endif  // SB_HAS(ON_SCREEN_KEYBOARD)
      web_module_loaded_(base::WaitableEvent::ResetPolicy::MANUAL,
                         base::WaitableEvent::InitialState::NOT_SIGNALED),
      web_module_recreated_callback_(options_.web_module_recreated_callback),
      navigate_time_("Time.Browser.Navigate", 0,
                     "The last time a navigation occurred."),
      on_load_event_time_("Time.Browser.OnLoadEvent", 0,
                          "The last time the window.OnLoad event fired."),
      javascript_reserved_memory_(
          "Memory.JS", 0,
          "The total memory that is reserved by the JavaScript engine, which "
          "includes both parts that have live JavaScript values, as well as "
          "preallocated space for future values."),
      disabled_media_codecs_(
          "Media.DisabledMediaCodecs", "",
          "List of codecs that should currently be reported as unsupported."),
#if defined(ENABLE_DEBUGGER)
      ALLOW_THIS_IN_INITIALIZER_LIST(fuzzer_toggle_command_handler_(
          kFuzzerToggleCommand,
          base::Bind(&BrowserModule::OnFuzzerToggle, base::Unretained(this)),
          kFuzzerToggleCommandShortHelp, kFuzzerToggleCommandLongHelp)),
      ALLOW_THIS_IN_INITIALIZER_LIST(set_media_config_command_handler_(
          kSetMediaConfigCommand,
          base::Bind(&BrowserModule::OnSetMediaConfig, base::Unretained(this)),
          kSetMediaConfigCommandShortHelp, kSetMediaConfigCommandLongHelp)),
      ALLOW_THIS_IN_INITIALIZER_LIST(screenshot_command_handler_(
          kScreenshotCommand,
          base::Bind(&OnScreenshotMessage, base::Unretained(this)),
          kScreenshotCommandShortHelp, kScreenshotCommandLongHelp)),
      ALLOW_THIS_IN_INITIALIZER_LIST(disable_media_codecs_command_handler_(
          kDisableMediaCodecsCommand,
          base::Bind(&BrowserModule::OnDisableMediaCodecs,
                     base::Unretained(this)),
          kDisableMediaCodecsCommandShortHelp,
          kDisableMediaCodecsCommandLongHelp)),
#endif  // defined(ENABLE_DEBUGGER)
      has_resumed_(base::WaitableEvent::ResetPolicy::MANUAL,
                   base::WaitableEvent::InitialState::NOT_SIGNALED),
#if defined(COBALT_CHECK_RENDER_TIMEOUT)
      timeout_polling_thread_(kTimeoutPollingThreadName),
      render_timeout_count_(0),
#endif
      on_error_retry_count_(0),
      waiting_for_error_retry_(false),
      will_quit_(false),
      application_state_(initial_application_state),
      main_web_module_generation_(0),
      next_timeline_id_(1),
      current_splash_screen_timeline_id_(-1),
      current_main_web_module_timeline_id_(-1),
      web_module_loaded_callback_(options_.web_module_loaded_callback) {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::BrowserModule()");

  // Apply platform memory setting adjustments and defaults.
  ApplyAutoMemSettings();

#if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
  SbCoreDumpRegisterHandler(BrowserModule::CoreDumpHandler, this);
  on_error_triggered_count_ = 0;
#if defined(COBALT_CHECK_RENDER_TIMEOUT)
  recovery_mechanism_triggered_count_ = 0;
  timeout_response_trigger_count_ = 0;
#endif  // defined(COBALT_CHECK_RENDER_TIMEOUT)
#endif  // SB_HAS(CORE_DUMP_HANDLER_SUPPORT)

#if defined(COBALT_CHECK_RENDER_TIMEOUT)
  timeout_polling_thread_.Start();
  timeout_polling_thread_.message_loop()->task_runner()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&BrowserModule::OnPollForRenderTimeout, base::Unretained(this),
                 url),
      base::TimeDelta::FromSeconds(kRenderTimeOutPollingDelaySeconds));
#endif

  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();

  // Create the main web module layer.
  main_web_module_layer_ =
      render_tree_combiner_.CreateLayer(kMainWebModuleZIndex);
  // Create the splash screen layer.
  splash_screen_layer_ = render_tree_combiner_.CreateLayer(kSplashScreenZIndex);
// Create the debug console layer.
#if defined(ENABLE_DEBUGGER)
  debug_console_layer_ = render_tree_combiner_.CreateLayer(kDebugConsoleZIndex);
#endif
  if (command_line->HasSwitch(browser::switches::kQrCodeOverlay)) {
    qr_overlay_info_layer_ =
        render_tree_combiner_.CreateLayer(kOverlayInfoZIndex);
  } else {
    overlay_info::OverlayInfoRegistry::Disable();
  }

  // Setup our main web module to have the H5VCC API injected into it.
  DCHECK(!ContainsKey(options_.web_module_options.injected_window_attributes,
                      "h5vcc"));
  h5vcc::H5vcc::Settings h5vcc_settings;
  h5vcc_settings.media_module = media_module_.get();
  h5vcc_settings.network_module = &network_module_;
  h5vcc_settings.account_manager = account_manager;
  h5vcc_settings.event_dispatcher = event_dispatcher_;
  h5vcc_settings.initial_deep_link = options_.initial_deep_link;
  options_.web_module_options.injected_window_attributes["h5vcc"] =
      base::Bind(&CreateH5VCC, h5vcc_settings);

  if (command_line->HasSwitch(switches::kDisableTimerResolutionLimit)) {
    options_.web_module_options.limit_performance_timer_resolution = false;
  }

#if defined(ENABLE_PARTIAL_LAYOUT_CONTROL)
  options_.web_module_options.enable_partial_layout =
      !command_line->HasSwitch(switches::kDisablePartialLayout);
#endif  // defined(ENABLE_PARTIAL_LAYOUT_CONTROL)

  base::Optional<std::string> extension_object_name =
      GetWebAPIExtensionObjectPropertyName();
  if (extension_object_name) {
    options_.web_module_options
        .injected_window_attributes[*extension_object_name] =
        base::Bind(&CreateExtensionInterface);
  }

#if defined(ENABLE_DEBUGGER) && defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  if (command_line->HasSwitch(switches::kInputFuzzer)) {
    OnFuzzerToggle(std::string());
  }
  if (command_line->HasSwitch(switches::kSuspendFuzzer)) {
    suspend_fuzzer_.emplace();
  }
#endif  // ENABLE_DEBUGGER && ENABLE_DEBUG_COMMAND_LINE_SWITCHES

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  if (command_line->HasSwitch(switches::kDisableMediaCodecs)) {
    std::string codecs =
        command_line->GetSwitchValueASCII(switches::kDisableMediaCodecs);
    if (!codecs.empty()) {
#if defined(ENABLE_DEBUGGER)
      OnDisableMediaCodecs(codecs);
#else   // ENABLE_DEBUGGER
      // Here command line switches are enabled but the debug console is not.
      can_play_type_handler_->SetDisabledMediaCodecs(codecs);
#endif  // ENABLE_DEBUGGER
    }
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES

  if (application_state_ == base::kApplicationStateStarted ||
      application_state_ == base::kApplicationStatePaused) {
    InitializeSystemWindow();
  } else if (application_state_ == base::kApplicationStatePreloading) {
    resource_provider_stub_.emplace(true /*allocate_image_data*/);
  }

#if defined(ENABLE_DEBUGGER)
  debug_console_.reset(new DebugConsole(
      application_state_,
      base::Bind(&BrowserModule::QueueOnDebugConsoleRenderTreeProduced,
                 base::Unretained(this)),
      &network_module_, GetViewportSize(), GetResourceProvider(),
      kLayoutMaxRefreshFrequencyInHz,
      base::Bind(&BrowserModule::CreateDebugClient, base::Unretained(this))));
  lifecycle_observers_.AddObserver(debug_console_.get());
#endif  // defined(ENABLE_DEBUGGER)

  if (command_line->HasSwitch(switches::kEnableMapToMeshRectanglar)) {
    options_.web_module_options.enable_map_to_mesh_rectangular = true;
  }

  if (qr_overlay_info_layer_) {
    math::Size width_height = GetViewportSize().width_height();
    qr_code_overlay_.reset(new overlay_info::QrCodeOverlay(
        width_height, GetResourceProvider(),
        base::Bind(&BrowserModule::QueueOnQrCodeOverlayRenderTreeProduced,
                   base::Unretained(this))));
  }

  fallback_splash_screen_url_ = options.fallback_splash_screen_url;

  // Synchronously construct our WebModule object.
  Navigate(url);
  DCHECK(web_module_);
}

BrowserModule::~BrowserModule() {
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);

  // Transition into the suspended state from whichever state we happen to
  // currently be in, to prepare for shutdown.
  switch (application_state_) {
    case base::kApplicationStateStarted:
      Pause();
    // Intentional fall-through.
    case base::kApplicationStatePaused:
    case base::kApplicationStatePreloading:
      Suspend();
      break;
    case base::kApplicationStateStopped:
      NOTREACHED() << "BrowserModule does not support the stopped state.";
      break;
    case base::kApplicationStateSuspended:
      break;
  }

  on_error_retry_timer_.Stop();
#if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
  SbCoreDumpUnregisterHandler(BrowserModule::CoreDumpHandler, this);
#endif
}

void BrowserModule::Navigate(const GURL& url_reference) {
  // The argument is sometimes |pending_navigate_url_|, and Navigate can modify
  // |pending_navigate_url_|, so we want to keep a copy of the argument to
  // preserve its original value.
  GURL url = url_reference;
  DLOG(INFO) << "In BrowserModule::Navigate " << url;
  TRACE_EVENT1("cobalt::browser", "BrowserModule::Navigate()", "url",
               url.spec());
  // Reset the waitable event regardless of the thread. This ensures that the
  // webdriver won't incorrectly believe that the webmodule has finished loading
  // when it calls Navigate() and waits for the |web_module_loaded_| signal.
  web_module_loaded_.Reset();

  // Repost to our own message loop if necessary.
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&BrowserModule::Navigate, weak_this_, url));
    return;
  }

  // First try the registered handlers (e.g. for h5vcc://). If one of these
  // handles the URL, we don't use the web module.
  if (TryURLHandlers(url)) {
    return;
  }

  // Clear error handling once we're told to navigate, either because it's the
  // retry from the error or something decided we should navigate elsewhere.
  on_error_retry_timer_.Stop();
  waiting_for_error_retry_ = false;

  // Navigations aren't allowed if the app is suspended. If this is the case,
  // simply set the pending navigate url, which will cause the navigation to
  // occur when Cobalt resumes, and return.
  if (application_state_ == base::kApplicationStateSuspended) {
    pending_navigate_url_ = url;
    return;
  }

  // Now that we know the navigation is occurring, clear out
  // |pending_navigate_url_|.
  pending_navigate_url_ = GURL::EmptyGURL();

#if defined(ENABLE_DEBUGGER)
  // Save the debugger state to be restored in the new WebModule.
  std::unique_ptr<debug::backend::DebuggerState> debugger_state;
  if (web_module_) {
    debugger_state = web_module_->FreezeDebugger();
  }
#endif  // defined(ENABLE_DEBUGGER)

  // Destroy old WebModule first, so we don't get a memory high-watermark after
  // the second WebModule's constructor runs, but before
  // std::unique_ptr::reset() is run.
  if (web_module_) {
    lifecycle_observers_.RemoveObserver(web_module_.get());
  }
  web_module_.reset(NULL);

  // Increment the navigation generation so that we can attach it to event
  // callbacks as a way of identifying the new web module from the old ones.
  ++main_web_module_generation_;
  current_splash_screen_timeline_id_ = next_timeline_id_++;
  current_main_web_module_timeline_id_ = next_timeline_id_++;

  main_web_module_layer_->Reset();

  // Wait until after the old WebModule is destroyed before setting the navigate
  // time so that it won't be included in the time taken to load the URL.
  navigate_time_ = base::TimeTicks::Now().ToInternalValue();

  // Show a splash screen while we're waiting for the web page to load.
  const ViewportSize viewport_size = GetViewportSize();

  DestroySplashScreen(base::TimeDelta());
  if (options_.enable_splash_screen_on_reloads ||
      main_web_module_generation_ == 1) {
    base::Optional<std::string> key = SplashScreenCache::GetKeyForStartUrl(url);
    if (fallback_splash_screen_url_ ||
        (key && splash_screen_cache_->IsSplashScreenCached(*key))) {
      splash_screen_.reset(new SplashScreen(
          application_state_,
          base::Bind(&BrowserModule::QueueOnSplashScreenRenderTreeProduced,
                     base::Unretained(this)),
          &network_module_, viewport_size, GetResourceProvider(),
          kLayoutMaxRefreshFrequencyInHz, fallback_splash_screen_url_, url,
          splash_screen_cache_.get(),
          base::Bind(&BrowserModule::DestroySplashScreen, weak_this_)));
      lifecycle_observers_.AddObserver(splash_screen_.get());
    }
  }

  // Create new WebModule.
#if !defined(COBALT_FORCE_CSP)
  options_.web_module_options.csp_insecure_allowed_token =
      dom::CspDelegateFactory::GetInsecureAllowedToken();
#endif
  WebModule::Options options(options_.web_module_options);
  options.splash_screen_cache = splash_screen_cache_.get();
  options.navigation_callback =
      base::Bind(&BrowserModule::Navigate, base::Unretained(this));
  options.loaded_callbacks.push_back(
      base::Bind(&BrowserModule::OnLoad, base::Unretained(this)));
#if defined(ENABLE_FAKE_MICROPHONE)
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kFakeMicrophone)) {
    options.dom_settings_options.microphone_options.enable_fake_microphone =
        true;
  }
#endif  // defined(ENABLE_FAKE_MICROPHONE)
  if (on_screen_keyboard_bridge_) {
    options.on_screen_keyboard_bridge = on_screen_keyboard_bridge_.get();
  }
  options.image_cache_capacity_multiplier_when_playing_video =
      COBALT_IMAGE_CACHE_CAPACITY_MULTIPLIER_WHEN_PLAYING_VIDEO;
  if (input_device_manager_) {
    options.camera_3d = input_device_manager_->camera_3d();
  }

  float video_pixel_ratio = 1.0f;
  if (system_window_) {
    video_pixel_ratio = system_window_->GetVideoPixelRatio();
  }

  // Make sure that automem has been run before creating the WebModule, so that
  // we use properly configured options for all parameters.
  DCHECK(auto_mem_);

  options.provide_screenshot_function =
      base::Bind(&ScreenShotWriter::RequestScreenshotToMemoryUnencoded,
                 base::Unretained(screen_shot_writer_.get()));

#if defined(ENABLE_DEBUGGER)
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kWaitForWebDebugger)) {
    int wait_for_generation =
        SbStringAToI(base::CommandLine::ForCurrentProcess()
                         ->GetSwitchValueASCII(switches::kWaitForWebDebugger)
                         .c_str());
    if (wait_for_generation < 1) wait_for_generation = 1;
    options.wait_for_web_debugger =
        (wait_for_generation == main_web_module_generation_);
  }

  options.debugger_state = debugger_state.get();
#endif  // ENABLE_DEBUGGER

  web_module_.reset(new WebModule(
      url, application_state_,
      base::Bind(&BrowserModule::QueueOnRenderTreeProduced,
                 base::Unretained(this), main_web_module_generation_),
      base::Bind(&BrowserModule::OnError, base::Unretained(this)),
      base::Bind(&BrowserModule::OnWindowClose, base::Unretained(this)),
      base::Bind(&BrowserModule::OnWindowMinimize, base::Unretained(this)),
      can_play_type_handler_.get(), media_module_.get(), &network_module_,
      viewport_size, video_pixel_ratio, GetResourceProvider(),
      kLayoutMaxRefreshFrequencyInHz, options));
  lifecycle_observers_.AddObserver(web_module_.get());
  if (!web_module_recreated_callback_.is_null()) {
    web_module_recreated_callback_.Run();
  }

  if (system_window_) {
    web_module_->GetUiNavRoot()->SetContainerWindow(
        system_window_->GetSbWindow());
  }
}

void BrowserModule::Reload() {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::Reload()");
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  DCHECK(web_module_);
  web_module_->ExecuteJavascript(
      "location.reload();",
      base::SourceLocation("[object BrowserModule]", 1, 1),
      NULL /* output: succeeded */);
}

#if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
// static
void BrowserModule::CoreDumpHandler(void* browser_module_as_void) {
  BrowserModule* browser_module =
      static_cast<BrowserModule*>(browser_module_as_void);
  SbCoreDumpLogInteger("BrowserModule.on_error_triggered_count_",
                       browser_module->on_error_triggered_count_);
#if defined(COBALT_CHECK_RENDER_TIMEOUT)
  SbCoreDumpLogInteger("BrowserModule.recovery_mechanism_triggered_count_",
                       browser_module->recovery_mechanism_triggered_count_);
  SbCoreDumpLogInteger("BrowserModule.timeout_response_trigger_count_",
                       browser_module->timeout_response_trigger_count_);
#endif  // defined(COBALT_CHECK_RENDER_TIMEOUT)
}
#endif  // SB_HAS(CORE_DUMP_HANDLER_SUPPORT)

void BrowserModule::OnLoad() {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::OnLoad()");
  // Repost to our own message loop if necessary. This also prevents
  // asynchronous access to this object by |web_module_| during destruction.
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&BrowserModule::OnLoad, weak_this_));
    return;
  }

  // This log is relied on by the webdriver benchmark tests, so it shouldn't be
  // changed unless the corresponding benchmark logic is changed as well.
  LOG(INFO) << "Loaded WebModule";

  // Clear |on_error_retry_count_| after a successful load.
  on_error_retry_count_ = 0;

  on_load_event_time_ = base::TimeTicks::Now().ToInternalValue();

  web_module_loaded_.Signal();

  if (!web_module_loaded_callback_.is_null()) {
    web_module_loaded_callback_.Run();
  }
}

bool BrowserModule::WaitForLoad(const base::TimeDelta& timeout) {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::WaitForLoad()");
  return web_module_loaded_.TimedWait(timeout);
}

void BrowserModule::RequestScreenshotToFile(
    const base::FilePath& path,
    loader::image::EncodedStaticImage::ImageFormat image_format,
    const base::Optional<math::Rect>& clip_rect,
    const base::Closure& done_callback) {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::RequestScreenshotToFile()");
  DCHECK(screen_shot_writer_);

  scoped_refptr<render_tree::Node> render_tree = GetLastSubmissionAnimated();
  if (!render_tree) {
    LOG(WARNING) << "Unable to get animated render tree";
    return;
  }

  screen_shot_writer_->RequestScreenshotToFile(image_format, path, render_tree,
                                               clip_rect, done_callback);
}

void BrowserModule::RequestScreenshotToMemory(
    loader::image::EncodedStaticImage::ImageFormat image_format,
    const base::Optional<math::Rect>& clip_rect,
    const ScreenShotWriter::ImageEncodeCompleteCallback& screenshot_ready) {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::RequestScreenshotToMemory()");
  DCHECK(screen_shot_writer_);

  scoped_refptr<render_tree::Node> render_tree = GetLastSubmissionAnimated();
  if (!render_tree) {
    LOG(WARNING) << "Unable to get animated render tree";
    return;
  }

  screen_shot_writer_->RequestScreenshotToMemory(image_format, render_tree,
                                                 clip_rect, screenshot_ready);
}

scoped_refptr<render_tree::Node> BrowserModule::GetLastSubmissionAnimated() {
  DCHECK(main_web_module_layer_);
  base::Optional<renderer::Submission> last_submission =
      main_web_module_layer_->GetCurrentSubmission();
  if (!last_submission) {
    LOG(WARNING) << "Unable to find last submission.";
    return nullptr;
  }
  DCHECK(last_submission->render_tree);

  render_tree::animations::AnimateNode* animate_node =
      base::polymorphic_downcast<render_tree::animations::AnimateNode*>(
          last_submission->render_tree.get());
  render_tree::animations::AnimateNode::AnimateResults results =
      animate_node->Apply(last_submission->time_offset);

  return results.animated->source();
}

void BrowserModule::ProcessRenderTreeSubmissionQueue() {
  TRACE_EVENT0("cobalt::browser",
               "BrowserModule::ProcessRenderTreeSubmissionQueue()");
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  render_tree_submission_queue_.ProcessAll();
}

void BrowserModule::QueueOnRenderTreeProduced(
    int main_web_module_generation,
    const browser::WebModule::LayoutResults& layout_results) {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::QueueOnRenderTreeProduced()");
  render_tree_submission_queue_.AddMessage(
      base::Bind(&BrowserModule::OnRenderTreeProduced, base::Unretained(this),
                 main_web_module_generation, layout_results));
  self_message_loop_->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&BrowserModule::ProcessRenderTreeSubmissionQueue, weak_this_));
}

void BrowserModule::QueueOnSplashScreenRenderTreeProduced(
    const browser::WebModule::LayoutResults& layout_results) {
  TRACE_EVENT0("cobalt::browser",
               "BrowserModule::QueueOnSplashScreenRenderTreeProduced()");
  render_tree_submission_queue_.AddMessage(
      base::Bind(&BrowserModule::OnSplashScreenRenderTreeProduced,
                 base::Unretained(this), layout_results));
  self_message_loop_->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&BrowserModule::ProcessRenderTreeSubmissionQueue, weak_this_));
}

void BrowserModule::OnRenderTreeProduced(
    int main_web_module_generation,
    const browser::WebModule::LayoutResults& layout_results) {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::OnRenderTreeProduced()");
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);

  if (main_web_module_generation != main_web_module_generation_) {
    // Ignore render trees produced by old stale web modules.  This might happen
    // during a navigation transition.
    return;
  }

  if (splash_screen_) {
    if (on_screen_keyboard_show_called_) {
      // Hide the splash screen as quickly as possible.
      DestroySplashScreen(base::TimeDelta());
    } else if (!splash_screen_->ShutdownSignaled()) {
      splash_screen_->Shutdown();
    }
  }
  if (application_state_ == base::kApplicationStatePreloading) {
    layout_results.on_rasterized_callback.Run();
    return;
  }

  renderer::Submission renderer_submission(
      CreateSubmissionFromLayoutResults(layout_results));

  // Set the timeline id for the main web module.  The main web module is
  // assumed to be an interactive experience for which the default timeline
  // configuration is already designed for, so we don't configure anything
  // explicitly.
  renderer_submission.timeline_info.id = current_main_web_module_timeline_id_;

  renderer_submission.on_rasterized_callbacks.push_back(base::Bind(
      &BrowserModule::OnRendererSubmissionRasterized, base::Unretained(this)));

  if (!splash_screen_) {
    render_tree_combiner_.SetTimelineLayer(main_web_module_layer_.get());
  }
  main_web_module_layer_->Submit(renderer_submission);

  SubmitCurrentRenderTreeToRenderer();
}

void BrowserModule::OnSplashScreenRenderTreeProduced(
    const browser::WebModule::LayoutResults& layout_results) {
  TRACE_EVENT0("cobalt::browser",
               "BrowserModule::OnSplashScreenRenderTreeProduced()");
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);

  if (application_state_ == base::kApplicationStatePreloading ||
      !splash_screen_) {
    return;
  }

  renderer::Submission renderer_submission(
      CreateSubmissionFromLayoutResults(layout_results));

  // We customize some of the renderer pipeline timeline behavior to cater for
  // non-interactive splash screen playback.
  renderer_submission.timeline_info.id = current_splash_screen_timeline_id_;
  // Since the splash screen is non-interactive, latency is not a concern.
  // Latency reduction implies a speedup in animation playback speed which can
  // make the splash screen play out quicker than intended.
  renderer_submission.timeline_info.allow_latency_reduction = false;
  // Increase the submission queue size to a larger value than usual.  This
  // is done because a) since we do not attempt to reduce latency, the queue
  // tends to fill up more and b) the pipeline may end up receiving a number
  // of render tree submissions caused by updated main web module render trees,
  // which can fill the submission queue.  Blowing the submission queue is
  // particularly bad for the splash screen as it results in dropping of older
  // submissions, which results in skipping forward during animations, which
  // sucks.
  renderer_submission.timeline_info.max_submission_queue_size =
      std::max(8, renderer_submission.timeline_info.max_submission_queue_size);

  renderer_submission.on_rasterized_callbacks.push_back(base::Bind(
      &BrowserModule::OnRendererSubmissionRasterized, base::Unretained(this)));

  render_tree_combiner_.SetTimelineLayer(splash_screen_layer_.get());
  splash_screen_layer_->Submit(renderer_submission);

  // TODO: write screen shot using render_tree_combiner_ (to combine
  // splash screen and main web_module). Consider when the splash
  // screen is overlaid on top of the main web module render tree, and
  // a screenshot is taken : there will be a race condition on which
  // web module update their render tree last.

  SubmitCurrentRenderTreeToRenderer();
}

void BrowserModule::QueueOnQrCodeOverlayRenderTreeProduced(
    const scoped_refptr<render_tree::Node>& render_tree) {
  TRACE_EVENT0("cobalt::browser",
               "BrowserModule::QueueOnQrCodeOverlayRenderTreeProduced()");
  render_tree_submission_queue_.AddMessage(
      base::Bind(&BrowserModule::OnQrCodeOverlayRenderTreeProduced,
                 base::Unretained(this), render_tree));
  self_message_loop_->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&BrowserModule::ProcessRenderTreeSubmissionQueue, weak_this_));
}

void BrowserModule::OnQrCodeOverlayRenderTreeProduced(
    const scoped_refptr<render_tree::Node>& render_tree) {
  TRACE_EVENT0("cobalt::browser",
               "BrowserModule::OnQrCodeOverlayRenderTreeProduced()");
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  DCHECK(qr_overlay_info_layer_);

  if (application_state_ == base::kApplicationStatePreloading) {
    return;
  }

  qr_overlay_info_layer_->Submit(renderer::Submission(render_tree));

  SubmitCurrentRenderTreeToRenderer();
}

void BrowserModule::OnWindowClose(base::TimeDelta close_time) {
#if defined(ENABLE_DEBUGGER)
  if (input_device_manager_fuzzer_) {
    return;
  }
#endif

  SbSystemRequestStop(0);
}

void BrowserModule::OnWindowMinimize() {
#if defined(ENABLE_DEBUGGER)
  if (input_device_manager_fuzzer_) {
    return;
  }
#endif

  SbSystemRequestSuspend();
}

#if SB_API_VERSION >= 8
void BrowserModule::OnWindowSizeChanged(const ViewportSize& viewport_size,
                                        float video_pixel_ratio) {
  if (web_module_) {
    web_module_->SetSize(viewport_size, video_pixel_ratio);
  }
#if defined(ENABLE_DEBUGGER)
  if (debug_console_) {
    debug_console_->web_module().SetSize(viewport_size, video_pixel_ratio);
  }
#endif  // defined(ENABLE_DEBUGGER)
  if (splash_screen_) {
    splash_screen_->web_module().SetSize(viewport_size, video_pixel_ratio);
  }

  return;
}
#endif  // SB_API_VERSION >= 8

#if SB_HAS(ON_SCREEN_KEYBOARD)
void BrowserModule::OnOnScreenKeyboardShown(
    const base::OnScreenKeyboardShownEvent* event) {
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  // Only inject shown events to the main WebModule.
  on_screen_keyboard_show_called_ = true;
  if (splash_screen_ && splash_screen_->ShutdownSignaled()) {
    DestroySplashScreen(base::TimeDelta());
  }
  if (web_module_) {
    web_module_->InjectOnScreenKeyboardShownEvent(event->ticket());
  }
}

void BrowserModule::OnOnScreenKeyboardHidden(
    const base::OnScreenKeyboardHiddenEvent* event) {
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  // Only inject hidden events to the main WebModule.
  if (web_module_) {
    web_module_->InjectOnScreenKeyboardHiddenEvent(event->ticket());
  }
}

void BrowserModule::OnOnScreenKeyboardFocused(
    const base::OnScreenKeyboardFocusedEvent* event) {
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  // Only inject focused events to the main WebModule.
  if (web_module_) {
    web_module_->InjectOnScreenKeyboardFocusedEvent(event->ticket());
  }
}

void BrowserModule::OnOnScreenKeyboardBlurred(
    const base::OnScreenKeyboardBlurredEvent* event) {
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  // Only inject blurred events to the main WebModule.
  if (web_module_) {
    web_module_->InjectOnScreenKeyboardBlurredEvent(event->ticket());
  }
}

#if SB_API_VERSION >= 11
void BrowserModule::OnOnScreenKeyboardSuggestionsUpdated(
    const base::OnScreenKeyboardSuggestionsUpdatedEvent* event) {
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  // Only inject updated suggestions events to the main WebModule.
  if (web_module_) {
    web_module_->InjectOnScreenKeyboardSuggestionsUpdatedEvent(event->ticket());
  }
}
#endif  // SB_API_VERSION >= 11
#endif  // SB_HAS(ON_SCREEN_KEYBOARD)

#if SB_HAS(CAPTIONS)
void BrowserModule::OnCaptionSettingsChanged(
    const base::AccessibilityCaptionSettingsChangedEvent* /*event*/) {
  if (web_module_) {
    web_module_->InjectCaptionSettingsChangedEvent();
  }
}
#endif  // SB_HAS(CAPTIONS)

#if defined(ENABLE_DEBUGGER)
void BrowserModule::OnFuzzerToggle(const std::string& message) {
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&BrowserModule::OnFuzzerToggle, weak_this_, message));
    return;
  }

  if (!input_device_manager_fuzzer_) {
    // Wire up the input fuzzer key generator to the keyboard event callback.
    input_device_manager_fuzzer_ = std::unique_ptr<input::InputDeviceManager>(
        new input::InputDeviceManagerFuzzer(
            base::Bind(&BrowserModule::InjectKeyEventToMainWebModule,
                       base::Unretained(this))));
  } else {
    input_device_manager_fuzzer_.reset();
  }
}

void BrowserModule::OnSetMediaConfig(const std::string& config) {
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&BrowserModule::OnSetMediaConfig, weak_this_, config));
    return;
  }

  std::vector<std::string> tokens = base::SplitString(
      config, "=", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

  int value;
  if (tokens.size() != 2 || !base::StringToInt(tokens[1], &value)) {
    LOG(WARNING) << "Media configuration '" << config << "' is not in the"
                 << " form of '<string name>=<int value>'.";
    return;
  }
  if (media_module_->SetConfiguration(tokens[0], value)) {
    LOG(INFO) << "Successfully setting " << tokens[0] << " to " << value;
  } else {
    LOG(WARNING) << "Failed to set " << tokens[0] << " to " << value;
  }
}

void BrowserModule::OnDisableMediaCodecs(const std::string& codecs) {
  disabled_media_codecs_ = codecs;
  can_play_type_handler_->SetDisabledMediaCodecs(codecs);
}

void BrowserModule::QueueOnDebugConsoleRenderTreeProduced(
    const browser::WebModule::LayoutResults& layout_results) {
  TRACE_EVENT0("cobalt::browser",
               "BrowserModule::QueueOnDebugConsoleRenderTreeProduced()");
  render_tree_submission_queue_.AddMessage(
      base::Bind(&BrowserModule::OnDebugConsoleRenderTreeProduced,
                 base::Unretained(this), layout_results));
  self_message_loop_->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&BrowserModule::ProcessRenderTreeSubmissionQueue, weak_this_));
}

void BrowserModule::OnDebugConsoleRenderTreeProduced(
    const browser::WebModule::LayoutResults& layout_results) {
  TRACE_EVENT0("cobalt::browser",
               "BrowserModule::OnDebugConsoleRenderTreeProduced()");
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  if (application_state_ == base::kApplicationStatePreloading) {
    return;
  }

  if (debug_console_->GetMode() == debug::console::DebugHub::kDebugConsoleOff) {
    // If the layer already has no render tree then simply return. In that case
    // nothing is changing.
    if (!debug_console_layer_->HasRenderTree()) {
      return;
    }
    debug_console_layer_->Submit(base::nullopt);
  } else {
    debug_console_layer_->Submit(
        CreateSubmissionFromLayoutResults(layout_results));
  }

  SubmitCurrentRenderTreeToRenderer();
}

#endif  // defined(ENABLE_DEBUGGER)

#if SB_HAS(ON_SCREEN_KEYBOARD)
void BrowserModule::OnOnScreenKeyboardInputEventProduced(
    base::Token type, const dom::InputEventInit& event) {
  TRACE_EVENT0("cobalt::browser",
               "BrowserModule::OnOnScreenKeyboardInputEventProduced()");
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&BrowserModule::OnOnScreenKeyboardInputEventProduced,
                   weak_this_, type, event));
    return;
  }

#if defined(ENABLE_DEBUGGER)
  // If the debug console is fully visible, it gets the next chance to handle
  // input events.
  if (debug_console_->GetMode() >= debug::console::DebugHub::kDebugConsoleOn) {
    if (!debug_console_->InjectOnScreenKeyboardInputEvent(type, event)) {
      return;
    }
  }
#endif  // defined(ENABLE_DEBUGGER)

  InjectOnScreenKeyboardInputEventToMainWebModule(type, event);
}
#endif  // SB_HAS(ON_SCREEN_KEYBOARD)

void BrowserModule::OnKeyEventProduced(base::Token type,
                                       const dom::KeyboardEventInit& event) {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::OnKeyEventProduced()");
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&BrowserModule::OnKeyEventProduced, weak_this_,
                              type, event));
    return;
  }

  // Filter the key event.
  if (!FilterKeyEvent(type, event)) {
    return;
  }

  InjectKeyEventToMainWebModule(type, event);
}

void BrowserModule::OnPointerEventProduced(base::Token type,
                                           const dom::PointerEventInit& event) {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::OnPointerEventProduced()");
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&BrowserModule::OnPointerEventProduced,
                              weak_this_, type, event));
    return;
  }

#if defined(ENABLE_DEBUGGER)
  // If the debug console is fully visible, it gets the next chance to handle
  // pointer events.
  if (debug_console_->GetMode() >= debug::console::DebugHub::kDebugConsoleOn) {
    if (!debug_console_->FilterPointerEvent(type, event)) {
      return;
    }
  }

#endif  // defined(ENABLE_DEBUGGER)

  DCHECK(web_module_);
  web_module_->InjectPointerEvent(type, event);
}

void BrowserModule::OnWheelEventProduced(base::Token type,
                                         const dom::WheelEventInit& event) {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::OnWheelEventProduced()");
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&BrowserModule::OnWheelEventProduced, weak_this_,
                              type, event));
    return;
  }

#if defined(ENABLE_DEBUGGER)
  // If the debug console is fully visible, it gets the next chance to handle
  // wheel events.
  if (debug_console_->GetMode() >= debug::console::DebugHub::kDebugConsoleOn) {
    if (!debug_console_->FilterWheelEvent(type, event)) {
      return;
    }
  }

#endif  // defined(ENABLE_DEBUGGER)

  DCHECK(web_module_);
  web_module_->InjectWheelEvent(type, event);
}

void BrowserModule::InjectKeyEventToMainWebModule(
    base::Token type, const dom::KeyboardEventInit& event) {
  TRACE_EVENT0("cobalt::browser",
               "BrowserModule::InjectKeyEventToMainWebModule()");
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&BrowserModule::InjectKeyEventToMainWebModule,
                              weak_this_, type, event));
    return;
  }

  DCHECK(web_module_);
  web_module_->InjectKeyboardEvent(type, event);
}

#if SB_HAS(ON_SCREEN_KEYBOARD)
void BrowserModule::InjectOnScreenKeyboardInputEventToMainWebModule(
    base::Token type, const dom::InputEventInit& event) {
  TRACE_EVENT0(
      "cobalt::browser",
      "BrowserModule::InjectOnScreenKeyboardInputEventToMainWebModule()");
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE,
        base::Bind(
            &BrowserModule::InjectOnScreenKeyboardInputEventToMainWebModule,
            weak_this_, type, event));
    return;
  }

  DCHECK(web_module_);
  web_module_->InjectOnScreenKeyboardInputEvent(type, event);
}
#endif  // SB_HAS(ON_SCREEN_KEYBOARD)

void BrowserModule::OnError(const GURL& url, const std::string& error) {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::OnError()");
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&BrowserModule::OnError, weak_this_, url, error));
    return;
  }

#if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
  on_error_triggered_count_++;
#endif

  // Set |pending_navigate_url_| to the url where the error occurred. This will
  // cause the OnError callback to Navigate() to this URL if it receives a
  // positive response; otherwise, if Cobalt is currently preloaded or
  // suspended, then this is the url that Cobalt will navigate to when it starts
  // or resumes.
  pending_navigate_url_ = url;

  // Start the OnErrorRetry() timer if it isn't already running.
  // The minimum delay between calls to OnErrorRetry() exponentially grows as
  // |on_error_retry_count_| increases. |on_error_retry_count_| is reset when
  // OnLoad() is called.
  if (!on_error_retry_timer_.IsRunning()) {
    const int64 kBaseRetryDelayInMilliseconds = 1000;
    // Cap the max error shift at 10 (1024 * kBaseDelayInMilliseconds)
    // This results in the minimum delay being capped at ~17 minutes.
    const int kMaxOnErrorRetryCountShift = 10;
    int64 min_delay = kBaseRetryDelayInMilliseconds << std::min(
                          kMaxOnErrorRetryCountShift, on_error_retry_count_);
    int64 required_delay = std::max(
        min_delay -
            (base::TimeTicks::Now() - on_error_retry_time_).InMilliseconds(),
        static_cast<int64>(0));

    on_error_retry_timer_.Start(
        FROM_HERE, base::TimeDelta::FromMilliseconds(required_delay), this,
        &BrowserModule::OnErrorRetry);
  }
}

void BrowserModule::OnErrorRetry() {
  ++on_error_retry_count_;
  on_error_retry_time_ = base::TimeTicks::Now();
  waiting_for_error_retry_ = true;

  SystemPlatformErrorHandler::SystemPlatformErrorOptions options;
  options.error_type = kSbSystemPlatformErrorTypeConnectionError;
  options.callback =
      base::Bind(&BrowserModule::OnNetworkFailureSystemPlatformResponse,
                 base::Unretained(this));
  system_platform_error_handler_.RaiseSystemPlatformError(options);
}

void BrowserModule::OnNetworkFailureSystemPlatformResponse(
    SbSystemPlatformErrorResponse response) {
  // A positive response means we should retry, anything else we stop.
  if (response == kSbSystemPlatformErrorResponsePositive) {
    // We shouldn't be here if we don't have a pending URL from an error.
    DCHECK(pending_navigate_url_.is_valid());
    if (pending_navigate_url_.is_valid()) {
      Navigate(pending_navigate_url_);
    }
  } else {
    LOG(ERROR) << "Stop after network error";
    SbSystemRequestStop(0);
  }
}

bool BrowserModule::FilterKeyEvent(base::Token type,
                                   const dom::KeyboardEventInit& event) {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::FilterKeyEvent()");
  // Check for hotkeys first. If it is a hotkey, no more processing is needed.
  // TODO: Let WebModule handle the event first, and let the web app prevent
  // this default behavior of the user agent.
  // https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault
  if (!FilterKeyEventForHotkeys(type, event)) {
    return false;
  }

#if defined(ENABLE_DEBUGGER)
  // If the debug console is fully visible, it gets the next chance to handle
  // key events.
  if (debug_console_->GetMode() >= debug::console::DebugHub::kDebugConsoleOn) {
    if (!debug_console_->FilterKeyEvent(type, event)) {
      return false;
    }
  }
#endif  // defined(ENABLE_DEBUGGER)

  return true;
}

bool BrowserModule::FilterKeyEventForHotkeys(
    base::Token type, const dom::KeyboardEventInit& event) {
#if !defined(ENABLE_DEBUGGER)
#else
  if (event.key_code() == dom::keycode::kF1 ||
      (event.ctrl_key() && event.key_code() == dom::keycode::kO)) {
    if (type == base::Tokens::keydown()) {
      // Ctrl+O toggles the debug console display.
      debug_console_->CycleMode();
    }
    return false;
  } else if (event.key_code() == dom::keycode::kF5) {
    if (type == base::Tokens::keydown()) {
      // F5 reloads the page.
      Reload();
    }
  }
#endif  // defined(ENABLE_DEBUGGER)

  return true;
}

void BrowserModule::AddURLHandler(
    const URLHandler::URLHandlerCallback& callback) {
  url_handlers_.push_back(callback);
}

void BrowserModule::RemoveURLHandler(
    const URLHandler::URLHandlerCallback& callback) {
  for (URLHandlerCollection::iterator iter = url_handlers_.begin();
       iter != url_handlers_.end(); ++iter) {
    if (iter->Equals(callback)) {
      url_handlers_.erase(iter);
      return;
    }
  }
}

bool BrowserModule::TryURLHandlers(const GURL& url) {
  for (URLHandlerCollection::const_iterator iter = url_handlers_.begin();
       iter != url_handlers_.end(); ++iter) {
    if (iter->Run(url)) {
      return true;
    }
  }

  // No registered handler handled the URL, let the caller handle it.
  return false;
}

void BrowserModule::DestroySplashScreen(base::TimeDelta close_time) {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::DestroySplashScreen()");
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&BrowserModule::DestroySplashScreen, weak_this_,
                              close_time));
    return;
  }
  if (splash_screen_) {
    lifecycle_observers_.RemoveObserver(splash_screen_.get());
    if (!close_time.is_zero() && renderer_module_) {
      // Ensure that the renderer renders each frame up until the window.close()
      // is called on the splash screen's timeline, in order to ensure that the
      // splash screen shutdown transition plays out completely.
      renderer_module_->pipeline()->TimeFence(close_time);
    }
    splash_screen_layer_->Reset();
    SubmitCurrentRenderTreeToRenderer();
    splash_screen_.reset(NULL);
  }
}

#if defined(ENABLE_WEBDRIVER)
std::unique_ptr<webdriver::SessionDriver> BrowserModule::CreateSessionDriver(
    const webdriver::protocol::SessionId& session_id) {
  return base::WrapUnique(new webdriver::SessionDriver(
      session_id,
      base::Bind(&BrowserModule::CreateWindowDriver, base::Unretained(this)),
      base::Bind(&BrowserModule::WaitForLoad, base::Unretained(this))));
}

std::unique_ptr<webdriver::WindowDriver> BrowserModule::CreateWindowDriver(
    const webdriver::protocol::WindowId& window_id) {
  // Repost to our message loop to ensure synchronous access to |web_module_|.
  std::unique_ptr<webdriver::WindowDriver> window_driver;
  self_message_loop_->task_runner()->PostBlockingTask(
      FROM_HERE, base::Bind(&BrowserModule::CreateWindowDriverInternal,
                            base::Unretained(this), window_id,
                            base::Unretained(&window_driver)));

  // This log is relied on by the webdriver benchmark tests, so it shouldn't be
  // changed unless the corresponding benchmark logic is changed as well.
  LOG(INFO) << "Created WindowDriver: ID=" << window_id.id();
  DCHECK(window_driver);
  return window_driver;
}

void BrowserModule::CreateWindowDriverInternal(
    const webdriver::protocol::WindowId& window_id,
    std::unique_ptr<webdriver::WindowDriver>* out_window_driver) {
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  DCHECK(web_module_);
  *out_window_driver = web_module_->CreateWindowDriver(window_id);
}
#endif  // defined(ENABLE_WEBDRIVER)

#if defined(ENABLE_DEBUGGER)
std::unique_ptr<debug::DebugClient> BrowserModule::CreateDebugClient(
    debug::DebugClient::Delegate* delegate) {
  // Repost to our message loop to ensure synchronous access to |web_module_|.
  debug::backend::DebugDispatcher* debug_dispatcher = NULL;
  self_message_loop_->task_runner()->PostBlockingTask(
      FROM_HERE,
      base::Bind(&BrowserModule::GetDebugDispatcherInternal,
                 base::Unretained(this), base::Unretained(&debug_dispatcher)));
  DCHECK(debug_dispatcher);
  return std::unique_ptr<debug::DebugClient>(
      new debug::DebugClient(debug_dispatcher, delegate));
}

void BrowserModule::GetDebugDispatcherInternal(
    debug::backend::DebugDispatcher** out_debug_dispatcher) {
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  DCHECK(web_module_);
  *out_debug_dispatcher = web_module_->GetDebugDispatcher();
}
#endif  // ENABLE_DEBUGGER

void BrowserModule::SetProxy(const std::string& proxy_rules) {
  // NetworkModule will ensure this happens on the correct thread.
  network_module_.SetProxy(proxy_rules);
}

void BrowserModule::Start() {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::Start()");
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  DCHECK(application_state_ == base::kApplicationStatePreloading);

  SuspendInternal(true /*is_start*/);
  StartOrResumeInternalPreStateUpdate(true /*is_start*/);

  application_state_ = base::kApplicationStateStarted;

  StartOrResumeInternalPostStateUpdate();
}

void BrowserModule::Pause() {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::Pause()");
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  DCHECK(application_state_ == base::kApplicationStateStarted);
  FOR_EACH_OBSERVER(LifecycleObserver, lifecycle_observers_, Pause());
  application_state_ = base::kApplicationStatePaused;
}

void BrowserModule::Unpause() {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::Unpause()");
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  DCHECK(application_state_ == base::kApplicationStatePaused);
  FOR_EACH_OBSERVER(LifecycleObserver, lifecycle_observers_, Unpause());
  application_state_ = base::kApplicationStateStarted;
}

void BrowserModule::Suspend() {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::Suspend()");
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  DCHECK(application_state_ == base::kApplicationStatePaused ||
         application_state_ == base::kApplicationStatePreloading);

  SuspendInternal(false /*is_start*/);

  application_state_ = base::kApplicationStateSuspended;
}

void BrowserModule::Resume() {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::Resume()");
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  DCHECK(application_state_ == base::kApplicationStateSuspended);

  StartOrResumeInternalPreStateUpdate(false /*is_start*/);

  application_state_ = base::kApplicationStatePaused;

  StartOrResumeInternalPostStateUpdate();
}

void BrowserModule::ReduceMemory() {
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  if (splash_screen_) {
    splash_screen_->ReduceMemory();
  }

#if defined(ENABLE_DEBUGGER)
  if (debug_console_) {
    debug_console_->ReduceMemory();
  }
#endif  // defined(ENABLE_DEBUGGER)

  if (web_module_) {
    web_module_->ReduceMemory();
  }
}

void BrowserModule::CheckMemory(
    const int64_t& used_cpu_memory,
    const base::Optional<int64_t>& used_gpu_memory) {
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  if (!auto_mem_) {
    return;
  }

  memory_settings_checker_.RunChecks(*auto_mem_, used_cpu_memory,
                                     used_gpu_memory);
}

void BrowserModule::UpdateJavaScriptHeapStatistics() {
  web_module_->RequestJavaScriptHeapStatistics(base::Bind(
      &BrowserModule::GetHeapStatisticsCallback, base::Unretained(this)));
}

void BrowserModule::OnRendererSubmissionRasterized() {
  TRACE_EVENT0("cobalt::browser",
               "BrowserModule::OnRendererSubmissionRasterized()");
  if (!is_rendered_) {
    // Hide the system splash screen when the first render has completed.
    is_rendered_ = true;
    SbSystemHideSplashScreen();
  }
}

#if defined(COBALT_CHECK_RENDER_TIMEOUT)
void BrowserModule::OnPollForRenderTimeout(const GURL& url) {
  SbTime last_render_timestamp = static_cast<SbTime>(SbAtomicAcquire_Load64(
      non_trivial_global_variables.Get().last_render_timestamp));
  base::Time last_render = base::Time::FromSbTime(last_render_timestamp);
  bool timeout_expiration = base::Time::Now() - base::TimeDelta::FromSeconds(
                                                    kLastRenderTimeoutSeconds) >
                            last_render;
  bool timeout_response_trigger = false;
  if (timeout_expiration) {
    // The timeout only triggers if the timeout expiration has been detected
    // without interruption at least kMinimumContinuousRenderTimeoutExpirations
    // times.
    ++render_timeout_count_;
    timeout_response_trigger =
        render_timeout_count_ >= kMinimumContinuousRenderTimeoutExpirations;
  } else {
    render_timeout_count_ = 0;
  }

  if (timeout_response_trigger) {
#if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
    timeout_response_trigger_count_++;
#endif
    SbAtomicNoBarrier_Exchange64(
        non_trivial_global_variables.Get().last_render_timestamp,
        static_cast<SbAtomic64>(kSbTimeMax));
    if (SbSystemGetRandomUInt64() <
        kRenderTimeoutErrorPercentage * (UINT64_MAX / 100)) {
      OnError(url, std::string("Rendering Timeout"));
#if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
      recovery_mechanism_triggered_count_++;
#endif
    } else {
      SB_DLOG(INFO) << "Received OnRenderTimeout, ignoring by random chance.";
    }
  } else {
    timeout_polling_thread_.message_loop()->task_runner()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&BrowserModule::OnPollForRenderTimeout,
                   base::Unretained(this), url),
        base::TimeDelta::FromSeconds(kRenderTimeOutPollingDelaySeconds));
  }
}
#endif

render_tree::ResourceProvider* BrowserModule::GetResourceProvider() {
  if (!renderer_module_) {
    if (resource_provider_stub_) {
      DCHECK(application_state_ == base::kApplicationStatePreloading);
      return &(resource_provider_stub_.value());
    }

    return NULL;
  }

  return renderer_module_->resource_provider();
}

void BrowserModule::InitializeSystemWindow() {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::InitializeSystemWindow()");
  resource_provider_stub_ = base::nullopt;
  DCHECK(!system_window_);
  base::Optional<math::Size> maybe_size;
  if (options_.requested_viewport_size) {
    maybe_size = options_.requested_viewport_size->width_height();
  }
  system_window_.reset(
      new system_window::SystemWindow(event_dispatcher_, maybe_size));
  // Reapply automem settings now that we may have a different viewport size.
  ApplyAutoMemSettings();

  input_device_manager_ = input::InputDeviceManager::CreateFromWindow(
      base::Bind(&BrowserModule::OnKeyEventProduced, base::Unretained(this)),
      base::Bind(&BrowserModule::OnPointerEventProduced,
                 base::Unretained(this)),
      base::Bind(&BrowserModule::OnWheelEventProduced, base::Unretained(this)),
#if SB_HAS(ON_SCREEN_KEYBOARD)
      base::Bind(&BrowserModule::OnOnScreenKeyboardInputEventProduced,
                 base::Unretained(this)),
#endif  // SB_HAS(ON_SCREEN_KEYBOARD)
      system_window_.get());
  InstantiateRendererModule();

#if SB_API_VERSION >= 10
  options_.media_module_options.allow_resume_after_suspend =
      SbSystemSupportsResume();
#endif  // SB_API_VERSION >= 10
  media_module_.reset(new media::MediaModule(system_window_.get(),
                                             GetResourceProvider(),
                                             options_.media_module_options));

  if (web_module_) {
    web_module_->SetCamera3D(input_device_manager_->camera_3d());
    web_module_->SetWebMediaPlayerFactory(media_module_.get());
    web_module_->GetUiNavRoot()->SetContainerWindow(
        system_window_->GetSbWindow());
  }
}

void BrowserModule::InstantiateRendererModule() {
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  DCHECK(system_window_);
  DCHECK(!renderer_module_);

  renderer_module_.reset(new renderer::RendererModule(
      system_window_.get(),
      RendererModuleWithCameraOptions(options_.renderer_module_options,
                                      input_device_manager_->camera_3d())));
  screen_shot_writer_.reset(new ScreenShotWriter(renderer_module_->pipeline()));
}

void BrowserModule::DestroyRendererModule() {
  DCHECK_EQ(base::MessageLoop::current(), self_message_loop_);
  DCHECK(renderer_module_);

  screen_shot_writer_.reset();
  renderer_module_.reset();
}

void BrowserModule::UpdateScreenSize() {
  ViewportSize size = GetViewportSize();
  float video_pixel_ratio = system_window_->GetVideoPixelRatio();
#if defined(ENABLE_DEBUGGER)
  if (debug_console_) {
    debug_console_->SetSize(size, video_pixel_ratio);
  }
#endif  // defined(ENABLE_DEBUGGER)

  if (splash_screen_) {
    splash_screen_->SetSize(size, video_pixel_ratio);
  }

  if (web_module_) {
    web_module_->SetSize(size, video_pixel_ratio);
  }

  if (qr_code_overlay_) {
    qr_code_overlay_->SetSize(size.width_height());
  }
}

void BrowserModule::SuspendInternal(bool is_start) {
  TRACE_EVENT1("cobalt::browser", "BrowserModule::SuspendInternal", "is_start",
               is_start ? "true" : "false");
  // First suspend all our web modules which implies that they will release
  // their resource provider and all resources created through it.
  if (is_start) {
    FOR_EACH_OBSERVER(LifecycleObserver, lifecycle_observers_, Prestart());
  } else {
    FOR_EACH_OBSERVER(LifecycleObserver, lifecycle_observers_, Suspend());
  }

  if (qr_code_overlay_) {
    qr_code_overlay_->SetResourceProvider(NULL);
  }

  // Flush out any submitted render trees pushed since we started shutting down
  // the web modules above.
  render_tree_submission_queue_.ProcessAll();

  // Clear out the render tree combiner so that it doesn't hold on to any
  // render tree resources either.
  main_web_module_layer_->Reset();
  splash_screen_layer_->Reset();
#if defined(ENABLE_DEBUGGER)
  debug_console_layer_->Reset();
#endif  // defined(ENABLE_DEBUGGER)
  if (qr_overlay_info_layer_) {
    qr_overlay_info_layer_->Reset();
  }

  if (media_module_) {
    media_module_->Suspend();
  }

  if (renderer_module_) {
    // Destroy the renderer module into so that it releases all its graphical
    // resources.
    DestroyRendererModule();
  }
}

void BrowserModule::StartOrResumeInternalPreStateUpdate(bool is_start) {
  TRACE_EVENT1("cobalt::browser",
               "BrowserModule::StartOrResumeInternalPreStateUpdate", "is_start",
               is_start ? "true" : "false");
  if (!system_window_) {
    InitializeSystemWindow();
  } else {
    InstantiateRendererModule();
    media_module_->Resume(GetResourceProvider());
  }

  // Propagate the current screen size.
  UpdateScreenSize();

  if (is_start) {
    FOR_EACH_OBSERVER(LifecycleObserver, lifecycle_observers_,
                      Start(GetResourceProvider()));
  } else {
    FOR_EACH_OBSERVER(LifecycleObserver, lifecycle_observers_,
                      Resume(GetResourceProvider()));
  }
  if (qr_code_overlay_) {
    qr_code_overlay_->SetResourceProvider(GetResourceProvider());
  }
}

void BrowserModule::StartOrResumeInternalPostStateUpdate() {
  TRACE_EVENT0("cobalt::browser",
               "BrowserModule::StartOrResumeInternalPostStateUpdate");
  // If there's a navigation that's pending, then attempt to navigate to its
  // specified URL now, unless we're still waiting for an error retry.
  if (pending_navigate_url_.is_valid() && !waiting_for_error_retry_) {
    Navigate(pending_navigate_url_);
  }
}

ViewportSize BrowserModule::GetViewportSize() {
  // We trust the renderer module for width and height the most, if it exists.
  if (renderer_module_) {
    math::Size target_size = renderer_module_->render_target_size();
    // ...but get the diagonal from one of the other modules.
    float diagonal_inches = 0;
    if (system_window_) {
      diagonal_inches = system_window_->GetDiagonalSizeInches();
      // For those platforms that can have a main window size smaller than the
      // render target size, the system_window_ size (if exists) should be
      // trusted over the renderer_module_ render target size.
      math::Size window_size = system_window_->GetWindowSize();
      if (window_size.width() <= target_size.width() &&
          window_size.height() <= target_size.height()) {
        target_size = window_size;
      }
    } else if (options_.requested_viewport_size) {
      diagonal_inches = options_.requested_viewport_size->diagonal_inches();
    }

    ViewportSize v(target_size.width(), target_size.height(), diagonal_inches);
    return v;
  }

  // If the system window exists, that's almost just as good.
  if (system_window_) {
    math::Size size = system_window_->GetWindowSize();
    ViewportSize v(size.width(), size.height(),
                   system_window_->GetDiagonalSizeInches());
    return v;
  }

  // Otherwise, we assume we'll get the viewport size that was requested.
  if (options_.requested_viewport_size) {
    return *options_.requested_viewport_size;
  }

  // TODO: Allow platforms to define the default window size and return that
  // here.

  // No window and no viewport size was requested, so we return a conservative
  // default.
  ViewportSize view_size(1280, 720, 0);
  return view_size;
}

void BrowserModule::ApplyAutoMemSettings() {
  TRACE_EVENT0("cobalt::browser", "BrowserModule::ApplyAutoMemSettings()");
  auto_mem_.reset(new memory_settings::AutoMem(
      GetViewportSize().width_height(), options_.command_line_auto_mem_settings,
      options_.build_auto_mem_settings));

  LOG(INFO) << "\n\n" << auto_mem_->ToPrettyPrintString(SbLogIsTty()) << "\n\n";

  if (javascript_gc_threshold_in_bytes_) {
    DCHECK_EQ(*javascript_gc_threshold_in_bytes_,
              auto_mem_->javascript_gc_threshold_in_bytes()->value());
  } else {
    javascript_gc_threshold_in_bytes_ =
        auto_mem_->javascript_gc_threshold_in_bytes()->value();
  }

  // Web Module options.
  options_.web_module_options.encoded_image_cache_capacity =
      static_cast<int>(auto_mem_->encoded_image_cache_size_in_bytes()->value());
  options_.web_module_options.image_cache_capacity =
      static_cast<int>(auto_mem_->image_cache_size_in_bytes()->value());
  options_.web_module_options.remote_typeface_cache_capacity = static_cast<int>(
      auto_mem_->remote_typeface_cache_size_in_bytes()->value());
  options_.web_module_options.javascript_engine_options.gc_threshold_bytes =
      static_cast<size_t>(
          auto_mem_->javascript_gc_threshold_in_bytes()->value());
  if (web_module_) {
    web_module_->SetImageCacheCapacity(
        auto_mem_->image_cache_size_in_bytes()->value());
    web_module_->SetRemoteTypefaceCacheCapacity(
        auto_mem_->remote_typeface_cache_size_in_bytes()->value());
  }

  // Renderer Module options.
  options_.renderer_module_options.skia_cache_size_in_bytes =
      static_cast<int>(auto_mem_->skia_cache_size_in_bytes()->value());
  options_.renderer_module_options.software_surface_cache_size_in_bytes =
      static_cast<int>(
          auto_mem_->software_surface_cache_size_in_bytes()->value());
  options_.renderer_module_options.offscreen_target_cache_size_in_bytes =
      static_cast<int>(
          auto_mem_->offscreen_target_cache_size_in_bytes()->value());

  const memory_settings::TextureDimensions skia_glyph_atlas_texture_dimensions =
      auto_mem_->skia_atlas_texture_dimensions()->value();
  if (skia_glyph_atlas_texture_dimensions.bytes_per_pixel() > 0) {
    // Right now the bytes_per_pixel is assumed in the engine. Any other value
    // is currently forbidden.
    DCHECK_EQ(2, skia_glyph_atlas_texture_dimensions.bytes_per_pixel());

    options_.renderer_module_options.skia_glyph_texture_atlas_dimensions =
        math::Size(skia_glyph_atlas_texture_dimensions.width(),
                   skia_glyph_atlas_texture_dimensions.height());
  }
}

void BrowserModule::GetHeapStatisticsCallback(
    const script::HeapStatistics& heap_statistics) {
  if (base::MessageLoop::current() != self_message_loop_) {
    self_message_loop_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&BrowserModule::GetHeapStatisticsCallback,
                              base::Unretained(this), heap_statistics));
    return;
  }
  javascript_reserved_memory_ = heap_statistics.total_heap_size;
}

void BrowserModule::SubmitCurrentRenderTreeToRenderer() {
  if (!renderer_module_) {
    return;
  }

  base::Optional<renderer::Submission> submission =
      render_tree_combiner_.GetCurrentSubmission();
  if (submission) {
    renderer_module_->pipeline()->Submit(*submission);
  }
}

SbWindow BrowserModule::GetSbWindow() {
  if (!system_window_) {
    return NULL;
  }
  return system_window_->GetSbWindow();
}

}  // namespace browser
}  // namespace cobalt
