// 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/application.h"

#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/metrics/statistics_recorder.h"
#include "base/optional.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/task/task_scheduler/task_scheduler.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cobalt/base/accessibility_caption_settings_changed_event.h"
#include "cobalt/base/accessibility_settings_changed_event.h"
#include "cobalt/base/accessibility_text_to_speech_settings_changed_event.h"
#include "cobalt/base/cobalt_paths.h"
#include "cobalt/base/date_time_configuration_changed_event.h"
#include "cobalt/base/deep_link_event.h"
#include "cobalt/base/get_application_key.h"
#include "cobalt/base/init_cobalt.h"
#include "cobalt/base/language.h"
#include "cobalt/base/localized_strings.h"
#include "cobalt/base/on_screen_keyboard_blurred_event.h"
#include "cobalt/base/on_screen_keyboard_focused_event.h"
#include "cobalt/base/on_screen_keyboard_hidden_event.h"
#include "cobalt/base/on_screen_keyboard_shown_event.h"
#include "cobalt/base/on_screen_keyboard_suggestions_updated_event.h"
#include "cobalt/base/startup_timer.h"
#if defined(COBALT_ENABLE_VERSION_COMPATIBILITY_VALIDATIONS)
#include "cobalt/base/version_compatibility.h"
#endif  // defined(COBALT_ENABLE_VERSION_COMPATIBILITY_VALIDATIONS)
#include "cobalt/base/window_on_offline_event.h"
#include "cobalt/base/window_on_online_event.h"
#include "cobalt/base/window_size_changed_event.h"
#include "cobalt/browser/device_authentication.h"
#include "cobalt/browser/memory_settings/auto_mem_settings.h"
#include "cobalt/browser/memory_tracker/tool.h"
#include "cobalt/browser/switches.h"
#include "cobalt/browser/user_agent_platform_info.h"
#include "cobalt/browser/user_agent_string.h"
#include "cobalt/cache/cache.h"
#include "cobalt/configuration/configuration.h"
#include "cobalt/loader/image/image_decoder.h"
#include "cobalt/math/size.h"
#include "cobalt/script/javascript_engine.h"
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
#include "cobalt/storage/savegame_fake.h"
#endif  // defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
#include "cobalt/system_window/input_event.h"
#include "cobalt/trace_event/scoped_trace_to_file.h"
#include "cobalt/watchdog/watchdog.h"
#include "starboard/configuration.h"
#include "starboard/event.h"
#include "starboard/extension/crash_handler.h"
#include "starboard/extension/installation_manager.h"
#include "starboard/system.h"
#include "starboard/time.h"
#include "url/gurl.h"

#if SB_IS(EVERGREEN)
#include "cobalt/updater/utils.h"
#endif

using cobalt::cssom::ViewportSize;

namespace cobalt {
namespace browser {

namespace {
const int kStatUpdatePeriodMs = 1000;

const char kDefaultURL[] = "https://www.youtube.com/tv";

#if defined(ENABLE_ABOUT_SCHEME)
const char kAboutBlankURL[] = "about:blank";
#endif  // defined(ENABLE_ABOUT_SCHEME)

const char kPersistentSettingsJson[] = "settings.json";

// The watchdog client name used to represent Stats.
const char kWatchdogName[] = "stats";
// The watchdog time interval in microseconds allowed between pings before
// triggering violations.
const int64_t kWatchdogTimeInterval = 10000000;
// The watchdog time wait in microseconds to initially wait before triggering
// violations.
const int64_t kWatchdogTimeWait = 2000000;

bool IsStringNone(const std::string& str) {
  return !base::strcasecmp(str.c_str(), "none");
}

#if defined(ENABLE_WEBDRIVER) || defined(ENABLE_DEBUGGER)
std::string GetDevServersListenIp() {
  bool ip_v6;
  ip_v6 = SbSocketIsIpv6Supported();
  // Default to INADDR_ANY
  std::string listen_ip(ip_v6 ? "::" : "0.0.0.0");

  // Desktop PCs default to loopback.
  if (SbSystemGetDeviceType() == kSbSystemDeviceTypeDesktopPC) {
    listen_ip = ip_v6 ? "::1" : "127.0.0.1";
  }

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kDevServersListenIp)) {
    listen_ip =
        command_line->GetSwitchValueASCII(switches::kDevServersListenIp);
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES

  return listen_ip;
}
#endif  // defined(ENABLE_WEBDRIVER) || defined(ENABLE_DEBUGGER)

#if defined(ENABLE_DEBUGGER)
int GetRemoteDebuggingPort() {
#if defined(SB_OVERRIDE_DEFAULT_REMOTE_DEBUGGING_PORT)
  const unsigned int kDefaultRemoteDebuggingPort =
      SB_OVERRIDE_DEFAULT_REMOTE_DEBUGGING_PORT;
#else
  const unsigned int kDefaultRemoteDebuggingPort = 9222;
#endif  // defined(SB_OVERRIDE_DEFAULT_REMOTE_DEBUGGING_PORT)
  unsigned int remote_debugging_port = kDefaultRemoteDebuggingPort;
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kRemoteDebuggingPort)) {
    std::string switch_value =
        command_line->GetSwitchValueASCII(switches::kRemoteDebuggingPort);
    if (!base::StringToUint(switch_value, &remote_debugging_port)) {
      DLOG(ERROR) << "Invalid port specified for remote debug server: "
                  << switch_value
                  << ". Using default port: " << kDefaultRemoteDebuggingPort;
      remote_debugging_port = kDefaultRemoteDebuggingPort;
    }
  }
  DCHECK(remote_debugging_port != 0 ||
         !command_line->HasSwitch(switches::kWaitForWebDebugger))
      << switches::kWaitForWebDebugger << " switch can't be used when "
      << switches::kRemoteDebuggingPort << " is 0 (disabled).";
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
  return uint16_t(remote_debugging_port);
}
#endif  // ENABLE_DEBUGGER

#if defined(ENABLE_WEBDRIVER)
int GetWebDriverPort() {
// The default port on which the webdriver server should listen for incoming
// connections.
#if defined(SB_OVERRIDE_DEFAULT_WEBDRIVER_PORT)
  const int kDefaultWebDriverPort = SB_OVERRIDE_DEFAULT_WEBDRIVER_PORT;
#else
  const int kDefaultWebDriverPort = 4444;
#endif  // defined(SB_OVERRIDE_DEFAULT_WEBDRIVER_PORT)
  int webdriver_port = kDefaultWebDriverPort;
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kWebDriverPort)) {
    if (!base::StringToInt(
            command_line->GetSwitchValueASCII(switches::kWebDriverPort),
            &webdriver_port)) {
      DLOG(ERROR) << "Invalid port specified for WebDriver server: "
                  << command_line->GetSwitchValueASCII(switches::kWebDriverPort)
                  << ". Using default port: " << kDefaultWebDriverPort;
      webdriver_port = kDefaultWebDriverPort;
    }
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
  return webdriver_port;
}
#endif  // ENABLE_WEBDRIVER

GURL GetInitialURL(bool should_preload) {
  GURL initial_url = GURL(kDefaultURL);
  // Allow the user to override the default URL via a command line parameter.
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kInitialURL)) {
    std::string url_switch =
        command_line->GetSwitchValueASCII(switches::kInitialURL);
#if defined(ENABLE_ABOUT_SCHEME)
    // Check the switch itself since some non-empty strings parse to empty URLs.
    if (url_switch.empty()) {
      LOG(ERROR) << "URL from parameter is empty, using " << kAboutBlankURL;
      return GURL(kAboutBlankURL);
    }
#endif  // defined(ENABLE_ABOUT_SCHEME)
    GURL url = GURL(url_switch);
    if (url.is_valid()) {
      initial_url = url;
    } else {
      LOG(ERROR) << "URL \"" << url_switch
                 << "\" from parameter is not valid, using default URL "
                 << initial_url;
    }
  }

  if (should_preload) {
    std::string query = initial_url.query();
    if (!query.empty()) {
      query += "&";
    }
    query += "launch=preload";
    GURL::Replacements replacements;
    replacements.SetQueryStr(query);
    initial_url = initial_url.ReplaceComponents(replacements);
  }

  if (!command_line->HasSwitch(
          switches::kOmitDeviceAuthenticationQueryParameters)) {
    // Append the device authentication query parameters based on the platform's
    // certification secret to the initial URL.
    std::string query = initial_url.query();
    std::string device_authentication_query_string =
        GetDeviceAuthenticationSignedURLQueryString();
    if (!query.empty() && !device_authentication_query_string.empty()) {
      query += "&";
    }
    query += device_authentication_query_string;

    if (!query.empty()) {
      GURL::Replacements replacements;
      replacements.SetQueryStr(query);
      initial_url = initial_url.ReplaceComponents(replacements);
    }
  }

  return initial_url;
}

bool ValidateSplashScreen(const base::Optional<GURL>& url) {
  if (url->is_valid() &&
      (url->SchemeIsFile() || url->SchemeIs("h5vcc-embedded"))) {
    return true;
  }
  LOG(FATAL) << "Ignoring invalid fallback splash screen: " << url->spec();
  return false;
}

base::Optional<GURL> GetFallbackSplashScreenURL() {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  std::string fallback_splash_screen_string;
  if (command_line->HasSwitch(switches::kFallbackSplashScreenURL)) {
    fallback_splash_screen_string =
        command_line->GetSwitchValueASCII(switches::kFallbackSplashScreenURL);
  } else {
    fallback_splash_screen_string = configuration::Configuration::GetInstance()
                                        ->CobaltFallbackSplashScreenUrl();
  }
  if (IsStringNone(fallback_splash_screen_string)) {
    return base::Optional<GURL>();
  }
  base::Optional<GURL> fallback_splash_screen_url =
      GURL(fallback_splash_screen_string);
  ValidateSplashScreen(fallback_splash_screen_url);
  return fallback_splash_screen_url;
}

// Parses the fallback_splash_screen_topics command line parameter
// and maps topics to full file url locations, if valid.
void ParseFallbackSplashScreenTopics(
    const base::Optional<GURL>& default_fallback_splash_screen_url,
    std::map<std::string, GURL>* fallback_splash_screen_topic_map) {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  std::string topics;
  if (command_line->HasSwitch(switches::kFallbackSplashScreenTopics)) {
    topics = command_line->GetSwitchValueASCII(
        switches::kFallbackSplashScreenTopics);
  } else {
    topics = configuration::Configuration::GetInstance()
                 ->CobaltFallbackSplashScreenTopics();
  }

  // Note: values in topics_map may be either file paths or filenames.
  std::map<std::string, std::string> topics_map;
  BrowserModule::GetParamMap(topics, topics_map);
  for (auto iterator = topics_map.begin(); iterator != topics_map.end();
       iterator++) {
    std::string topic = iterator->first;
    std::string location = iterator->second;
    base::Optional<GURL> topic_fallback_url = GURL(location);

    // If not a valid url, check whether it is a valid filename in the
    // same directory as the default fallback url.
    if (!topic_fallback_url->is_valid()) {
      if (default_fallback_splash_screen_url) {
        topic_fallback_url = GURL(
            default_fallback_splash_screen_url->GetWithoutFilename().spec() +
            location);
      } else {
        break;
      }
    }
    if (ValidateSplashScreen(topic_fallback_url)) {
      (*fallback_splash_screen_topic_map)[topic] = topic_fallback_url.value();
    }
  }
}

base::TimeDelta GetTimedTraceDuration() {
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  int duration_in_seconds = 0;
  if (command_line->HasSwitch(switches::kTimedTrace) &&
      base::StringToInt(
          command_line->GetSwitchValueASCII(switches::kTimedTrace),
          &duration_in_seconds)) {
    return base::TimeDelta::FromSeconds(duration_in_seconds);
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES

  return base::TimeDelta();
}

base::FilePath GetExtraWebFileDir() {
  // Default is empty, command line can override.
  base::FilePath result;

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kExtraWebFileDir)) {
    result = base::FilePath(
        command_line->GetSwitchValueASCII(switches::kExtraWebFileDir));
    if (!result.IsAbsolute()) {
      // Non-absolute paths are relative to the executable directory.
      base::FilePath content_path;
      base::PathService::Get(base::DIR_EXE, &content_path);
      result = content_path.DirName().DirName().Append(result);
    }
    DLOG(INFO) << "Extra web file dir: " << result.value();
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES

  return result;
}

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
void EnableUsingStubImageDecoderIfRequired() {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kStubImageDecoder)) {
    loader::image::ImageDecoder::UseStubImageDecoder();
  }
}
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES

base::Optional<cssom::ViewportSize> GetRequestedViewportSize(
    base::CommandLine* command_line) {
  DCHECK(command_line);
  if (!command_line->HasSwitch(browser::switches::kViewport)) {
    return base::nullopt;
  }

  std::string switch_value =
      command_line->GetSwitchValueASCII(browser::switches::kViewport);

  std::vector<std::string> lengths = base::SplitString(
      switch_value, "x", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

  if (lengths.empty()) {
    DLOG(ERROR) << "Viewport " << switch_value << " is invalid.";
    return base::nullopt;
  }

  int width = 0;
  if (!base::StringToInt(lengths[0], &width)) {
    DLOG(ERROR) << "Viewport " << switch_value << " has invalid width.";
    return base::nullopt;
  }

  if (lengths.size() < 2) {
    // Allow shorthand specification of the viewport by only giving the
    // width. This calculates the height at 4:3 aspect ratio for smaller
    // viewport widths, and 16:9 for viewports 1280 pixels wide or larger.
    if (width >= 1280) {
      return ViewportSize(width, 9 * width / 16);
    }
    return ViewportSize(width, 3 * width / 4);
  }

  int height = 0;
  if (!base::StringToInt(lengths[1], &height)) {
    DLOG(ERROR) << "Viewport " << switch_value << " has invalid height.";
    return base::nullopt;
  }

  if (lengths.size() < 3) {
    return ViewportSize(width, height);
  }

  double screen_diagonal_inches = 0.0f;
  if (lengths.size() >= 3) {
    if (!base::StringToDouble(lengths[2], &screen_diagonal_inches)) {
      DLOG(ERROR) << "Viewport " << switch_value
                  << " has invalid screen_diagonal_inches.";
      return base::nullopt;
    }
  }

  double video_pixel_ratio = 1.0f;
  if (lengths.size() >= 4) {
    if (!base::StringToDouble(lengths[3], &video_pixel_ratio)) {
      DLOG(ERROR) << "Viewport " << switch_value
                  << " has invalid video_pixel_ratio.";
      return base::nullopt;
    }
  }

  return ViewportSize(width, height, static_cast<float>(video_pixel_ratio),
                      static_cast<float>(screen_diagonal_inches));
}

std::string GetMinLogLevelString() {
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kMinLogLevel)) {
    return command_line->GetSwitchValueASCII(switches::kMinLogLevel);
  }
#if defined(OFFICIAL_BUILD)
  return "fatal";
#else
  return "info";
#endif
}

int StringToLogLevel(const std::string& log_level) {
  if (log_level == "info") {
    return logging::LOG_INFO;
  } else if (log_level == "warning") {
    return logging::LOG_WARNING;
  } else if (log_level == "error") {
    return logging::LOG_ERROR;
  } else if (log_level == "fatal") {
    return logging::LOG_FATAL;
  } else {
    NOTREACHED() << "Unrecognized logging level: " << log_level;
#if defined(OFFICIAL_BUILD)
    return logging::LOG_FATAL;
#else
    return logging::LOG_INFO;
#endif
  }
}

void SetIntegerIfSwitchIsSet(const char* switch_name, int* output) {
  if (base::CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) {
    int32 out;
    if (base::StringToInt32(
            base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(
                switch_name),
            &out)) {
      LOG(INFO) << "Command line switch '" << switch_name << "': Modifying "
                << *output << " -> " << out;
      *output = out;
    } else {
      LOG(ERROR) << "Invalid value for command line setting: " << switch_name;
    }
  }
}

void ApplyCommandLineSettingsToRendererOptions(
    renderer::RendererModule::Options* options) {
  SetIntegerIfSwitchIsSet(browser::switches::kScratchSurfaceCacheSizeInBytes,
                          &options->scratch_surface_cache_size_in_bytes);
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  auto command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(browser::switches::kDisableRasterizerCaching) ||
      command_line->HasSwitch(
          browser::switches::kForceDeterministicRendering)) {
    options->force_deterministic_rendering = true;
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
}

struct NonTrivialStaticFields {
  NonTrivialStaticFields() : system_language(base::GetSystemLanguage()) {}

  const std::string system_language;
  std::string user_agent;

 private:
  DISALLOW_COPY_AND_ASSIGN(NonTrivialStaticFields);
};

struct SecurityFlags {
  csp::CSPHeaderPolicy csp_header_policy;
  network::HTTPSRequirement https_requirement;
};

// |non_trivial_static_fields| will be lazily created on the first time it's
// accessed.
base::LazyInstance<NonTrivialStaticFields>::DestructorAtExit
    non_trivial_static_fields = LAZY_INSTANCE_INITIALIZER;

#if defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
const char kMemoryTrackerCommand[] = "memory_tracker";
const char kMemoryTrackerCommandShortHelp[] = "Create a memory tracker.";
const char kMemoryTrackerCommandLongHelp[] =
    "Create a memory tracker of the given type. Use an empty string to see the "
    "available trackers.";
#endif  // defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)

void AddCrashHandlerAnnotations() {
  auto crash_handler_extension =
      static_cast<const CobaltExtensionCrashHandlerApi*>(
          SbSystemGetExtension(kCobaltExtensionCrashHandlerName));
  if (!crash_handler_extension) {
    LOG(INFO) << "No crash handler extension, not sending annotations.";
    return;
  }

  auto platform_info = cobalt::browser::GetUserAgentPlatformInfoFromSystem();
  std::string user_agent =
      cobalt::browser::CreateUserAgentString(platform_info);
  std::string version = "";
#if SB_IS(EVERGREEN)
  version = cobalt::updater::GetCurrentEvergreenVersion();
  std::string product = "Cobalt_Evergreen";
#else
  std::string product = "Cobalt";
#endif
  if (version.empty()) {
    base::StringAppendF(&version, "%s.%s-%s",
                        platform_info.cobalt_version().c_str(),
                        platform_info.cobalt_build_version_number().c_str(),
                        platform_info.build_configuration().c_str());
  }

  user_agent.push_back('\0');
  product.push_back('\0');
  version.push_back('\0');

  bool result = true;
  if (crash_handler_extension->version == 1) {
    CrashpadAnnotations crashpad_annotations;
    memset(&crashpad_annotations, 0, sizeof(CrashpadAnnotations));
    strncpy(crashpad_annotations.user_agent_string, user_agent.c_str(),
            USER_AGENT_STRING_MAX_SIZE);
    strncpy(crashpad_annotations.product, product.c_str(),
            CRASHPAD_ANNOTATION_DEFAULT_LENGTH);
    strncpy(crashpad_annotations.version, version.c_str(),
            CRASHPAD_ANNOTATION_DEFAULT_LENGTH);
    result = crash_handler_extension->OverrideCrashpadAnnotations(
        &crashpad_annotations);
  } else if (crash_handler_extension->version > 1) {
    // These particular annotation key names (e.g., ver) are expected by
    // Crashpad.
    // TODO(b/201538792): figure out a clean way to define these constants once
    // and use them everywhere.
    if (!crash_handler_extension->SetString("user_agent_string",
                                            user_agent.c_str())) {
      result = false;
    }
    // TODO(b/265339522): move crashpad prod and ver setter to starboard.
    if (!crash_handler_extension->SetString("prod", product.c_str())) {
      result = false;
    }
    if (!crash_handler_extension->SetString("ver", version.c_str())) {
      result = false;
    }
  } else {
    result = false;
  }  // Invalid extension version
  if (result) {
    LOG(INFO) << "Sent annotations to crash handler";
  } else {
    LOG(ERROR) << "Could not send some annotation(s) to crash handler.";
  }
}

}  // namespace

// Helper stub to disable histogram tracking in StatisticsRecorder
struct RecordCheckerStub : public base::RecordHistogramChecker {
  bool ShouldRecord(uint64_t) const override { return false; }
};

// Static user logs
ssize_t Application::available_memory_ = 0;
int64 Application::lifetime_in_ms_ = 0;

Application::Application(const base::Closure& quit_closure, bool should_preload,
                         SbTimeMonotonic timestamp)
    : message_loop_(base::MessageLoop::current()),
      quit_closure_(quit_closure)
#if defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
      ,
      ALLOW_THIS_IN_INITIALIZER_LIST(memory_tracker_command_handler_(
          kMemoryTrackerCommand,
          base::Bind(&Application::OnMemoryTrackerCommand,
                     base::Unretained(this)),
          kMemoryTrackerCommandShortHelp, kMemoryTrackerCommandLongHelp))
#endif  // defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
{
  DCHECK(!quit_closure_.is_null());
  if (should_preload) {
    preload_timestamp_ = timestamp;
  } else {
    start_timestamp_ = timestamp;
  }
  // Check to see if a timed_trace has been set, indicating that we should
  // begin a timed trace upon startup.
  base::TimeDelta trace_duration = GetTimedTraceDuration();
  if (trace_duration != base::TimeDelta()) {
    trace_event::TraceToFileForDuration(
        base::FilePath(FILE_PATH_LITERAL("timed_trace.json")), trace_duration);
  }

  TRACE_EVENT0("cobalt::browser", "Application::Application()");

  DCHECK(base::MessageLoop::current());
  DCHECK_EQ(
      base::MessageLoop::TYPE_UI,
      static_cast<base::MessageLoop*>(base::MessageLoop::current())->type());

  DETACH_FROM_THREAD(network_event_thread_checker_);
  DETACH_FROM_THREAD(application_event_thread_checker_);

  // Set the minimum logging level, if specified on the command line.
  logging::SetMinLogLevel(StringToLogLevel(GetMinLogLevelString()));

  stats_update_timer_.Start(
      FROM_HERE, base::TimeDelta::FromMilliseconds(kStatUpdatePeriodMs),
      base::Bind(&Application::UpdatePeriodicStats, base::Unretained(this)));

  // Get the initial URL.
  GURL initial_url = GetInitialURL(should_preload);
  DLOG(INFO) << "Initial URL: " << initial_url;

  // Get the fallback splash screen URL.
  base::Optional<GURL> fallback_splash_screen_url =
      GetFallbackSplashScreenURL();
  DLOG(INFO) << "Fallback splash screen URL: "
             << (fallback_splash_screen_url ? fallback_splash_screen_url->spec()
                                            : "none");

  // Get the system language and initialize our localized strings.
  std::string language = base::GetSystemLanguage();
  base::LocalizedStrings::GetInstance()->Initialize(language);

  // Disable histogram tracking before TaskScheduler creates StatisticsRecorder
  // instances.
  auto record_checker = std::make_unique<RecordCheckerStub>();
  base::StatisticsRecorder::SetRecordChecker(std::move(record_checker));

  // A one-per-process task scheduler is needed for usage of APIs in
  // base/post_task.h which will be used by some net APIs like
  // URLRequestContext;
  base::TaskScheduler::CreateAndStartWithDefaultParams("Cobalt TaskScheduler");

  // Initializes persistent settings.
  persistent_settings_ =
      std::make_unique<persistent_storage::PersistentSettings>(
          kPersistentSettingsJson);

  // Initializes Watchdog.
  watchdog::Watchdog* watchdog =
      watchdog::Watchdog::CreateInstance(persistent_settings_.get());
  DCHECK(watchdog);

  // Registers Stats as a watchdog client.
  if (watchdog)
    watchdog->Register(kWatchdogName, kWatchdogName,
                       base::kApplicationStateStarted, kWatchdogTimeInterval,
                       kWatchdogTimeWait, watchdog::NONE);

  cobalt::cache::Cache::GetInstance()->set_persistent_settings(
      persistent_settings_.get());

  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  base::Optional<cssom::ViewportSize> requested_viewport_size =
      GetRequestedViewportSize(command_line);

  unconsumed_deep_link_ = GetInitialDeepLink();
  DLOG(INFO) << "Initial deep link: " << unconsumed_deep_link_;

  storage::StorageManager::Options storage_manager_options;
  network::NetworkModule::Options network_module_options;
  // Create the main components of our browser.
  BrowserModule::Options options;
  network_module_options.preferred_language = language;
  network_module_options.persistent_settings = persistent_settings_.get();
  options.persistent_settings = persistent_settings_.get();
  options.command_line_auto_mem_settings =
      memory_settings::GetSettings(*command_line);
  options.build_auto_mem_settings = memory_settings::GetDefaultBuildSettings();
  options.fallback_splash_screen_url = fallback_splash_screen_url;

  ParseFallbackSplashScreenTopics(fallback_splash_screen_url,
                                  &options.fallback_splash_screen_topic_map);

  if (command_line->HasSwitch(browser::switches::kFPSPrint)) {
    options.renderer_module_options.enable_fps_stdout = true;
  }
  if (command_line->HasSwitch(browser::switches::kFPSOverlay)) {
    options.renderer_module_options.enable_fps_overlay = true;
  }

  ApplyCommandLineSettingsToRendererOptions(&options.renderer_module_options);

  if (command_line->HasSwitch(browser::switches::kDisableJavaScriptJit)) {
    options.web_module_options.web_options.javascript_engine_options
        .disable_jit = true;
  }

  if (command_line->HasSwitch(
          browser::switches::kRetainRemoteTypefaceCacheDuringSuspend)) {
    options.web_module_options.should_retain_remote_typeface_cache_on_freeze =
        true;
  }

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  if (command_line->HasSwitch(browser::switches::kNullSavegame)) {
    storage_manager_options.savegame_options.factory =
        &storage::SavegameFake::Create;
  }

  if (command_line->HasSwitch(browser::switches::kDisableOnScreenKeyboard)) {
    options.enable_on_screen_keyboard = false;
  }

#endif  // defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)

#if defined(COBALT_ENABLE_VERSION_COMPATIBILITY_VALIDATIONS)
  constexpr int kDefaultMinCompatibilityVersion = 1;
  int minimum_version = kDefaultMinCompatibilityVersion;
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  if (command_line->HasSwitch(browser::switches::kMinCompatibilityVersion)) {
    std::string switch_value =
        command_line->GetSwitchValueASCII(switches::kMinCompatibilityVersion);
    if (!base::StringToInt(switch_value, &minimum_version)) {
      DLOG(ERROR) << "Invalid min_compatibility_version provided.";
    }
  }
#endif  // defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  base::VersionCompatibility::GetInstance()->SetMinimumVersion(minimum_version);
#endif  // defined(COBALT_ENABLE_VERSION_COMPATIBILITY_VALIDATIONS)

  base::Optional<std::string> partition_key;
  if (command_line->HasSwitch(browser::switches::kLocalStoragePartitionUrl)) {
    std::string local_storage_partition_url = command_line->GetSwitchValueASCII(
        browser::switches::kLocalStoragePartitionUrl);
    partition_key = base::GetApplicationKey(GURL(local_storage_partition_url));
    CHECK(partition_key) << "local_storage_partition_url is not a valid URL.";
  } else {
    partition_key = base::GetApplicationKey(initial_url);
  }
  storage_manager_options.savegame_options.id = partition_key;

  base::Optional<std::string> default_key =
      base::GetApplicationKey(GURL(kDefaultURL));
  if (command_line->HasSwitch(
          browser::switches::kForceMigrationForStoragePartitioning) ||
      partition_key == default_key) {
    storage_manager_options.savegame_options.fallback_to_default_id = true;
  }

  // User can specify an extra search path entry for files loaded via file://.
  options.web_module_options.web_options.extra_web_file_dir =
      GetExtraWebFileDir();
  SecurityFlags security_flags{csp::kCSPRequired, network::kHTTPSRequired};
  // Set callback to be notified when a navigation occurs that destroys the
  // underlying WebModule.
  options.web_module_created_callback =
      base::Bind(&Application::MainWebModuleCreated, base::Unretained(this));

  // The main web module's stat tracker tracks event stats.
  options.web_module_options.track_event_stats = true;

  if (command_line->HasSwitch(browser::switches::kProxy)) {
    network_module_options.custom_proxy =
        command_line->GetSwitchValueASCII(browser::switches::kProxy);
  }

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
#if defined(ENABLE_IGNORE_CERTIFICATE_ERRORS)
  if (command_line->HasSwitch(browser::switches::kIgnoreCertificateErrors)) {
    network_module_options.ignore_certificate_errors = true;
  }
#endif  // defined(ENABLE_IGNORE_CERTIFICATE_ERRORS)

  if (!command_line->HasSwitch(switches::kRequireHTTPSLocation)) {
    security_flags.https_requirement = network::kHTTPSOptional;
  }

  if (!command_line->HasSwitch(browser::switches::kRequireCSP)) {
    security_flags.csp_header_policy = csp::kCSPOptional;
  }

  if (command_line->HasSwitch(browser::switches::kProd)) {
    security_flags.https_requirement = network::kHTTPSRequired;
    security_flags.csp_header_policy = csp::kCSPRequired;
  }

  if (command_line->HasSwitch(switches::kVideoPlaybackRateMultiplier)) {
    double playback_rate = 1.0;
    base::StringToDouble(command_line->GetSwitchValueASCII(
                             switches::kVideoPlaybackRateMultiplier),
                         &playback_rate);
    options.web_module_options.video_playback_rate_multiplier =
        static_cast<float>(playback_rate);
    DLOG(INFO) << "Set video playback rate multiplier to "
               << options.web_module_options.video_playback_rate_multiplier;
  }

  EnableUsingStubImageDecoderIfRequired();

#if defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
  if (command_line->HasSwitch(switches::kMemoryTracker)) {
    std::string command_arg =
        command_line->GetSwitchValueASCII(switches::kMemoryTracker);
    memory_tracker_tool_ = memory_tracker::CreateMemoryTrackerTool(command_arg);
  }
#endif  // defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)

  if (command_line->HasSwitch(switches::kDisableImageAnimations)) {
    options.web_module_options.enable_image_animations = false;
  }
  if (command_line->HasSwitch(switches::kDisableSplashScreenOnReloads)) {
    options.enable_splash_screen_on_reloads = false;
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES

// Production-builds override all switches to the most secure configuration.
#if defined(COBALT_FORCE_HTTPS)
  security_flags.https_requirement = network::kHTTPSRequired;
#endif  // defined(COBALT_FORCE_HTTPS)

#if defined(COBALT_FORCE_CSP)
  security_flags.csp_header_policy = csp::kCSPRequired;
#endif  // defined(COBALT_FORCE_CSP)

  network_module_options.https_requirement = security_flags.https_requirement;
  options.web_module_options.csp_header_policy =
      security_flags.csp_header_policy;
  options.web_module_options.csp_enforcement_type = web::kCspEnforcementEnable;

  options.requested_viewport_size = requested_viewport_size;

  // Set callback to collect unload event time before firing document's unload
  // event.
  options.web_module_options.collect_unload_event_time_callback = base::Bind(
      &Application::CollectUnloadEventTimingInfo, base::Unretained(this));

  account_manager_.reset(new account::AccountManager());

  storage_manager_.reset(new storage::StorageManager(storage_manager_options));

  network_module_.reset(new network::NetworkModule(
      CreateUserAgentString(GetUserAgentPlatformInfoFromSystem()),
      storage_manager_.get(), &event_dispatcher_, network_module_options));

  AddCrashHandlerAnnotations();

#if SB_IS(EVERGREEN)
  if (SbSystemGetExtension(kCobaltExtensionInstallationManagerName) &&
      !command_line->HasSwitch(switches::kDisableUpdaterModule)) {
    uint64_t update_check_delay_sec =
        cobalt::updater::kDefaultUpdateCheckDelaySeconds;
    if (command_line->HasSwitch(browser::switches::kUpdateCheckDelaySeconds)) {
      std::string seconds_value = command_line->GetSwitchValueASCII(
          browser::switches::kUpdateCheckDelaySeconds);
      if (!base::StringToUint64(seconds_value, &update_check_delay_sec)) {
        LOG(WARNING) << "Invalid delay specified for the update check: "
                     << seconds_value << ". Using default value: "
                     << cobalt::updater::kDefaultUpdateCheckDelaySeconds;
        update_check_delay_sec =
            cobalt::updater::kDefaultUpdateCheckDelaySeconds;
      }
    }
    updater_module_.reset(new updater::UpdaterModule(network_module_.get(),
                                                     update_check_delay_sec));
  }
#endif
  browser_module_.reset(new BrowserModule(
      initial_url,
      (should_preload ? base::kApplicationStateConcealed
                      : base::kApplicationStateStarted),
      &event_dispatcher_, account_manager_.get(), network_module_.get(),
#if SB_IS(EVERGREEN)
      updater_module_.get(),
#endif
      options));

  UpdateUserAgent();

  // Register event callbacks.
  window_size_change_event_callback_ = base::Bind(
      &Application::OnWindowSizeChangedEvent, base::Unretained(this));
  event_dispatcher_.AddEventCallback(base::WindowSizeChangedEvent::TypeId(),
                                     window_size_change_event_callback_);
  on_screen_keyboard_shown_event_callback_ = base::Bind(
      &Application::OnOnScreenKeyboardShownEvent, base::Unretained(this));
  event_dispatcher_.AddEventCallback(base::OnScreenKeyboardShownEvent::TypeId(),
                                     on_screen_keyboard_shown_event_callback_);
  on_screen_keyboard_hidden_event_callback_ = base::Bind(
      &Application::OnOnScreenKeyboardHiddenEvent, base::Unretained(this));
  event_dispatcher_.AddEventCallback(
      base::OnScreenKeyboardHiddenEvent::TypeId(),
      on_screen_keyboard_hidden_event_callback_);
  on_screen_keyboard_focused_event_callback_ = base::Bind(
      &Application::OnOnScreenKeyboardFocusedEvent, base::Unretained(this));
  event_dispatcher_.AddEventCallback(
      base::OnScreenKeyboardFocusedEvent::TypeId(),
      on_screen_keyboard_focused_event_callback_);
  on_screen_keyboard_blurred_event_callback_ = base::Bind(
      &Application::OnOnScreenKeyboardBlurredEvent, base::Unretained(this));
  event_dispatcher_.AddEventCallback(
      base::OnScreenKeyboardBlurredEvent::TypeId(),
      on_screen_keyboard_blurred_event_callback_);
  on_screen_keyboard_suggestions_updated_event_callback_ =
      base::Bind(&Application::OnOnScreenKeyboardSuggestionsUpdatedEvent,
                 base::Unretained(this));
  event_dispatcher_.AddEventCallback(
      base::OnScreenKeyboardSuggestionsUpdatedEvent::TypeId(),
      on_screen_keyboard_suggestions_updated_event_callback_);
  on_caption_settings_changed_event_callback_ = base::Bind(
      &Application::OnCaptionSettingsChangedEvent, base::Unretained(this));
  event_dispatcher_.AddEventCallback(
      base::AccessibilityCaptionSettingsChangedEvent::TypeId(),
      on_caption_settings_changed_event_callback_);
  on_window_on_online_event_callback_ =
      base::Bind(&Application::OnWindowOnOnlineEvent, base::Unretained(this));
  event_dispatcher_.AddEventCallback(base::WindowOnOnlineEvent::TypeId(),
                                     on_window_on_online_event_callback_);
  on_window_on_offline_event_callback_ =
      base::Bind(&Application::OnWindowOnOfflineEvent, base::Unretained(this));
  event_dispatcher_.AddEventCallback(base::WindowOnOfflineEvent::TypeId(),
                                     on_window_on_offline_event_callback_);
#if SB_API_VERSION >= 13
  on_date_time_configuration_changed_event_callback_ =
      base::Bind(&Application::OnDateTimeConfigurationChangedEvent,
                 base::Unretained(this));
  event_dispatcher_.AddEventCallback(
      base::DateTimeConfigurationChangedEvent::TypeId(),
      on_date_time_configuration_changed_event_callback_);
#endif

#if defined(ENABLE_WEBDRIVER)
#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  bool create_webdriver_module =
      !command_line->HasSwitch(switches::kDisableWebDriver);
#else
  bool create_webdriver_module = true;
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
  if (create_webdriver_module) {
    web_driver_module_.reset(new webdriver::WebDriverModule(
        GetWebDriverPort(), GetDevServersListenIp(),
        base::Bind(&BrowserModule::CreateSessionDriver,
                   base::Unretained(browser_module_.get())),
        base::Bind(&BrowserModule::RequestScreenshotToMemory,
                   base::Unretained(browser_module_.get())),
        base::Bind(&BrowserModule::SetProxy,
                   base::Unretained(browser_module_.get())),
        base::Bind(&Application::Quit, base::Unretained(this))));
  }
#endif  // ENABLE_WEBDRIVER

#if defined(ENABLE_DEBUGGER)
  int remote_debugging_port = GetRemoteDebuggingPort();
  if (remote_debugging_port == 0) {
    DLOG(INFO) << "Remote web debugger disabled because "
               << switches::kRemoteDebuggingPort << " is 0.";
  } else {
    debug_web_server_.reset(new debug::remote::DebugWebServer(
        remote_debugging_port, GetDevServersListenIp(),
        base::Bind(&BrowserModule::CreateDebugClient,
                   base::Unretained(browser_module_.get()))));
  }
#endif  // ENABLE_DEBUGGER

#if defined(ENABLE_DEBUG_COMMAND_LINE_SWITCHES)
  int duration_in_seconds = 0;
  if (command_line->HasSwitch(switches::kShutdownAfter) &&
      base::StringToInt(
          command_line->GetSwitchValueASCII(switches::kShutdownAfter),
          &duration_in_seconds)) {
    // If the "shutdown_after" command line option is specified, setup a delayed
    // message to quit the application after the specified number of seconds
    // have passed.
    message_loop_->task_runner()->PostDelayedTask(
        FROM_HERE, quit_closure_,
        base::TimeDelta::FromSeconds(duration_in_seconds));
  }
#endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
}

Application::~Application() {
  // explicitly reset here because the destruction of the object is complex
  // and involves a thread join. If this were to hang the app then having
  // the destruction at this point gives a real file-line number and a place
  // for the debugger to land.
  watchdog::Watchdog::DeleteInstance();

#if defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
  memory_tracker_tool_.reset(NULL);
#endif  // defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)

  // Unregister event callbacks.
  event_dispatcher_.RemoveEventCallback(base::WindowSizeChangedEvent::TypeId(),
                                        window_size_change_event_callback_);
  event_dispatcher_.RemoveEventCallback(
      base::OnScreenKeyboardShownEvent::TypeId(),
      on_screen_keyboard_shown_event_callback_);
  event_dispatcher_.RemoveEventCallback(
      base::OnScreenKeyboardHiddenEvent::TypeId(),
      on_screen_keyboard_hidden_event_callback_);
  event_dispatcher_.RemoveEventCallback(
      base::OnScreenKeyboardFocusedEvent::TypeId(),
      on_screen_keyboard_focused_event_callback_);
  event_dispatcher_.RemoveEventCallback(
      base::OnScreenKeyboardBlurredEvent::TypeId(),
      on_screen_keyboard_blurred_event_callback_);
  event_dispatcher_.RemoveEventCallback(
      base::OnScreenKeyboardSuggestionsUpdatedEvent::TypeId(),
      on_screen_keyboard_suggestions_updated_event_callback_);
  event_dispatcher_.RemoveEventCallback(
      base::AccessibilityCaptionSettingsChangedEvent::TypeId(),
      on_caption_settings_changed_event_callback_);
#if SB_API_VERSION >= 13
  event_dispatcher_.RemoveEventCallback(
      base::DateTimeConfigurationChangedEvent::TypeId(),
      on_date_time_configuration_changed_event_callback_);
#endif
}

void Application::Start(SbTimeMonotonic timestamp) {
  if (base::MessageLoop::current() != message_loop_) {
    message_loop_->task_runner()->PostTask(
        FROM_HERE,
        base::Bind(&Application::Start, base::Unretained(this), timestamp));
    return;
  }
  DCHECK_CALLED_ON_VALID_THREAD(application_event_thread_checker_);

  if (!start_timestamp_.has_value()) {
    start_timestamp_ = timestamp;
  }
  OnApplicationEvent(kSbEventTypeStart, timestamp);
}

void Application::Quit() {
  if (base::MessageLoop::current() != message_loop_) {
    message_loop_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&Application::Quit, base::Unretained(this)));
    return;
  }
  DCHECK_CALLED_ON_VALID_THREAD(application_event_thread_checker_);

  quit_closure_.Run();
}

void Application::HandleStarboardEvent(const SbEvent* starboard_event) {
  DCHECK(starboard_event);
  DCHECK_EQ(base::MessageLoop::current(), message_loop_);

  // Forward input events to |SystemWindow|.
  if (starboard_event->type == kSbEventTypeInput) {
    system_window::HandleInputEvent(starboard_event);
    return;
  }

  // Create a Cobalt event from the Starboard event, if recognized.
  switch (starboard_event->type) {
#if SB_API_VERSION >= 13
    case kSbEventTypeBlur:
    case kSbEventTypeFocus:
    case kSbEventTypeConceal:
    case kSbEventTypeReveal:
    case kSbEventTypeFreeze:
    case kSbEventTypeUnfreeze:
    case kSbEventTypeLowMemory:
      OnApplicationEvent(starboard_event->type, starboard_event->timestamp);
      break;
#else
    case kSbEventTypePause:
    case kSbEventTypeUnpause:
    case kSbEventTypeSuspend:
    case kSbEventTypeResume:
    case kSbEventTypeLowMemory:
      OnApplicationEvent(starboard_event->type, SbTimeGetMonotonicNow());
      break;
#endif  // SB_API_VERSION >= 13
    case kSbEventTypeWindowSizeChanged:
      DispatchEventInternal(new base::WindowSizeChangedEvent(
          static_cast<SbEventWindowSizeChangedData*>(starboard_event->data)
              ->window,
          static_cast<SbEventWindowSizeChangedData*>(starboard_event->data)
              ->size));
      break;
    case kSbEventTypeOnScreenKeyboardShown:
      DCHECK(starboard_event->data);
      DispatchEventInternal(new base::OnScreenKeyboardShownEvent(
          *static_cast<int*>(starboard_event->data)));
      break;
    case kSbEventTypeOnScreenKeyboardHidden:
      DispatchEventInternal(new base::OnScreenKeyboardHiddenEvent(
          *static_cast<int*>(starboard_event->data)));
      break;
    case kSbEventTypeOnScreenKeyboardFocused:
      DCHECK(starboard_event->data);
      DispatchEventInternal(new base::OnScreenKeyboardFocusedEvent(
          *static_cast<int*>(starboard_event->data)));
      break;
    case kSbEventTypeOnScreenKeyboardBlurred:
      DispatchEventInternal(new base::OnScreenKeyboardBlurredEvent(
          *static_cast<int*>(starboard_event->data)));
      break;
    case kSbEventTypeOnScreenKeyboardSuggestionsUpdated:
      DispatchEventInternal(new base::OnScreenKeyboardSuggestionsUpdatedEvent(
          *static_cast<int*>(starboard_event->data)));
      break;
    case kSbEventTypeLink: {
#if SB_API_VERSION >= 13
      DispatchDeepLink(static_cast<const char*>(starboard_event->data),
                       starboard_event->timestamp);
#else   // SB_API_VERSION >= 13
      DispatchDeepLink(static_cast<const char*>(starboard_event->data),
                       SbTimeGetMonotonicNow());
#endif  // SB_API_VERSION >= 13
      break;
    }
#if SB_API_VERSION >= 13
    case kSbEventTypeAccessibilitySettingsChanged:
#else
    case kSbEventTypeAccessiblitySettingsChanged:
#endif  // SB_API_VERSION >= 13
      DispatchEventInternal(new base::AccessibilitySettingsChangedEvent());
      break;
    case kSbEventTypeAccessibilityCaptionSettingsChanged:
      DispatchEventInternal(
          new base::AccessibilityCaptionSettingsChangedEvent());
      break;
#if SB_API_VERSION >= 13
    case kSbEventTypeAccessibilityTextToSpeechSettingsChanged:
#else
    case kSbEventTypeAccessiblityTextToSpeechSettingsChanged:
#endif  // SB_API_VERSION >= 13
      DispatchEventInternal(
          new base::AccessibilityTextToSpeechSettingsChangedEvent());
      break;
#if SB_API_VERSION >= 13
    case kSbEventTypeOsNetworkDisconnected:
      DispatchEventInternal(new base::WindowOnOfflineEvent());
      break;
    case kSbEventTypeOsNetworkConnected:
      DispatchEventInternal(new base::WindowOnOnlineEvent());
      break;
#endif
#if SB_API_VERSION >= 13
    case kSbEventDateTimeConfigurationChanged:
      DispatchEventInternal(new base::DateTimeConfigurationChangedEvent());
      break;
#endif
    // Explicitly list unhandled cases here so that the compiler can give a
    // warning when a value is added, but not handled.
    case kSbEventTypeInput:
    case kSbEventTypePreload:
    case kSbEventTypeScheduled:
    case kSbEventTypeStart:
    case kSbEventTypeStop:
    case kSbEventTypeUser:
    case kSbEventTypeVerticalSync:
      DLOG(WARNING) << "Unhandled Starboard event of type: "
                    << starboard_event->type;
  }
}

void Application::OnApplicationEvent(SbEventType event_type,
                                     SbTimeMonotonic timestamp) {
  TRACE_EVENT0("cobalt::browser", "Application::OnApplicationEvent()");
  DCHECK_CALLED_ON_VALID_THREAD(application_event_thread_checker_);

  watchdog::Watchdog* watchdog = watchdog::Watchdog::GetInstance();

  switch (event_type) {
    case kSbEventTypeStop:
      LOG(INFO) << "Got quit event.";
      if (watchdog) watchdog->UpdateState(base::kApplicationStateStopped);
      Quit();
      LOG(INFO) << "Finished quitting.";
      break;
    case kSbEventTypeStart:
      LOG(INFO) << "Got start event.";
      browser_module_->Reveal(timestamp);
      browser_module_->Focus(timestamp);
      LOG(INFO) << "Finished starting.";
      break;
#if SB_API_VERSION >= 13
    case kSbEventTypeBlur:
      LOG(INFO) << "Got blur event.";
      browser_module_->Blur(timestamp);
      LOG(INFO) << "Finished blurring.";
      break;
    case kSbEventTypeFocus:
      LOG(INFO) << "Got focus event.";
      browser_module_->Focus(timestamp);
      LOG(INFO) << "Finished focusing.";
      break;
    case kSbEventTypeConceal:
      LOG(INFO) << "Got conceal event.";
      browser_module_->Conceal(timestamp);
      LOG(INFO) << "Finished concealing.";
      break;
    case kSbEventTypeReveal:
      DCHECK(SbSystemSupportsResume());
      LOG(INFO) << "Got reveal event.";
      browser_module_->Reveal(timestamp);
      LOG(INFO) << "Finished revealing.";
      break;
    case kSbEventTypeFreeze:
      LOG(INFO) << "Got freeze event.";
      browser_module_->Freeze(timestamp);
#if SB_IS(EVERGREEN)
      if (updater_module_) updater_module_->Suspend();
#endif
      LOG(INFO) << "Finished freezing.";
      break;
    case kSbEventTypeUnfreeze:
      LOG(INFO) << "Got unfreeze event.";
      browser_module_->Unfreeze(timestamp);
#if SB_IS(EVERGREEN)
      if (updater_module_) updater_module_->Resume();
#endif
      LOG(INFO) << "Finished unfreezing.";
      break;
#else
    case kSbEventTypePause:
      LOG(INFO) << "Got pause event.";
      browser_module_->Blur(timestamp);
      LOG(INFO) << "Finished pausing.";
      break;
    case kSbEventTypeUnpause:
      LOG(INFO) << "Got unpause event.";
      browser_module_->Focus(timestamp);
      LOG(INFO) << "Finished unpausing.";
      break;
    case kSbEventTypeSuspend:
      LOG(INFO) << "Got suspend event.";
      browser_module_->Conceal(timestamp);
      browser_module_->Freeze(timestamp);
#if SB_IS(EVERGREEN)
      if (updater_module_) updater_module_->Suspend();
#endif
      LOG(INFO) << "Finished suspending.";
      break;
    case kSbEventTypeResume:
      DCHECK(SbSystemSupportsResume());
      LOG(INFO) << "Got resume event.";
      browser_module_->Unfreeze(timestamp);
      browser_module_->Reveal(timestamp);
#if SB_IS(EVERGREEN)
      if (updater_module_) updater_module_->Resume();
#endif
      LOG(INFO) << "Finished resuming.";
      break;
#endif  // SB_API_VERSION >= 13
    case kSbEventTypeLowMemory:
      DLOG(INFO) << "Got low memory event.";
      browser_module_->ReduceMemory();
      DLOG(INFO) << "Finished reducing memory usage.";
      break;
    // All of the remaining event types are unexpected:
    case kSbEventTypePreload:
    case kSbEventTypeWindowSizeChanged:
    case kSbEventTypeAccessibilityCaptionSettingsChanged:
#if SB_API_VERSION >= 13
    case kSbEventTypeAccessibilityTextToSpeechSettingsChanged:
#else
    case kSbEventTypeAccessiblityTextToSpeechSettingsChanged:
#endif  // SB_API_VERSION >= 13
    case kSbEventTypeOnScreenKeyboardBlurred:
    case kSbEventTypeOnScreenKeyboardFocused:
    case kSbEventTypeOnScreenKeyboardHidden:
    case kSbEventTypeOnScreenKeyboardShown:
    case kSbEventTypeOnScreenKeyboardSuggestionsUpdated:
#if SB_API_VERSION >= 13
    case kSbEventTypeAccessibilitySettingsChanged:
#else
    case kSbEventTypeAccessiblitySettingsChanged:
#endif  // SB_API_VERSION >= 13
    case kSbEventTypeInput:
    case kSbEventTypeLink:
    case kSbEventTypeScheduled:
    case kSbEventTypeUser:
    case kSbEventTypeVerticalSync:
#if SB_API_VERSION >= 13
    case kSbEventTypeOsNetworkDisconnected:
    case kSbEventTypeOsNetworkConnected:
#endif
#if SB_API_VERSION >= 13
    case kSbEventDateTimeConfigurationChanged:
#endif
      NOTREACHED() << "Unexpected event type: " << event_type;
      return;
  }
  if (watchdog) watchdog->UpdateState(browser_module_->GetApplicationState());
}

void Application::OnWindowSizeChangedEvent(const base::Event* event) {
  TRACE_EVENT0("cobalt::browser", "Application::OnWindowSizeChangedEvent()");
  const base::WindowSizeChangedEvent* window_size_change_event =
      base::polymorphic_downcast<const base::WindowSizeChangedEvent*>(event);
  const auto& size = window_size_change_event->size();
  float diagonal =
      SbWindowGetDiagonalSizeInInches(window_size_change_event->window());

  // A value of 0.0 for the video pixel ratio means that the ratio could not be
  // determined. In that case it should be assumed to be the same as the
  // graphics resolution, which corresponds to a device pixel ratio of 1.0.
  float device_pixel_ratio =
      (size.video_pixel_ratio == 0) ? 1.0f : size.video_pixel_ratio;
  cssom::ViewportSize viewport_size(size.width, size.height, diagonal,
                                    device_pixel_ratio);
  browser_module_->OnWindowSizeChanged(viewport_size);
}

void Application::OnOnScreenKeyboardShownEvent(const base::Event* event) {
  TRACE_EVENT0("cobalt::browser",
               "Application::OnOnScreenKeyboardShownEvent()");
  browser_module_->OnOnScreenKeyboardShown(
      base::polymorphic_downcast<const base::OnScreenKeyboardShownEvent*>(
          event));
}

void Application::OnOnScreenKeyboardHiddenEvent(const base::Event* event) {
  TRACE_EVENT0("cobalt::browser",
               "Application::OnOnScreenKeyboardHiddenEvent()");
  browser_module_->OnOnScreenKeyboardHidden(
      base::polymorphic_downcast<const base::OnScreenKeyboardHiddenEvent*>(
          event));
}

void Application::OnOnScreenKeyboardFocusedEvent(const base::Event* event) {
  TRACE_EVENT0("cobalt::browser",
               "Application::OnOnScreenKeyboardFocusedEvent()");
  browser_module_->OnOnScreenKeyboardFocused(
      base::polymorphic_downcast<const base::OnScreenKeyboardFocusedEvent*>(
          event));
}

void Application::OnOnScreenKeyboardBlurredEvent(const base::Event* event) {
  TRACE_EVENT0("cobalt::browser",
               "Application::OnOnScreenKeyboardBlurredEvent()");
  browser_module_->OnOnScreenKeyboardBlurred(
      base::polymorphic_downcast<const base::OnScreenKeyboardBlurredEvent*>(
          event));
}

void Application::OnOnScreenKeyboardSuggestionsUpdatedEvent(
    const base::Event* event) {
  TRACE_EVENT0("cobalt::browser",
               "Application::OnOnScreenKeyboardSuggestionsUpdatedEvent()");
  browser_module_->OnOnScreenKeyboardSuggestionsUpdated(
      base::polymorphic_downcast<
          const base::OnScreenKeyboardSuggestionsUpdatedEvent*>(event));
}

void Application::OnCaptionSettingsChangedEvent(const base::Event* event) {
  TRACE_EVENT0("cobalt::browser",
               "Application::OnCaptionSettingsChangedEvent()");
  browser_module_->OnCaptionSettingsChanged(
      base::polymorphic_downcast<
          const base::AccessibilityCaptionSettingsChangedEvent*>(event));
}

void Application::OnWindowOnOnlineEvent(const base::Event* event) {
  browser_module_->OnWindowOnOnlineEvent(
      base::polymorphic_downcast<const base::WindowOnOnlineEvent*>(event));
}
void Application::OnWindowOnOfflineEvent(const base::Event* event) {
  browser_module_->OnWindowOnOfflineEvent(
      base::polymorphic_downcast<const base::WindowOnOfflineEvent*>(event));
}

#if SB_API_VERSION >= 13
void Application::OnDateTimeConfigurationChangedEvent(
    const base::Event* event) {
  TRACE_EVENT0("cobalt::browser",
               "Application::OnDateTimeConfigurationChangedEvent()");
  browser_module_->OnDateTimeConfigurationChanged(
      base::polymorphic_downcast<
          const base::DateTimeConfigurationChangedEvent*>(event));
}
#endif

void Application::MainWebModuleCreated(WebModule* web_module) {
  TRACE_EVENT0("cobalt::browser", "Application::MainWebModuleCreated()");
  // Note: This is a callback function that runs in the MainWebModule thread.
  DCHECK(web_module);
  if (preload_timestamp_.has_value()) {
    web_module->SetApplicationStartOrPreloadTimestamp(
        true, preload_timestamp_.value());
  }
  if (start_timestamp_.has_value()) {
    web_module->SetApplicationStartOrPreloadTimestamp(false,
                                                      start_timestamp_.value());
  }
  DispatchDeepLinkIfNotConsumed();
#if defined(ENABLE_WEBDRIVER)
  if (web_driver_module_) {
    web_driver_module_->OnWindowRecreated();
  }
#endif
  if (!unload_event_start_time_.is_null() ||
      !unload_event_end_time_.is_null()) {
    web_module->SetUnloadEventTimingInfo(unload_event_start_time_,
                                         unload_event_end_time_);
  }
}

void Application::CollectUnloadEventTimingInfo(base::TimeTicks start_time,
                                               base::TimeTicks end_time) {
  unload_event_start_time_ = start_time;
  unload_event_end_time_ = end_time;
}

Application::CValStats::CValStats()
    : free_cpu_memory("Memory.CPU.Free", 0,
                      "Total free application CPU memory remaining."),
      used_cpu_memory("Memory.CPU.Used", 0,
                      "Total CPU memory allocated via the app's allocators."),
      app_start_time("Time.Cobalt.Start",
                     base::StartupTimer::StartTime().ToInternalValue(),
                     "Start time of the application in microseconds."),
      app_lifetime("Cobalt.Lifetime", base::TimeDelta(),
                   "Application lifetime in microseconds.") {
  if (SbSystemHasCapability(kSbSystemCapabilityCanQueryGPUMemoryStats)) {
    free_gpu_memory.emplace("Memory.GPU.Free", 0,
                            "Total free application GPU memory remaining.");
    used_gpu_memory.emplace("Memory.GPU.Used", 0,
                            "Total GPU memory allocated by the application.");
  }
}

// NOTE: UserAgent registration is handled separately, as the value is not
// available when the app is first being constructed. Registration must happen
// each time the user agent is modified, because the string may be pointing
// to a new location on the heap.
void Application::UpdateUserAgent() {
  non_trivial_static_fields.Get().user_agent = browser_module_->GetUserAgent();
  LOG(INFO) << "User Agent: " << non_trivial_static_fields.Get().user_agent;
}

void Application::UpdatePeriodicStats() {
  TRACE_EVENT0("cobalt::browser", "Application::UpdatePeriodicStats()");
  c_val_stats_.app_lifetime = base::StartupTimer::TimeElapsed();

  // Pings watchdog.
  watchdog::Watchdog* watchdog = watchdog::Watchdog::GetInstance();
  if (watchdog) {
#if defined(_DEBUG)
    // Injects delay for watchdog debugging.
    watchdog->MaybeInjectDebugDelay(kWatchdogName);
#endif  // defined(_DEBUG)
    watchdog->Ping(kWatchdogName);
  }

  int64_t used_cpu_memory = SbSystemGetUsedCPUMemory();
  base::Optional<int64_t> used_gpu_memory;
  if (SbSystemHasCapability(kSbSystemCapabilityCanQueryGPUMemoryStats)) {
    used_gpu_memory = SbSystemGetUsedGPUMemory();
  }

  available_memory_ =
      static_cast<ssize_t>(SbSystemGetTotalCPUMemory() - used_cpu_memory);
  c_val_stats_.free_cpu_memory = available_memory_;
  c_val_stats_.used_cpu_memory = used_cpu_memory;

  if (used_gpu_memory) {
    *c_val_stats_.free_gpu_memory =
        SbSystemGetTotalGPUMemory() - *used_gpu_memory;
    *c_val_stats_.used_gpu_memory = *used_gpu_memory;
  }

  browser_module_->UpdateJavaScriptHeapStatistics();

  browser_module_->CheckMemory(used_cpu_memory, used_gpu_memory);
}

void Application::DispatchEventInternal(base::Event* event) {
  event_dispatcher_.DispatchEvent(std::unique_ptr<base::Event>(event));
}

#if defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
void Application::OnMemoryTrackerCommand(const std::string& message) {
  if (base::MessageLoop::current() != message_loop_) {
    message_loop_->task_runner()->PostTask(
        FROM_HERE, base::Bind(&Application::OnMemoryTrackerCommand,
                              base::Unretained(this), message));
    return;
  }

  if (memory_tracker_tool_) {
    LOG(ERROR) << "Can not create a memory tracker when one is already active.";
    return;
  }
  LOG(WARNING) << "Creating \"" << message << "\" memory tracker.";
  memory_tracker_tool_ = memory_tracker::CreateMemoryTrackerTool(message);
}
#endif  // defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)

// Called to handle deep link consumed events.
void Application::OnDeepLinkConsumedCallback(const std::string& link) {
  LOG(INFO) << "Got deep link consumed callback: " << link;
  base::AutoLock auto_lock(unconsumed_deep_link_lock_);
  if (link == unconsumed_deep_link_) {
    unconsumed_deep_link_.clear();
  }
}

void Application::DispatchDeepLink(const char* link,
                                   SbTimeMonotonic timestamp) {
  if (!link || *link == 0) {
    return;
  }

  std::string deep_link;
  // This block exists to ensure that the lock is held while accessing
  // unconsumed_deep_link_.
  {
    base::AutoLock auto_lock(unconsumed_deep_link_lock_);
    // Stash the deep link so that if it is not consumed, it can be dispatched
    // again after the next WebModule is created.
    unconsumed_deep_link_ = link;
    deep_link = unconsumed_deep_link_;
    deep_link_timestamp_ = timestamp;
  }

  LOG(INFO) << "Dispatching deep link: " << deep_link;
  DispatchEventInternal(new base::DeepLinkEvent(
      deep_link, base::Bind(&Application::OnDeepLinkConsumedCallback,
                            base::Unretained(this), deep_link)));
#if SB_API_VERSION >= 13
  if (browser_module_) {
    browser_module_->SetDeepLinkTimestamp(timestamp);
  }
#endif  // SB_API_VERSION >= 13
}

void Application::DispatchDeepLinkIfNotConsumed() {
  std::string deep_link;
#if SB_API_VERSION >= 13
  SbTimeMonotonic timestamp;
#endif  // SB_API_VERSION >= 13
  // This block exists to ensure that the lock is held while accessing
  // unconsumed_deep_link_.
  {
    base::AutoLock auto_lock(unconsumed_deep_link_lock_);
    deep_link = unconsumed_deep_link_;
#if SB_API_VERSION >= 13
    timestamp = deep_link_timestamp_;
#endif  // SB_API_VERSION >= 13
  }

  if (!deep_link.empty()) {
    LOG(INFO) << "Dispatching deep link: " << deep_link;
    DispatchEventInternal(new base::DeepLinkEvent(
        deep_link, base::Bind(&Application::OnDeepLinkConsumedCallback,
                              base::Unretained(this), deep_link)));
  }
#if SB_API_VERSION >= 13
  if (browser_module_) {
    browser_module_->SetDeepLinkTimestamp(timestamp);
  }
#endif  // SB_API_VERSION >= 13
}

}  // namespace browser
}  // namespace cobalt

const char* GetCobaltUserAgentString() {
  static std::string ua = cobalt::browser::CreateUserAgentString(
      cobalt::browser::GetUserAgentPlatformInfoFromSystem());
  return ua.c_str();
}
