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

#include <algorithm>
#include <memory>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/base/tokens.h"
#include "cobalt/cssom/css_computed_style_declaration.h"
#include "cobalt/cssom/user_agent_style_sheet.h"
#include "cobalt/cssom/viewport_size.h"
#include "cobalt/dom/base64.h"
#include "cobalt/dom/camera_3d.h"
#include "cobalt/dom/console.h"
#include "cobalt/dom/device_orientation_event.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/dom_settings.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/error_event.h"
#include "cobalt/dom/error_event_init.h"
#include "cobalt/dom/event.h"
#include "cobalt/dom/history.h"
#include "cobalt/dom/html_element.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/dom/input_event.h"
#include "cobalt/dom/keyboard_event.h"
#include "cobalt/dom/location.h"
#include "cobalt/dom/media_source.h"
#include "cobalt/dom/mouse_event.h"
#include "cobalt/dom/mutation_observer_task_manager.h"
#include "cobalt/dom/navigator.h"
#include "cobalt/dom/performance.h"
#include "cobalt/dom/pointer_event.h"
#include "cobalt/dom/screen.h"
#include "cobalt/dom/screenshot.h"
#include "cobalt/dom/screenshot_manager.h"
#include "cobalt/dom/storage.h"
#include "cobalt/dom/wheel_event.h"
#include "cobalt/dom/window_timers.h"
#include "cobalt/media_session/media_session_client.h"
#include "cobalt/script/environment_settings.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/speech/speech_synthesis.h"
#include "starboard/file.h"

using cobalt::cssom::ViewportSize;
using cobalt::media_session::MediaSession;

namespace cobalt {
namespace dom {

// This class fires the window's load event when the document is loaded.
class Window::RelayLoadEvent : public DocumentObserver {
 public:
  explicit RelayLoadEvent(Window* window) : window_(window) {}

  // From DocumentObserver.
  void OnLoad() override {
    window_->PostToDispatchEventName(FROM_HERE, base::Tokens::load());
  }
  void OnMutation() override {}
  void OnFocusChanged() override {}

 private:
  Window* window_;

  DISALLOW_COPY_AND_ASSIGN(RelayLoadEvent);
};

namespace {
// Ensure that the timer resolution is at the lowest 20 microseconds in
// order to mitigate potential Spectre-related attacks.  This is following
// Mozilla's lead as described here:
//   https://www.mozilla.org/en-US/security/advisories/mfsa2018-01/
const int64_t kPerformanceTimerMinResolutionInMicroseconds = 20;
}  // namespace

Window::Window(
    script::EnvironmentSettings* settings, const ViewportSize& view_size,
    base::ApplicationState initial_application_state,
    cssom::CSSParser* css_parser, Parser* dom_parser,
    loader::FetcherFactory* fetcher_factory,
    loader::LoaderFactory* loader_factory,
    render_tree::ResourceProvider** resource_provider,
    loader::image::AnimatedImageTracker* animated_image_tracker,
    loader::image::ImageCache* image_cache,
    loader::image::ReducedCacheCapacityManager*
        reduced_image_cache_capacity_manager,
    loader::font::RemoteTypefaceCache* remote_typeface_cache,
    loader::mesh::MeshCache* mesh_cache,
    LocalStorageDatabase* local_storage_database,
    media::CanPlayTypeHandler* can_play_type_handler,
    media::WebMediaPlayerFactory* web_media_player_factory,
    script::ExecutionState* execution_state,
    script::ScriptRunner* script_runner,
    script::ScriptValueFactory* script_value_factory,
    MediaSource::Registry* media_source_registry,
    DomStatTracker* dom_stat_tracker, const GURL& url,
    const std::string& user_agent, const std::string& language,
    const std::string& font_language_script,
    const base::Callback<void(const GURL&)> navigation_callback,
    const loader::Decoder::OnCompleteFunction& load_complete_callback,
    network_bridge::CookieJar* cookie_jar,
    const network_bridge::PostSender& post_sender,
    csp::CSPHeaderPolicy require_csp, CspEnforcementType csp_enforcement_mode,
    const base::Closure& csp_policy_changed_callback,
    const base::Closure& ran_animation_frame_callbacks_callback,
    const CloseCallback& window_close_callback,
    const base::Closure& window_minimize_callback,
    OnScreenKeyboardBridge* on_screen_keyboard_bridge,
    const scoped_refptr<input::Camera3D>& camera_3d,
    const scoped_refptr<MediaSession>& media_session,
    const OnStartDispatchEventCallback& on_start_dispatch_event_callback,
    const OnStopDispatchEventCallback& on_stop_dispatch_event_callback,
    const ScreenshotManager::ProvideScreenshotFunctionCallback&
        screenshot_function_callback,
    base::WaitableEvent* synchronous_loader_interrupt,
    bool enable_inline_script_warnings,
    const scoped_refptr<ui_navigation::NavItem>& ui_nav_root,
    bool enable_map_to_mesh, int csp_insecure_allowed_token,
    int dom_max_element_depth, float video_playback_rate_multiplier,
    ClockType clock_type, const CacheCallback& splash_screen_cache_callback,
    const scoped_refptr<captions::SystemCaptionSettings>& captions,
    bool log_tts)
    // 'window' object EventTargets require special handling for onerror events,
    // see EventTarget constructor for more details.
    : EventTarget(settings, kUnpackOnErrorEvents),
      viewport_size_(view_size),
      is_resize_event_pending_(false),
      is_reporting_script_error_(false),
#if defined(ENABLE_TEST_RUNNER)
      test_runner_(new TestRunner()),
#endif  // ENABLE_TEST_RUNNER
      html_element_context_(new HTMLElementContext(
          settings, fetcher_factory, loader_factory, css_parser, dom_parser,
          can_play_type_handler, web_media_player_factory, script_runner,
          script_value_factory, media_source_registry, resource_provider,
          animated_image_tracker, image_cache,
          reduced_image_cache_capacity_manager, remote_typeface_cache,
          mesh_cache, dom_stat_tracker, font_language_script,
          initial_application_state, synchronous_loader_interrupt,
          enable_inline_script_warnings, video_playback_rate_multiplier)),
      performance_(new Performance(MakePerformanceClock(clock_type))),
      ALLOW_THIS_IN_INITIALIZER_LIST(document_(new Document(
          html_element_context_.get(),
          Document::Options(
              url, this,
              base::Bind(&Window::FireHashChangeEvent, base::Unretained(this)),
              performance_->timing()->GetNavigationStartClock(),
              navigation_callback, ParseUserAgentStyleSheet(css_parser),
              view_size, cookie_jar, post_sender, require_csp,
              csp_enforcement_mode, csp_policy_changed_callback,
              csp_insecure_allowed_token, dom_max_element_depth)))),
      document_loader_(nullptr),
      history_(new History()),
      navigator_(new Navigator(settings, user_agent, language, media_session,
                               captions, script_value_factory)),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          relay_on_load_event_(new RelayLoadEvent(this))),
      console_(new Console(execution_state)),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          window_timers_(new WindowTimers(this, debugger_hooks()))),
      ALLOW_THIS_IN_INITIALIZER_LIST(animation_frame_request_callback_list_(
          new AnimationFrameRequestCallbackList(this, debugger_hooks()))),
      crypto_(new Crypto()),
      speech_synthesis_(
          new speech::SpeechSynthesis(settings, navigator_, log_tts)),
      ALLOW_THIS_IN_INITIALIZER_LIST(local_storage_(
          new Storage(this, Storage::kLocalStorage, local_storage_database))),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          session_storage_(new Storage(this, Storage::kSessionStorage, NULL))),
      screen_(new Screen(view_size)),
      preflight_cache_(new loader::CORSPreflightCache()),
      ran_animation_frame_callbacks_callback_(
          ran_animation_frame_callbacks_callback),
      window_close_callback_(window_close_callback),
      window_minimize_callback_(window_minimize_callback),
      // We only have an on_screen_keyboard_bridge when the platform supports
      // it. Otherwise don't even expose it in the DOM.
      on_screen_keyboard_(on_screen_keyboard_bridge
                              ? new OnScreenKeyboard(settings,
                                                     on_screen_keyboard_bridge,
                                                     script_value_factory)
                              : NULL),
      splash_screen_cache_callback_(splash_screen_cache_callback),
      on_start_dispatch_event_callback_(on_start_dispatch_event_callback),
      on_stop_dispatch_event_callback_(on_stop_dispatch_event_callback),
      screenshot_manager_(settings, screenshot_function_callback),
      ui_nav_root_(ui_nav_root),
      enable_map_to_mesh_(enable_map_to_mesh) {
#if !defined(ENABLE_TEST_RUNNER)
#endif
  document_->AddObserver(relay_on_load_event_.get());
  html_element_context_->page_visibility_state()->AddObserver(this);
  SetCamera3D(camera_3d);

  // Document load start is deferred from this constructor so that we can be
  // guaranteed that this Window object is fully constructed before document
  // loading begins.
  base::MessageLoop::current()->task_runner()->PostTask(
      FROM_HERE,
      base::Bind(&Window::StartDocumentLoad, base::Unretained(this),
                 fetcher_factory, url, dom_parser, load_complete_callback));
}

void Window::StartDocumentLoad(
    loader::FetcherFactory* fetcher_factory, const GURL& url,
    Parser* dom_parser,
    const loader::Decoder::OnCompleteFunction& load_complete_callback) {
  document_loader_.reset(new loader::Loader(
      base::Bind(&loader::FetcherFactory::CreateFetcher,
                 base::Unretained(fetcher_factory), url),
      base::Bind(&Parser::ParseDocumentAsync, base::Unretained(dom_parser),
                 document_, base::SourceLocation(url.spec(), 1, 1)),
      load_complete_callback));
}

scoped_refptr<base::BasicClock> Window::MakePerformanceClock(
    ClockType clock_type) {
  switch (clock_type) {
    case kClockTypeTestRunner: {
#if defined(ENABLE_TEST_RUNNER)
      return test_runner_->GetClock();
#else
      NOTREACHED();
#endif
    } break;
    case kClockTypeSystemTime: {
      return new base::SystemMonotonicClock();
    } break;
    case kClockTypeResolutionLimitedSystemTime: {
      return new base::MinimumResolutionClock(
          new base::SystemMonotonicClock(),
          base::TimeDelta::FromMicroseconds(
              kPerformanceTimerMinResolutionInMicroseconds));
    } break;
  }
  NOTREACHED();
  return scoped_refptr<base::BasicClock>();
}

const scoped_refptr<Document>& Window::document() const { return document_; }

const scoped_refptr<Location>& Window::location() const {
  return document_->location();
}

const scoped_refptr<History>& Window::history() const { return history_; }

// https://www.w3.org/TR/html50/browsers.html#dom-window-close
void Window::Close() {
  LOG(INFO) << __func__;
  if (!window_close_callback_.is_null()) {
    window_close_callback_.Run(
        performance_->timing()->GetNavigationStartClock()->Now());
  }
}

void Window::Minimize() {
  if (!window_minimize_callback_.is_null()) {
    window_minimize_callback_.Run();
  }
}

const scoped_refptr<Navigator>& Window::navigator() const { return navigator_; }

script::Handle<ScreenshotManager::InterfacePromise> Window::Screenshot() {
  scoped_refptr<render_tree::Node> render_tree_root =
      document_->DoSynchronousLayoutAndGetRenderTree();

  script::Handle<ScreenshotManager::InterfacePromise> promise =
      html_element_context()
          ->script_value_factory()
          ->CreateInterfacePromise<dom::Screenshot>();

  std::unique_ptr<ScreenshotManager::InterfacePromiseValue::Reference>
      promise_reference(new ScreenshotManager::InterfacePromiseValue::Reference(
          this, promise));

  screenshot_manager_.Screenshot(
      loader::image::EncodedStaticImage::ImageFormat::kPNG, render_tree_root,
      std::move(promise_reference));

  return promise;
}

scoped_refptr<cssom::CSSStyleDeclaration> Window::GetComputedStyle(
    const scoped_refptr<Element>& elt) {
  scoped_refptr<HTMLElement> html_element = elt->AsHTMLElement();
  if (html_element) {
    document_->UpdateComputedStyleOnElementAndAncestor(html_element.get());
    return html_element->css_computed_style_declaration();
  }
  return NULL;
}

scoped_refptr<cssom::CSSStyleDeclaration> Window::GetComputedStyle(
    const scoped_refptr<Element>& elt, const std::string& pseudo_elt) {
  // The getComputedStyle(elt, pseudoElt) method must run these steps:
  // https://www.w3.org/TR/2013/WD-cssom-20131205/#dom-window-getcomputedstyle

  // 1. Let doc be the Document associated with the Window object on which the
  // method was invoked.
  DCHECK_EQ(document_, elt->node_document())
      << "getComputedStyle not supported for elements outside of the document";

  scoped_refptr<HTMLElement> html_element = elt->AsHTMLElement();
  scoped_refptr<cssom::CSSComputedStyleDeclaration> obj;
  if (html_element) {
    document_->UpdateComputedStyleOnElementAndAncestor(html_element.get());

    // 2. Let obj be elt.
    obj = html_element->css_computed_style_declaration();

    // 3. If pseudoElt is as an ASCII case-insensitive match for either
    // ':before' or '::before' let obj be the ::before pseudo-element of elt.
    if (base::LowerCaseEqualsASCII(pseudo_elt, ":before") ||
        base::LowerCaseEqualsASCII(pseudo_elt, "::before")) {
      PseudoElement* pseudo_element =
          html_element->pseudo_element(kBeforePseudoElementType);
      obj = pseudo_element ? pseudo_element->css_computed_style_declaration()
                           : NULL;
    }

    // 4. If pseudoElt is as an ASCII case-insensitive match for either ':after'
    // or '::after' let obj be the ::after pseudo-element of elt.
    if (base::LowerCaseEqualsASCII(pseudo_elt, ":after") ||
        base::LowerCaseEqualsASCII(pseudo_elt, "::after")) {
      PseudoElement* pseudo_element =
          html_element->pseudo_element(kAfterPseudoElementType);
      obj = pseudo_element ? pseudo_element->css_computed_style_declaration()
                           : NULL;
    }
  }
  // 5. Return a live CSS declaration block.
  return obj;
}

int32 Window::RequestAnimationFrame(
    const AnimationFrameRequestCallbackList::FrameRequestCallbackArg&
        callback) {
  return animation_frame_request_callback_list_->RequestAnimationFrame(
      callback);
}

void Window::CancelAnimationFrame(int32 handle) {
  animation_frame_request_callback_list_->CancelAnimationFrame(handle);
}

scoped_refptr<MediaQueryList> Window::MatchMedia(const std::string& query) {
  DCHECK(html_element_context_->css_parser());
  scoped_refptr<cssom::MediaList> media_list =
      html_element_context_->css_parser()->ParseMediaList(
          query, GetInlineSourceLocation());
  return base::WrapRefCounted(new MediaQueryList(media_list, screen_));
}

const scoped_refptr<Screen>& Window::screen() { return screen_; }

scoped_refptr<Crypto> Window::crypto() const { return crypto_; }

std::string Window::Btoa(const std::string& string_to_encode,
                         script::ExceptionState* exception_state) {
  TRACE_EVENT0("cobalt::dom", "Window::Btoa()");
  LOG_ONCE(WARNING)
      << "In older Cobalt(<19), btoa() can not take a string"
         " containing NULL. Be careful that you don't need to stay "
         "compatible with old versions of Cobalt if you use btoa.";
  auto output = ForgivingBase64Encode(string_to_encode);
  if (!output) {
    DOMException::Raise(DOMException::kInvalidCharacterErr, exception_state);
    return std::string();
  }
  return *output;
}

std::vector<uint8_t> Window::Atob(const std::string& encoded_string,
                                  script::ExceptionState* exception_state) {
  TRACE_EVENT0("cobalt::dom", "Window::Atob()");
  auto output = ForgivingBase64Decode(encoded_string);
  if (!output) {
    DOMException::Raise(DOMException::kInvalidCharacterErr, exception_state);
    return {};
  }
  return *output;
}

int Window::SetTimeout(const WindowTimers::TimerCallbackArg& handler,
                       int timeout) {
  DLOG_IF(WARNING, timeout < 0)
      << "Window::SetTimeout received negative timeout: " << timeout;
  timeout = std::max(timeout, 0);

  int return_value = 0;
  if (window_timers_) {
    return_value = window_timers_->SetTimeout(handler, timeout);
  } else {
    DLOG(WARNING) << "window_timers_ does not exist.  Already destroyed?";
  }

  return return_value;
}

void Window::ClearTimeout(int handle) {
  if (window_timers_) {
    window_timers_->ClearTimeout(handle);
  } else {
    DLOG(WARNING) << "window_timers_ does not exist.  Already destroyed?";
  }
}

int Window::SetInterval(const WindowTimers::TimerCallbackArg& handler,
                        int timeout) {
  DLOG_IF(WARNING, timeout < 0)
      << "Window::SetInterval received negative timeout: " << timeout;
  timeout = std::max(timeout, 0);

  int return_value = 0;
  if (window_timers_) {
    return_value = window_timers_->SetInterval(handler, timeout);
  } else {
    DLOG(WARNING) << "window_timers_ does not exist.  Already destroyed?";
  }

  return return_value;
}

void Window::ClearInterval(int handle) {
  if (window_timers_) {
    window_timers_->ClearInterval(handle);
  } else {
    DLOG(WARNING) << "window_timers_ does not exist.  Already destroyed?";
  }
}

void Window::DestroyTimers() { window_timers_->DisableCallbacks(); }

scoped_refptr<Storage> Window::local_storage() const { return local_storage_; }

scoped_refptr<Storage> Window::session_storage() const {
  return session_storage_;
}

const scoped_refptr<Performance>& Window::performance() const {
  return performance_;
}

scoped_refptr<speech::SpeechSynthesis> Window::speech_synthesis() const {
  return speech_synthesis_;
}

const scoped_refptr<Console>& Window::console() const { return console_; }

const scoped_refptr<Camera3D>& Window::camera_3d() const { return camera_3d_; }

#if defined(ENABLE_TEST_RUNNER)
const scoped_refptr<TestRunner>& Window::test_runner() const {
  return test_runner_;
}
#endif  // ENABLE_TEST_RUNNER

void Window::Gc(script::EnvironmentSettings* settings) {
  if (settings) {
    DOMSettings* dom_settings =
        base::polymorphic_downcast<dom::DOMSettings*>(settings);
    dom_settings->javascript_engine()->CollectGarbage();
  }
}

HTMLElementContext* Window::html_element_context() const {
  return html_element_context_.get();
}

void Window::RunAnimationFrameCallbacks() {
  // Scope the StopWatch. It should not include any processing from
  // |ran_animation_frame_callbacks_callback_|.
  {
    base::StopWatch stop_watch_run_animation_frame_callbacks(
        DomStatTracker::kStopWatchTypeRunAnimationFrameCallbacks,
        base::StopWatch::kAutoStartOn,
        html_element_context()->dom_stat_tracker());

    // First grab the current list of frame request callbacks and hold on to it
    // here locally.
    std::unique_ptr<AnimationFrameRequestCallbackList> frame_request_list =
        std::move(animation_frame_request_callback_list_);

    // Then setup the Window's frame request callback list with a freshly
    // created and empty one.
    animation_frame_request_callback_list_.reset(
        new AnimationFrameRequestCallbackList(this, debugger_hooks()));

    // Now, iterate through each of the callbacks and call them.
    frame_request_list->RunCallbacks(*document_->timeline()->current_time());
  }

  // Run the callback if one exists.
  if (!ran_animation_frame_callbacks_callback_.is_null()) {
    ran_animation_frame_callbacks_callback_.Run();
  }
}

bool Window::HasPendingAnimationFrameCallbacks() const {
  return animation_frame_request_callback_list_->HasPendingCallbacks();
}

void Window::InjectEvent(const scoped_refptr<Event>& event) {
  TRACE_EVENT1("cobalt::dom", "Window::InjectEvent()", "event",
               event->type().c_str());

  // Forward the event on to the correct object in DOM.
  if (event->GetWrappableType() == base::GetTypeId<KeyboardEvent>()) {
    // Event.target:focused element processing the key event or if no element
    // focused, then the body element if available, otherwise the root element.
    //   https://www.w3.org/TR/2016/WD-uievents-20160804/#event-type-keydown
    //   https://www.w3.org/TR/2016/WD-uievents-20160804/#event-type-keypress
    //   https://www.w3.org/TR/2016/WD-uievents-20160804/#event-type-keyup
    if (document_->active_element()) {
      document_->active_element()->DispatchEvent(event);
    } else {
      document_->DispatchEvent(event);
    }
  } else if (event->GetWrappableType() == base::GetTypeId<InputEvent>()) {
    // Dispatch any InputEvent directly to the OnScreenKeyboard element.
    if (on_screen_keyboard_) {
      on_screen_keyboard_->DispatchEvent(event);
    }
  } else {
    SB_NOTREACHED();
  }
}

void Window::SetApplicationState(base::ApplicationState state) {
  html_element_context_->page_visibility_state()->SetApplicationState(state);
}

bool Window::ReportScriptError(const script::ErrorReport& error_report) {
  // Runtime script errors: when the user agent is required to report an error
  // for a particular script, it must run these steps, after which the error is
  // either handled or not handled:
  //   https://www.w3.org/TR/html50/webappapis.html#runtime-script-errors

  // 1. If target is in error reporting mode, then abort these steps; the error
  //    is not handled.
  if (is_reporting_script_error_) {
    return false;
  }

  // 2. Let target be in error reporting mode.
  is_reporting_script_error_ = true;

  // 7. Let event be a new trusted ErrorEvent object that does not bubble but is
  //    cancelable, and which has the event name error.
  // NOTE: Cobalt does not currently support trusted events.
  ErrorEventInit error_event_init;
  error_event_init.set_bubbles(false);
  error_event_init.set_cancelable(true);

  if (error_report.is_muted) {
    // 6. If script has muted errors, then set message to "Script error.", set
    //    location to the empty string, set line and col to 0, and set error
    //    object to null.
    error_event_init.set_message("Script error.");
    error_event_init.set_filename("");
    error_event_init.set_lineno(0);
    error_event_init.set_colno(0);
    error_event_init.set_error(NULL);
  } else {
    // 8. Initialize event's message attribute to message.
    error_event_init.set_message(error_report.message);
    // 9. Initialize event's filename attribute to location.
    error_event_init.set_filename(error_report.filename);
    // 10. Initialize event's lineno attribute to line.
    error_event_init.set_lineno(error_report.line_number);
    // 11. Initialize event's colno attribute to col.
    error_event_init.set_colno(error_report.column_number);
    // 12. Initialize event's error attribute to error object.
    error_event_init.set_error(error_report.error ? error_report.error.get()
                                                  : NULL);
  }

  scoped_refptr<ErrorEvent> error_event(
      new ErrorEvent(base::Tokens::error(), error_event_init));

  // 13. Dispatch event at target.
  DispatchEvent(error_event);

  // 14. Let target no longer be in error reporting mode.
  is_reporting_script_error_ = false;

  // 15. If event was canceled, then the error is handled. Otherwise, the error
  //     is not handled.
  return error_event->default_prevented();
}

void Window::SetSynchronousLayoutCallback(const base::Closure& callback) {
  document_->set_synchronous_layout_callback(callback);
}

void Window::SetSynchronousLayoutAndProduceRenderTreeCallback(
    const SynchronousLayoutAndProduceRenderTreeCallback& callback) {
  document_->set_synchronous_layout_and_produce_render_tree_callback(callback);
}

void Window::SetSize(ViewportSize size) {
  if (size == viewport_size_) {
    return;
  }

  viewport_size_ = size;
  screen_->SetSize(viewport_size_);
  // This will cause layout invalidation.
  document_->SetViewport(viewport_size_);

  if (html_element_context_->page_visibility_state()->GetVisibilityState() ==
      page_visibility::kVisibilityStateVisible) {
    DispatchEvent(new Event(base::Tokens::resize()));
  } else {
    is_resize_event_pending_ = true;
  }
}

void Window::SetCamera3D(const scoped_refptr<input::Camera3D>& camera_3d) {
  camera_3d_ = new Camera3D(camera_3d);
  camera_3d_->StartOrientationEvents(base::AsWeakPtr(this));
}

void Window::OnWindowFocusChanged(bool has_focus) {
  DispatchEvent(
      new Event(has_focus ? base::Tokens::focus() : base::Tokens::blur()));
}

void Window::OnVisibilityStateChanged(
    page_visibility::VisibilityState visibility_state) {
  if (is_resize_event_pending_ &&
      visibility_state == page_visibility::kVisibilityStateVisible) {
    is_resize_event_pending_ = false;
    DispatchEvent(new Event(base::Tokens::resize()));
  }
}

void Window::OnDocumentRootElementUnableToProvideOffsetDimensions() {
  DLOG(WARNING) << "Document root element unable to provide offset dimensions!";
  // If the root element was unable to provide its dimensions as a result of
  // the app being in a visibility state that disables layout, then prepare a
  // pending resize event, so that the resize will occur once layouts are again
  // available.
  if (html_element_context_->page_visibility_state()->GetVisibilityState() !=
      page_visibility::kVisibilityStateVisible) {
    is_resize_event_pending_ = true;
  }
}

void Window::OnStartDispatchEvent(const scoped_refptr<dom::Event>& event) {
  if (!on_start_dispatch_event_callback_.is_null()) {
    on_start_dispatch_event_callback_.Run(event);
  }
}

void Window::OnStopDispatchEvent(const scoped_refptr<dom::Event>& event) {
  if (!on_stop_dispatch_event_callback_.is_null()) {
    on_stop_dispatch_event_callback_.Run(event);
  }
}

void Window::ClearPointerStateForShutdown() {
  document_->pointer_state()->ClearForShutdown();
}

void Window::TraceMembers(script::Tracer* tracer) {
  EventTarget::TraceMembers(tracer);

#if defined(ENABLE_TEST_RUNNER)
  tracer->Trace(test_runner_);
#endif  // ENABLE_TEST_RUNNER
  tracer->Trace(performance_);
  tracer->Trace(document_);
  tracer->Trace(history_);
  tracer->Trace(navigator_);
  tracer->Trace(console_);
  tracer->Trace(camera_3d_);
  tracer->Trace(crypto_);
  tracer->Trace(speech_synthesis_);
  tracer->Trace(local_storage_);
  tracer->Trace(session_storage_);
  tracer->Trace(screen_);
  tracer->Trace(on_screen_keyboard_);
}

void Window::CacheSplashScreen(const std::string& content,
                               const base::Optional<std::string>& topic) {
  if (splash_screen_cache_callback_.is_null()) {
    return;
  }
  DLOG(INFO) << "Caching splash screen for URL " << location()->url();
  splash_screen_cache_callback_.Run(content, topic);
}

const scoped_refptr<OnScreenKeyboard>& Window::on_screen_keyboard() const {
  return on_screen_keyboard_;
}

void Window::ReleaseOnScreenKeyboard() { on_screen_keyboard_ = nullptr; }

Window::~Window() {
  if (ui_nav_root_) {
    ui_nav_root_->SetEnabled(false);
  }
  html_element_context_->page_visibility_state()->RemoveObserver(this);
}

void Window::FireHashChangeEvent() {
  PostToDispatchEventName(FROM_HERE, base::Tokens::hashchange());
}

}  // namespace dom
}  // namespace cobalt
