Commit 988465ae authored by Mike Wasserman's avatar Mike Wasserman Committed by Commit Bot

Fugu: Use Display mojom and extend Screen interface for Screen Enumeration

Update code to better match the latest Screen Enumeration proposal:
https://github.com/spark008/screen-enumeration/blob/master/EXPLAINER.md

Use the existing Display mojo struct, instead of a new parallel struct.
Add [RuntimeEnabled=ScreenEnumeration] Screen attributes, instead of a new parallel object.
Rename requestDisplays to getScreens. Update test expectations.

Test with chrome://flags#enable-experimental-web-platform-features or --enable-blink-features=ScreenEnumeration

Bug: 994889
Test: Automated; getScreens() works with flag enabled.
Change-Id: I54f1594c5b6f1ad2a6532f3ee5f8a0184408c7b3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1842339
Commit-Queue: Michael Wasserman <msw@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarStaphany Park <staphany@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712839}
parent 778e9192
...@@ -6,11 +6,9 @@ ...@@ -6,11 +6,9 @@
#include <memory> #include <memory>
#include "content/public/browser/render_frame_host.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "ui/display/display.h" #include "ui/display/display.h"
#include "ui/display/screen.h" #include "ui/display/screen.h"
#include "url/origin.h"
namespace content { namespace content {
...@@ -24,30 +22,12 @@ void ScreenEnumerationImpl::Create( ...@@ -24,30 +22,12 @@ void ScreenEnumerationImpl::Create(
ScreenEnumerationImpl::ScreenEnumerationImpl() = default; ScreenEnumerationImpl::ScreenEnumerationImpl() = default;
ScreenEnumerationImpl::~ScreenEnumerationImpl() = default; ScreenEnumerationImpl::~ScreenEnumerationImpl() = default;
void ScreenEnumerationImpl::RequestDisplays(RequestDisplaysCallback callback) { void ScreenEnumerationImpl::GetDisplays(GetDisplaysCallback callback) {
display::Screen* screen = display::Screen::GetScreen(); display::Screen* screen = display::Screen::GetScreen();
std::vector<display::Display> displays = screen->GetAllDisplays(); const std::vector<display::Display> displays = screen->GetAllDisplays();
int64_t primary_id = screen->GetPrimaryDisplay().id(); const int64_t primary_id = screen->GetPrimaryDisplay().id();
// TODO(msw): Return no data and |false| if a permission check fails.
std::vector<blink::mojom::DisplayPtr> result; std::move(callback).Run(std::move(displays), primary_id, true);
for (const display::Display& display : displays) {
const gfx::Rect& bounds = display.bounds();
auto mojo_display = blink::mojom::Display::New();
// TODO(staphany): Get actual display name instead of hardcoded value.
mojo_display->name = "Generic Display";
mojo_display->scale_factor = display.device_scale_factor();
mojo_display->width = bounds.width();
mojo_display->height = bounds.height();
mojo_display->left = bounds.x();
mojo_display->top = bounds.y();
mojo_display->color_depth = display.color_depth();
mojo_display->is_primary = (display.id() == primary_id);
mojo_display->is_internal = display.IsInternal();
result.emplace_back(std::move(mojo_display));
}
// TODO(staphany): Add a permission prompt, and return empty |result| and
// |false| if the permission check fails.
std::move(callback).Run(std::move(result), true);
} }
} // namespace content } // namespace content
\ No newline at end of file
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
namespace content { namespace content {
// A backend for the proposed interface to query the device's screen space.
class ScreenEnumerationImpl : public blink::mojom::ScreenEnumeration { class ScreenEnumerationImpl : public blink::mojom::ScreenEnumeration {
public: public:
static void Create( static void Create(
...@@ -21,7 +22,7 @@ class ScreenEnumerationImpl : public blink::mojom::ScreenEnumeration { ...@@ -21,7 +22,7 @@ class ScreenEnumerationImpl : public blink::mojom::ScreenEnumeration {
ScreenEnumerationImpl& operator=(const ScreenEnumerationImpl&) = delete; ScreenEnumerationImpl& operator=(const ScreenEnumerationImpl&) = delete;
// blink::mojom::ScreenEnumeration: // blink::mojom::ScreenEnumeration:
void RequestDisplays(RequestDisplaysCallback callback) override; void GetDisplays(GetDisplaysCallback callback) override;
}; };
} // namespace content } // namespace content
......
...@@ -180,6 +180,7 @@ mojom("mojom_platform") { ...@@ -180,6 +180,7 @@ mojom("mojom_platform") {
"//skia/public/mojom", "//skia/public/mojom",
"//third_party/blink/public/mojom/usb", "//third_party/blink/public/mojom/usb",
"//ui/base/ime/mojom", "//ui/base/ime/mojom",
"//ui/display/mojom",
"//ui/gfx/geometry/mojom", "//ui/gfx/geometry/mojom",
"//ui/gfx/mojom", "//ui/gfx/mojom",
"//url/mojom:url_mojom_gurl", "//url/mojom:url_mojom_gurl",
......
...@@ -4,42 +4,15 @@ ...@@ -4,42 +4,15 @@
module blink.mojom; module blink.mojom;
// A physical or virtual unit of rendering space connected to the device. import "ui/display/mojom/display.mojom";
//
// Display structures typically correspond 1:1 with internal laptop/phone/tablet
// screens and externally-connected monitors.
//
// Properties are populated from the corresponding display::Display object and
// Web-exposed through the Display object in the Screen Enumeration API. The
// following properties should be equivalent to those in the Screen interface:
// width, height, colorDepth.
struct Display {
// A human-readable name for the display.
string name;
// The number of hardware pixels per CSS pixel.
float scale_factor;
// The full width of the display, in CSS pixels.
int32 width;
// The full height of the display, in CSS pixels.
int32 height;
// The x-coordinate of the display's left edge in the screen's coordinate
// system (top-left corner of the primary display is the origin).
int32 left;
// The y-coordinate of the display's top edge in the screen's coordinate
// system (top-left corner of the primary display is the origin).
int32 top;
// The number of bits allocated to pixel color.
int32 color_depth;
// Whether the display is the primary display.
bool is_primary;
// Whether the display is internal (built-in) or external.
bool is_internal;
};
// This interface is implemented by the browser process to pass screen data to // This interface is implemented by the browser process to pass screen data to
// window and worker processes. // window and worker processes.
interface ScreenEnumeration { interface ScreenEnumeration {
// If success is false, |displays| is meaningless. Otherwise, |displays| is // If success is false, other returned values are meaningless. Otherwise,
// the list of all the device's Displays. // |displays| is the list of connected display devices, and |primary_id| is
RequestDisplays() => (array<Display> displays, bool success); // the id of the primary display.
GetDisplays() => (array<display.mojom.Display> displays,
int64 primary_id,
bool success);
}; };
...@@ -112,6 +112,7 @@ source_set("prerequisites") { ...@@ -112,6 +112,7 @@ source_set("prerequisites") {
"//third_party/snappy", "//third_party/snappy",
"//third_party/zlib", "//third_party/zlib",
"//ui/base/ime/mojom", "//ui/base/ime/mojom",
"//ui/display/mojom:mojom_blink",
"//ui/events:dom_keycode_converter", "//ui/events:dom_keycode_converter",
"//ui/gfx/geometry", "//ui/gfx/geometry",
"//ui/native_theme", "//ui/native_theme",
......
...@@ -81,6 +81,7 @@ include_rules = [ ...@@ -81,6 +81,7 @@ include_rules = [
"+ui/base/ime/mojom/ime_types.mojom-blink.h", "+ui/base/ime/mojom/ime_types.mojom-blink.h",
"+ui/base/ime/mojom/ime_types.mojom-blink-forward.h", "+ui/base/ime/mojom/ime_types.mojom-blink-forward.h",
"+ui/base/resource/scale_factor.h", "+ui/base/resource/scale_factor.h",
"+ui/display/mojom/display.mojom-blink.h",
"+ui/gfx/mac/cocoa_scrollbar_painter.h", "+ui/gfx/mac/cocoa_scrollbar_painter.h",
"+ui/gfx/geometry", "+ui/gfx/geometry",
"+ui/gfx/skia_util.h", "+ui/gfx/skia_util.h",
......
...@@ -50,8 +50,11 @@ Screen::Screen(LocalFrame* frame) : DOMWindowClient(frame) {} ...@@ -50,8 +50,11 @@ Screen::Screen(LocalFrame* frame) : DOMWindowClient(frame) {}
int Screen::height() const { int Screen::height() const {
LocalFrame* frame = GetFrame(); LocalFrame* frame = GetFrame();
if (!frame) if (!frame) {
if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return display_->bounds.height;
return 0; return 0;
}
Page* page = frame->GetPage(); Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame); WebScreenInfo screen_info = GetScreenInfo(*frame);
...@@ -63,8 +66,11 @@ int Screen::height() const { ...@@ -63,8 +66,11 @@ int Screen::height() const {
int Screen::width() const { int Screen::width() const {
LocalFrame* frame = GetFrame(); LocalFrame* frame = GetFrame();
if (!frame) if (!frame) {
if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return display_->bounds.width;
return 0; return 0;
}
Page* page = frame->GetPage(); Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame); WebScreenInfo screen_info = GetScreenInfo(*frame);
...@@ -76,22 +82,31 @@ int Screen::width() const { ...@@ -76,22 +82,31 @@ int Screen::width() const {
unsigned Screen::colorDepth() const { unsigned Screen::colorDepth() const {
LocalFrame* frame = GetFrame(); LocalFrame* frame = GetFrame();
if (!frame) if (!frame) {
if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return display_->color_depth;
return 0; return 0;
}
return static_cast<unsigned>(GetScreenInfo(*frame).depth); return static_cast<unsigned>(GetScreenInfo(*frame).depth);
} }
unsigned Screen::pixelDepth() const { unsigned Screen::pixelDepth() const {
LocalFrame* frame = GetFrame(); LocalFrame* frame = GetFrame();
if (!frame) if (!frame) {
if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return display_->color_depth;
return 0; return 0;
}
return static_cast<unsigned>(GetScreenInfo(*frame).depth); return static_cast<unsigned>(GetScreenInfo(*frame).depth);
} }
int Screen::availLeft() const { int Screen::availLeft() const {
LocalFrame* frame = GetFrame(); LocalFrame* frame = GetFrame();
if (!frame) if (!frame) {
if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return display_->work_area.x;
return 0; return 0;
}
Page* page = frame->GetPage(); Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame); WebScreenInfo screen_info = GetScreenInfo(*frame);
...@@ -103,8 +118,11 @@ int Screen::availLeft() const { ...@@ -103,8 +118,11 @@ int Screen::availLeft() const {
int Screen::availTop() const { int Screen::availTop() const {
LocalFrame* frame = GetFrame(); LocalFrame* frame = GetFrame();
if (!frame) if (!frame) {
if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return display_->work_area.y;
return 0; return 0;
}
Page* page = frame->GetPage(); Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame); WebScreenInfo screen_info = GetScreenInfo(*frame);
...@@ -116,8 +134,11 @@ int Screen::availTop() const { ...@@ -116,8 +134,11 @@ int Screen::availTop() const {
int Screen::availHeight() const { int Screen::availHeight() const {
LocalFrame* frame = GetFrame(); LocalFrame* frame = GetFrame();
if (!frame) if (!frame) {
if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return display_->work_area.width;
return 0; return 0;
}
Page* page = frame->GetPage(); Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame); WebScreenInfo screen_info = GetScreenInfo(*frame);
...@@ -129,8 +150,11 @@ int Screen::availHeight() const { ...@@ -129,8 +150,11 @@ int Screen::availHeight() const {
int Screen::availWidth() const { int Screen::availWidth() const {
LocalFrame* frame = GetFrame(); LocalFrame* frame = GetFrame();
if (!frame) if (!frame) {
if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return display_->work_area.height;
return 0; return 0;
}
Page* page = frame->GetPage(); Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) { if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame); WebScreenInfo screen_info = GetScreenInfo(*frame);
...@@ -146,4 +170,75 @@ void Screen::Trace(blink::Visitor* visitor) { ...@@ -146,4 +170,75 @@ void Screen::Trace(blink::Visitor* visitor) {
Supplementable<Screen>::Trace(visitor); Supplementable<Screen>::Trace(visitor);
} }
Screen::Screen(display::mojom::blink::DisplayPtr display, bool primary)
: DOMWindowClient(static_cast<LocalFrame*>(nullptr)),
display_(std::move(display)),
primary_(primary) {}
int Screen::left() const {
LocalFrame* frame = GetFrame();
if (!frame) {
if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return display_->bounds.x;
return 0;
}
Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame);
return static_cast<int>(
lroundf(screen_info.rect.x * screen_info.device_scale_factor));
}
return GetScreenInfo(*frame).rect.x;
}
int Screen::top() const {
LocalFrame* frame = GetFrame();
if (!frame) {
if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return display_->bounds.y;
return 0;
}
Page* page = frame->GetPage();
if (page->GetSettings().GetReportScreenSizeInPhysicalPixelsQuirk()) {
WebScreenInfo screen_info = GetScreenInfo(*frame);
return static_cast<int>(
lroundf(screen_info.rect.y * screen_info.device_scale_factor));
}
return GetScreenInfo(*frame).rect.y;
}
bool Screen::internal() const {
// TODO(http://crbug.com/994889): Implement this.
NOTIMPLEMENTED_LOG_ONCE();
return false;
}
bool Screen::primary() const {
LocalFrame* frame = GetFrame();
if (!frame && RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return primary_.has_value() && primary_.value();
// TODO(http://crbug.com/994889): Implement this for |window.screen|?
NOTIMPLEMENTED_LOG_ONCE();
return false;
}
float Screen::scaleFactor() const {
LocalFrame* frame = GetFrame();
if (!frame) {
if (RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return display_->device_scale_factor;
return 0;
}
return GetScreenInfo(*frame).device_scale_factor;
}
const String Screen::name() const {
// TODO(http://crbug.com/994889): Implement this.
NOTIMPLEMENTED_LOG_ONCE();
LocalFrame* frame = GetFrame();
if (!frame && RuntimeEnabledFeatures::ScreenEnumerationEnabled() && display_)
return "Generic Screen";
return String();
}
} // namespace blink } // namespace blink
...@@ -29,11 +29,14 @@ ...@@ -29,11 +29,14 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SCREEN_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SCREEN_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SCREEN_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_SCREEN_H_
#include "base/optional.h"
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/supplementable.h" #include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "ui/display/mojom/display.mojom-blink.h"
namespace blink { namespace blink {
...@@ -58,6 +61,27 @@ class CORE_EXPORT Screen final : public ScriptWrappable, ...@@ -58,6 +61,27 @@ class CORE_EXPORT Screen final : public ScriptWrappable,
int availWidth() const; int availWidth() const;
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
// Proposed extensions to the Screen interface.
// https://github.com/spark008/screen-enumeration/blob/master/EXPLAINER.md
// TODO(msw): Resolve different info sources, caching, and lifetimes.
Screen(display::mojom::blink::DisplayPtr display, bool primary);
int left() const;
int top() const;
bool internal() const;
bool primary() const;
float scaleFactor() const;
const String name() const;
private:
// A static snapshot of the display's information, provided upon construction.
// This member is only valid for Screen objects obtained via the experimental
// Screen Enumeration API.
const display::mojom::blink::DisplayPtr display_;
// True if this is the primary screen of the operating system; it is a static
// value provided upon construction. This member is only valid for Screen
// objects obtained via the experimental Screen Enumeration API.
const base::Optional<bool> primary_;
}; };
} // namespace blink } // namespace blink
......
...@@ -41,4 +41,13 @@ ...@@ -41,4 +41,13 @@
// Non-standard // Non-standard
[HighEntropy, Measure] readonly attribute long availLeft; [HighEntropy, Measure] readonly attribute long availLeft;
[HighEntropy, Measure] readonly attribute long availTop; [HighEntropy, Measure] readonly attribute long availTop;
// Proposed
// https://github.com/spark008/screen-enumeration/blob/master/EXPLAINER.md
[RuntimeEnabled=ScreenEnumeration] readonly attribute long left;
[RuntimeEnabled=ScreenEnumeration] readonly attribute long top;
[RuntimeEnabled=ScreenEnumeration] readonly attribute boolean internal;
[RuntimeEnabled=ScreenEnumeration] readonly attribute boolean primary;
[RuntimeEnabled=ScreenEnumeration] readonly attribute float scaleFactor;
[RuntimeEnabled=ScreenEnumeration] readonly attribute DOMString name;
}; };
...@@ -776,7 +776,6 @@ modules_dictionary_idl_files = ...@@ -776,7 +776,6 @@ modules_dictionary_idl_files =
"quota/storage_usage_details.idl", "quota/storage_usage_details.idl",
"scheduler/scheduler_post_task_options.idl", "scheduler/scheduler_post_task_options.idl",
"scheduler/task_queue_post_task_options.idl", "scheduler/task_queue_post_task_options.idl",
"screen_enumeration/display.idl",
"sensor/sensor_error_event_init.idl", "sensor/sensor_error_event_init.idl",
"sensor/sensor_options.idl", "sensor/sensor_options.idl",
"sensor/spatial_sensor_options.idl", "sensor/spatial_sensor_options.idl",
......
...@@ -12,7 +12,8 @@ blink_modules_sources("screen_enumeration") { ...@@ -12,7 +12,8 @@ blink_modules_sources("screen_enumeration") {
"screen_manager.h", "screen_manager.h",
] ]
deps = [ public_deps = [
"//third_party/blink/renderer/platform", "//third_party/blink/renderer/platform",
"//ui/display/mojom:mojom_blink",
] ]
} }
include_rules = [
"+ui/display/mojom/display.mojom-blink.h",
]
// Copyright 2019 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.
// https://github.com/spark008/screen-enumeration/blob/master/EXPLAINER.md
// TODO(staphany): Add working-area versions of width, height, left, and top
// (e.g. like availWidth in the Screen interface).
// TODO(staphany): Add orientation.
dictionary Display {
required DOMString name;
required float scaleFactor;
required long width;
required long height;
required long left;
required long top;
required long colorDepth;
required boolean isPrimary;
required boolean isInternal;
};
\ No newline at end of file
...@@ -5,40 +5,35 @@ ...@@ -5,40 +5,35 @@
#include "third_party/blink/renderer/modules/screen_enumeration/screen_manager.h" #include "third_party/blink/renderer/modules/screen_enumeration/screen_manager.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/modules/screen_enumeration/display.h" #include "third_party/blink/renderer/core/frame/screen.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h" #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "ui/display/mojom/display.mojom-blink.h"
namespace blink { namespace blink {
namespace { namespace {
void DidReceiveDisplays(ScriptPromiseResolver* resolver, void DidGetDisplays(
WTF::Vector<mojom::blink::DisplayPtr> backend_displays, ScriptPromiseResolver* resolver,
WTF::Vector<display::mojom::blink::DisplayPtr> backend_displays,
int64_t primary_id,
bool success) { bool success) {
ScriptState* script_state = resolver->GetScriptState(); ScriptState* script_state = resolver->GetScriptState();
if (!script_state->ContextIsValid()) if (!script_state->ContextIsValid())
return; return;
HeapVector<Member<Display>> displays; HeapVector<Member<Screen>> screens;
displays.ReserveInitialCapacity(backend_displays.size()); screens.ReserveInitialCapacity(backend_displays.size());
for (const auto& backend_display : backend_displays) { for (display::mojom::blink::DisplayPtr& backend_display : backend_displays) {
auto* display = MakeGarbageCollected<Display>(); const bool primary = backend_display->id == primary_id;
display->setName(backend_display->name); screens.emplace_back(
display->setScaleFactor(backend_display->scale_factor); MakeGarbageCollected<Screen>(std::move(backend_display), primary));
display->setWidth(backend_display->width);
display->setHeight(backend_display->height);
display->setLeft(backend_display->left);
display->setTop(backend_display->top);
display->setColorDepth(backend_display->color_depth);
display->setIsPrimary(backend_display->is_primary);
display->setIsInternal(backend_display->is_internal);
displays.emplace_back(display);
} }
resolver->Resolve(std::move(displays)); resolver->Resolve(std::move(screens));
} }
} // namespace } // namespace
...@@ -50,7 +45,7 @@ ScreenManager::ScreenManager( ...@@ -50,7 +45,7 @@ ScreenManager::ScreenManager(
&ScreenManager::OnBackendDisconnected, WrapWeakPersistent(this))); &ScreenManager::OnBackendDisconnected, WrapWeakPersistent(this)));
} }
ScriptPromise ScreenManager::requestDisplays(ScriptState* script_state, ScriptPromise ScreenManager::getScreens(ScriptState* script_state,
ExceptionState& exception_state) { ExceptionState& exception_state) {
if (!backend_) { if (!backend_) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
...@@ -59,8 +54,7 @@ ScriptPromise ScreenManager::requestDisplays(ScriptState* script_state, ...@@ -59,8 +54,7 @@ ScriptPromise ScreenManager::requestDisplays(ScriptState* script_state,
} }
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
backend_->RequestDisplays( backend_->GetDisplays(WTF::Bind(&DidGetDisplays, WrapPersistent(resolver)));
WTF::Bind(&DidReceiveDisplays, WrapPersistent(resolver)));
return resolver->Promise(); return resolver->Promise();
} }
......
...@@ -14,10 +14,9 @@ namespace blink { ...@@ -14,10 +14,9 @@ namespace blink {
class ScriptState; class ScriptState;
// An interface for querying the state of the device's screen space. // A proposed interface for querying the state of the device's screen space.
// // https://github.com/spark008/screen-enumeration/blob/master/EXPLAINER.md
// The interface is available in both window and service worker execution // The interface is available in both window and worker execution contexts.
// contexts.
class ScreenManager final : public ScriptWrappable { class ScreenManager final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO(); DEFINE_WRAPPERTYPEINFO();
...@@ -25,8 +24,8 @@ class ScreenManager final : public ScriptWrappable { ...@@ -25,8 +24,8 @@ class ScreenManager final : public ScriptWrappable {
// Creates a ScreenManager and binds it to the browser-side implementation. // Creates a ScreenManager and binds it to the browser-side implementation.
explicit ScreenManager(mojo::Remote<mojom::blink::ScreenEnumeration> backend); explicit ScreenManager(mojo::Remote<mojom::blink::ScreenEnumeration> backend);
// Resolves to the list of |Display| objects in the device's screen space. // Resolves to the list of |Screen| objects in the device's screen space.
ScriptPromise requestDisplays(ScriptState*, ExceptionState&); ScriptPromise getScreens(ScriptState*, ExceptionState&);
// Called if the backend is disconnected, e.g. during renderer shutdown. // Called if the backend is disconnected, e.g. during renderer shutdown.
void OnBackendDisconnected(); void OnBackendDisconnected();
......
...@@ -8,5 +8,5 @@ ...@@ -8,5 +8,5 @@
Exposed=(Window,Worker), Exposed=(Window,Worker),
RuntimeEnabled=ScreenEnumeration RuntimeEnabled=ScreenEnumeration
] interface ScreenManager { ] interface ScreenManager {
[CallWith=ScriptState, RaisesException] Promise<sequence<Display>> requestDisplays(); [CallWith=ScriptState, RaisesException] Promise<sequence<Screen>> getScreens();
}; };
// META: global=window,dedicatedworker,sharedworker,serviceworker
'use strict';
promise_test(async testCase => {
assert_class_string(navigator.screen, 'ScreenManager');
assert_equals(typeof navigator.screen.getScreens, 'function');
}, 'navigator.screen.getScreens is present');
promise_test(async testCase => {
const screens = await navigator.screen.getScreens();
assert_greater_than(screens.length, 0);
assert_equals(typeof screens[0].availWidth, 'number');
assert_equals(typeof screens[0].availHeight, 'number');
assert_equals(typeof screens[0].width, 'number');
assert_equals(typeof screens[0].height, 'number');
assert_equals(typeof screens[0].colorDepth, 'number');
assert_equals(typeof screens[0].pixelDepth, 'number');
assert_equals(typeof screens[0].availLeft, 'number');
assert_equals(typeof screens[0].availTop, 'number');
assert_equals(typeof screens[0].left, 'number');
assert_equals(typeof screens[0].top, 'number');
assert_equals(typeof screens[0].orientation, 'object');
assert_equals(typeof screens[0].primary, 'boolean');
assert_equals(typeof screens[0].internal, 'boolean');
assert_equals(typeof screens[0].scaleFactor, 'number');
assert_equals(typeof screens[0].name, 'string');
}, 'navigator.screen.getScreens returns at least 1 Screen');
\ No newline at end of file
// META: global=window,dedicatedworker,sharedworker,serviceworker
'use strict';
promise_test(async testCase => {
assert_class_string(navigator.screen, 'ScreenManager');
assert_equals(typeof navigator.screen.requestDisplays, 'function');
}, 'navigator.screen.requestDisplays is present');
promise_test(async testCase => {
const displays = await navigator.screen.requestDisplays();
assert_greater_than(displays.length, 0);
assert_equals(typeof displays[0].name, 'string');
assert_equals(typeof displays[0].scaleFactor, 'number');
assert_equals(typeof displays[0].width, 'number');
assert_equals(typeof displays[0].height, 'number');
assert_equals(typeof displays[0].left, 'number');
assert_equals(typeof displays[0].top, 'number');
assert_equals(typeof displays[0].colorDepth, 'number');
assert_equals(typeof displays[0].isPrimary, 'boolean');
assert_equals(typeof displays[0].isInternal, 'boolean');
}, 'navigator.screen.requestDisplays returns at least 1 Display');
\ No newline at end of file
...@@ -94,7 +94,13 @@ PASS window.cached_screen.availTop is 0 ...@@ -94,7 +94,13 @@ PASS window.cached_screen.availTop is 0
PASS window.cached_screen.availWidth is 0 PASS window.cached_screen.availWidth is 0
PASS window.cached_screen.colorDepth is 0 PASS window.cached_screen.colorDepth is 0
PASS window.cached_screen.height is 0 PASS window.cached_screen.height is 0
PASS window.cached_screen.internal is false
PASS window.cached_screen.left is 0
PASS window.cached_screen.name is ''
PASS window.cached_screen.pixelDepth is 0 PASS window.cached_screen.pixelDepth is 0
PASS window.cached_screen.primary is false
PASS window.cached_screen.scaleFactor is 0
PASS window.cached_screen.top is 0
PASS window.cached_screen.width is 0 PASS window.cached_screen.width is 0
PASS window.cached_screen_orientation.angle is 0 PASS window.cached_screen_orientation.angle is 0
PASS window.cached_screen_orientation.onchange is null PASS window.cached_screen_orientation.onchange is null
......
...@@ -94,7 +94,13 @@ PASS window.cached_screen.availTop is 0 ...@@ -94,7 +94,13 @@ PASS window.cached_screen.availTop is 0
PASS window.cached_screen.availWidth is 0 PASS window.cached_screen.availWidth is 0
PASS window.cached_screen.colorDepth is 0 PASS window.cached_screen.colorDepth is 0
PASS window.cached_screen.height is 0 PASS window.cached_screen.height is 0
PASS window.cached_screen.internal is false
PASS window.cached_screen.left is 0
PASS window.cached_screen.name is ''
PASS window.cached_screen.pixelDepth is 0 PASS window.cached_screen.pixelDepth is 0
PASS window.cached_screen.primary is false
PASS window.cached_screen.scaleFactor is 0
PASS window.cached_screen.top is 0
PASS window.cached_screen.width is 0 PASS window.cached_screen.width is 0
PASS window.cached_screen_orientation.angle is 0 PASS window.cached_screen_orientation.angle is 0
PASS window.cached_screen_orientation.onchange is null PASS window.cached_screen_orientation.onchange is null
......
...@@ -94,7 +94,13 @@ PASS window.cached_screen.availTop is 0 ...@@ -94,7 +94,13 @@ PASS window.cached_screen.availTop is 0
PASS window.cached_screen.availWidth is 0 PASS window.cached_screen.availWidth is 0
PASS window.cached_screen.colorDepth is 0 PASS window.cached_screen.colorDepth is 0
PASS window.cached_screen.height is 0 PASS window.cached_screen.height is 0
PASS window.cached_screen.internal is false
PASS window.cached_screen.left is 0
PASS window.cached_screen.name is ''
PASS window.cached_screen.pixelDepth is 0 PASS window.cached_screen.pixelDepth is 0
PASS window.cached_screen.primary is false
PASS window.cached_screen.scaleFactor is 0
PASS window.cached_screen.top is 0
PASS window.cached_screen.width is 0 PASS window.cached_screen.width is 0
PASS window.cached_screen_orientation.angle is 0 PASS window.cached_screen_orientation.angle is 0
PASS window.cached_screen_orientation.onchange is null PASS window.cached_screen_orientation.onchange is null
......
...@@ -223,10 +223,16 @@ PASS oldChildWindow.screen.availTop is newChildWindow.screen.availTop ...@@ -223,10 +223,16 @@ PASS oldChildWindow.screen.availTop is newChildWindow.screen.availTop
PASS oldChildWindow.screen.availWidth is newChildWindow.screen.availWidth PASS oldChildWindow.screen.availWidth is newChildWindow.screen.availWidth
PASS oldChildWindow.screen.colorDepth is newChildWindow.screen.colorDepth PASS oldChildWindow.screen.colorDepth is newChildWindow.screen.colorDepth
PASS oldChildWindow.screen.height is newChildWindow.screen.height PASS oldChildWindow.screen.height is newChildWindow.screen.height
PASS oldChildWindow.screen.internal is newChildWindow.screen.internal
PASS oldChildWindow.screen.left is newChildWindow.screen.left
PASS oldChildWindow.screen.name is newChildWindow.screen.name
PASS oldChildWindow.screen.orientation.angle is newChildWindow.screen.orientation.angle PASS oldChildWindow.screen.orientation.angle is newChildWindow.screen.orientation.angle
PASS oldChildWindow.screen.orientation.onchange is newChildWindow.screen.orientation.onchange PASS oldChildWindow.screen.orientation.onchange is newChildWindow.screen.orientation.onchange
PASS oldChildWindow.screen.orientation.type is newChildWindow.screen.orientation.type PASS oldChildWindow.screen.orientation.type is newChildWindow.screen.orientation.type
PASS oldChildWindow.screen.pixelDepth is newChildWindow.screen.pixelDepth PASS oldChildWindow.screen.pixelDepth is newChildWindow.screen.pixelDepth
PASS oldChildWindow.screen.primary is newChildWindow.screen.primary
PASS oldChildWindow.screen.scaleFactor is newChildWindow.screen.scaleFactor
PASS oldChildWindow.screen.top is newChildWindow.screen.top
PASS oldChildWindow.screen.width is newChildWindow.screen.width PASS oldChildWindow.screen.width is newChildWindow.screen.width
PASS oldChildWindow.screenLeft is newChildWindow.screenLeft PASS oldChildWindow.screenLeft is newChildWindow.screenLeft
PASS oldChildWindow.screenTop is newChildWindow.screenTop PASS oldChildWindow.screenTop is newChildWindow.screenTop
......
...@@ -161,7 +161,13 @@ PASS childWindow.screen.availTop is 0 ...@@ -161,7 +161,13 @@ PASS childWindow.screen.availTop is 0
PASS childWindow.screen.availWidth is 0 PASS childWindow.screen.availWidth is 0
PASS childWindow.screen.colorDepth is 0 PASS childWindow.screen.colorDepth is 0
PASS childWindow.screen.height is 0 PASS childWindow.screen.height is 0
PASS childWindow.screen.internal is false
PASS childWindow.screen.left is 0
PASS childWindow.screen.name is ''
PASS childWindow.screen.pixelDepth is 0 PASS childWindow.screen.pixelDepth is 0
PASS childWindow.screen.primary is false
PASS childWindow.screen.scaleFactor is 0
PASS childWindow.screen.top is 0
PASS childWindow.screen.width is 0 PASS childWindow.screen.width is 0
PASS childWindow.screenLeft is 0 PASS childWindow.screenLeft is 0
PASS childWindow.screenTop is 0 PASS childWindow.screenTop is 0
......
...@@ -161,7 +161,13 @@ PASS childWindow.screen.availTop is 0 ...@@ -161,7 +161,13 @@ PASS childWindow.screen.availTop is 0
PASS childWindow.screen.availWidth is 0 PASS childWindow.screen.availWidth is 0
PASS childWindow.screen.colorDepth is 0 PASS childWindow.screen.colorDepth is 0
PASS childWindow.screen.height is 0 PASS childWindow.screen.height is 0
PASS childWindow.screen.internal is false
PASS childWindow.screen.left is 0
PASS childWindow.screen.name is ''
PASS childWindow.screen.pixelDepth is 0 PASS childWindow.screen.pixelDepth is 0
PASS childWindow.screen.primary is false
PASS childWindow.screen.scaleFactor is 0
PASS childWindow.screen.top is 0
PASS childWindow.screen.width is 0 PASS childWindow.screen.width is 0
PASS childWindow.screenLeft is 0 PASS childWindow.screenLeft is 0
PASS childWindow.screenTop is 0 PASS childWindow.screenTop is 0
......
...@@ -29,8 +29,14 @@ PASS screen.availTop == "LEFTOVER" is false ...@@ -29,8 +29,14 @@ PASS screen.availTop == "LEFTOVER" is false
PASS screen.availWidth == "LEFTOVER" is false PASS screen.availWidth == "LEFTOVER" is false
PASS screen.colorDepth == "LEFTOVER" is false PASS screen.colorDepth == "LEFTOVER" is false
PASS screen.height == "LEFTOVER" is false PASS screen.height == "LEFTOVER" is false
PASS screen.internal == "LEFTOVER" is false
PASS screen.left == "LEFTOVER" is false
PASS screen.name == "LEFTOVER" is false
PASS screen.orientation == "LEFTOVER" is false PASS screen.orientation == "LEFTOVER" is false
PASS screen.pixelDepth == "LEFTOVER" is false PASS screen.pixelDepth == "LEFTOVER" is false
PASS screen.primary == "LEFTOVER" is false
PASS screen.scaleFactor == "LEFTOVER" is false
PASS screen.top == "LEFTOVER" is false
PASS screen.width == "LEFTOVER" is false PASS screen.width == "LEFTOVER" is false
PASS scrollbars.visible == "LEFTOVER" is false PASS scrollbars.visible == "LEFTOVER" is false
PASS statusbar.visible == "LEFTOVER" is false PASS statusbar.visible == "LEFTOVER" is false
......
...@@ -1285,7 +1285,7 @@ interface Response ...@@ -1285,7 +1285,7 @@ interface Response
interface ScreenManager interface ScreenManager
attribute @@toStringTag attribute @@toStringTag
method constructor method constructor
method requestDisplays method getScreens
interface SecurityPolicyViolationEvent : Event interface SecurityPolicyViolationEvent : Event
attribute @@toStringTag attribute @@toStringTag
getter blockedURI getter blockedURI
......
...@@ -1224,7 +1224,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -1224,7 +1224,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] interface ScreenManager [Worker] interface ScreenManager
[Worker] attribute @@toStringTag [Worker] attribute @@toStringTag
[Worker] method constructor [Worker] method constructor
[Worker] method requestDisplays [Worker] method getScreens
[Worker] interface SecurityPolicyViolationEvent : Event [Worker] interface SecurityPolicyViolationEvent : Event
[Worker] attribute @@toStringTag [Worker] attribute @@toStringTag
[Worker] getter blockedURI [Worker] getter blockedURI
......
...@@ -7511,14 +7511,20 @@ interface Screen ...@@ -7511,14 +7511,20 @@ interface Screen
getter availWidth getter availWidth
getter colorDepth getter colorDepth
getter height getter height
getter internal
getter left
getter name
getter orientation getter orientation
getter pixelDepth getter pixelDepth
getter primary
getter scaleFactor
getter top
getter width getter width
method constructor method constructor
interface ScreenManager interface ScreenManager
attribute @@toStringTag attribute @@toStringTag
method constructor method constructor
method requestDisplays method getScreens
interface ScreenOrientation : EventTarget interface ScreenOrientation : EventTarget
attribute @@toStringTag attribute @@toStringTag
getter angle getter angle
......
...@@ -1202,7 +1202,7 @@ Starting worker: resources/global-interface-listing-worker.js ...@@ -1202,7 +1202,7 @@ Starting worker: resources/global-interface-listing-worker.js
[Worker] interface ScreenManager [Worker] interface ScreenManager
[Worker] attribute @@toStringTag [Worker] attribute @@toStringTag
[Worker] method constructor [Worker] method constructor
[Worker] method requestDisplays [Worker] method getScreens
[Worker] interface SecurityPolicyViolationEvent : Event [Worker] interface SecurityPolicyViolationEvent : Event
[Worker] attribute @@toStringTag [Worker] attribute @@toStringTag
[Worker] getter blockedURI [Worker] getter blockedURI
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
import("//mojo/public/tools/bindings/mojom.gni") import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") { mojom("mojom") {
generate_java = true
sources = [ sources = [
"display.mojom", "display.mojom",
"display_constants.mojom", "display_constants.mojom",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment