[go: nahoru, domu]

Add PlatformScreen interface in Ozone.

Added OzonePlatform::CreateScreen(), which returns in instance of the
new PlatformScren interface. Also added aura::SceenOzone that implements
display::Screen on top of PlatformScreen.

Bug: 850650
Change-Id: I3481dda921f564f0c117d9c8a0e8ce060254f4c3
Reviewed-on: https://chromium-review.googlesource.com/1162354
Commit-Queue: Sergey Ulanov <sergeyu@chromium.org>
Reviewed-by: Scott Violet <sky@chromium.org>
Reviewed-by: Robert Kroeger <rjkroege@chromium.org>
Reviewed-by: Michael Spang <spang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582792}
diff --git a/content/shell/browser/shell_aura.cc b/content/shell/browser/shell_aura.cc
index 51f15cd..10ae46aa 100644
--- a/content/shell/browser/shell_aura.cc
+++ b/content/shell/browser/shell_aura.cc
@@ -7,7 +7,6 @@
 #include "content/public/browser/web_contents.h"
 #include "content/shell/browser/shell_platform_data_aura.h"
 #include "ui/aura/env.h"
-#include "ui/aura/test/test_screen.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
 
@@ -16,8 +15,6 @@
 // static
 void Shell::PlatformInitialize(const gfx::Size& default_window_size) {
   CHECK(!platform_);
-  aura::TestScreen* screen = aura::TestScreen::Create(gfx::Size());
-  display::Screen::SetScreenInstance(screen);
   platform_ = new ShellPlatformDataAura(default_window_size);
 }
 
@@ -26,17 +23,13 @@
   platform_ = nullptr;
 }
 
-void Shell::PlatformCleanUp() {
-}
+void Shell::PlatformCleanUp() {}
 
-void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) {
-}
+void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) {}
 
-void Shell::PlatformSetAddressBarURL(const GURL& url) {
-}
+void Shell::PlatformSetAddressBarURL(const GURL& url) {}
 
-void Shell::PlatformSetIsLoading(bool loading) {
-}
+void Shell::PlatformSetIsLoading(bool loading) {}
 
 void Shell::PlatformCreateWindow(int width, int height) {
   CHECK(platform_);
@@ -56,14 +49,12 @@
   content->Show();
 }
 
-void Shell::PlatformResizeSubViews() {
-}
+void Shell::PlatformResizeSubViews() {}
 
 void Shell::Close() {
   delete this;
 }
 
-void Shell::PlatformSetTitle(const base::string16& title) {
-}
+void Shell::PlatformSetTitle(const base::string16& title) {}
 
 }  // namespace content
diff --git a/content/shell/browser/shell_platform_data_aura.cc b/content/shell/browser/shell_platform_data_aura.cc
index 076783d..c95dc76d 100644
--- a/content/shell/browser/shell_platform_data_aura.cc
+++ b/content/shell/browser/shell_platform_data_aura.cc
@@ -11,6 +11,7 @@
 #include "ui/aura/env.h"
 #include "ui/aura/layout_manager.h"
 #include "ui/aura/test/test_focus_client.h"
+#include "ui/aura/test/test_screen.h"
 #include "ui/aura/test/test_window_parenting_client.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
@@ -26,6 +27,10 @@
 #include "base/fuchsia/component_context.h"
 #endif
 
+#if defined(USE_OZONE)
+#include "ui/aura/screen_ozone.h"
+#endif
+
 namespace content {
 
 namespace {
@@ -78,6 +83,27 @@
 ShellPlatformDataAura::ShellPlatformDataAura(const gfx::Size& initial_size) {
   CHECK(aura::Env::GetInstance());
 
+  // Setup global display::Screen singleton.
+  if (!display::Screen::GetScreen()) {
+#if defined(USE_OZONE)
+    auto platform_screen = ui::OzonePlatform::GetInstance()->CreateScreen();
+    if (platform_screen)
+      screen_ = std::make_unique<aura::ScreenOzone>(std::move(platform_screen));
+#endif  // defined(USE_OZONE)
+
+    // Use aura::TestScreen for Ozone platforms that don't provide
+    // PlatformScreen.
+    // TODO(https://crbug.com/872339): Implement PlatformScreen for all
+    // platforms and remove this code.
+    if (!screen_) {
+      // Some layout tests expect to be able to resize the window, so the screen
+      // must be larger than the window.
+      screen_.reset(
+          aura::TestScreen::Create(gfx::ScaleToCeiledSize(initial_size, 2.0)));
+    }
+    display::Screen::SetScreenInstance(screen_.get());
+  }
+
   ui::PlatformWindowInitProperties properties;
   properties.bounds = gfx::Rect(initial_size);
 
@@ -113,7 +139,10 @@
       new aura::test::TestWindowParentingClient(host_->window()));
 }
 
-ShellPlatformDataAura::~ShellPlatformDataAura() = default;
+ShellPlatformDataAura::~ShellPlatformDataAura() {
+  if (screen_)
+    display::Screen::SetScreenInstance(nullptr);
+}
 
 void ShellPlatformDataAura::ShowWindow() {
   host_->Show();
diff --git a/content/shell/browser/shell_platform_data_aura.h b/content/shell/browser/shell_platform_data_aura.h
index de91498e..fae33e69 100644
--- a/content/shell/browser/shell_platform_data_aura.h
+++ b/content/shell/browser/shell_platform_data_aura.h
@@ -18,6 +18,10 @@
 }
 }
 
+namespace display {
+class Screen;
+}
+
 namespace gfx {
 class Size;
 }
@@ -35,6 +39,8 @@
   aura::WindowTreeHost* host() { return host_.get(); }
 
  private:
+  std::unique_ptr<display::Screen> screen_;
+
   std::unique_ptr<aura::WindowTreeHost> host_;
   std::unique_ptr<aura::client::FocusClient> focus_client_;
   std::unique_ptr<aura::client::DefaultCaptureClient> capture_client_;
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn
index 578427b..8c5bf69 100644
--- a/ui/aura/BUILD.gn
+++ b/ui/aura/BUILD.gn
@@ -208,6 +208,8 @@
 
   if (use_ozone) {
     deps += [ "//ui/ozone" ]
+    public += [ "screen_ozone.h" ]
+    sources += [ "screen_ozone.cc" ]
   }
 
   if (is_android) {
diff --git a/ui/aura/screen_ozone.cc b/ui/aura/screen_ozone.cc
new file mode 100644
index 0000000..28493ac
--- /dev/null
+++ b/ui/aura/screen_ozone.cc
@@ -0,0 +1,92 @@
+// Copyright 2018 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.
+
+#include "ui/aura/screen_ozone.h"
+
+#include "ui/aura/window.h"
+#include "ui/aura/window_tree_host.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
+
+namespace aura {
+
+ScreenOzone::ScreenOzone(std::unique_ptr<ui::PlatformScreen> platform_screen)
+    : platform_screen_(std::move(platform_screen)) {}
+ScreenOzone::~ScreenOzone() = default;
+
+gfx::Point ScreenOzone::GetCursorScreenPoint() {
+  return platform_screen_->GetCursorScreenPoint();
+}
+
+bool ScreenOzone::IsWindowUnderCursor(gfx::NativeWindow window) {
+  return GetWindowAtScreenPoint(GetCursorScreenPoint()) == window;
+}
+
+gfx::NativeWindow ScreenOzone::GetWindowAtScreenPoint(const gfx::Point& point) {
+  auto widget = platform_screen_->GetAcceleratedWidgetAtScreenPoint(point);
+  if (!widget)
+    return nullptr;
+
+  aura::WindowTreeHost* host =
+      aura::WindowTreeHost::GetForAcceleratedWidget(widget);
+  return host ? host->window() : nullptr;
+}
+
+int ScreenOzone::GetNumDisplays() const {
+  return GetAllDisplays().size();
+}
+
+const std::vector<display::Display>& ScreenOzone::GetAllDisplays() const {
+  return platform_screen_->GetAllDisplays();
+}
+
+display::Display ScreenOzone::GetDisplayNearestWindow(
+    gfx::NativeWindow window) const {
+  gfx::AcceleratedWidget widget = GetAcceleratedWidgetForWindow(window);
+  if (!widget)
+    return GetPrimaryDisplay();
+
+  return platform_screen_->GetDisplayForAcceleratedWidget(widget);
+}
+
+display::Display ScreenOzone::GetDisplayNearestView(
+    gfx::NativeView view) const {
+  return GetDisplayNearestWindow(view);
+}
+
+display::Display ScreenOzone::GetDisplayNearestPoint(
+    const gfx::Point& point) const {
+  return platform_screen_->GetDisplayNearestPoint(point);
+}
+
+display::Display ScreenOzone::GetDisplayMatching(
+    const gfx::Rect& match_rect) const {
+  return platform_screen_->GetDisplayMatching(match_rect);
+}
+
+display::Display ScreenOzone::GetPrimaryDisplay() const {
+  return platform_screen_->GetPrimaryDisplay();
+}
+
+void ScreenOzone::AddObserver(display::DisplayObserver* observer) {
+  platform_screen_->AddObserver(observer);
+}
+
+void ScreenOzone::RemoveObserver(display::DisplayObserver* observer) {
+  platform_screen_->RemoveObserver(observer);
+}
+
+gfx::AcceleratedWidget ScreenOzone::GetAcceleratedWidgetForWindow(
+    aura::Window* window) const {
+  if (!window)
+    return gfx::kNullAcceleratedWidget;
+
+  aura::WindowTreeHost* host = window->GetHost();
+  if (!host)
+    return gfx::kNullAcceleratedWidget;
+
+  return host->GetAcceleratedWidget();
+}
+
+}  // namespace aura
\ No newline at end of file
diff --git a/ui/aura/screen_ozone.h b/ui/aura/screen_ozone.h
new file mode 100644
index 0000000..132ea591
--- /dev/null
+++ b/ui/aura/screen_ozone.h
@@ -0,0 +1,50 @@
+// Copyright 2018 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_SCREEN_OZONE_H_
+#define UI_AURA_SCREEN_OZONE_H_
+
+#include "base/macros.h"
+#include "ui/aura/aura_export.h"
+#include "ui/display/screen.h"
+#include "ui/ozone/public/platform_screen.h"
+
+namespace aura {
+
+// display::Screen implementation on top of ui::PlatformScreen provided by
+// Ozone.
+class AURA_EXPORT ScreenOzone : public display::Screen {
+ public:
+  explicit ScreenOzone(std::unique_ptr<ui::PlatformScreen> platform_screen);
+  ~ScreenOzone() override;
+
+  // display::Screen interface.
+  gfx::Point GetCursorScreenPoint() override;
+  bool IsWindowUnderCursor(gfx::NativeWindow window) override;
+  gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override;
+  int GetNumDisplays() const override;
+  const std::vector<display::Display>& GetAllDisplays() const override;
+  display::Display GetDisplayNearestWindow(
+      gfx::NativeWindow window) const override;
+  display::Display GetDisplayNearestView(gfx::NativeView view) const override;
+  display::Display GetDisplayNearestPoint(
+      const gfx::Point& point) const override;
+  display::Display GetDisplayMatching(
+      const gfx::Rect& match_rect) const override;
+  display::Display GetPrimaryDisplay() const override;
+  void AddObserver(display::DisplayObserver* observer) override;
+  void RemoveObserver(display::DisplayObserver* observer) override;
+
+ private:
+  gfx::AcceleratedWidget GetAcceleratedWidgetForWindow(
+      aura::Window* window) const;
+
+  std::unique_ptr<ui::PlatformScreen> platform_screen_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScreenOzone);
+};
+
+}  // namespace aura
+
+#endif  // UI_AURA_SCREEN_OZONE_H_
\ No newline at end of file
diff --git a/ui/base/layout.cc b/ui/base/layout.cc
index 29a0e0e..027f357 100644
--- a/ui/base/layout.cc
+++ b/ui/base/layout.cc
@@ -108,7 +108,13 @@
     return 1.0f;
   display::Display display =
       display::Screen::GetScreen()->GetDisplayNearestView(view);
-  DCHECK(display.is_valid());
+
+  // GetDisplayNearestView() may return null Display if the |view| is not shown
+  // on the screen and there is no primary display. In that case use scale
+  // factor 1.0.
+  if (!display.is_valid())
+    return 1.0f;
+
   return display.device_scale_factor();
 }
 
diff --git a/ui/ozone/BUILD.gn b/ui/ozone/BUILD.gn
index 3363568..b35403f1 100644
--- a/ui/ozone/BUILD.gn
+++ b/ui/ozone/BUILD.gn
@@ -91,6 +91,7 @@
     "public/overlay_surface_candidate.h",
     "public/ozone_switches.cc",
     "public/ozone_switches.h",
+    "public/platform_screen.h",
     "public/surface_factory_ozone.cc",
     "public/surface_factory_ozone.h",
     "public/surface_ozone_canvas.h",
@@ -104,6 +105,7 @@
     "//gpu/vulkan:buildflags",
     "//ipc",
     "//skia",
+    "//ui/display",
     "//ui/display/types",
     "//ui/display/util",
     "//ui/events",
diff --git a/ui/ozone/public/ozone_platform.cc b/ui/ozone/public/ozone_platform.cc
index 1a731e2..b496a02 100644
--- a/ui/ozone/public/ozone_platform.cc
+++ b/ui/ozone/public/ozone_platform.cc
@@ -7,9 +7,11 @@
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/trace_event/trace_event.h"
+#include "ui/display/screen.h"
 #include "ui/events/devices/device_data_manager.h"
 #include "ui/ozone/platform_object.h"
 #include "ui/ozone/platform_selection.h"
+#include "ui/ozone/public/platform_screen.h"
 
 namespace ui {
 
@@ -111,6 +113,10 @@
   return nullptr;
 }
 
+std::unique_ptr<PlatformScreen> OzonePlatform::CreateScreen() {
+  return nullptr;
+}
+
 const OzonePlatform::PlatformProperties&
 OzonePlatform::GetPlatformProperties() {
   return kDefaultPlatformProperties;
diff --git a/ui/ozone/public/ozone_platform.h b/ui/ozone/public/ozone_platform.h
index c6073ed..ecf1fd85 100644
--- a/ui/ozone/public/ozone_platform.h
+++ b/ui/ozone/public/ozone_platform.h
@@ -7,11 +7,13 @@
 
 #include <memory>
 
+#include "base/callback.h"
 #include "base/macros.h"
 #include "base/message_loop/message_loop.h"
 #include "services/service_manager/public/cpp/bind_source_info.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
 #include "ui/events/system_input_injector.h"
+#include "ui/gfx/native_widget_types.h"
 #include "ui/ozone/ozone_export.h"
 
 namespace display {
@@ -32,6 +34,7 @@
 class InputController;
 class GpuPlatformSupportHost;
 class OverlayManagerOzone;
+class PlatformScreen;
 class PlatformWindow;
 class PlatformWindowDelegate;
 class SurfaceFactoryOzone;
@@ -139,6 +142,7 @@
       PlatformWindowInitProperties properties) = 0;
   virtual std::unique_ptr<display::NativeDisplayDelegate>
   CreateNativeDisplayDelegate() = 0;
+  virtual std::unique_ptr<PlatformScreen> CreateScreen();
 
   // Returns a struct that contains configuration and requirements for the
   // current platform implementation.
diff --git a/ui/ozone/public/platform_screen.h b/ui/ozone/public/platform_screen.h
new file mode 100644
index 0000000..d998751
--- /dev/null
+++ b/ui/ozone/public/platform_screen.h
@@ -0,0 +1,59 @@
+// Copyright 2018 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_OZONE_PUBLIC_PLATFORM_SCREEN_H_
+#define UI_OZONE_PUBLIC_PLATFORM_SCREEN_H_
+
+#include "ui/gfx/native_widget_types.h"
+
+namespace display {
+class Display;
+class DisplayObserver;
+}  // namespace display
+
+namespace gfx {
+class Point;
+class Rect;
+}  // namespace gfx
+
+namespace ui {
+
+class PlatformScreen {
+ public:
+  PlatformScreen() = default;
+  virtual ~PlatformScreen() = default;
+
+  virtual const std::vector<display::Display>& GetAllDisplays() const = 0;
+
+  virtual display::Display GetPrimaryDisplay() const = 0;
+
+  // Returns Desktop objects that the |widget| belongs to.
+  virtual display::Display GetDisplayForAcceleratedWidget(
+      gfx::AcceleratedWidget widget) const = 0;
+
+  // Returns cursor position in DIPs relative to the desktop.
+  virtual gfx::Point GetCursorScreenPoint() const = 0;
+
+  virtual gfx::AcceleratedWidget GetAcceleratedWidgetAtScreenPoint(
+      const gfx::Point& point) const = 0;
+
+  // Returns the display nearest the specified point. |point| must be in DIPs.
+  virtual display::Display GetDisplayNearestPoint(
+      const gfx::Point& point) const = 0;
+
+  // Returns the display that most closely intersects the provided rect.
+  virtual display::Display GetDisplayMatching(
+      const gfx::Rect& match_rect) const = 0;
+
+  // Adds/Removes display observers.
+  virtual void AddObserver(display::DisplayObserver* observer) = 0;
+  virtual void RemoveObserver(display::DisplayObserver* observer) = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PlatformScreen);
+};
+
+}  // namespace ui
+
+#endif  // UI_OZONE_PUBLIC_PLATFORM_SCREEN_H_
\ No newline at end of file
diff --git a/webrunner/BUILD.gn b/webrunner/BUILD.gn
index 81d4652..4363012 100644
--- a/webrunner/BUILD.gn
+++ b/webrunner/BUILD.gn
@@ -79,6 +79,7 @@
     "//services/network/public/cpp",
     "//ui/aura",
     "//ui/display",
+    "//ui/ozone",
     "//ui/platform_window",
   ]
 
diff --git a/webrunner/browser/DEPS b/webrunner/browser/DEPS
index 5791cd1..598b434 100644
--- a/webrunner/browser/DEPS
+++ b/webrunner/browser/DEPS
@@ -2,5 +2,6 @@
   "+content/public/browser",
   "+ui/aura",
   "+ui/display",
+  "+ui/ozone/public",
   "+ui/platform_window",
 ]
\ No newline at end of file
diff --git a/webrunner/browser/webrunner_browser_main_parts.cc b/webrunner/browser/webrunner_browser_main_parts.cc
index b431578..852da48 100644
--- a/webrunner/browser/webrunner_browser_main_parts.cc
+++ b/webrunner/browser/webrunner_browser_main_parts.cc
@@ -6,6 +6,8 @@
 
 #include "base/command_line.h"
 #include "base/files/file_util.h"
+#include "ui/aura/screen_ozone.h"
+#include "ui/ozone/public/ozone_platform.h"
 #include "webrunner/browser/context_impl.h"
 #include "webrunner/browser/webrunner_browser_context.h"
 #include "webrunner/browser/webrunner_screen.h"
@@ -17,11 +19,22 @@
     zx::channel context_channel)
     : context_channel_(std::move(context_channel)) {}
 
-WebRunnerBrowserMainParts::~WebRunnerBrowserMainParts() = default;
+WebRunnerBrowserMainParts::~WebRunnerBrowserMainParts() {
+  display::Screen::SetScreenInstance(nullptr);
+}
 
 void WebRunnerBrowserMainParts::PreMainMessageLoopRun() {
   DCHECK(!screen_);
-  screen_ = std::make_unique<WebRunnerScreen>();
+
+  auto platform_screen = ui::OzonePlatform::GetInstance()->CreateScreen();
+  if (platform_screen) {
+    screen_ = std::make_unique<aura::ScreenOzone>(std::move(platform_screen));
+  } else {
+    // Use dummy display::Screen for Ozone platforms that don't provide
+    // PlatformScreen.
+    screen_ = std::make_unique<WebRunnerScreen>();
+  }
+
   display::Screen::SetScreenInstance(screen_.get());
 
   DCHECK(!browser_context_);
diff --git a/webrunner/browser/webrunner_browser_main_parts.h b/webrunner/browser/webrunner_browser_main_parts.h
index 27c8184..9813a38 100644
--- a/webrunner/browser/webrunner_browser_main_parts.h
+++ b/webrunner/browser/webrunner_browser_main_parts.h
@@ -12,11 +12,14 @@
 #include "content/public/browser/browser_main_parts.h"
 #include "webrunner/fidl/chromium/web/cpp/fidl.h"
 
+namespace display {
+class Screen;
+}
+
 namespace webrunner {
 
 class ContextImpl;
 class WebRunnerBrowserContext;
-class WebRunnerScreen;
 
 class WebRunnerBrowserMainParts : public content::BrowserMainParts {
  public:
@@ -30,7 +33,7 @@
  private:
   zx::channel context_channel_;
 
-  std::unique_ptr<WebRunnerScreen> screen_;
+  std::unique_ptr<display::Screen> screen_;
   std::unique_ptr<WebRunnerBrowserContext> browser_context_;
 
   std::unique_ptr<ContextImpl> context_impl_;