// 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 <utility>

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

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, UserAgentPlatformInfo* platform_info,
    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 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
      performance_(new Performance(settings, MakePerformanceClock(clock_type))),
      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,
          performance_.get(), enable_inline_script_warnings,
          video_playback_rate_multiplier)),
      ALLOW_THIS_IN_INITIALIZER_LIST(document_(new Document(
          html_element_context(),
          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, platform_info, language,
                               captions, script_value_factory)),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          relay_on_load_event_(new RelayLoadEvent(this))),
      ALLOW_THIS_IN_INITIALIZER_LIST(window_timers_(
          new WindowTimers(this, dom_stat_tracker, debugger_hooks(),
                           initial_application_state))),
      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()->application_lifecycle_state()->AddObserver(this);
  UpdateCamera3D(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(
              Performance::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) {
  LOG_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 {
    LOG(WARNING) << "window_timers_ does not exist.  Already destroyed?";
  }

  return return_value;
}

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

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

  int return_value = 0;
  if (window_timers_) {
    return_value = window_timers_->SetInterval(handler, timeout);
  } else {
    LOG(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<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();
  }
}

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,
                                 SbTimeMonotonic timestamp) {
  html_element_context()->application_lifecycle_state()->SetApplicationState(
      state);
  if (timestamp == 0) return;
  performance_->SetApplicationState(state, timestamp);
  window_timers_->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()
          ->application_lifecycle_state()
          ->GetVisibilityState() == kVisibilityStateVisible) {
    DispatchEvent(new Event(base::Tokens::resize()));
  } else {
    is_resize_event_pending_ = true;
  }
}

void Window::UpdateCamera3D(const scoped_refptr<input::Camera3D>& camera_3d) {
  if (camera_3d_ && camera_3d_->impl()) {
    // Update input object for existing camera.
    camera_3d_->impl()->SetInput(camera_3d);
  } else {
    // Create a new camera which uses the given input camera object.
    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(VisibilityState visibility_state) {
  if (is_resize_event_pending_ && visibility_state == kVisibilityStateVisible) {
    is_resize_event_pending_ = false;
    DispatchEvent(new Event(base::Tokens::resize()));
  }
}

void Window::OnFrozennessChanged(bool is_frozen) {
  // Ignored by this class.
}

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()
          ->application_lifecycle_state()
          ->GetVisibilityState() != kVisibilityStateVisible) {
    is_resize_event_pending_ = true;
  }
}

void Window::OnWindowOnOnlineEvent() {
  DispatchEvent(new Event(base::Tokens::online()));
}

void Window::OnWindowOnOfflineEvent() {
  DispatchEvent(new Event(base::Tokens::offline()));
}

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

const scoped_refptr<media_session::MediaSession> Window::media_session() const {
  return navigator_->media_session();
}

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()->application_lifecycle_state()->RemoveObserver(this);
}

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

}  // namespace dom
}  // namespace cobalt
