// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_AURA_WINDOW_TREE_HOST_H_
#define UI_AURA_WINDOW_TREE_HOST_H_

#include <stdint.h>

#include <memory>
#include <string>

#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/common/surfaces/local_surface_id.h"
#include "ui/aura/aura_export.h"
#include "ui/aura/window.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/ime/input_method_delegate.h"
#include "ui/compositor/compositor_observer.h"
#include "ui/display/display_observer.h"
#include "ui/events/event_source.h"
#include "ui/events/platform_event.h"
#include "ui/gfx/native_widget_types.h"

namespace gfx {
class Point;
class Rect;
class Size;
class Transform;
}

namespace ui {
class Compositor;
enum class DomCode;
class EventSink;
class InputMethod;
class ViewProp;
struct PlatformWindowInitProperties;
}

namespace aura {

namespace test {
class WindowTreeHostTestApi;
}

class Env;
class ScopedKeyboardHook;
class WindowEventDispatcher;
class WindowTreeHostObserver;

// WindowTreeHost bridges between a native window and the embedded RootWindow.
// It provides the accelerated widget and maps events from the native os to
// aura.
class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
                                   public ui::EventSource,
                                   public display::DisplayObserver,
                                   public ui::CompositorObserver {
 public:
  ~WindowTreeHost() override;

  // Creates a new WindowTreeHost with the specified |properties| and an
  // optional |env|. If |env| is null, the default Env::GetInstance() is used.
  static std::unique_ptr<WindowTreeHost> Create(
      ui::PlatformWindowInitProperties properties,
      Env* env = nullptr);

  // Returns the WindowTreeHost for the specified accelerated widget, or NULL
  // if there is none associated.
  static WindowTreeHost* GetForAcceleratedWidget(gfx::AcceleratedWidget widget);

  void InitHost();

  void AddObserver(WindowTreeHostObserver* observer);
  void RemoveObserver(WindowTreeHostObserver* observer);

  Window* window() { return window_; }
  const Window* window() const { return window_; }

  ui::EventSink* event_sink();

  WindowEventDispatcher* dispatcher() {
    return const_cast<WindowEventDispatcher*>(
        const_cast<const WindowTreeHost*>(this)->dispatcher());
  }
  const WindowEventDispatcher* dispatcher() const { return dispatcher_.get(); }

  ui::Compositor* compositor() { return compositor_.get(); }

  // Gets/Sets the root window's transform.
  virtual gfx::Transform GetRootTransform() const;
  virtual void SetRootTransform(const gfx::Transform& transform);
  virtual gfx::Transform GetInverseRootTransform() const;

  // These functions are used in event translation for translating the local
  // coordinates of LocatedEvents. Default implementation calls to non-local
  // ones (e.g. GetRootTransform()).
  virtual gfx::Transform GetRootTransformForLocalEventCoordinates() const;
  virtual gfx::Transform GetInverseRootTransformForLocalEventCoordinates()
      const;

  // Updates the root window's size using |host_size_in_pixels|, current
  // transform and outsets.
  // TODO(ccameron): Make this function no longer public. The interaction
  // between this call, GetBounds, and OnHostResizedInPixels is ambiguous and
  // allows for inconsistencies.
  void UpdateRootWindowSizeInPixels();

  // Converts |point| from the root window's coordinate system to native
  // screen's.
  void ConvertDIPToScreenInPixels(gfx::Point* point) const;

  // Converts |point| from native screen coordinate system to the root window's.
  void ConvertScreenInPixelsToDIP(gfx::Point* point) const;

  // Converts |point| from the root window's coordinate system to the
  // host window's.
  virtual void ConvertDIPToPixels(gfx::Point* point) const;

  // Converts |point| from the host window's coordinate system to the
  // root window's.
  virtual void ConvertPixelsToDIP(gfx::Point* point) const;

  // Cursor.
  // Sets the currently-displayed cursor. If the cursor was previously hidden
  // via ShowCursor(false), it will remain hidden until ShowCursor(true) is
  // called, at which point the cursor that was last set via SetCursor() will be
  // used.
  void SetCursor(gfx::NativeCursor cursor);

  // Invoked when the cursor's visibility has changed.
  void OnCursorVisibilityChanged(bool visible);

  // Moves the cursor to the specified location relative to the root window.
  void MoveCursorToLocationInDIP(const gfx::Point& location_in_dip);

  // Moves the cursor to the |location_in_pixels| given in host coordinates.
  void MoveCursorToLocationInPixels(const gfx::Point& location_in_pixels);

  gfx::NativeCursor last_cursor() const { return last_cursor_; }

  // Gets the InputMethod instance, if NULL, creates & owns it.
  ui::InputMethod* GetInputMethod();
  bool has_input_method() const { return input_method_ != nullptr; }

  // Sets a shared unowned InputMethod. This is used when there is a singleton
  // InputMethod shared between multiple WindowTreeHost instances.
  //
  // This is used for Ash only. There are 2 reasons:
  // 1) ChromeOS virtual keyboard needs to receive ShowVirtualKeyboardIfEnabled
  // notification from InputMethod. Multiple InputMethod instances makes it hard
  // to register/unregister the observer for that notification. 2) For Ozone,
  // there is no native focus state for the root window and WindowTreeHost. See
  // DrmWindowHost::CanDispatchEvent, the key events always goes to the primary
  // WindowTreeHost. And after InputMethod processed the key event and continue
  // dispatching it, WindowTargeter::FindTargetForEvent may re-dispatch it to a
  // different WindowTreeHost. So the singleton InputMethod can make sure the
  // correct InputMethod instance processes the key event no matter which
  // WindowTreeHost is the target for event. Please refer to the test:
  // ExtendedDesktopTest.KeyEventsOnLockScreen.
  //
  // TODO(shuchen): remove this method after above reasons become invalid.
  // A possible solution is to make sure DrmWindowHost can find the correct
  // WindowTreeHost to dispatch events.
  void SetSharedInputMethod(ui::InputMethod* input_method);

  // Overridden from ui::internal::InputMethodDelegate:
  ui::EventDispatchDetails DispatchKeyEventPostIME(
      ui::KeyEvent* event,
      base::OnceCallback<void(bool)> ack_callback) final;

  // Returns the id of the display. Default implementation queries Screen.
  virtual int64_t GetDisplayId();

  // Returns the EventSource responsible for dispatching events to the window
  // tree.
  virtual ui::EventSource* GetEventSource() = 0;

  // Returns the accelerated widget.
  virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0;

  // Shows the WindowTreeHost.
  void Show();

  // Hides the WindowTreeHost.
  void Hide();

  // Sets/Gets the bounds of the WindowTreeHost (in pixels). Note that a call to
  // GetBoundsInPixels() immediately following a SetBoundsInPixels() can return
  // the old bounds, because SetBoundsInPixels() can take effect asynchronously,
  // depending on the platform. The |local_surface_id| takes effect when (and
  // if) the new size is confirmed (potentially asynchronously) by the platform.
  // If |local_surface_id| is invalid, then a new LocalSurfaceId is allocated
  // when the size change takes effect.
  virtual void SetBoundsInPixels(
      const gfx::Rect& bounds_in_pixels,
      const viz::LocalSurfaceId& local_surface_id = viz::LocalSurfaceId(),
      base::TimeTicks allocation_time = base::TimeTicks()) = 0;
  virtual gfx::Rect GetBoundsInPixels() const = 0;

  // Sets the OS capture to the root window.
  virtual void SetCapture() = 0;

  // Releases OS capture of the root window.
  virtual void ReleaseCapture() = 0;

  // Returns the device scale assumed by the WindowTreeHost (set during the
  // most recent call to OnHostResizedInPixels).
  float device_scale_factor() const { return device_scale_factor_; }

  // Requests that |keys| be intercepted at the platform level and routed
  // directly to the web content.  If |codes| is empty, all keys will be
  // intercepted.  Returns a ScopedKeyboardHook instance which stops capturing
  // system key events when destroyed.
  std::unique_ptr<ScopedKeyboardHook> CaptureSystemKeyEvents(
      base::Optional<base::flat_set<ui::DomCode>> codes);

  // Returns a map of KeyboardEvent code to KeyboardEvent key values.
  virtual base::flat_map<std::string, std::string> GetKeyboardLayoutMap() = 0;

  // Returns true if KeyEvents should be send to IME. This is called from
  // WindowEventDispatcher during event dispatch.
  virtual bool ShouldSendKeyEventToIme();

 protected:
  friend class ScopedKeyboardHook;
  friend class TestScreen;  // TODO(beng): see if we can remove/consolidate.

  explicit WindowTreeHost(std::unique_ptr<Window> window = nullptr);

  void DestroyCompositor();
  void DestroyDispatcher();

  // If frame_sink_id is not passed in, one will be grabbed from
  // ContextFactoryPrivate. |are_events_in_pixels| indicates if events are
  // received in pixels. If |are_events_in_pixels| is false, events are
  // received in DIPs. See Compositor() for details on |trace_environment_name|.
  void CreateCompositor(
      const viz::FrameSinkId& frame_sink_id = viz::FrameSinkId(),
      bool force_software_compositor = false,
      bool external_begin_frames_enabled = false,
      bool are_events_in_pixels = true,
      const char* trace_environment_name = nullptr);

  void InitCompositor();
  void OnAcceleratedWidgetAvailable();

  // Returns the location of the RootWindow on native screen.
  virtual gfx::Point GetLocationOnScreenInPixels() const = 0;

  void OnHostMovedInPixels(const gfx::Point& new_location_in_pixels);
  void OnHostResizedInPixels(
      const gfx::Size& new_size_in_pixels,
      const viz::LocalSurfaceId& local_surface_id = viz::LocalSurfaceId(),
      base::TimeTicks new_allocation_time = base::TimeTicks());
  void OnHostWorkspaceChanged();
  void OnHostDisplayChanged();
  void OnHostCloseRequested();
  void OnHostLostWindowCapture();

  // Sets the currently displayed cursor.
  virtual void SetCursorNative(gfx::NativeCursor cursor) = 0;

  // Moves the cursor to the specified location relative to the root window.
  virtual void MoveCursorToScreenLocationInPixels(
      const gfx::Point& location_in_pixels) = 0;

  // Called when the cursor visibility has changed.
  virtual void OnCursorVisibilityChangedNative(bool show) = 0;

  // Shows the WindowTreeHost.
  virtual void ShowImpl() = 0;

  // Hides the WindowTreeHost.
  virtual void HideImpl() = 0;

  // Overridden from ui::EventSource:
  ui::EventSink* GetEventSink() override;

  // display::DisplayObserver implementation.
  void OnDisplayMetricsChanged(const display::Display& display,
                               uint32_t metrics) override;

  // Begins capturing system key events.  Returns true if successful.
  virtual bool CaptureSystemKeyEventsImpl(
      base::Optional<base::flat_set<ui::DomCode>> dom_codes) = 0;

  // Stops capturing system keyboard events.
  virtual void ReleaseSystemKeyEventCapture() = 0;

  // True if |dom_code| is reserved for an active KeyboardLock request.
  virtual bool IsKeyLocked(ui::DomCode dom_code) = 0;

  virtual gfx::Rect GetTransformedRootWindowBoundsInPixels(
      const gfx::Size& size_in_pixels) const;

  const base::ObserverList<WindowTreeHostObserver>::Unchecked& observers()
      const {
    return observers_;
  }

 private:
  friend class test::WindowTreeHostTestApi;

  // Moves the cursor to the specified location. This method is internally used
  // by MoveCursorToLocationInDIP() and MoveCursorToLocationInPixels().
  void MoveCursorToInternal(const gfx::Point& root_location,
                            const gfx::Point& host_location);

  // Overrided from CompositorObserver:
  void OnCompositingDidCommit(ui::Compositor* compositor) override;
  void OnCompositingStarted(ui::Compositor* compositor,
                            base::TimeTicks start_time) override;
  void OnCompositingEnded(ui::Compositor* compositor) override;
  void OnCompositingChildResizing(ui::Compositor* compositor) override;
  void OnCompositingShuttingDown(ui::Compositor* compositor) override;

  // We don't use a std::unique_ptr for |window_| since we need this ptr to be
  // valid during its deletion. (Window's dtor notifies observers that may
  // attempt to reach back up to access this object which will be valid until
  // the end of the dtor).
  Window* window_;  // Owning.

  base::ObserverList<WindowTreeHostObserver>::Unchecked observers_;

  std::unique_ptr<WindowEventDispatcher> dispatcher_;

  std::unique_ptr<ui::Compositor> compositor_;

  // The device scale factor is snapshotted in OnHostResizedInPixels.
  // TODO(ccameron): The size and location from OnHostResizedInPixels and
  // OnHostMovedInPixels should be snapshotted here as well.
  float device_scale_factor_ = 1.f;

  // Last cursor set.  Used for testing.
  gfx::NativeCursor last_cursor_;
  gfx::Point last_cursor_request_position_in_host_;

  std::unique_ptr<ui::ViewProp> prop_;

  // The InputMethod instance used to process key events.
  // If owned it, it is created in GetInputMethod() method;
  // If not owned it, it is passed in through SetSharedInputMethod() method.
  ui::InputMethod* input_method_;

  // Whether the InputMethod instance is owned by this WindowTreeHost.
  bool owned_input_method_;

  // Set to the time the synchronization event began.
  base::TimeTicks synchronization_start_time_;

  // Set to true if this WindowTreeHost is currently holding pointer moves.
  bool holding_pointer_moves_ = false;

  base::WeakPtrFactory<WindowTreeHost> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(WindowTreeHost);
};

}  // namespace aura

#endif  // UI_AURA_WINDOW_TREE_HOST_H_
