diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-23 17:21:03 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-23 16:25:15 +0000 |
commit | c551f43206405019121bd2b2c93714319a0a3300 (patch) | |
tree | 1f48c30631c421fd4bbb3c36da20183c8a2ed7d7 /chromium/third_party/blink/renderer/modules | |
parent | 7961cea6d1041e3e454dae6a1da660b453efd238 (diff) | |
download | qtwebengine-chromium-c551f43206405019121bd2b2c93714319a0a3300.tar.gz |
BASELINE: Update Chromium to 79.0.3945.139
Change-Id: I336b7182fab9bca80b709682489c07db112eaca5
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/modules')
959 files changed, 19604 insertions, 10040 deletions
diff --git a/chromium/third_party/blink/renderer/modules/BUILD.gn b/chromium/third_party/blink/renderer/modules/BUILD.gn index 30dcfb2b62c..e2b05af5f10 100644 --- a/chromium/third_party/blink/renderer/modules/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/BUILD.gn @@ -3,7 +3,6 @@ # found in the LICENSE file. import("//build/config/chromecast_build.gni") -import("//build/split_static_library.gni") import("//testing/libfuzzer/fuzzer_test.gni") import("//third_party/blink/renderer/bindings/bindings.gni") import("//third_party/blink/renderer/bindings/modules/v8/generated.gni") @@ -18,37 +17,19 @@ if (is_android) { visibility = [ "//third_party/blink/renderer/*" ] -if (!is_component_build && is_win) { - # This target as a static library (for non-component builds) is >2GB for - # official builds and some goma builds on Windows. This causes linking to - # fail. As a workaround, force using a split static library for these - # configurations. - modules_target_type = "split_static_library" -} else { - modules_target_type = "component" -} - config("modules_implementation") { defines = [ "BLINK_MODULES_IMPLEMENTATION=1" ] } -config("notouch_config") { - defines = [ "TOUCHLESS_MEDIA_CONTROLS" ] -} - make_names("module_names") { in_files = [ "indexeddb/indexed_db_names.json5" ] output_dir = blink_modules_output_dir deps = [] # Don't use default deps (otherwise it will be circular). } -target("jumbo_" + modules_target_type, "modules") { +jumbo_component("modules") { output_name = "blink_modules" - if (modules_target_type == "split_static_library") { - split_count = 5 - } - visibility = [] # Allow re-assignment of list. visibility = [ "//third_party/blink/*" ] @@ -103,6 +84,7 @@ target("jumbo_" + modules_target_type, "modules") { "//third_party/blink/renderer/modules/credentialmanager", "//third_party/blink/renderer/modules/crypto", "//third_party/blink/renderer/modules/csspaint", + "//third_party/blink/renderer/modules/compression", "//third_party/blink/renderer/modules/device_orientation", "//third_party/blink/renderer/modules/document_metadata", "//third_party/blink/renderer/modules/donottrack", @@ -139,6 +121,7 @@ target("jumbo_" + modules_target_type, "modules") { "//third_party/blink/renderer/modules/nfc", "//third_party/blink/renderer/modules/notifications", "//third_party/blink/renderer/modules/payments", + "//third_party/blink/renderer/modules/p2p", "//third_party/blink/renderer/modules/peerconnection", "//third_party/blink/renderer/modules/permissions", "//third_party/blink/renderer/modules/picture_in_picture", @@ -175,6 +158,7 @@ target("jumbo_" + modules_target_type, "modules") { deps = [ ":make_modules_generated", ":module_names", + "//jingle:webrtc_glue", "//net:net", "//third_party/blink/renderer/bindings/modules:generated", "//third_party/blink/renderer/bindings/modules/v8:bindings_modules_impl", @@ -182,6 +166,9 @@ target("jumbo_" + modules_target_type, "modules") { "//third_party/blink/renderer/core", "//third_party/icu", "//third_party/webrtc/api/audio:aec3_config_json", + "//third_party/webrtc/api/rtc_event_log:rtc_event_log_factory", + "//third_party/webrtc/media:rtc_internal_video_codecs", + "//third_party/webrtc/modules/video_coding:webrtc_h264", "//third_party/webrtc/pc:libjingle_peerconnection", "//third_party/webrtc/rtc_base:rtc_base", "//third_party/webrtc_overrides:init_webrtc", @@ -202,10 +189,6 @@ target("jumbo_" + modules_target_type, "modules") { configs -= [ "//build/config/compiler:default_symbols" ] configs += blink_symbols_config - - if (is_android && notouch_build) { - configs += [ ":notouch_config" ] - } } jumbo_source_set("modules_testing") { @@ -383,6 +366,8 @@ jumbo_source_set("unit_tests") { "peerconnection/adapters/quic_packet_transport_adapter_test.cc", "peerconnection/byte_buffer_queue_test.cc", "peerconnection/call_setup_state_tracker_unittest.cc", + "peerconnection/media_stream_remote_video_source_test.cc", + "peerconnection/media_stream_video_webrtc_sink_test.cc", "peerconnection/rtc_data_channel_test.cc", "peerconnection/rtc_ice_transport_test.cc", "peerconnection/rtc_ice_transport_test.h", @@ -390,7 +375,13 @@ jumbo_source_set("unit_tests") { "peerconnection/rtc_quic_stream_test.cc", "peerconnection/rtc_quic_transport_test.cc", "peerconnection/rtc_quic_transport_test.h", + "peerconnection/rtc_rtp_receiver_impl_test.cc", + "peerconnection/rtc_rtp_sender_impl_test.cc", + "peerconnection/rtc_rtp_transceiver_impl_test.cc", "peerconnection/rtc_sctp_transport_test.cc", + "peerconnection/transceiver_state_surfacer_test.cc", + "peerconnection/webrtc_media_stream_track_adapter_map_test.cc", + "peerconnection/webrtc_media_stream_track_adapter_test.cc", "picture_in_picture/picture_in_picture_controller_test.cc", "presentation/mock_presentation_service.h", "presentation/presentation_availability_state_test.cc", @@ -402,13 +393,17 @@ jumbo_source_set("unit_tests") { "push_messaging/push_subscription_test.cc", "remoteplayback/remote_playback_test.cc", "screen_orientation/screen_orientation_controller_impl_test.cc", + "sensor/ambient_light_sensor_test.cc", + "sensor/sensor_test_utils.cc", + "sensor/sensor_test_utils.h", "service_worker/service_worker_container_test.cc", "service_worker/service_worker_installed_scripts_manager_test.cc", "service_worker/service_worker_timeout_timer_test.cc", "service_worker/thread_safe_script_container_test.cc", "service_worker/web_embedded_worker_impl_test.cc", - "wake_lock/wake_lock_controller_test.cc", + "wake_lock/wake_lock_sentinel_test.cc", "wake_lock/wake_lock_state_record_test.cc", + "wake_lock/wake_lock_test.cc", "wake_lock/wake_lock_test_utils.cc", "wake_lock/wake_lock_test_utils.h", "webaudio/audio_basic_processor_handler_test.cc", @@ -442,14 +437,6 @@ jumbo_source_set("unit_tests") { sources += [ "payments/skip_to_gpay_utils_test.cc" ] } - if (is_android && notouch_build) { - sources += [ - "media_controls/touchless/media_controls_touchless_impl_test.cc", - "media_controls/touchless/test_media_controls_menu_host.cc", - "media_controls/touchless/test_media_controls_menu_host.h", - ] - } - configs += [ "//third_party/blink/renderer:config", "//third_party/blink/renderer:inside_blink", @@ -470,10 +457,12 @@ jumbo_source_set("unit_tests") { "//third_party/blink/renderer/core", "//third_party/blink/renderer/modules/gamepad:unit_tests", "//third_party/blink/renderer/modules/hid:unit_tests", + "//third_party/blink/renderer/modules/native_file_system:unit_tests", "//third_party/blink/renderer/modules/storage:unit_tests", "//third_party/blink/renderer/platform", "//third_party/blink/renderer/platform/wtf", "//third_party/opus", + "//third_party/webrtc/api:rtc_error", "//third_party/webrtc/rtc_base:rtc_base", "//v8", ] @@ -496,6 +485,20 @@ group("mediastream_unittests_data") { ] } +fuzzer_test("web_app_manifest_fuzzer") { + sources = [ + "manifest/manifest_fuzzer.cc", + ] + + dict = "manifest/manifest_fuzzer.dict" + seed_corpus = "manifest/fuzzer_seed_corpus" + + deps = [ + ":modules", + "//third_party/blink/renderer/platform:blink_fuzzer_test_support", + ] +} + if (use_libfuzzer) { fuzzer_test("media_capabilities_fuzzer") { sources = [ diff --git a/chromium/third_party/blink/renderer/modules/DEPS b/chromium/third_party/blink/renderer/modules/DEPS index 01c7bc15c08..04ac79802bf 100644 --- a/chromium/third_party/blink/renderer/modules/DEPS +++ b/chromium/third_party/blink/renderer/modules/DEPS @@ -5,6 +5,7 @@ include_rules = [ "+mojo/public/cpp/bindings", "+services/network/public/cpp/shared_url_loader_factory.h", "+services/service_manager/public/mojom/interface_provider.mojom-blink.h", + "+services/service_manager/public/mojom/interface_provider.mojom-blink-forward.h", "+services/viz/public/mojom/hit_test/hit_test_region_list.mojom-blink.h", "+third_party/blink/public/common", "+third_party/blink/public/web", diff --git a/chromium/third_party/blink/renderer/modules/accessibility/DEPS b/chromium/third_party/blink/renderer/modules/accessibility/DEPS index 44011c4a0c6..7f78b77b1af 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/DEPS +++ b/chromium/third_party/blink/renderer/modules/accessibility/DEPS @@ -1,6 +1,7 @@ include_rules = [ "+mojo/public/cpp/bindings/binding.h", "+ui/accessibility/ax_enums.mojom-blink.h", + "+ui/accessibility/ax_enums.mojom-blink-forward.h", "-third_party/blink/renderer/modules", "+third_party/blink/renderer/modules/accessibility", "+third_party/blink/renderer/modules/media_controls", diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc index a562d988634..dd4f45e43d0 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.cc @@ -100,8 +100,6 @@ #include "third_party/blink/renderer/platform/text/text_direction.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" -using blink::WebLocalizedString; - namespace { bool IsNeutralWithinTable(blink::AXObject* obj) { if (!obj) @@ -115,13 +113,10 @@ bool IsNeutralWithinTable(blink::AXObject* obj) { namespace blink { -using namespace html_names; - AXLayoutObject::AXLayoutObject(LayoutObject* layout_object, AXObjectCacheImpl& ax_object_cache) : AXNodeObject(layout_object->GetNode(), ax_object_cache), - layout_object_(layout_object), - is_autofill_available_(false) { + layout_object_(layout_object) { // TODO(aleventhal) Get correct current state of autofill. #if DCHECK_IS_ON() layout_object_->SetHasAXObject(true); @@ -517,7 +512,7 @@ AccessibilityGrabbedState AXLayoutObject::IsGrabbed() const { if (!SupportsARIADragging()) return kGrabbedStateUndefined; - const AtomicString& grabbed = GetAttribute(kAriaGrabbedAttr); + const AtomicString& grabbed = GetAttribute(html_names::kAriaGrabbedAttr); return EqualIgnoringASCIICase(grabbed, "true") ? kGrabbedStateTrue : kGrabbedStateFalse; } @@ -763,7 +758,8 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored( bool AXLayoutObject::HasAriaCellRole(Element* elem) const { DCHECK(elem); - const AtomicString& aria_role_str = elem->FastGetAttribute(kRoleAttr); + const AtomicString& aria_role_str = + elem->FastGetAttribute(html_names::kRoleAttr); if (aria_role_str.IsEmpty()) return false; @@ -877,7 +873,7 @@ const AtomicString& AXLayoutObject::AccessKey() const { auto* element = DynamicTo<Element>(layout_object_->GetNode()); if (!element) return g_null_atom; - return element->getAttribute(kAccesskeyAttr); + return element->getAttribute(html_names::kAccesskeyAttr); } RGBA32 AXLayoutObject::ComputeBackgroundColor() const { @@ -934,7 +930,7 @@ RGBA32 AXLayoutObject::GetColor() const { return color.Rgb(); } -AtomicString AXLayoutObject::FontFamily() const { +String AXLayoutObject::FontFamily() const { if (!GetLayoutObject()) return AXNodeObject::FontFamily(); @@ -942,9 +938,11 @@ AtomicString AXLayoutObject::FontFamily() const { if (!style) return AXNodeObject::FontFamily(); - FontDescription& font_description = - const_cast<FontDescription&>(style->GetFontDescription()); - return font_description.FirstFamily().Family(); + const SimpleFontData* primary_font = style->GetFont().PrimaryFont(); + if (!primary_font) + return AXNodeObject::FontFamily(); + + return primary_font->PlatformData().FontFamilyName(); } // Font size is in pixels. @@ -1429,15 +1427,15 @@ String AXLayoutObject::StringValue() const { // LayoutMenuList will go straight to the text() of its selected item. // This has to be overridden in the case where the selected item has an ARIA // label. - HTMLSelectElement* select_element = - ToHTMLSelectElement(layout_object_->GetNode()); + auto* select_element = To<HTMLSelectElement>(layout_object_->GetNode()); int selected_index = select_element->selectedIndex(); const HeapVector<Member<HTMLElement>>& list_items = select_element->GetListItems(); if (selected_index >= 0 && static_cast<size_t>(selected_index) < list_items.size()) { const AtomicString& overridden_description = - list_items[selected_index]->FastGetAttribute(kAriaLabelAttr); + list_items[selected_index]->FastGetAttribute( + html_names::kAriaLabelAttr); if (!overridden_description.IsNull()) return overridden_description; } @@ -1604,18 +1602,18 @@ ax::mojom::HasPopup AXLayoutObject::HasPopup() const { // a future version of WAI-ARIA. After that we will re-implement them // following new spec. bool AXLayoutObject::SupportsARIADragging() const { - const AtomicString& grabbed = GetAttribute(kAriaGrabbedAttr); + const AtomicString& grabbed = GetAttribute(html_names::kAriaGrabbedAttr); return EqualIgnoringASCIICase(grabbed, "true") || EqualIgnoringASCIICase(grabbed, "false"); } void AXLayoutObject::Dropeffects( Vector<ax::mojom::Dropeffect>& dropeffects) const { - if (!HasAttribute(kAriaDropeffectAttr)) + if (!HasAttribute(html_names::kAriaDropeffectAttr)) return; Vector<String> str_dropeffects; - TokenVectorFromAttribute(str_dropeffects, kAriaDropeffectAttr); + TokenVectorFromAttribute(str_dropeffects, html_names::kAriaDropeffectAttr); if (str_dropeffects.IsEmpty()) { dropeffects.push_back(ax::mojom::Dropeffect::kNone); @@ -1643,13 +1641,13 @@ ax::mojom::Dropeffect AXLayoutObject::ParseDropeffect( } bool AXLayoutObject::SupportsARIAFlowTo() const { - return !GetAttribute(kAriaFlowtoAttr).IsEmpty(); + return !GetAttribute(html_names::kAriaFlowtoAttr).IsEmpty(); } bool AXLayoutObject::SupportsARIAOwns() const { if (!layout_object_) return false; - const AtomicString& aria_owns = GetAttribute(kAriaOwnsAttr); + const AtomicString& aria_owns = GetAttribute(html_names::kAriaOwnsAttr); return !aria_owns.IsEmpty(); } @@ -1728,7 +1726,7 @@ AXObject* AXLayoutObject::AccessibilityHitTest(const IntPoint& point) const { if (auto* area = DynamicTo<HTMLAreaElement>(node)) return AccessibilityImageMapHitTest(area, point); - if (auto* option = ToHTMLOptionElementOrNull(node)) { + if (auto* option = DynamicTo<HTMLOptionElement>(node)) { node = option->OwnerSelectElement(); if (!node) return nullptr; @@ -2348,11 +2346,15 @@ void AXLayoutObject::HandleAriaExpandedChanged() { } } -void AXLayoutObject::HandleAutofillStateChanged(bool available) { - if (is_autofill_available_ != available) { - is_autofill_available_ = available; - AXObjectCache().MarkAXObjectDirty(this, false); - } +bool AXLayoutObject::IsAutofillAvailable() const { + // Autofill state is stored in AXObjectCache. + WebAXAutofillState state = AXObjectCache().GetAutofillState(AXObjectID()); + return state == WebAXAutofillState::kAutofillAvailable; +} + +void AXLayoutObject::HandleAutofillStateChanged(WebAXAutofillState state) { + // Autofill state is stored in AXObjectCache. + AXObjectCache().SetAutofillState(AXObjectID(), state); } void AXLayoutObject::TextChanged() { @@ -2534,7 +2536,7 @@ bool AXLayoutObject::IsDataTable() const { valid_cell_count++; // Any <th> tag -> treat as data table. - if (cell_node->HasTagName(kThTag)) + if (cell_node->HasTagName(html_names::kThTag)) return true; // In this case, the developer explicitly assigned a "data" table @@ -2543,7 +2545,7 @@ bool AXLayoutObject::IsDataTable() const { HTMLTableCellElement& cell_element = ToHTMLTableCellElement(*cell_node); if (!cell_element.Headers().IsEmpty() || !cell_element.Abbr().IsEmpty() || !cell_element.Axis().IsEmpty() || - !cell_element.FastGetAttribute(kScopeAttr).IsEmpty()) + !cell_element.FastGetAttribute(html_names::kScopeAttr).IsEmpty()) return true; } @@ -2791,7 +2793,7 @@ static bool IsNonEmptyNonHeaderCell(const LayoutNGTableCellInterface* cell) { return false; if (Node* node = cell->ToLayoutObject()->GetNode()) - return node->hasChildren() && node->HasTagName(kTdTag); + return node->hasChildren() && node->HasTagName(html_names::kTdTag); return false; } @@ -2801,7 +2803,7 @@ static bool IsHeaderCell(const LayoutNGTableCellInterface* cell) { return false; if (Node* node = cell->ToLayoutObject()->GetNode()) - return node->HasTagName(kThTag); + return node->HasTagName(html_names::kThTag); return false; } @@ -2884,10 +2886,10 @@ ax::mojom::Role AXLayoutObject::DetermineTableCellRole() const { if (parent->RoleValue() == ax::mojom::Role::kLayoutTableRow) return ax::mojom::Role::kLayoutTableCell; - if (!GetNode() || !GetNode()->HasTagName(kThTag)) + if (!GetNode() || !GetNode()->HasTagName(html_names::kThTag)) return ax::mojom::Role::kCell; - const AtomicString& scope = GetAttribute(kScopeAttr); + const AtomicString& scope = GetAttribute(html_names::kScopeAttr); if (EqualIgnoringASCIICase(scope, "row") || EqualIgnoringASCIICase(scope, "rowgroup")) return ax::mojom::Role::kRowHeader; diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h index 8c5c0a99f3f..fef4861c90c 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object.h @@ -77,7 +77,7 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { bool IsAXLayoutObject() const override { return true; } // Check object role or purpose. - bool IsAutofillAvailable() override { return is_autofill_available_; } + bool IsAutofillAvailable() const override; bool IsDefault() const override; bool IsEditable() const override; bool IsRichlyEditable() const override; @@ -103,7 +103,7 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { const AtomicString& AccessKey() const override; RGBA32 ComputeBackgroundColor() const final; RGBA32 GetColor() const final; - AtomicString FontFamily() const final; + String FontFamily() const final; // Font size is in pixels. float FontSize() const final; float FontWeight() const final; @@ -186,8 +186,8 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { // Notifications that this object may have changed. void HandleActiveDescendantChanged() override; void HandleAriaExpandedChanged() override; - // Called when autofill becomes available/unavailable on a form control. - void HandleAutofillStateChanged(bool) override; + // Called when autofill/autocomplete state changes on a form control. + void HandleAutofillStateChanged(WebAXAutofillState state) override; void TextChanged() override; // For a table. @@ -239,8 +239,6 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { TextDecorationStyleToAXTextDecorationStyle( const ETextDecorationStyle text_decoration_style); - bool is_autofill_available_; - DISALLOW_COPY_AND_ASSIGN(AXLayoutObject); }; diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_list.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_list.cc index 5ef457e2da1..576bea195ca 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_list.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_list.cc @@ -34,8 +34,6 @@ namespace blink { -using namespace html_names; - AXList::AXList(LayoutObject* layout_object, AXObjectCacheImpl& ax_object_cache) : AXLayoutObject(layout_object, ax_object_cache) {} @@ -51,7 +49,7 @@ bool AXList::IsDescriptionList() const { return false; Node* node = layout_object_->GetNode(); - return node && node->HasTagName(kDlTag); + return node && node->HasTagName(html_names::kDlTag); } ax::mojom::Role AXList::RoleValue() const { diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.cc index fc601746aac..3f9c26a9deb 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box.cc @@ -51,10 +51,10 @@ ax::mojom::Role AXListBox::DetermineAccessibilityRole() { } AXObject* AXListBox::ActiveDescendant() { - if (!IsHTMLSelectElement(GetNode())) + auto* select = DynamicTo<HTMLSelectElement>(GetNode()); + if (!select) return nullptr; - HTMLSelectElement* select = ToHTMLSelectElement(GetNode()); int active_index = select->ActiveSelectionEndListIndex(); if (active_index >= 0 && active_index < static_cast<int>(select->length())) { HTMLOptionElement* option = select->item(active_index_); @@ -65,10 +65,10 @@ AXObject* AXListBox::ActiveDescendant() { } void AXListBox::ActiveIndexChanged() { - if (!IsHTMLSelectElement(GetNode())) + auto* select = DynamicTo<HTMLSelectElement>(GetNode()); + if (!select) return; - HTMLSelectElement* select = ToHTMLSelectElement(GetNode()); int active_index = select->ActiveSelectionEndListIndex(); if (active_index == active_index_) return; diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc index d9330ea3e5d..7161e3ab512 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_list_box_option.cc @@ -77,10 +77,9 @@ AccessibilitySelectedState AXListBoxOption::IsSelected() const { if (!GetNode() || !CanSetSelectedAttribute()) return kSelectedStateUndefined; - return (IsHTMLOptionElement(GetNode()) && - ToHTMLOptionElement(GetNode())->Selected()) - ? kSelectedStateTrue - : kSelectedStateFalse; + auto* option_element = DynamicTo<HTMLOptionElement>(GetNode()); + return (option_element && option_element->Selected()) ? kSelectedStateTrue + : kSelectedStateFalse; } bool AXListBoxOption::IsSelectedOptionActive() const { @@ -124,7 +123,7 @@ String AXListBoxOption::TextAlternative(bool recursive, return text_alternative; name_from = ax::mojom::NameFrom::kContents; - text_alternative = ToHTMLOptionElement(GetNode())->DisplayLabel(); + text_alternative = To<HTMLOptionElement>(GetNode())->DisplayLabel(); if (name_sources) { name_sources->push_back(NameSource(found_text_alternative)); name_sources->back().type = name_from; @@ -151,7 +150,7 @@ bool AXListBoxOption::OnNativeSetSelectedAction(bool selected) { if ((is_selected && selected) || (!is_selected && !selected)) return false; - select_element->SelectOptionByAccessKey(ToHTMLOptionElement(GetNode())); + select_element->SelectOptionByAccessKey(To<HTMLOptionElement>(GetNode())); return true; } @@ -159,7 +158,7 @@ HTMLSelectElement* AXListBoxOption::ListBoxOptionParentNode() const { if (!GetNode()) return nullptr; - if (auto* option = ToHTMLOptionElementOrNull(GetNode())) + if (auto* option = DynamicTo<HTMLOptionElement>(GetNode())) return option->OwnerSelectElement(); return nullptr; diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_media_element.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_media_element.cc index 93b3356564b..9ce8949afa4 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_media_element.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_media_element.cc @@ -4,14 +4,13 @@ #include "third_party/blink/renderer/modules/accessibility/ax_media_element.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/platform/text/platform_locale.h" namespace blink { -using blink::WebLocalizedString; - AXObject* AccessibilityMediaElement::Create( LayoutObject* layout_object, AXObjectCacheImpl& ax_object_cache) { @@ -35,8 +34,7 @@ String AccessibilityMediaElement::TextAlternative( if (IsUnplayable()) { HTMLMediaElement* element = static_cast<HTMLMediaElement*>(layout_object_->GetNode()); - return element->GetLocale().QueryString( - WebLocalizedString::kAXMediaPlaybackError); + return element->GetLocale().QueryString(IDS_MEDIA_PLAYBACK_ERROR); } return AXLayoutObject::TextAlternative( recursive, in_aria_labelled_by_traversal, visited, name_from, diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc index 3113e675cb3..47d04bfc266 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.cc @@ -73,7 +73,7 @@ AXObject* AXMenuListOption::ComputeParent() const { Node* node = GetNode(); if (!node) return nullptr; - HTMLSelectElement* select = ToHTMLOptionElement(node)->OwnerSelectElement(); + auto* select = To<HTMLOptionElement>(node)->OwnerSelectElement(); if (!select) return nullptr; AXObject* select_ax_object = AXObjectCache().GetOrCreate(select); @@ -212,7 +212,7 @@ HTMLSelectElement* AXMenuListOption::ParentSelectNode() const { if (!GetNode()) return nullptr; - if (auto* option = ToHTMLOptionElementOrNull(GetNode())) + if (auto* option = DynamicTo<HTMLOptionElement>(GetNode())) return option->OwnerSelectElement(); return nullptr; diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc index ce724fe7051..47a28a72ca4 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_popup.cc @@ -59,7 +59,7 @@ bool AXMenuListPopup::ComputeAccessibilityIsIgnored( AXMenuListOption* AXMenuListPopup::MenuListOptionAXObject( HTMLElement* element) const { DCHECK(element); - if (!IsHTMLOptionElement(*element)) + if (!IsA<HTMLOptionElement>(*element)) return nullptr; AXObject* object = AXObjectCache().GetOrCreate(element); @@ -73,11 +73,10 @@ int AXMenuListPopup::GetSelectedIndex() const { if (!parent_) return -1; - Node* parent_node = parent_->GetNode(); - if (!IsHTMLSelectElement(parent_node)) + auto* html_select_element = DynamicTo<HTMLSelectElement>(parent_->GetNode()); + if (!html_select_element) return -1; - HTMLSelectElement* html_select_element = ToHTMLSelectElement(parent_node); return html_select_element->selectedIndex(); } @@ -93,11 +92,10 @@ void AXMenuListPopup::AddChildren() { if (!parent_) return; - Node* parent_node = parent_->GetNode(); - if (!IsHTMLSelectElement(parent_node)) + auto* html_select_element = DynamicTo<HTMLSelectElement>(parent_->GetNode()); + if (!html_select_element) return; - HTMLSelectElement* html_select_element = ToHTMLSelectElement(parent_node); have_children_ = true; if (active_index_ == -1) diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index 9e3755dcc67..5b2ea42c4c4 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.cc @@ -30,6 +30,7 @@ #include <math.h> +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/aom/accessible_node.h" #include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h" #include "third_party/blink/renderer/core/dom/element.h" @@ -84,7 +85,10 @@ namespace blink { -using namespace html_names; +using html_names::kAltAttr; +using html_names::kTitleAttr; +using html_names::kTypeAttr; +using html_names::kValueAttr; // In ARIA 1.1, default value of aria-level was changed to 2. const int kDefaultHeadingLevel = 2; @@ -214,8 +218,8 @@ AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics( // Header and footer tags may also be exposed as landmark roles but not // always. - if (GetNode() && - (GetNode()->HasTagName(kHeaderTag) || GetNode()->HasTagName(kFooterTag))) + if (GetNode() && (GetNode()->HasTagName(html_names::kHeaderTag) || + GetNode()->HasTagName(html_names::kFooterTag))) return kIncludeObject; // All controls are accessible. @@ -382,7 +386,7 @@ bool AXNodeObject::ComputeAccessibilityIsIgnored( } static bool IsListElement(Node* node) { - return IsHTMLUListElement(*node) || IsHTMLOListElement(*node) || + return IsHTMLUListElement(*node) || IsA<HTMLOListElement>(*node) || IsA<HTMLDListElement>(*node); } @@ -456,16 +460,16 @@ const AXObject* AXNodeObject::InheritsPresentationalRoleFrom() const { static HashSet<QualifiedName>& GetLandmarkRolesNotAllowed() { DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, landmark_roles_not_allowed, ()); if (landmark_roles_not_allowed.IsEmpty()) { - landmark_roles_not_allowed.insert(kArticleTag); - landmark_roles_not_allowed.insert(kAsideTag); - landmark_roles_not_allowed.insert(kNavTag); - landmark_roles_not_allowed.insert(kSectionTag); - landmark_roles_not_allowed.insert(kBlockquoteTag); - landmark_roles_not_allowed.insert(kDetailsTag); - landmark_roles_not_allowed.insert(kFieldsetTag); - landmark_roles_not_allowed.insert(kFigureTag); - landmark_roles_not_allowed.insert(kTdTag); - landmark_roles_not_allowed.insert(kMainTag); + landmark_roles_not_allowed.insert(html_names::kArticleTag); + landmark_roles_not_allowed.insert(html_names::kAsideTag); + landmark_roles_not_allowed.insert(html_names::kNavTag); + landmark_roles_not_allowed.insert(html_names::kSectionTag); + landmark_roles_not_allowed.insert(html_names::kBlockquoteTag); + landmark_roles_not_allowed.insert(html_names::kDetailsTag); + landmark_roles_not_allowed.insert(html_names::kFieldsetTag); + landmark_roles_not_allowed.insert(html_names::kFigureTag); + landmark_roles_not_allowed.insert(html_names::kTdTag); + landmark_roles_not_allowed.insert(html_names::kMainTag); } return landmark_roles_not_allowed; } @@ -515,7 +519,7 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const { if (IsHTMLSummaryElement(*GetNode())) { ContainerNode* parent = LayoutTreeBuilderTraversal::Parent(*GetNode()); - if (parent && IsHTMLSlotElement(parent)) + if (IsA<HTMLSlotElement>(parent)) parent = LayoutTreeBuilderTraversal::Parent(*parent); if (parent && IsA<HTMLDetailsElement>(parent)) return ax::mojom::Role::kDisclosureTriangle; @@ -577,12 +581,12 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const { return ax::mojom::Role::kTextField; } - if (auto* select_element = ToHTMLSelectElementOrNull(*GetNode())) { + if (auto* select_element = DynamicTo<HTMLSelectElement>(*GetNode())) { return select_element->IsMultiple() ? ax::mojom::Role::kListBox : ax::mojom::Role::kPopUpButton; } - if (auto* option = ToHTMLOptionElementOrNull(*GetNode())) { + if (auto* option = DynamicTo<HTMLOptionElement>(*GetNode())) { HTMLSelectElement* select_element = option->OwnerSelectElement(); return !select_element || select_element->IsMultiple() ? ax::mojom::Role::kListBoxOption @@ -598,16 +602,16 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const { if (IsHTMLDivElement(*GetNode())) return ax::mojom::Role::kGenericContainer; - if (IsHTMLMeterElement(*GetNode())) + if (IsA<HTMLMeterElement>(*GetNode())) return ax::mojom::Role::kMeter; - if (IsHTMLProgressElement(*GetNode())) + if (IsA<HTMLProgressElement>(*GetNode())) return ax::mojom::Role::kProgressIndicator; - if (IsHTMLOutputElement(*GetNode())) + if (IsA<HTMLOutputElement>(*GetNode())) return ax::mojom::Role::kStatus; - if (IsHTMLParagraphElement(*GetNode())) + if (IsA<HTMLParagraphElement>(*GetNode())) return ax::mojom::Role::kParagraph; if (IsA<HTMLLabelElement>(*GetNode())) @@ -627,52 +631,53 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const { if (IsHTMLVideoElement(*GetNode())) return ax::mojom::Role::kVideo; - if (GetNode()->HasTagName(kDdTag)) + if (GetNode()->HasTagName(html_names::kDdTag)) return ax::mojom::Role::kDescriptionListDetail; - if (GetNode()->HasTagName(kDtTag)) + if (GetNode()->HasTagName(html_names::kDtTag)) return ax::mojom::Role::kDescriptionListTerm; if (GetNode()->nodeName() == "math") return ax::mojom::Role::kMath; - if (GetNode()->HasTagName(kRpTag) || GetNode()->HasTagName(kRtTag)) - return ax::mojom::Role::kAnnotation; + if (GetNode()->HasTagName(html_names::kRpTag) || + GetNode()->HasTagName(html_names::kRtTag)) + return ax::mojom::Role::kRubyAnnotation; if (IsHTMLFormElement(*GetNode())) return ax::mojom::Role::kForm; - if (GetNode()->HasTagName(kAbbrTag)) + if (GetNode()->HasTagName(html_names::kAbbrTag)) return ax::mojom::Role::kAbbr; - if (GetNode()->HasTagName(kArticleTag)) + if (GetNode()->HasTagName(html_names::kArticleTag)) return ax::mojom::Role::kArticle; - if (GetNode()->HasTagName(kDelTag)) + if (GetNode()->HasTagName(html_names::kDelTag)) return ax::mojom::Role::kContentDeletion; - if (GetNode()->HasTagName(kInsTag)) + if (GetNode()->HasTagName(html_names::kInsTag)) return ax::mojom::Role::kContentInsertion; - if (GetNode()->HasTagName(kMainTag)) + if (GetNode()->HasTagName(html_names::kMainTag)) return ax::mojom::Role::kMain; - if (GetNode()->HasTagName(kMarkTag)) + if (GetNode()->HasTagName(html_names::kMarkTag)) return ax::mojom::Role::kMark; - if (GetNode()->HasTagName(kNavTag)) + if (GetNode()->HasTagName(html_names::kNavTag)) return ax::mojom::Role::kNavigation; - if (GetNode()->HasTagName(kAsideTag)) + if (GetNode()->HasTagName(html_names::kAsideTag)) return ax::mojom::Role::kComplementary; - if (GetNode()->HasTagName(kPreTag)) + if (GetNode()->HasTagName(html_names::kPreTag)) return ax::mojom::Role::kPre; - if (GetNode()->HasTagName(kSectionTag)) - return ax::mojom::Role::kRegion; + if (GetNode()->HasTagName(html_names::kSectionTag)) + return ax::mojom::Role::kSection; - if (GetNode()->HasTagName(kAddressTag)) + if (GetNode()->HasTagName(html_names::kAddressTag)) return ax::mojom::Role::kGenericContainer; if (IsA<HTMLDialogElement>(*GetNode())) @@ -695,28 +700,28 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const { // There should only be one banner/contentInfo per page. If header/footer are // being used within an article or section then it should not be exposed as // whole page's banner/contentInfo but as a generic container role. - if (GetNode()->HasTagName(kHeaderTag)) { + if (GetNode()->HasTagName(html_names::kHeaderTag)) { if (IsDescendantOfElementType(GetLandmarkRolesNotAllowed())) - return ax::mojom::Role::kGenericContainer; - return ax::mojom::Role::kBanner; + return ax::mojom::Role::kHeaderAsNonLandmark; + return ax::mojom::Role::kHeader; } - if (GetNode()->HasTagName(kFooterTag)) { + if (GetNode()->HasTagName(html_names::kFooterTag)) { if (IsDescendantOfElementType(GetLandmarkRolesNotAllowed())) - return ax::mojom::Role::kGenericContainer; + return ax::mojom::Role::kFooterAsNonLandmark; return ax::mojom::Role::kFooter; } - if (GetNode()->HasTagName(kBlockquoteTag)) + if (GetNode()->HasTagName(html_names::kBlockquoteTag)) return ax::mojom::Role::kBlockquote; - if (GetNode()->HasTagName(kCaptionTag)) + if (GetNode()->HasTagName(html_names::kCaptionTag)) return ax::mojom::Role::kCaption; - if (GetNode()->HasTagName(kFigcaptionTag)) + if (GetNode()->HasTagName(html_names::kFigcaptionTag)) return ax::mojom::Role::kFigcaption; - if (GetNode()->HasTagName(kFigureTag)) + if (GetNode()->HasTagName(html_names::kFigureTag)) return ax::mojom::Role::kFigure; if (GetNode()->nodeName() == "TIME") @@ -806,7 +811,7 @@ bool AXNodeObject::IsMultiline() const { // also return true if an ancestor is editable. bool AXNodeObject::HasContentEditableAttributeSet() const { const AtomicString& content_editable_value = - GetAttribute(kContenteditableAttr); + GetAttribute(html_names::kContenteditableAttr); if (content_editable_value.IsNull()) return false; // Both "true" (case-insensitive) and the empty string count as true. @@ -1057,8 +1062,8 @@ bool AXNodeObject::IsMultiSelectable() const { break; } - return IsHTMLSelectElement(GetNode()) && - ToHTMLSelectElement(*GetNode()).IsMultiple(); + auto* html_select_element = DynamicTo<HTMLSelectElement>(GetNode()); + return html_select_element && html_select_element->IsMultiple(); } bool AXNodeObject::IsNativeCheckboxOrRadio() const { @@ -1189,7 +1194,7 @@ AXRestriction AXNodeObject::Restriction() const { return kRestrictionNone; // An <optgroup> is not exposed directly in the AX tree. - if (IsHTMLOptGroupElement(elem)) + if (IsA<HTMLOptGroupElement>(elem)) return kRestrictionNone; // According to ARIA, all elements of the base markup can be disabled. @@ -1251,7 +1256,8 @@ AccessibilityExpanded AXNodeObject::IsExpanded() const { if (GetNode() && IsHTMLSummaryElement(*GetNode())) { if (GetNode()->parentNode() && IsA<HTMLDetailsElement>(GetNode()->parentNode())) - return To<Element>(GetNode()->parentNode())->hasAttribute(kOpenAttr) + return To<Element>(GetNode()->parentNode()) + ->hasAttribute(html_names::kOpenAttr) ? kExpandedExpanded : kExpandedCollapsed; } @@ -1315,22 +1321,22 @@ int AXNodeObject::HeadingLevel() const { if (!element) return 0; - if (element->HasTagName(kH1Tag)) + if (element->HasTagName(html_names::kH1Tag)) return 1; - if (element->HasTagName(kH2Tag)) + if (element->HasTagName(html_names::kH2Tag)) return 2; - if (element->HasTagName(kH3Tag)) + if (element->HasTagName(html_names::kH3Tag)) return 3; - if (element->HasTagName(kH4Tag)) + if (element->HasTagName(html_names::kH4Tag)) return 4; - if (element->HasTagName(kH5Tag)) + if (element->HasTagName(html_names::kH5Tag)) return 5; - if (element->HasTagName(kH6Tag)) + if (element->HasTagName(html_names::kH6Tag)) return 6; if (RoleValue() == ax::mojom::Role::kHeading) @@ -1369,8 +1375,12 @@ unsigned AXNodeObject::HierarchicalLevel() const { return level; } -// TODO: rename this just AutoComplete, it's not only ARIA. -String AXNodeObject::AriaAutoComplete() const { +String AXNodeObject::AutoComplete() const { + // Check cache for auto complete state. + if (AXObjectCache().GetAutofillState(AXObjectID()) == + WebAXAutofillState::kAutocompleteAvailable) + return "list"; + if (IsNativeTextControl() || IsARIATextControl()) { const AtomicString& aria_auto_complete = GetAOMPropertyOrARIAAttribute(AOMStringProperty::kAutocomplete) @@ -1395,7 +1405,7 @@ bool MarkerTypeIsUsedForAccessibility(DocumentMarker::MarkerType type) { return DocumentMarker::MarkerTypes( DocumentMarker::kSpelling | DocumentMarker::kGrammar | DocumentMarker::kTextMatch | DocumentMarker::kActiveSuggestion | - DocumentMarker::kSuggestion) + DocumentMarker::kSuggestion | DocumentMarker::kTextFragment) .Contains(type); } @@ -1727,7 +1737,7 @@ bool AXNodeObject::ValueForRange(float* out_value) const { return std::isfinite(*out_value); } - if (auto* meter = ToHTMLMeterElementOrNull(GetNode())) { + if (auto* meter = DynamicTo<HTMLMeterElement>(GetNode())) { *out_value = meter->value(); return true; } @@ -1773,7 +1783,7 @@ bool AXNodeObject::MaxValueForRange(float* out_value) const { return std::isfinite(*out_value); } - if (auto* meter = ToHTMLMeterElementOrNull(GetNode())) { + if (auto* meter = DynamicTo<HTMLMeterElement>(GetNode())) { *out_value = meter->max(); return true; } @@ -1806,7 +1816,7 @@ bool AXNodeObject::MinValueForRange(float* out_value) const { return std::isfinite(*out_value); } - if (auto* meter = ToHTMLMeterElementOrNull(GetNode())) { + if (auto* meter = DynamicTo<HTMLMeterElement>(GetNode())) { *out_value = meter->min(); return true; } @@ -1904,14 +1914,15 @@ String AXNodeObject::StringValue() const { if (!node) return String(); - if (auto* select_element = ToHTMLSelectElementOrNull(*node)) { + if (auto* select_element = DynamicTo<HTMLSelectElement>(*node)) { int selected_index = select_element->selectedIndex(); const HeapVector<Member<HTMLElement>>& list_items = select_element->GetListItems(); if (selected_index >= 0 && static_cast<wtf_size_t>(selected_index) < list_items.size()) { const AtomicString& overridden_description = - list_items[selected_index]->FastGetAttribute(kAriaLabelAttr); + list_items[selected_index]->FastGetAttribute( + html_names::kAriaLabelAttr); if (!overridden_description.IsNull()) return overridden_description; } @@ -2060,7 +2071,7 @@ String AXNodeObject::TextAlternative(bool recursive, // Step 2F / 2G from: http://www.w3.org/TR/accname-aam-1.1 if (in_aria_labelled_by_traversal || NameFromContents(recursive)) { Node* node = GetNode(); - if (!IsHTMLSelectElement(node)) { // Avoid option descendant text + if (!IsA<HTMLSelectElement>(node)) { // Avoid option descendant text name_from = ax::mojom::NameFrom::kContents; if (name_sources) { name_sources->push_back(NameSource(found_text_alternative)); @@ -2673,7 +2684,7 @@ bool AXNodeObject::OnNativeFocusAction() { // using AOM. To be extra safe, exclude objects that are clickable themselves. // This won't prevent anyone from having a click handler on the object's // container. - if (!IsClickable() && element->FastHasAttribute(kIdAttr) && + if (!IsClickable() && element->FastHasAttribute(html_names::kIdAttr) && CanBeActiveDescendant()) { return OnNativeClickAction(); } @@ -2784,8 +2795,7 @@ void AXNodeObject::UpdateChildrenIfNecessary() { } void AXNodeObject::SelectedOptions(AXObjectVector& options) const { - if (IsHTMLSelectElement(GetNode())) { - HTMLSelectElement* select = ToHTMLSelectElement(GetNode()); + if (auto* select = DynamicTo<HTMLSelectElement>(GetNode())) { for (auto* const option : *select->selectedOptions()) { AXObject* ax_option = AXObjectCache().GetOrCreate(option); if (ax_option) @@ -2877,11 +2887,11 @@ void AXNodeObject::ComputeAriaOwnsChildren( return; } - if (!HasAttribute(kAriaOwnsAttr)) + if (!HasAttribute(html_names::kAriaOwnsAttr)) return; // Case 2: aria-owns attribute - TokenVectorFromAttribute(id_vector, kAriaOwnsAttr); + TokenVectorFromAttribute(id_vector, html_names::kAriaOwnsAttr); AXObjectCache().UpdateAriaOwns(this, id_vector, owned_children); } @@ -2926,8 +2936,9 @@ String AXNodeObject::NativeTextAlternative( ++label_index) { Element* label = labels->item(label_index); if (name_sources) { - if (!label->getAttribute(kForAttr).IsEmpty() && - label->getAttribute(kForAttr) == html_element->GetIdAttribute()) { + if (!label->getAttribute(html_names::kForAttr).IsEmpty() && + label->getAttribute(html_names::kForAttr) == + html_element->GetIdAttribute()) { name_sources->back().native_source = kAXTextFromNativeHTMLLabelFor; } else { name_sources->back().native_source = @@ -3061,8 +3072,8 @@ String AXNodeObject::NativeTextAlternative( // localised default value ("Submit") name_from = ax::mojom::NameFrom::kValue; - text_alternative = input_element->GetLocale().QueryString( - WebLocalizedString::kSubmitButtonDefaultLabel); + text_alternative = + input_element->GetLocale().QueryString(IDS_FORM_SUBMIT_LABEL); if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative, kTypeAttr)); NameSource& source = name_sources->back(); @@ -3081,7 +3092,7 @@ String AXNodeObject::NativeTextAlternative( name_from = ax::mojom::NameFrom::kPlaceholder; if (name_sources) { name_sources->push_back( - NameSource(*found_text_alternative, kPlaceholderAttr)); + NameSource(*found_text_alternative, html_names::kPlaceholderAttr)); NameSource& source = name_sources->back(); source.type = name_from; } @@ -3092,7 +3103,7 @@ String AXNodeObject::NativeTextAlternative( NameSource& source = name_sources->back(); source.text = text_alternative; source.attribute_value = - html_element->FastGetAttribute(kPlaceholderAttr); + html_element->FastGetAttribute(html_names::kPlaceholderAttr); *found_text_alternative = true; } else { return text_alternative; @@ -3104,8 +3115,8 @@ String AXNodeObject::NativeTextAlternative( if (IsTextControl()) { name_from = ax::mojom::NameFrom::kPlaceholder; if (name_sources) { - name_sources->push_back( - NameSource(*found_text_alternative, kAriaPlaceholderAttr)); + name_sources->push_back(NameSource(*found_text_alternative, + html_names::kAriaPlaceholderAttr)); NameSource& source = name_sources->back(); source.type = name_from; } @@ -3127,7 +3138,7 @@ String AXNodeObject::NativeTextAlternative( } // 5.7 figure and figcaption Elements - if (GetNode()->HasTagName(kFigureTag)) { + if (GetNode()->HasTagName(html_names::kFigureTag)) { // figcaption name_from = ax::mojom::NameFrom::kRelatedElement; if (name_sources) { @@ -3137,7 +3148,7 @@ String AXNodeObject::NativeTextAlternative( } Element* figcaption = nullptr; for (Element& element : ElementTraversal::DescendantsOf(*(GetNode()))) { - if (element.HasTagName(kFigcaptionTag)) { + if (element.HasTagName(html_names::kFigcaptionTag)) { figcaption = &element; break; } @@ -3233,10 +3244,10 @@ String AXNodeObject::NativeTextAlternative( name_from = ax::mojom::NameFrom::kAttribute; if (name_sources) { name_sources->push_back( - NameSource(*found_text_alternative, kSummaryAttr)); + NameSource(*found_text_alternative, html_names::kSummaryAttr)); name_sources->back().type = name_from; } - const AtomicString& summary = GetAttribute(kSummaryAttr); + const AtomicString& summary = GetAttribute(html_names::kSummaryAttr); if (!summary.IsNull()) { text_alternative = summary; if (name_sources) { @@ -3332,7 +3343,7 @@ String AXNodeObject::NativeTextAlternative( name_from = ax::mojom::NameFrom::kAttribute; if (name_sources) { name_sources->push_back( - NameSource(found_text_alternative, kAriaLabelAttr)); + NameSource(found_text_alternative, html_names::kAriaLabelAttr)); name_sources->back().type = name_from; } if (Element* document_element = document->documentElement()) { @@ -3440,13 +3451,14 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from, description_from = ax::mojom::DescriptionFrom::kRelatedElement; if (description_sources) { description_sources->push_back( - DescriptionSource(found_description, kAriaDescribedbyAttr)); + DescriptionSource(found_description, html_names::kAriaDescribedbyAttr)); description_sources->back().type = description_from; } // aria-describedby overrides any other accessible description, from: // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html - const AtomicString& aria_describedby = GetAttribute(kAriaDescribedbyAttr); + const AtomicString& aria_describedby = + GetAttribute(html_names::kAriaDescribedbyAttr); if (!aria_describedby.IsNull()) { if (description_sources) description_sources->back().attribute_value = aria_describedby; @@ -3582,10 +3594,10 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from, description_from = ax::mojom::DescriptionFrom::kAttribute; if (description_sources) { description_sources->push_back( - DescriptionSource(found_description, kAriaHelpAttr)); + DescriptionSource(found_description, html_names::kAriaHelpAttr)); description_sources->back().type = description_from; } - const AtomicString& help = GetAttribute(kAriaHelpAttr); + const AtomicString& help = GetAttribute(html_names::kAriaHelpAttr); if (!help.IsEmpty()) { description = help; if (description_sources) { diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h index 814ede0ef39..2140d86db54 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_node_object.h @@ -64,7 +64,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject { void AlterSliderOrSpinButtonValue(bool increase); AXObject* ActiveDescendant() override; String AriaAccessibilityDescription() const; - String AriaAutoComplete() const override; + String AutoComplete() const override; void AccessibilityChildrenFromAOMProperty(AOMRelationListProperty, AXObject::AXObjectVector&) const; diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc index 1bc953837a6..6be853a7529 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc @@ -28,6 +28,7 @@ #include "third_party/blink/renderer/modules/accessibility/ax_object.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/platform/web_scroll_into_view_params.h" #include "third_party/blink/renderer/core/aom/accessible_node.h" #include "third_party/blink/renderer/core/aom/accessible_node_list.h" @@ -55,7 +56,9 @@ #include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h" #include "third_party/blink/renderer/modules/accessibility/ax_range.h" #include "third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/language.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/text/platform_locale.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" @@ -63,12 +66,8 @@ #include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" #include "third_party/skia/include/core/SkMatrix44.h" -using blink::WebLocalizedString; - namespace blink { -using namespace html_names; - namespace { struct RoleHashTraits : HashTraits<ax::mojom::Role> { @@ -91,6 +90,11 @@ struct RoleEntry { const RoleEntry kRoles[] = { {"alert", ax::mojom::Role::kAlert}, {"alertdialog", ax::mojom::Role::kAlertDialog}, + {"annotation-attribution", ax::mojom::Role::kAnnotationAttribution}, + {"annotation-commentary", ax::mojom::Role::kAnnotationCommentary}, + {"annotation-presence", ax::mojom::Role::kAnnotationPresence}, + {"annotation-revision", ax::mojom::Role::kAnnotationRevision}, + {"annotation-suggestion", ax::mojom::Role::kAnnotationSuggestion}, {"application", ax::mojom::Role::kApplication}, {"article", ax::mojom::Role::kArticle}, {"banner", ax::mojom::Role::kBanner}, @@ -230,7 +234,11 @@ const InternalRoleEntry kInternalRoles[] = { {ax::mojom::Role::kAlertDialog, "AlertDialog"}, {ax::mojom::Role::kAlert, "Alert"}, {ax::mojom::Role::kAnchor, "Anchor"}, - {ax::mojom::Role::kAnnotation, "Annotation"}, + {ax::mojom::Role::kAnnotationAttribution, "kAnnotationAttribution"}, + {ax::mojom::Role::kAnnotationCommentary, "AnnotationCommentary"}, + {ax::mojom::Role::kAnnotationPresence, "AnnotationPresence"}, + {ax::mojom::Role::kAnnotationRevision, "AnnotationRevision"}, + {ax::mojom::Role::kAnnotationSuggestion, "AnnotationSuggestion"}, {ax::mojom::Role::kApplication, "Application"}, {ax::mojom::Role::kArticle, "Article"}, {ax::mojom::Role::kAudio, "Audio"}, @@ -313,6 +321,7 @@ const InternalRoleEntry kInternalRoles[] = { {ax::mojom::Role::kFigcaption, "Figcaption"}, {ax::mojom::Role::kFigure, "Figure"}, {ax::mojom::Role::kFooter, "Footer"}, + {ax::mojom::Role::kFooterAsNonLandmark, "FooterAsNonLandmark"}, {ax::mojom::Role::kForm, "Form"}, {ax::mojom::Role::kGenericContainer, "GenericContainer"}, // -------------------------------------------------------------- @@ -325,6 +334,8 @@ const InternalRoleEntry kInternalRoles[] = { // -------------------------------------------------------------- {ax::mojom::Role::kGrid, "Grid"}, {ax::mojom::Role::kGroup, "Group"}, + {ax::mojom::Role::kHeader, "Header"}, + {ax::mojom::Role::kHeaderAsNonLandmark, "HeaderAsNonLandmark"}, {ax::mojom::Role::kHeading, "Heading"}, {ax::mojom::Role::kIframePresentational, "IframePresentational"}, {ax::mojom::Role::kIframe, "Iframe"}, @@ -377,6 +388,8 @@ const InternalRoleEntry kInternalRoles[] = { {ax::mojom::Role::kRowHeader, "RowHeader"}, {ax::mojom::Role::kRow, "Row"}, {ax::mojom::Role::kRuby, "Ruby"}, + {ax::mojom::Role::kRubyAnnotation, "RubyAnnotation"}, + {ax::mojom::Role::kSection, "Section"}, {ax::mojom::Role::kSvgRoot, "SVGRoot"}, {ax::mojom::Role::kScrollBar, "ScrollBar"}, {ax::mojom::Role::kScrollView, "ScrollView"}, @@ -418,12 +431,14 @@ static_assert(base::size(kInternalRoles) == // Roles which we need to map in the other direction const RoleEntry kReverseRoles[] = { + {"banner", ax::mojom::Role::kHeader}, {"button", ax::mojom::Role::kToggleButton}, {"combobox", ax::mojom::Role::kPopUpButton}, {"contentinfo", ax::mojom::Role::kFooter}, {"menuitem", ax::mojom::Role::kMenuButton}, {"menuitem", ax::mojom::Role::kMenuListOption}, {"progressbar", ax::mojom::Role::kMeter}, + {"region", ax::mojom::Role::kSection}, {"textbox", ax::mojom::Role::kTextField}, {"combobox", ax::mojom::Role::kComboBoxMenuButton}, {"combobox", ax::mojom::Role::kTextFieldWithComboBox}}; @@ -808,10 +823,12 @@ bool AXObject::IsLandmarkRelated() const { case ax::mojom::Role::kDocToc: case ax::mojom::Role::kFooter: case ax::mojom::Role::kForm: + case ax::mojom::Role::kHeader: case ax::mojom::Role::kMain: case ax::mojom::Role::kNavigation: case ax::mojom::Role::kRegion: case ax::mojom::Role::kSearch: + case ax::mojom::Role::kSection: return true; default: return false; @@ -1081,7 +1098,7 @@ const AXObject* AXObject::InertRoot() const { element = FlatTreeTraversal::ParentElement(*node); while (element) { - if (element->hasAttribute(kInertAttr)) + if (element->hasAttribute(html_names::kInertAttr)) return AXObjectCache().GetOrCreate(element); element = FlatTreeTraversal::ParentElement(*element); } @@ -1195,11 +1212,6 @@ bool AXObject::ComputeAccessibilityIsIgnoredButIncludedInTree() const { if (!GetNode()) return false; - // Disallow inert nodes from the tree to ensure the dialog is always the - // first child of the root. - if (GetNode()->IsInert()) - return false; - // If the node is part of the user agent shadow dom, or has the explicit // internal Role::kIgnored, they aren't interesting for paragraph navigation // or LabelledBy/DescribedBy relationships. @@ -1213,16 +1225,29 @@ bool AXObject::ComputeAccessibilityIsIgnoredButIncludedInTree() const { if (IsLineBreakingObject()) return true; - // Allow the browser side ax tree to access aria-hidden="true", "visibility: - // hidden", and "visibility: collapse" nodes. This is useful for APIs that - // return the node referenced by aria-labeledby and aria-describedby - if (GetLayoutObject()) { + // Allow the browser side ax tree to access "visibility: [hidden|collapse]" + // and "display: none" nodes. This is useful for APIs that return the node + // referenced by aria-labeledby and aria-describedby. + // An element must have an id attribute or it cannot be referenced by + // aria-labelledby or aria-describedby. + if (RuntimeEnabledFeatures::AccessibilityExposeDisplayNoneEnabled()) { + if (Element* element = GetElement()) { + if (element->FastHasAttribute(html_names::kIdAttr) && + IsHiddenForTextAlternativeCalculation()) { + return true; + } + } + } else if (GetLayoutObject()) { if (GetLayoutObject()->Style()->Visibility() != EVisibility::kVisible) return true; - if (AriaHiddenRoot()) - return true; } + // Allow the browser side ax tree to access "aria-hidden" nodes. + // This is useful for APIs that return the node referenced by + // aria-labeledby and aria-describedby. + if (GetLayoutObject() && AriaHiddenRoot()) + return true; + return false; } @@ -1291,7 +1316,7 @@ bool AXObject::CanReceiveAccessibilityFocus() const { return true; // aria-activedescendant focus - return elem->FastHasAttribute(kIdAttr) && CanBeActiveDescendant(); + return elem->FastHasAttribute(html_names::kIdAttr) && CanBeActiveDescendant(); } bool AXObject::CanSetValueAttribute() const { @@ -1536,6 +1561,9 @@ String AXObject::GetName(ax::mojom::NameFrom& name_from, bool hidden_and_ignored_but_included_in_tree = IsHiddenForTextAlternativeCalculation() && AccessibilityIsIgnoredButIncludedInTree(); + // Initialize |name_from|, as TextAlternative() might never set it in some + // cases. + name_from = ax::mojom::NameFrom::kNone; String text = TextAlternative(false, hidden_and_ignored_but_included_in_tree, visited, name_from, &related_objects, nullptr); @@ -1610,8 +1638,7 @@ bool AXObject::IsHiddenForTextAlternativeCalculation() const { if (Node* node = GetNode()) { auto* element = DynamicTo<Element>(node); if (element && node->isConnected()) { - scoped_refptr<ComputedStyle> style = - document->EnsureStyleResolver().StyleForElement(element); + const ComputedStyle* style = element->EnsureComputedStyle(); return style->Display() == EDisplay::kNone || style->Visibility() != EVisibility::kVisible; } @@ -1645,9 +1672,10 @@ String AXObject::AriaTextAlternative(bool recursive, // Check ARIA attributes. const QualifiedName& attr = - HasAttribute(kAriaLabeledbyAttr) && !HasAttribute(kAriaLabelledbyAttr) - ? kAriaLabeledbyAttr - : kAriaLabelledbyAttr; + HasAttribute(html_names::kAriaLabeledbyAttr) && + !HasAttribute(html_names::kAriaLabelledbyAttr) + ? html_names::kAriaLabeledbyAttr + : html_names::kAriaLabelledbyAttr; if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative, attr)); @@ -1690,7 +1718,7 @@ String AXObject::AriaTextAlternative(bool recursive, name_from = ax::mojom::NameFrom::kAttribute; if (name_sources) { name_sources->push_back( - NameSource(*found_text_alternative, kAriaLabelAttr)); + NameSource(*found_text_alternative, html_names::kAriaLabelAttr)); name_sources->back().type = name_from; } const AtomicString& aria_label = @@ -1777,9 +1805,9 @@ void AXObject::AriaLabelledbyElementVector( HeapVector<Member<Element>>& elements, Vector<String>& ids) const { // Try both spellings, but prefer aria-labelledby, which is the official spec. - ElementsFromAttribute(elements, kAriaLabelledbyAttr, ids); + ElementsFromAttribute(elements, html_names::kAriaLabelledbyAttr, ids); if (!ids.size()) - ElementsFromAttribute(elements, kAriaLabeledbyAttr, ids); + ElementsFromAttribute(elements, html_names::kAriaLabeledbyAttr, ids); } String AXObject::TextFromAriaLabelledby(AXObjectSet& visited, @@ -1794,7 +1822,7 @@ String AXObject::TextFromAriaDescribedby(AXRelatedObjectVector* related_objects, Vector<String>& ids) const { AXObjectSet visited; HeapVector<Member<Element>> elements; - ElementsFromAttribute(elements, kAriaDescribedbyAttr, ids); + ElementsFromAttribute(elements, html_names::kAriaDescribedbyAttr, ids); return TextFromElements(true, visited, elements, related_objects); } @@ -2043,6 +2071,22 @@ ax::mojom::Role AXObject::DetermineAriaRoleAttribute() const { ax::mojom::Role role = AriaRoleToWebCoreRole(aria_role); + switch (role) { + case ax::mojom::Role::kAnnotationAttribution: + case ax::mojom::Role::kAnnotationCommentary: + case ax::mojom::Role::kAnnotationPresence: + case ax::mojom::Role::kAnnotationRevision: + case ax::mojom::Role::kAnnotationSuggestion: + UseCounter::Count(GetDocument(), WebFeature::kARIAAnnotationRoles); + if (!RuntimeEnabledFeatures:: + AccessibilityExposeARIAAnnotationsEnabled()) { + role = ax::mojom::Role::kGenericContainer; + } + break; + default: + break; + } + // ARIA states if an item can get focus, it should not be presentational. // It also states user agents should ignore the presentational role if // the element has global ARIA states and properties. @@ -2516,8 +2560,10 @@ void AXObject::UpdateChildrenIfNecessary() { void AXObject::ClearChildren() { // Detach all weak pointers from objects to their parents. - for (const auto& child : children_) - child->DetachFromParent(); + for (const auto& child : children_) { + if (child->parent_ == this) + child->DetachFromParent(); + } children_.clear(); have_children_ = false; @@ -2568,7 +2614,7 @@ AtomicString AXObject::Language() const { // 2. The list of languages the browser sends in the [Accept-Language] header. // 3. The browser's default language. - const AtomicString& lang = GetAttribute(kLangAttr); + const AtomicString& lang = GetAttribute(html_names::kLangAttr); if (!lang.IsEmpty()) return lang; @@ -3161,8 +3207,10 @@ bool AXObject::OnNativeScrollToMakeVisibleAction() const { if (!node) return false; if (Element* locked_ancestor = - DisplayLockUtilities::NearestLockedInclusiveAncestor(*node)) - locked_ancestor->ActivateDisplayLockIfNeeded(); + DisplayLockUtilities::NearestLockedInclusiveAncestor(*node)) { + locked_ancestor->ActivateDisplayLockIfNeeded( + DisplayLockActivationReason::kUser); + } LayoutObject* layout_object = node->GetLayoutObject(); if (!layout_object || !node->isConnected()) return false; @@ -3314,7 +3362,7 @@ bool AXObject::NameFromSelectedOption(bool recursive) const { // This can be either a button widget with a non-false value of // aria-haspopup or a select element with size of 1. case ax::mojom::Role::kPopUpButton: - return ToHTMLSelectElementOrNull(*GetNode()) ? recursive : false; + return DynamicTo<HTMLSelectElement>(*GetNode()) ? recursive : false; default: return false; } @@ -3365,6 +3413,11 @@ bool AXObject::NameFromContents(bool recursive) const { // containers for many subobjects. Superset of nameFrom:author ARIA roles. case ax::mojom::Role::kAlert: case ax::mojom::Role::kAlertDialog: + case ax::mojom::Role::kAnnotationAttribution: + case ax::mojom::Role::kAnnotationCommentary: + case ax::mojom::Role::kAnnotationPresence: + case ax::mojom::Role::kAnnotationRevision: + case ax::mojom::Role::kAnnotationSuggestion: case ax::mojom::Role::kApplication: case ax::mojom::Role::kAudio: case ax::mojom::Role::kArticle: @@ -3428,6 +3481,7 @@ bool AXObject::NameFromContents(bool recursive) const { case ax::mojom::Role::kGraphicsSymbol: case ax::mojom::Role::kGrid: case ax::mojom::Role::kGroup: + case ax::mojom::Role::kHeader: case ax::mojom::Role::kIframePresentational: case ax::mojom::Role::kIframe: case ax::mojom::Role::kImage: @@ -3482,7 +3536,6 @@ bool AXObject::NameFromContents(bool recursive) const { // Some objects can contribute their contents to ancestor names, but // only have their own name if they are focusable case ax::mojom::Role::kAbbr: - case ax::mojom::Role::kAnnotation: case ax::mojom::Role::kCanvas: case ax::mojom::Role::kCaption: case ax::mojom::Role::kContentDeletion: @@ -3493,7 +3546,9 @@ bool AXObject::NameFromContents(bool recursive) const { case ax::mojom::Role::kDetails: case ax::mojom::Role::kFigcaption: case ax::mojom::Role::kFooter: + case ax::mojom::Role::kFooterAsNonLandmark: case ax::mojom::Role::kGenericContainer: + case ax::mojom::Role::kHeaderAsNonLandmark: case ax::mojom::Role::kIgnored: case ax::mojom::Role::kImageMap: case ax::mojom::Role::kInlineTextBox: @@ -3516,6 +3571,8 @@ bool AXObject::NameFromContents(bool recursive) const { // if the row might receive focus case ax::mojom::Role::kRow: case ax::mojom::Role::kRuby: + case ax::mojom::Role::kRubyAnnotation: + case ax::mojom::Role::kSection: result = recursive || (CanReceiveAccessibilityFocus() && !IsEditable()); break; diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h index 129600f6d87..fc0cb6b3231 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h @@ -35,6 +35,7 @@ #include <ostream> #include "base/macros.h" +#include "third_party/blink/public/web/web_ax_enums.h" #include "third_party/blink/renderer/core/accessibility/axid.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/editing/markers/document_marker.h" @@ -101,8 +102,8 @@ class IgnoredReason { void Trace(blink::Visitor* visitor) { visitor->Trace(related_object); } }; -class NameSourceRelatedObject - : public GarbageCollectedFinalized<NameSourceRelatedObject> { +class NameSourceRelatedObject final + : public GarbageCollected<NameSourceRelatedObject> { public: WeakMember<AXObject> object; String text; @@ -168,14 +169,14 @@ WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::DescriptionSource) namespace blink { -class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> { +class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { public: typedef HeapVector<Member<AXObject>> AXObjectVector; // Iterator for doing an in-order traversal of the accessibility tree. // Includes ignored objects in the traversal. class MODULES_EXPORT InOrderTraversalIterator final - : public GarbageCollectedFinalized<InOrderTraversalIterator> { + : public GarbageCollected<InOrderTraversalIterator> { public: ~InOrderTraversalIterator() = default; @@ -266,7 +267,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> { // Walks through all the unignored parents of the object up to the root. // Does not include the object itself in the list of ancestors. class MODULES_EXPORT AncestorsIterator final - : public GarbageCollectedFinalized<AncestorsIterator> { + : public GarbageCollected<AncestorsIterator> { public: ~AncestorsIterator() = default; @@ -469,7 +470,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> { } // Check object state. - virtual bool IsAutofillAvailable() { return false; } + virtual bool IsAutofillAvailable() const { return false; } virtual bool IsClickable() const; virtual AccessibilityExpanded IsExpanded() const { return kExpandedUndefined; @@ -621,7 +622,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> { // Used by objects of role ColorWellRole. virtual RGBA32 ColorValue() const { return Color::kTransparent; } virtual bool CanvasHasFallbackContent() const { return false; } - virtual AtomicString FontFamily() const { return g_null_atom; } + virtual String FontFamily() const { return String(); } // Font size is in pixels. virtual float FontSize() const { return 0.0f; } virtual float FontWeight() const { return 0.0f; } @@ -711,7 +712,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> { ax::mojom::Role DetermineAriaRoleAttribute() const; virtual ax::mojom::Role AriaRoleAttribute() const; virtual AXObject* ActiveDescendant() { return nullptr; } - virtual String AriaAutoComplete() const { return String(); } + virtual String AutoComplete() const { return String(); } virtual void AriaOwnsElements(AXObjectVector& owns) const {} virtual void AriaDescribedbyElements(AXObjectVector&) const {} virtual AXObject* ErrorMessage() const { return nullptr; } @@ -1000,7 +1001,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> { // Notifications that this object may have changed. virtual void ChildrenChanged() {} virtual void HandleActiveDescendantChanged() {} - virtual void HandleAutofillStateChanged(bool) {} + virtual void HandleAutofillStateChanged(WebAXAutofillState) {} virtual void HandleAriaExpandedChanged() {} virtual void SelectionChanged(); virtual void TextChanged() {} diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index 00568b6b8d9..94d449fcf50 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc @@ -88,11 +88,10 @@ #include "third_party/blink/renderer/modules/accessibility/ax_virtual_object.h" #include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h" #include "third_party/blink/renderer/modules/permissions/permission_utils.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { -using namespace html_names; - namespace { // Return a node for the current layout object or ancestor layout object. Node* GetClosestNodeForLayoutObject(LayoutObject* layout_object) { @@ -120,6 +119,7 @@ AXObjectCacheImpl::AXObjectCacheImpl(Document& document) AddPermissionStatusListener(); documents_.insert(&document); document.View()->RegisterForLifecycleNotifications(this); + relation_cache_->Init(); } AXObjectCacheImpl::~AXObjectCacheImpl() { @@ -168,6 +168,45 @@ void AXObjectCacheImpl::DisposePopup(Document* document) { documents_.erase(document); } +Node* AXObjectCacheImpl::FocusedElement() { + Node* focused_node = document_->FocusedElement(); + if (!focused_node) + focused_node = document_; + + // If it's an image map, get the focused link within the image map. + if (IsA<HTMLAreaElement>(focused_node)) + return focused_node; + + // See if there's a page popup, for example a calendar picker. + Element* adjusted_focused_element = document_->AdjustedFocusedElement(); + if (auto* input = ToHTMLInputElementOrNull(adjusted_focused_element)) { + if (AXObject* ax_popup = input->PopupRootAXObject()) { + if (Element* focused_element_in_popup = + ax_popup->GetDocument()->FocusedElement()) + focused_node = focused_element_in_popup; + } + } + + return focused_node; +} + +AXObject* AXObjectCacheImpl::GetOrCreateFocusedObjectFromNode(Node* node) { + // If it's an image map, get the focused link within the image map. + if (auto* area = DynamicTo<HTMLAreaElement>(node)) + return FocusedImageMapUIElement(area); + + AXObject* obj = GetOrCreate(node); + if (!obj) + return nullptr; + + // the HTML element, for example, is focusable but has an AX object that is + // ignored + if (!obj->AccessibilityIsIncludedInTree()) + obj = obj->ParentObjectIncludedInTree(); + + return obj; +} + AXObject* AXObjectCacheImpl::FocusedImageMapUIElement( HTMLAreaElement* area_element) { // Find the corresponding accessibility object for the HTMLAreaElement. This @@ -198,34 +237,7 @@ AXObject* AXObjectCacheImpl::FocusedImageMapUIElement( } AXObject* AXObjectCacheImpl::FocusedObject() { - Node* focused_node = document_->FocusedElement(); - if (!focused_node) - focused_node = document_; - - // If it's an image map, get the focused link within the image map. - if (auto* area = DynamicTo<HTMLAreaElement>(focused_node)) - return FocusedImageMapUIElement(area); - - // See if there's a page popup, for example a calendar picker. - Element* adjusted_focused_element = document_->AdjustedFocusedElement(); - if (auto* input = ToHTMLInputElementOrNull(adjusted_focused_element)) { - if (AXObject* ax_popup = input->PopupRootAXObject()) { - if (Element* focused_element_in_popup = - ax_popup->GetDocument()->FocusedElement()) - focused_node = focused_element_in_popup; - } - } - - AXObject* obj = GetOrCreate(focused_node); - if (!obj) - return nullptr; - - // the HTML element, for example, is focusable but has an AX object that is - // ignored - if (!obj->AccessibilityIsIncludedInTree()) - obj = obj->ParentObjectUnignored(); - - return obj; + return GetOrCreateFocusedObjectFromNode(this->FocusedElement()); } AXObject* AXObjectCacheImpl::Get(LayoutObject* layout_object) { @@ -259,10 +271,10 @@ AXObject* AXObjectCacheImpl::Get(LayoutObject* layout_object) { // Returns true if |node| is an <option> element and its parent <select> // is a menu list (not a list box). static bool IsMenuListOption(const Node* node) { - if (!IsHTMLOptionElement(node)) + auto* option_element = DynamicTo<HTMLOptionElement>(node); + if (!option_element) return false; - const HTMLSelectElement* select = - ToHTMLOptionElement(node)->OwnerSelectElement(); + const HTMLSelectElement* select = option_element->OwnerSelectElement(); if (!select) return false; const LayoutObject* layout_object = select->GetLayoutObject(); @@ -379,7 +391,8 @@ static bool NodeHasRole(Node* node, const String& role) { return false; // TODO(accessibility) support role strings with multiple roles. - return EqualIgnoringASCIICase(element->getAttribute(kRoleAttr), role); + return EqualIgnoringASCIICase(element->getAttribute(html_names::kRoleAttr), + role); } AXObject* AXObjectCacheImpl::CreateFromRenderer(LayoutObject* layout_object) { @@ -390,7 +403,7 @@ AXObject* AXObjectCacheImpl::CreateFromRenderer(LayoutObject* layout_object) { // ul/ol/dl type (it shouldn't be a list if aria says otherwise). if (NodeHasRole(node, "list") || NodeHasRole(node, "directory") || (NodeHasRole(node, g_null_atom) && - (IsHTMLUListElement(node) || IsHTMLOListElement(node) || + (IsHTMLUListElement(node) || IsA<HTMLOListElement>(node) || IsA<HTMLDListElement>(node)))) return MakeGarbageCollected<AXList>(layout_object, *this); @@ -398,7 +411,7 @@ AXObject* AXObjectCacheImpl::CreateFromRenderer(LayoutObject* layout_object) { if (node && node->IsMediaElement()) return AccessibilityMediaElement::Create(layout_object, *this); - if (IsHTMLOptionElement(node)) + if (IsA<HTMLOptionElement>(node)) return MakeGarbageCollected<AXListBoxOption>(layout_object, *this); if (IsHTMLInputElement(node) && @@ -431,7 +444,7 @@ AXObject* AXObjectCacheImpl::CreateFromRenderer(LayoutObject* layout_object) { AXObject* AXObjectCacheImpl::CreateFromNode(Node* node) { if (IsMenuListOption(node)) { - return MakeGarbageCollected<AXMenuListOption>(ToHTMLOptionElement(node), + return MakeGarbageCollected<AXMenuListOption>(To<HTMLOptionElement>(node), *this); } @@ -633,7 +646,7 @@ void AXObjectCacheImpl::Remove(AXID ax_id) { if (!ax_id) return; - // first fetch object to operate some cleanup functions on it + // First, fetch object to operate some cleanup functions on it. AXObject* obj = objects_.at(ax_id); if (!obj) return; @@ -641,7 +654,7 @@ void AXObjectCacheImpl::Remove(AXID ax_id) { obj->Detach(); RemoveAXID(obj); - // finally remove the object + // Finally, remove the object. if (!objects_.Take(ax_id)) return; @@ -731,6 +744,7 @@ void AXObjectCacheImpl::RemoveAXID(AXObject* object) { DCHECK(ids_in_use_.Contains(obj_id)); object->SetAXObjectID(0); ids_in_use_.erase(obj_id); + autofill_state_map_.erase(obj_id); relation_cache_->RemoveAXID(obj_id); } @@ -1171,8 +1185,35 @@ void AXObjectCacheImpl::HandleAriaSelectedChangedWithCleanLayout(Node* node) { PostNotification(obj, ax::mojom::Event::kCheckedStateChanged); AXObject* listbox = obj->ParentObjectUnignored(); - if (listbox && listbox->RoleValue() == ax::mojom::Role::kListBox) + if (listbox && listbox->RoleValue() == ax::mojom::Role::kListBox) { + // Ensure listbox options are in sync as selection status may have changed + MarkAXObjectDirty(listbox, true); PostNotification(listbox, ax::mojom::Event::kSelectedChildrenChanged); + } +} + +void AXObjectCacheImpl::HandleNodeLostFocusWithCleanLayout(Node* node) { + DCHECK(node); + DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node)); + AXObject* obj = Get(node); + if (!obj) + return; + + PostNotification(obj, ax::mojom::Event::kBlur); +} + +void AXObjectCacheImpl::HandleNodeGainedFocusWithCleanLayout(Node* node) { + DCHECK(node); + DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node)); + // Something about the call chain for this method seems to leave distribution + // in a dirty state - update it before we call GetOrCreate so that we don't + // crash. + node->UpdateDistributionForFlatTreeTraversal(); + AXObject* obj = GetOrCreateFocusedObjectFromNode(node); + if (!obj) + return; + + PostNotification(obj, ax::mojom::Event::kFocus); } // This might be the new target of a relation. Handle all possible cases. @@ -1219,12 +1260,8 @@ void AXObjectCacheImpl::HandleRoleChangeWithCleanLayout(Node* node) { DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node)); - AXObject* obj = Get(node); - if (!obj && IsHTMLSelectElement(node)) - obj = GetOrCreate(node); - // Invalidate the current object and make the parent reconsider its children. - if (obj) { + if (AXObject* obj = GetOrCreate(node)) { // Save parent for later use. AXObject* parent = obj->ParentObject(); @@ -1280,12 +1317,14 @@ bool AXObjectCacheImpl::HandleAttributeChanged(const QualifiedName& attr_name, DeferTreeUpdate(&AXObjectCacheImpl::HandleAttributeChangedWithCleanLayout, attr_name, element); - if (attr_name != kRoleAttr && attr_name != kTypeAttr && - attr_name != kSizeAttr && attr_name != kAltAttr && - attr_name != kTitleAttr && - (attr_name != kForAttr && !IsA<HTMLLabelElement>(*element)) && - attr_name != kIdAttr && attr_name != kTabindexAttr && - attr_name != kDisabledAttr && + if (attr_name != html_names::kRoleAttr && + attr_name != html_names::kTypeAttr && + attr_name != html_names::kSizeAttr && attr_name != html_names::kAltAttr && + attr_name != html_names::kTitleAttr && + (attr_name != html_names::kForAttr && !IsA<HTMLLabelElement>(*element)) && + attr_name != html_names::kIdAttr && + attr_name != html_names::kTabindexAttr && + attr_name != html_names::kDisabledAttr && !attr_name.LocalName().StartsWith("aria-")) { return false; } @@ -1314,26 +1353,32 @@ void AXObjectCacheImpl::HandleAttributeChangedWithCleanLayout( Element* element) { DCHECK(element); DCHECK(!element->GetDocument().NeedsLayoutTreeUpdateForNode(*element)); - if (attr_name == kRoleAttr || attr_name == kTypeAttr) { + if (attr_name == html_names::kRoleAttr || + attr_name == html_names::kTypeAttr) { HandleRoleChangeWithCleanLayout(element); - } else if (attr_name == kSizeAttr || attr_name == kAriaHaspopupAttr) { + } else if (attr_name == html_names::kSizeAttr || + attr_name == html_names::kAriaHaspopupAttr) { // Role won't change on edits. HandleRoleChangeIfNotEditableWithCleanLayout(element); - } else if (attr_name == kAltAttr || attr_name == kTitleAttr) { + } else if (attr_name == html_names::kAltAttr || + attr_name == html_names::kTitleAttr) { TextChangedWithCleanLayout(element); - } else if (attr_name == kForAttr && IsA<HTMLLabelElement>(*element)) { + } else if (attr_name == html_names::kForAttr && + IsA<HTMLLabelElement>(*element)) { LabelChangedWithCleanLayout(element); - } else if (attr_name == kIdAttr) { + } else if (attr_name == html_names::kIdAttr) { MaybeNewRelationTarget(element, Get(element)); - } else if (attr_name == kTabindexAttr) { + } else if (attr_name == html_names::kTabindexAttr) { FocusableChangedWithCleanLayout(element); - } else if (attr_name == kDisabledAttr || attr_name == kReadonlyAttr) { + } else if (attr_name == html_names::kDisabledAttr || + attr_name == html_names::kReadonlyAttr) { MarkElementDirty(element, false); - } else if (attr_name == kValueAttr) { + } else if (attr_name == html_names::kValueAttr) { HandleValueChanged(element); - } else if (attr_name == kMinAttr || attr_name == kMaxAttr) { + } else if (attr_name == html_names::kMinAttr || + attr_name == html_names::kMaxAttr) { MarkElementDirty(element, false); - } else if (attr_name == kStepAttr) { + } else if (attr_name == html_names::kStepAttr) { MarkElementDirty(element, false); } @@ -1341,30 +1386,32 @@ void AXObjectCacheImpl::HandleAttributeChangedWithCleanLayout( return; // Perform updates specific to each attribute. - if (attr_name == kAriaActivedescendantAttr) { + if (attr_name == html_names::kAriaActivedescendantAttr) { HandleActiveDescendantChangedWithCleanLayout(element); - } else if (attr_name == kAriaValuenowAttr || - attr_name == kAriaValuetextAttr) { + } else if (attr_name == html_names::kAriaValuenowAttr || + attr_name == html_names::kAriaValuetextAttr) { HandleValueChanged(element); - } else if (attr_name == kAriaLabelAttr || attr_name == kAriaLabeledbyAttr || - attr_name == kAriaLabelledbyAttr) { + } else if (attr_name == html_names::kAriaLabelAttr || + attr_name == html_names::kAriaLabeledbyAttr || + attr_name == html_names::kAriaLabelledbyAttr) { TextChangedWithCleanLayout(element); - } else if (attr_name == kAriaDescribedbyAttr) { + } else if (attr_name == html_names::kAriaDescribedbyAttr) { // TODO do we need a DescriptionChanged() ? TextChangedWithCleanLayout(element); - } else if (attr_name == kAriaCheckedAttr || attr_name == kAriaPressedAttr) { + } else if (attr_name == html_names::kAriaCheckedAttr || + attr_name == html_names::kAriaPressedAttr) { CheckedStateChanged(element); - } else if (attr_name == kAriaSelectedAttr) { + } else if (attr_name == html_names::kAriaSelectedAttr) { HandleAriaSelectedChangedWithCleanLayout(element); - } else if (attr_name == kAriaExpandedAttr) { + } else if (attr_name == html_names::kAriaExpandedAttr) { HandleAriaExpandedChangeWithCleanLayout(element); - } else if (attr_name == kAriaHiddenAttr) { + } else if (attr_name == html_names::kAriaHiddenAttr) { ChildrenChangedWithCleanLayout(element->parentNode()); - } else if (attr_name == kAriaInvalidAttr) { + } else if (attr_name == html_names::kAriaInvalidAttr) { PostNotification(element, ax::mojom::Event::kInvalidStatusChanged); - } else if (attr_name == kAriaErrormessageAttr) { + } else if (attr_name == html_names::kAriaErrormessageAttr) { MarkElementDirty(element, false); - } else if (attr_name == kAriaOwnsAttr) { + } else if (attr_name == html_names::kAriaOwnsAttr) { ChildrenChangedWithCleanLayout(element); // Ensure aria-owns update fires on original parent as well if (AXObject* obj = GetOrCreate(element)) { @@ -1590,13 +1637,23 @@ void AXObjectCacheImpl::HandleFocusedUIElementChanged( if (!page) return; - AXObject* focused_object = this->FocusedObject(); - if (!focused_object) - return; + if (RuntimeEnabledFeatures::AccessibilityExposeDisplayNoneEnabled()) { + if (old_focused_element) { + DeferTreeUpdate(&AXObjectCacheImpl::HandleNodeLostFocusWithCleanLayout, + old_focused_element); + } + + DeferTreeUpdate(&AXObjectCacheImpl::HandleNodeGainedFocusWithCleanLayout, + this->FocusedElement()); + } else { + AXObject* focused_object = this->FocusedObject(); + if (!focused_object) + return; - AXObject* old_focused_object = Get(old_focused_element); - PostNotification(old_focused_object, ax::mojom::Event::kBlur); - PostNotification(focused_object, ax::mojom::Event::kFocus); + AXObject* old_focused_object = Get(old_focused_element); + PostNotification(old_focused_object, ax::mojom::Event::kBlur); + PostNotification(focused_object, ax::mojom::Event::kFocus); + } } void AXObjectCacheImpl::HandleInitialFocus() { @@ -1852,4 +1909,19 @@ ax::mojom::EventFrom AXObjectCacheImpl::ComputeEventFrom() { return ax::mojom::EventFrom::kPage; } +WebAXAutofillState AXObjectCacheImpl::GetAutofillState(AXID id) const { + auto iter = autofill_state_map_.find(id); + if (iter == autofill_state_map_.end()) + return WebAXAutofillState::kNoSuggestions; + return iter->value; +} + +void AXObjectCacheImpl::SetAutofillState(AXID id, WebAXAutofillState state) { + WebAXAutofillState previous_state = GetAutofillState(id); + if (state != previous_state) { + autofill_state_map_.Set(id, state); + MarkAXObjectDirty(ObjectFromAXID(id), false); + } +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h index 0c4ceb5ecdd..dbbf20bc473 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h @@ -36,7 +36,9 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" +#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink-forward.h" #include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h" +#include "third_party/blink/public/web/web_ax_enums.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache_base.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" @@ -45,7 +47,7 @@ #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/vector.h" -#include "ui/accessibility/ax_enums.mojom-blink.h" +#include "ui/accessibility/ax_enums.mojom-blink-forward.h" namespace blink { @@ -194,6 +196,8 @@ class MODULES_EXPORT AXObjectCacheImpl void HandleRoleChangeIfNotEditableWithCleanLayout(Node*); void HandleAriaExpandedChangeWithCleanLayout(Node*); void HandleAriaSelectedChangedWithCleanLayout(Node*); + void HandleNodeLostFocusWithCleanLayout(Node*); + void HandleNodeGainedFocusWithCleanLayout(Node*); bool InlineTextBoxAccessibilityEnabled(); @@ -256,6 +260,9 @@ class MODULES_EXPORT AXObjectCacheImpl void set_is_handling_action(bool value) { is_handling_action_ = value; } + WebAXAutofillState GetAutofillState(AXID id) const; + void SetAutofillState(AXID id, WebAXAutofillState state); + protected: void PostPlatformNotification( AXObject*, @@ -268,7 +275,7 @@ class MODULES_EXPORT AXObjectCacheImpl AXObject* CreateFromInlineTextBox(AbstractInlineTextBox*); private: - struct AXEventParams : public GarbageCollectedFinalized<AXEventParams> { + struct AXEventParams final : public GarbageCollected<AXEventParams> { AXEventParams(AXObject* target, ax::mojom::Event event_type, ax::mojom::EventFrom event_from) @@ -280,7 +287,7 @@ class MODULES_EXPORT AXObjectCacheImpl void Trace(Visitor* visitor) { visitor->Trace(target); } }; - struct TreeUpdateParams : public GarbageCollectedFinalized<TreeUpdateParams> { + struct TreeUpdateParams final : public GarbageCollected<TreeUpdateParams> { TreeUpdateParams(Node* node, base::OnceClosure callback) : node(node), callback(std::move(callback)) {} WeakMember<Node> node; @@ -322,6 +329,12 @@ class MODULES_EXPORT AXObjectCacheImpl // ContextLifecycleObserver overrides. void ContextDestroyed(ExecutionContext*) override; + // Get the currently focused Node element. + Node* FocusedElement(); + + // GetOrCreate the focusable AXObject for a specific Node. + AXObject* GetOrCreateFocusedObjectFromNode(Node*); + AXObject* FocusedImageMapUIElement(HTMLAreaElement*); AXID GetOrCreateAXID(AXObject*); @@ -386,6 +399,9 @@ class MODULES_EXPORT AXObjectCacheImpl bool is_handling_action_ = false; + // Maps ids to their object's autofill state. + HashMap<AXID, WebAXAutofillState> autofill_state_map_; + DISALLOW_COPY_AND_ASSIGN(AXObjectCacheImpl); }; diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc index 2bf649ae277..b5426a0d1fa 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_test.cc @@ -396,5 +396,55 @@ TEST_F(AccessibilityTest, CheckNoDuplicateChildren) { ASSERT_EQ(ax_select->FirstChild()->ChildCount(), 1); } +TEST_F(AccessibilityTest, InitRelationCache) { + // All of the other tests already have accessibility initialized + // first, but we don't want to in this test. + // + // Get rid of the AXContext so the AXObjectCache is destroyed. + ax_context_.reset(nullptr); + + SetBodyInnerHTML(R"HTML( + <ul id="ul" aria-owns="li"></ul> + <label for="a"></label> + <input id="a"> + <input id="b"> + <div role="section" id="div"> + <li id="li"></li> + </div> + )HTML"); + + // Now recreate an AXContext, simulating what happens if accessibility + // is enabled after the document is loaded. + ax_context_.reset(new AXContext(GetDocument())); + + const AXObject* root = GetAXRootObject(); + ASSERT_NE(nullptr, root); + const AXObject* input_a = GetAXObjectByElementId("a"); + ASSERT_NE(nullptr, input_a); + const AXObject* input_b = GetAXObjectByElementId("b"); + ASSERT_NE(nullptr, input_b); + + EXPECT_TRUE( + GetAXObjectCache().MayHaveHTMLLabel(ToHTMLElement(*input_a->GetNode()))); + EXPECT_FALSE( + GetAXObjectCache().MayHaveHTMLLabel(ToHTMLElement(*input_b->GetNode()))); + + // Note: retrieve the LI first and check that its parent is not + // the paragraph element. If we were to retrieve the UL element, + // that would trigger the aria-owns check and wouln't allow us to + // test whether the relation cache was initialized. + const AXObject* li = GetAXObjectByElementId("li"); + ASSERT_NE(nullptr, li); + + const AXObject* div = GetAXObjectByElementId("div"); + ASSERT_NE(nullptr, div); + EXPECT_NE(li->ParentObjectUnignored(), div); + + const AXObject* ul = GetAXObjectByElementId("ul"); + ASSERT_NE(nullptr, ul); + + EXPECT_EQ(li->ParentObjectUnignored(), ul); +} + } // namespace test } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc index 15ebb4bdb28..fd7dd48d0e4 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc @@ -26,7 +26,7 @@ namespace blink { const AXPosition AXPosition::CreatePositionBeforeObject( const AXObject& child, const AXPositionAdjustmentBehavior adjustment_behavior) { - if (child.IsDetached()) + if (child.IsDetached() || !child.AccessibilityIsIncludedInTree()) return {}; // If |child| is a text object, but not a text control, make behavior the same @@ -37,6 +37,10 @@ const AXPosition AXPosition::CreatePositionBeforeObject( return CreateFirstPositionInObject(child, adjustment_behavior); const AXObject* parent = child.ParentObjectIncludedInTree(); + + if (!parent || parent->IsDetached()) + return {}; + DCHECK(parent); AXPosition position(*parent); position.text_offset_or_child_index_ = child.IndexInParent(); @@ -51,7 +55,7 @@ const AXPosition AXPosition::CreatePositionBeforeObject( const AXPosition AXPosition::CreatePositionAfterObject( const AXObject& child, const AXPositionAdjustmentBehavior adjustment_behavior) { - if (child.IsDetached()) + if (child.IsDetached() || !child.AccessibilityIsIncludedInTree()) return {}; // If |child| is a text object, but not a text control, make behavior the same @@ -62,6 +66,10 @@ const AXPosition AXPosition::CreatePositionAfterObject( return CreateLastPositionInObject(child, adjustment_behavior); const AXObject* parent = child.ParentObjectIncludedInTree(); + + if (!parent || parent->IsDetached()) + return {}; + DCHECK(parent); AXPosition position(*parent); position.text_offset_or_child_index_ = child.IndexInParent() + 1; diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc index c571e5eb323..31193add4e2 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_position_test.cc @@ -77,6 +77,12 @@ constexpr char kAOM[] = R"HTML( </script> )HTML"; +constexpr char kMap[] = R"HTML( + <br id="br"> + <map id="map"> + <area shape="rect" coords="0,0,10,10" href="about:blank"> + </map> + )HTML"; } // namespace // @@ -734,11 +740,12 @@ TEST_F(AccessibilityTest, PositionInIgnoredObject) { const AXObject* ax_body = ax_root->FirstChild(); ASSERT_NE(nullptr, ax_body); ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_body->RoleValue()); - ASSERT_EQ(1, ax_body->ChildCount()); + ASSERT_EQ(2, ax_body->ChildCount()); const AXObject* ax_hidden = GetAXObjectByElementId("hidden"); ASSERT_NE(nullptr, ax_hidden); ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_hidden->RoleValue()); + ASSERT_TRUE(ax_hidden->AccessibilityIsIgnoredButIncludedInTree()); const AXObject* ax_visible = GetAXObjectByElementId("visible"); ASSERT_NE(nullptr, ax_visible); @@ -762,10 +769,7 @@ TEST_F(AccessibilityTest, PositionInIgnoredObject) { ax_position_before_visible_from_dom.ChildAfterTreePosition()); // A position at the beginning of the body will appear to be before the hidden - // element in the DOM, but it should be before the visible object in the - // accessibility tree since the hidden element is not in the tree. Hence, when - // converting to the corresponding DOM position, it should be before the - // visible element in the DOM as well. + // element in the DOM. const auto ax_position_first = AXPosition::CreateFirstPositionInObject(*ax_root); const auto position_first = ax_position_first.ToPositionWithAffinity(); @@ -781,13 +785,13 @@ TEST_F(AccessibilityTest, PositionInIgnoredObject) { EXPECT_EQ(ax_body, ax_position_first_from_dom.ChildAfterTreePosition()); // A DOM position before |hidden| should convert to an accessibility position - // before |visible|. + // before |hidden| because the node is ignored but included in the tree. const auto position_before = Position::BeforeNode(*hidden); const auto ax_position_before_from_dom = AXPosition::FromPosition(position_before); EXPECT_EQ(ax_body, ax_position_before_from_dom.ContainerObject()); EXPECT_EQ(0, ax_position_before_from_dom.ChildIndex()); - EXPECT_EQ(ax_visible, ax_position_before_from_dom.ChildAfterTreePosition()); + EXPECT_EQ(ax_hidden, ax_position_before_from_dom.ChildAfterTreePosition()); // A DOM position after |hidden| should convert to an accessibility position // before |visible|. @@ -795,7 +799,7 @@ TEST_F(AccessibilityTest, PositionInIgnoredObject) { const auto ax_position_after_from_dom = AXPosition::FromPosition(position_after); EXPECT_EQ(ax_body, ax_position_after_from_dom.ContainerObject()); - EXPECT_EQ(0, ax_position_after_from_dom.ChildIndex()); + EXPECT_EQ(1, ax_position_after_from_dom.ChildIndex()); EXPECT_EQ(ax_visible, ax_position_after_from_dom.ChildAfterTreePosition()); } @@ -1622,5 +1626,33 @@ TEST_F(AccessibilityTest, DISABLED_PositionInVirtualAOMNode) { EXPECT_EQ(ax_after, ax_position_after_from_dom.ChildAfterTreePosition()); } +TEST_F(AccessibilityTest, PositionInInvalidMapLayout) { + SetBodyInnerHTML(kMap); + + Node* br = GetElementById("br"); + ASSERT_NE(nullptr, br); + Node* map = GetElementById("map"); + ASSERT_NE(nullptr, map); + + // Create an invalid layout by appending a child to the <br> + br->appendChild(map); + GetDocument().UpdateStyleAndLayoutTree(); + + const AXObject* ax_map = GetAXObjectByElementId("map"); + ASSERT_NE(nullptr, ax_map); + ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_map->RoleValue()); + + const auto ax_position_before = + AXPosition::CreatePositionBeforeObject(*ax_map); + const auto position_before = ax_position_before.ToPositionWithAffinity(); + EXPECT_EQ(nullptr, position_before.AnchorNode()); + EXPECT_EQ(0, position_before.GetPosition().OffsetInContainerNode()); + + const auto ax_position_after = AXPosition::CreatePositionAfterObject(*ax_map); + const auto position_after = ax_position_after.ToPositionWithAffinity(); + EXPECT_EQ(nullptr, position_after.AnchorNode()); + EXPECT_EQ(0, position_after.GetPosition().OffsetInContainerNode()); +} + } // namespace test } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc index 02eae002ace..2787cb858cd 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc @@ -5,17 +5,34 @@ #include "third_party/blink/renderer/modules/accessibility/ax_relation_cache.h" #include "base/memory/ptr_util.h" +#include "third_party/blink/renderer/core/dom/element_traversal.h" #include "third_party/blink/renderer/core/html/forms/html_label_element.h" namespace blink { -using namespace html_names; - AXRelationCache::AXRelationCache(AXObjectCacheImpl* object_cache) : object_cache_(object_cache) {} AXRelationCache::~AXRelationCache() = default; +void AXRelationCache::Init() { + // Init the relation cache with elements already in the document. + Document& document = object_cache_->GetDocument(); + for (Element& element : + ElementTraversal::DescendantsOf(*document.documentElement())) { + const auto& id = element.FastGetAttribute(html_names::kForAttr); + if (!id.IsEmpty()) + all_previously_seen_label_target_ids_.insert(id); + + if (element.FastHasAttribute(html_names::kAriaOwnsAttr)) { + if (AXObject* obj = object_cache_->GetOrCreate(&element)) { + obj->ClearChildren(); + obj->AddChildren(); + } + } + } +} + bool AXRelationCache::IsAriaOwned(const AXObject* child) const { return aria_owned_child_to_owner_mapping_.Contains(child->AXObjectID()); } @@ -270,7 +287,8 @@ void AXRelationCache::TextChanged(AXObject* object) { } void AXRelationCache::LabelChanged(Node* node) { - const auto& id = To<HTMLElement>(node)->FastGetAttribute(kForAttr); + const auto& id = + To<HTMLElement>(node)->FastGetAttribute(html_names::kForAttr); if (!id.IsEmpty()) { all_previously_seen_label_target_ids_.insert(id); if (auto* control = To<HTMLLabelElement>(node)->control()) diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h index a96097fd477..2dec5cfb6d0 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h @@ -22,6 +22,9 @@ class AXRelationCache { explicit AXRelationCache(AXObjectCacheImpl*); virtual ~AXRelationCache(); + // Scan the initial document. + void Init(); + // Returns true if the given object's position in the tree was due to // aria-owns. bool IsAriaOwned(const AXObject*) const; diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc index 7532b8ccc67..02efbea750f 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc @@ -156,6 +156,9 @@ AXSelection AXSelection::FromCurrentSelection( *ax_text_control, static_cast<int>(text_control.selectionEnd()), extent_affinity); + if (!ax_base.IsValid() || !ax_extent.IsValid()) + return {}; + AXSelection::Builder selection_builder; selection_builder.SetBase(ax_base).SetExtent(ax_extent); return selection_builder.Build(); @@ -214,6 +217,9 @@ AXSelection AXSelection::FromSelection( const auto ax_extent = AXPosition::FromPosition(dom_extent, extent_affinity, extent_adjustment); + if (!ax_base.IsValid() || !ax_extent.IsValid()) + return {}; + AXSelection::Builder selection_builder; selection_builder.SetBase(ax_base).SetExtent(ax_extent); return selection_builder.Build(); diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc index e9977f2c479..1091d5b0895 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection_test.cc @@ -302,7 +302,7 @@ TEST_F(AccessibilitySelectionTest, SetSelectionAcrossLineBreak) { const Node* paragraph = GetDocument().QuerySelector("p"); ASSERT_NE(nullptr, paragraph); - ASSERT_TRUE(IsHTMLParagraphElement(paragraph)); + ASSERT_TRUE(IsA<HTMLParagraphElement>(paragraph)); const Node* br = GetDocument().QuerySelector("br"); ASSERT_NE(nullptr, br); ASSERT_TRUE(IsA<HTMLBRElement>(br)); @@ -347,7 +347,7 @@ TEST_F(AccessibilitySelectionTest, SetSelectionAcrossLineBreakInEditableText) { const Node* paragraph = GetDocument().QuerySelector("p"); ASSERT_NE(nullptr, paragraph); - ASSERT_TRUE(IsHTMLParagraphElement(paragraph)); + ASSERT_TRUE(IsA<HTMLParagraphElement>(paragraph)); const Node* br = GetDocument().QuerySelector("br"); ASSERT_NE(nullptr, br); ASSERT_TRUE(IsA<HTMLBRElement>(br)); @@ -420,7 +420,7 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInDisplayNone) { ASSERT_NE(nullptr, ax_hidden1); ASSERT_EQ(ax::mojom::Role::kParagraph, ax_hidden1->RoleValue()); ASSERT_TRUE(ax_hidden1->AccessibilityIsIgnored()); - ASSERT_FALSE(ax_hidden1->AccessibilityIsIncludedInTree()); + ASSERT_TRUE(ax_hidden1->AccessibilityIsIncludedInTree()); const AXObject* ax_between = GetAXObjectByElementId("betweenHidden"); ASSERT_NE(nullptr, ax_between); ASSERT_EQ(ax::mojom::Role::kParagraph, ax_between->RoleValue()); @@ -428,7 +428,7 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInDisplayNone) { ASSERT_NE(nullptr, ax_hidden2); ASSERT_EQ(ax::mojom::Role::kParagraph, ax_hidden2->RoleValue()); ASSERT_TRUE(ax_hidden2->AccessibilityIsIgnored()); - ASSERT_FALSE(ax_hidden2->AccessibilityIsIncludedInTree()); + ASSERT_TRUE(ax_hidden2->AccessibilityIsIncludedInTree()); const AXObject* ax_after = GetAXObjectByElementId("afterHidden"); ASSERT_NE(nullptr, ax_after); ASSERT_EQ(ax::mojom::Role::kParagraph, ax_after->RoleValue()); @@ -444,27 +444,27 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInDisplayNone) { const auto ax_selection_extend = AXSelection::FromSelection( selection, AXSelectionBehavior::kExtendToValidDOMRange); - // The shrunk selection should encompass only the |AXObject| between the two - // aria-hidden elements and nothing else. This means that its anchor should be - // before and its focus after the |AXObject| in question. + // The "display: none" content is included in the AXTree as an ignored node, + // so shrunk selection should include those AXObjects. Note that the browser + // process will adjust the position to only encompass the |AXObject| between + // the two "display: none" elements, since they are ignored nodes. ASSERT_FALSE(ax_selection_shrink.Base().IsTextPosition()); - EXPECT_EQ(ax_main, ax_selection_shrink.Base().ContainerObject()); - EXPECT_EQ(ax_between->IndexInParent(), - ax_selection_shrink.Base().ChildIndex()); + EXPECT_EQ(ax_hidden1, ax_selection_shrink.Base().ContainerObject()); + EXPECT_EQ(0, ax_selection_shrink.Base().ChildIndex()); ASSERT_FALSE(ax_selection_shrink.Extent().IsTextPosition()); - EXPECT_EQ(ax_between, ax_selection_shrink.Extent().ContainerObject()); - EXPECT_EQ(1, ax_selection_shrink.Extent().ChildIndex()); + EXPECT_EQ(ax_hidden2, ax_selection_shrink.Extent().ContainerObject()); + EXPECT_EQ(0, ax_selection_shrink.Extent().ChildIndex()); - // The extended selection should start after the children of the paragraph - // before the first display:none element and end right before the paragraph - // after the last display:none element. + // The extended selection should start in the "display: none" content because + // they are included in the AXTree. The browser process will adjust ignored + // positions so that in this case it would only encompass the paragraph + // between the "display: none" nodes. ASSERT_FALSE(ax_selection_extend.Base().IsTextPosition()); - EXPECT_EQ(ax_before, ax_selection_extend.Base().ContainerObject()); - EXPECT_EQ(1, ax_selection_extend.Base().ChildIndex()); + EXPECT_EQ(ax_hidden1, ax_selection_extend.Base().ContainerObject()); + EXPECT_EQ(0, ax_selection_extend.Base().ChildIndex()); ASSERT_FALSE(ax_selection_extend.Extent().IsTextPosition()); - EXPECT_EQ(ax_main, ax_selection_extend.Extent().ContainerObject()); - EXPECT_EQ(ax_after->IndexInParent(), - ax_selection_extend.Extent().ChildIndex()); + EXPECT_EQ(ax_hidden2, ax_selection_extend.Extent().ContainerObject()); + EXPECT_EQ(0, ax_selection_extend.Extent().ChildIndex()); // Even though the two AX selections have different anchors and foci, the text // selected in the accessibility tree should not differ, because any @@ -476,8 +476,10 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInDisplayNone) { "++++<Main>\n" "++++++<Paragraph>\n" "++++++++<StaticText: Before display:none.>\n" + "++++++<Paragraph: Display:none 1.>\n" "^++++++<Paragraph>\n" "++++++++<StaticText: In between two display:none elements.>\n" + "++++++<Paragraph: Display:none 2.>\n" "|++++++<Paragraph>\n" "++++++++<StaticText: After display:none.>\n"); EXPECT_EQ(selection_text, GetSelectionText(ax_selection_shrink)); @@ -1692,6 +1694,33 @@ TEST_F(AccessibilitySelectionTest, SelectionWithEqualBaseAndExtent) { builder.SetBase(ax_position).SetExtent(ax_position).Build(); } +TEST_F(AccessibilitySelectionTest, InvalidSelectionOnAShadowRoot) { + GetPage().GetSettings().SetScriptEnabled(true); + SetBodyInnerHTML(R"HTML( + <div id="container"> + </div> + )HTML"); + Element* const script_element = + GetDocument().CreateRawElement(html_names::kScriptTag); + script_element->setTextContent(R"SCRIPT( + var container = document.getElementById("container"); + var shadow = container.attachShadow({mode: 'open'}); + var button = document.createElement("button"); + button.id = "button"; + shadow.appendChild(button); + )SCRIPT"); + GetDocument().body()->AppendChild(script_element); + UpdateAllLifecyclePhasesForTest(); + + Node* shadow_root = GetElementById("container")->GetShadowRoot(); + const Position base = Position::EditingPositionOf(shadow_root, 0); + const Position extent = Position::EditingPositionOf(shadow_root, 1); + + const auto selection = + SelectionInDOMTree::Builder().SetBaseAndExtent(base, extent).Build(); + EXPECT_FALSE(AXSelection::FromSelection(selection).IsValid()); +} + // // Declarative tests. // diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc index c15a9ed776b..a04a922d0c4 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc @@ -113,6 +113,10 @@ bool AXSlider::OnNativeSetValueAction(const String& value) { // Fire change event manually, as LayoutSlider::setValueForPosition does. input->DispatchFormControlChangeEvent(); + + // Ensure the AX node is updated. + AXObjectCache().MarkAXObjectDirty(this, false); + return true; } diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc index 52071bca0ec..0999dae6fe0 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc @@ -7,8 +7,6 @@ namespace blink { -using namespace html_names; - class BoolAttributeSetter : public AXSparseAttributeSetter { public: BoolAttributeSetter(AXBoolAttribute attribute) : attribute_(attribute) {} @@ -145,45 +143,47 @@ AXSparseAttributeSetterMap& GetSparseAttributeSetterMap() { ax_sparse_attribute_setter_map, ()); if (ax_sparse_attribute_setter_map.IsEmpty()) { ax_sparse_attribute_setter_map.Set( - kAriaActivedescendantAttr, + html_names::kAriaActivedescendantAttr, new ObjectAttributeSetter(AXObjectAttribute::kAriaActiveDescendant)); ax_sparse_attribute_setter_map.Set( - kAriaControlsAttr, new ObjectVectorAttributeSetter( - AXObjectVectorAttribute::kAriaControls)); + html_names::kAriaControlsAttr, + new ObjectVectorAttributeSetter( + AXObjectVectorAttribute::kAriaControls)); ax_sparse_attribute_setter_map.Set( - kAriaFlowtoAttr, + html_names::kAriaFlowtoAttr, new ObjectVectorAttributeSetter(AXObjectVectorAttribute::kAriaFlowTo)); ax_sparse_attribute_setter_map.Set( - kAriaDetailsAttr, + html_names::kAriaDetailsAttr, new ObjectAttributeSetter(AXObjectAttribute::kAriaDetails)); ax_sparse_attribute_setter_map.Set( - kAriaErrormessageAttr, + html_names::kAriaErrormessageAttr, new ObjectAttributeSetter(AXObjectAttribute::kAriaErrorMessage)); ax_sparse_attribute_setter_map.Set( - kAriaKeyshortcutsAttr, + html_names::kAriaKeyshortcutsAttr, new StringAttributeSetter(AXStringAttribute::kAriaKeyShortcuts)); ax_sparse_attribute_setter_map.Set( - kAriaRoledescriptionAttr, + html_names::kAriaRoledescriptionAttr, new StringAttributeSetter(AXStringAttribute::kAriaRoleDescription)); ax_sparse_attribute_setter_map.Set( - kAriaBusyAttr, new BoolAttributeSetter(AXBoolAttribute::kAriaBusy)); + html_names::kAriaBusyAttr, + new BoolAttributeSetter(AXBoolAttribute::kAriaBusy)); ax_sparse_attribute_setter_map.Set( - kAriaColcountAttr, + html_names::kAriaColcountAttr, new IntAttributeSetter(AXIntAttribute::kAriaColumnCount)); ax_sparse_attribute_setter_map.Set( - kAriaColindexAttr, + html_names::kAriaColindexAttr, new UIntAttributeSetter(AXUIntAttribute::kAriaColumnIndex)); ax_sparse_attribute_setter_map.Set( - kAriaColspanAttr, + html_names::kAriaColspanAttr, new UIntAttributeSetter(AXUIntAttribute::kAriaColumnSpan)); ax_sparse_attribute_setter_map.Set( - kAriaRowcountAttr, + html_names::kAriaRowcountAttr, new IntAttributeSetter(AXIntAttribute::kAriaRowCount)); ax_sparse_attribute_setter_map.Set( - kAriaRowindexAttr, + html_names::kAriaRowindexAttr, new UIntAttributeSetter(AXUIntAttribute::kAriaRowIndex)); ax_sparse_attribute_setter_map.Set( - kAriaRowspanAttr, + html_names::kAriaRowspanAttr, new UIntAttributeSetter(AXUIntAttribute::kAriaRowSpan)); } return ax_sparse_attribute_setter_map; diff --git a/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc b/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc index b825bd2b6e1..eeff1f668b8 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.cc @@ -11,6 +11,7 @@ #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/dom/node_list.h" +#include "third_party/blink/renderer/core/dom/text.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/inspector/identifiers_factory.h" @@ -34,8 +35,7 @@ using protocol::Accessibility::AXRelatedNode; using protocol::Accessibility::AXValue; using protocol::Maybe; using protocol::Response; - -using namespace html_names; +namespace AXPropertyNameEnum = protocol::Accessibility::AXPropertyNameEnum; namespace { @@ -212,7 +212,7 @@ bool RoleAllowsSort(ax::mojom::Role role) { void FillWidgetProperties(AXObject& ax_object, protocol::Array<AXProperty>& properties) { ax::mojom::Role role = ax_object.RoleValue(); - String autocomplete = ax_object.AriaAutoComplete(); + String autocomplete = ax_object.AutoComplete(); if (!autocomplete.IsEmpty()) properties.emplace_back( CreateProperty(AXPropertyNameEnum::Autocomplete, @@ -450,13 +450,14 @@ class SparseAttributeAXPropertyAdapter HeapVector<Member<AXObject>>& objects) override { switch (attribute) { case AXObjectVectorAttribute::kAriaControls: - properties_.emplace_back( - CreateRelatedNodeListProperty(AXPropertyNameEnum::Controls, objects, - kAriaControlsAttr, *ax_object_)); + properties_.emplace_back(CreateRelatedNodeListProperty( + AXPropertyNameEnum::Controls, objects, + html_names::kAriaControlsAttr, *ax_object_)); break; case AXObjectVectorAttribute::kAriaFlowTo: properties_.emplace_back(CreateRelatedNodeListProperty( - AXPropertyNameEnum::Flowto, objects, kAriaFlowtoAttr, *ax_object_)); + AXPropertyNameEnum::Flowto, objects, html_names::kAriaFlowtoAttr, + *ax_object_)); break; } } @@ -467,16 +468,17 @@ void FillRelationships(AXObject& ax_object, AXObject::AXObjectVector results; ax_object.AriaDescribedbyElements(results); if (!results.IsEmpty()) { - properties.emplace_back( - CreateRelatedNodeListProperty(AXPropertyNameEnum::Describedby, results, - kAriaDescribedbyAttr, ax_object)); + properties.emplace_back(CreateRelatedNodeListProperty( + AXPropertyNameEnum::Describedby, results, + html_names::kAriaDescribedbyAttr, ax_object)); } results.clear(); ax_object.AriaOwnsElements(results); if (!results.IsEmpty()) { - properties.emplace_back(CreateRelatedNodeListProperty( - AXPropertyNameEnum::Owns, results, kAriaOwnsAttr, ax_object)); + properties.emplace_back( + CreateRelatedNodeListProperty(AXPropertyNameEnum::Owns, results, + html_names::kAriaOwnsAttr, ax_object)); } results.clear(); } @@ -566,9 +568,18 @@ void InspectorAccessibilityAgent::AddAncestors( std::unique_ptr<protocol::Array<AXNode>>& nodes, AXObjectCacheImpl& cache) const { AXObject* ancestor = &first_ancestor; + AXObject* child = inspected_ax_object; while (ancestor) { - nodes->emplace_back(BuildProtocolAXObject(*ancestor, inspected_ax_object, - true, nodes, cache)); + std::unique_ptr<AXNode> parent_node_object = BuildProtocolAXObject( + *ancestor, inspected_ax_object, true, nodes, cache); + auto child_ids = std::make_unique<protocol::Array<AXNodeId>>(); + if (child) + child_ids->emplace_back(String::Number(child->AXObjectID())); + else + child_ids->emplace_back(String::Number(kIDForInspectedNodeWithNoAXNode)); + parent_node_object->setChildIds(std::move(child_ids)); + nodes->emplace_back(std::move(parent_node_object)); + child = ancestor; ancestor = ancestor->ParentObjectUnignored(); } } @@ -646,16 +657,7 @@ void InspectorAccessibilityAgent::PopulateDOMNodeAncestors( return; // Populate parent and ancestors. - std::unique_ptr<AXNode> parent_node_object = - BuildProtocolAXObject(*parent_ax_object, nullptr, true, nodes, cache); - auto child_ids = std::make_unique<protocol::Array<AXNodeId>>(); - child_ids->emplace_back(String::Number(kIDForInspectedNodeWithNoAXNode)); - parent_node_object->setChildIds(std::move(child_ids)); - nodes->emplace_back(std::move(parent_node_object)); - - AXObject* grandparent_ax_object = parent_ax_object->ParentObjectUnignored(); - if (grandparent_ax_object) - AddAncestors(*grandparent_ax_object, nullptr, nodes, cache); + AddAncestors(*parent_ax_object, nullptr, nodes, cache); } std::unique_ptr<AXNode> InspectorAccessibilityAgent::BuildProtocolAXObject( @@ -717,6 +719,8 @@ Response InspectorAccessibilityAgent::getFullAXTree( Document* document = inspected_frames_->Root()->GetDocument(); if (!document) return Response::Error("No document."); + if (document->View()->NeedsLayout() || document->NeedsLayoutTreeUpdate()) + document->UpdateStyleAndLayout(); *nodes = std::make_unique<protocol::Array<protocol::Accessibility::AXNode>>(); AXContext ax_context(*document); AXObjectCacheImpl& cache = ToAXObjectCacheImpl(ax_context.GetAXObjectCache()); diff --git a/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc b/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc index 3852bf325dd..c379a8f00ad 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.cc @@ -11,8 +11,7 @@ namespace blink { -using namespace html_names; -using namespace protocol::Accessibility; +using protocol::Accessibility::AXRelatedNode; std::unique_ptr<AXProperty> CreateProperty(const String& name, std::unique_ptr<AXValue> value) { @@ -167,43 +166,46 @@ std::unique_ptr<AXValue> CreateRelatedNodeListValue( } String ValueSourceType(ax::mojom::NameFrom name_from) { + namespace SourceType = protocol::Accessibility::AXValueSourceTypeEnum; + switch (name_from) { case ax::mojom::NameFrom::kAttribute: case ax::mojom::NameFrom::kAttributeExplicitlyEmpty: case ax::mojom::NameFrom::kTitle: case ax::mojom::NameFrom::kValue: - return AXValueSourceTypeEnum::Attribute; + return SourceType::Attribute; case ax::mojom::NameFrom::kContents: - return AXValueSourceTypeEnum::Contents; + return SourceType::Contents; case ax::mojom::NameFrom::kPlaceholder: - return AXValueSourceTypeEnum::Placeholder; + return SourceType::Placeholder; case ax::mojom::NameFrom::kCaption: case ax::mojom::NameFrom::kRelatedElement: - return AXValueSourceTypeEnum::RelatedElement; + return SourceType::RelatedElement; default: - return AXValueSourceTypeEnum::Implicit; // TODO(aboxhall): what to do - // here? + return SourceType::Implicit; // TODO(aboxhall): what to do here? } } String NativeSourceType(AXTextFromNativeHTML native_source) { + namespace SourceType = protocol::Accessibility::AXValueNativeSourceTypeEnum; + switch (native_source) { case kAXTextFromNativeHTMLFigcaption: - return AXValueNativeSourceTypeEnum::Figcaption; + return SourceType::Figcaption; case kAXTextFromNativeHTMLLabel: - return AXValueNativeSourceTypeEnum::Label; + return SourceType::Label; case kAXTextFromNativeHTMLLabelFor: - return AXValueNativeSourceTypeEnum::Labelfor; + return SourceType::Labelfor; case kAXTextFromNativeHTMLLabelWrapped: - return AXValueNativeSourceTypeEnum::Labelwrapped; + return SourceType::Labelwrapped; case kAXTextFromNativeHTMLTableCaption: - return AXValueNativeSourceTypeEnum::Tablecaption; + return SourceType::Tablecaption; case kAXTextFromNativeHTMLLegend: - return AXValueNativeSourceTypeEnum::Legend; + return SourceType::Legend; case kAXTextFromNativeHTMLTitleElement: - return AXValueNativeSourceTypeEnum::Title; + return SourceType::Title; default: - return AXValueNativeSourceTypeEnum::Other; + return SourceType::Other; } } @@ -212,8 +214,8 @@ std::unique_ptr<AXValueSource> CreateValueSource(NameSource& name_source) { std::unique_ptr<AXValueSource> value_source = AXValueSource::create().setType(type).build(); if (!name_source.related_objects.IsEmpty()) { - if (name_source.attribute == kAriaLabelledbyAttr || - name_source.attribute == kAriaLabeledbyAttr) { + if (name_source.attribute == html_names::kAriaLabelledbyAttr || + name_source.attribute == html_names::kAriaLabeledbyAttr) { std::unique_ptr<AXValue> attribute_value = CreateRelatedNodeListValue( name_source.related_objects, AXValueTypeEnum::IdrefList); if (!name_source.attribute_value.IsNull()) diff --git a/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.h b/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.h index 779815e6ae7..d0b5b50d910 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/inspector_type_builder_helper.h @@ -12,7 +12,10 @@ namespace blink { -using namespace protocol::Accessibility; +using protocol::Accessibility::AXProperty; +using protocol::Accessibility::AXValue; +using protocol::Accessibility::AXValueSource; +namespace AXValueTypeEnum = protocol::Accessibility::AXValueTypeEnum; std::unique_ptr<AXProperty> CreateProperty(const String& name, std::unique_ptr<AXValue>); diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h index 7461c5bd85f..0608c4edd9e 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h @@ -44,12 +44,13 @@ class AccessibilityTest : public RenderingTest { std::string PrintAXTree() const; + protected: + std::unique_ptr<AXContext> ax_context_; + private: std::ostringstream& PrintAXTreeHelper(std::ostringstream&, const AXObject* root, size_t level) const; - - std::unique_ptr<AXContext> ax_context_; }; } // namespace test diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc index c6929f56332..f4602a70570 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.cc @@ -263,8 +263,8 @@ Animator* AnimationWorkletGlobalScope::CreateInstance( v8::Local<v8::Value> v8_state = serialized_state ? serialized_state->Deserialize(isolate) : v8::Undefined(isolate).As<v8::Value>(); - ScriptValue options_value(script_state, v8_options); - ScriptValue state_value(script_state, v8_state); + ScriptValue options_value(isolate, v8_options); + ScriptValue state_value(isolate, v8_state); ScriptValue instance; if (!definition->ConstructorFunction() diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h index 74770067631..31fe8c68fcb 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.h @@ -26,7 +26,7 @@ class WorkletGlobalScope; // This is constructed on the main thread but it is used in the worklet backing // thread. class MODULES_EXPORT AnimationWorkletProxyClient - : public GarbageCollectedFinalized<AnimationWorkletProxyClient>, + : public GarbageCollected<AnimationWorkletProxyClient>, public Supplement<WorkerClients>, public AnimationWorkletMutator { USING_GARBAGE_COLLECTED_MIXIN(AnimationWorkletProxyClient); diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animator.h b/chromium/third_party/blink/renderer/modules/animationworklet/animator.h index 67e6a0fb903..bfafe9739cb 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animator.h +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator.h @@ -23,8 +23,7 @@ class AnimatorDefinition; // Represents an animator instance. It owns the underlying |v8::Object| for the // instance and knows how to invoke the |animate| function on it. // See also |AnimationWorkletGlobalScope::CreateInstance|. -class Animator final : public GarbageCollectedFinalized<Animator>, - public NameClient { +class Animator final : public GarbageCollected<Animator>, public NameClient { public: Animator(v8::Isolate*, AnimatorDefinition*, diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h b/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h index 85658f26e11..09bf9c6d352 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h @@ -21,7 +21,7 @@ class V8StateCallback; // |AnimationWorkletGlobalScope::registerAnimator| to validate the provided // Javascript class before completing the registration. class MODULES_EXPORT AnimatorDefinition final - : public GarbageCollectedFinalized<AnimatorDefinition>, + : public GarbageCollected<AnimatorDefinition>, public NameClient { public: explicit AnimatorDefinition(V8AnimatorConstructor* constructor, diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc index b0e5de5a844..2e0dd8354a9 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc +++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc @@ -571,6 +571,13 @@ bool WorkletAnimation::CanStartOnCompositor() { if (!CheckElementComposited(target)) return false; + // If the scroll source is not composited, fall back to main thread. + if (timeline_->IsScrollTimeline() && + !CheckElementComposited( + *ToScrollTimeline(timeline_)->ResolvedScrollSource())) { + return false; + } + return true; } diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc index fb79cdf8edc..1eeba64de51 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc +++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.cc @@ -31,8 +31,14 @@ ComputedEffectTiming* WorkletAnimationEffect::getComputedTiming() const { last_update_time_ = local_time; if (needs_update) { + // The playback rate is needed to calculate whether the effect is current or + // not (https://drafts.csswg.org/web-animations-1/#current). Since we only + // use this information to create a ComputedEffectTiming, which does not + // include that information, we do not need to supply one. + base::Optional<double> playback_rate = base::nullopt; calculated_ = specified_timing_.CalculateTimings( - local_time, Timing::AnimationDirection::kForwards, false); + local_time, Timing::AnimationDirection::kForwards, false, + playback_rate); } return specified_timing_.getComputedTiming(calculated_, diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc index 1c6f5178629..f4870f4290e 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc +++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation_test.cc @@ -89,7 +89,8 @@ class WorkletAnimationTest : public RenderingTest { void SetUp() override { RenderingTest::SetUp(); element_ = GetDocument().CreateElementForBinding("test"); - // Animator has to be registored before constructing WorkletAnimation. For + GetDocument().body()->appendChild(element_); + // Animator has to be registered before constructing WorkletAnimation. For // unit test this is faked by adding the animator name to // WorkletAnimationController. animator_name_ = "WorkletAnimationTest"; diff --git a/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.h b/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.h index 6fcf88be3db..f974bc49147 100644 --- a/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.h +++ b/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.h @@ -18,7 +18,7 @@ class HTMLMediaElement; class ScriptState; class MODULES_EXPORT HTMLMediaElementAudioOutputDevice final - : public GarbageCollectedFinalized<HTMLMediaElementAudioOutputDevice>, + : public GarbageCollected<HTMLMediaElementAudioOutputDevice>, public Supplement<HTMLMediaElement> { USING_GARBAGE_COLLECTED_MIXIN(HTMLMediaElementAudioOutputDevice); diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h index f88536db6be..dd17dd1a725 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h @@ -25,7 +25,7 @@ class BackgroundFetchRegistration; // connection to the BackgroundFetchService. It's keyed on an active Service // Worker Registration. class BackgroundFetchBridge final - : public GarbageCollectedFinalized<BackgroundFetchBridge>, + : public GarbageCollected<BackgroundFetchBridge>, public Supplement<ServiceWorkerRegistration> { USING_GARBAGE_COLLECTED_MIXIN(BackgroundFetchBridge); diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.h index 5f50663ec8d..d41ace1757b 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.h +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_EVENT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_EVENT_H_ -#include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom-blink.h" +#include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/service_worker/extendable_event.h" #include "third_party/blink/renderer/platform/heap/handle.h" diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h index c6ee8d864d4..3b425340c30 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h @@ -14,7 +14,7 @@ namespace blink { class BackgroundFetchBridge; class MODULES_EXPORT BackgroundFetchIconLoader final - : public GarbageCollectedFinalized<BackgroundFetchIconLoader> { + : public GarbageCollected<BackgroundFetchIconLoader> { public: // The bitmap may be empty if the request failed or the image data could not // be decoded. The int64_t returned is the scale of the ideal to chosen icon, diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc index 092f5a3bdb3..7a1464a97b8 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc @@ -8,6 +8,7 @@ #include "base/memory/scoped_refptr.h" #include "base/metrics/histogram_macros.h" +#include "services/network/public/mojom/ip_address_space.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/request_or_usv_string_or_request_or_usv_string_sequence.h" diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc index 01592306e7f..49cd93c6a56 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc @@ -184,7 +184,7 @@ TEST_F(BackgroundFetchManagerTest, BlobsExtracted) { RequestInit* request_init = RequestInit::Create(); request_init->setMethod("POST"); request_init->setBody(blink::ScriptValue( - scope.GetScriptState(), ToV8(body_text, scope.GetScriptState()))); + scope.GetIsolate(), ToV8(body_text, scope.GetScriptState()))); Request* image_request = Request::Create(scope.GetScriptState(), image_url.GetString(), request_init, scope.GetExceptionState()); diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc index 63e740a0573..08cb59a00ea 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc @@ -71,8 +71,11 @@ void BackgroundFetchRegistration::Initialize( registration_ = registration; registration_service_.Bind(std::move(registration_service)); - auto task_runner = - GetExecutionContext()->GetTaskRunner(TaskType::kBackgroundFetch); + ExecutionContext* context = GetExecutionContext(); + if (!context || context->IsContextDestroyed()) + return; + + auto task_runner = context->GetTaskRunner(TaskType::kBackgroundFetch); registration_service_->AddRegistrationObserver( observer_receiver_.BindNewPipeAndPassRemote(task_runner)); } diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h index 7e5aba36679..8a491c15e9e 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_UPDATE_UI_EVENT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BACKGROUND_FETCH_BACKGROUND_FETCH_UPDATE_UI_EVENT_H_ -#include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom-blink.h" +#include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/modules/background_fetch/background_fetch_event.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h" diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h index 6e6d12f938a..abd4ce489da 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h +++ b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h @@ -16,8 +16,7 @@ namespace blink { class BackgroundFetchManager; class ServiceWorkerRegistrationBackgroundFetch final - : public GarbageCollectedFinalized< - ServiceWorkerRegistrationBackgroundFetch>, + : public GarbageCollected<ServiceWorkerRegistrationBackgroundFetch>, public Supplement<ServiceWorkerRegistration> { USING_GARBAGE_COLLECTED_MIXIN(ServiceWorkerRegistrationBackgroundFetch); diff --git a/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h b/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h index 6c3c435eecb..ba2920e3d98 100644 --- a/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h +++ b/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h @@ -17,7 +17,7 @@ class SyncManager; class ServiceWorkerRegistration; class ServiceWorkerRegistrationSync final - : public GarbageCollectedFinalized<ServiceWorkerRegistrationSync>, + : public GarbageCollected<ServiceWorkerRegistrationSync>, public Supplement<ServiceWorkerRegistration> { USING_GARBAGE_COLLECTED_MIXIN(ServiceWorkerRegistrationSync); diff --git a/chromium/third_party/blink/renderer/modules/badging/BUILD.gn b/chromium/third_party/blink/renderer/modules/badging/BUILD.gn index 8af60813b49..0e248dc70ea 100644 --- a/chromium/third_party/blink/renderer/modules/badging/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/badging/BUILD.gn @@ -6,7 +6,7 @@ import("//third_party/blink/renderer/modules/modules.gni") blink_modules_sources("badging") { sources = [ - "badge.cc", - "badge.h", + "navigator_badge.cc", + "navigator_badge.h", ] } diff --git a/chromium/third_party/blink/renderer/modules/badging/badge.cc b/chromium/third_party/blink/renderer/modules/badging/badge.cc deleted file mode 100644 index 8471c032e7c..00000000000 --- a/chromium/third_party/blink/renderer/modules/badging/badge.cc +++ /dev/null @@ -1,98 +0,0 @@ -// 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 "third_party/blink/renderer/modules/badging/badge.h" - -#include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/modules/badging/badge_options.h" -#include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/bindings/script_state.h" - -namespace blink { - -const char Badge::kSupplementName[] = "Badge"; - -Badge::~Badge() = default; - -// static -Badge* Badge::From(ExecutionContext* context) { - Badge* supplement = Supplement<ExecutionContext>::From<Badge>(context); - if (!supplement) { - supplement = MakeGarbageCollected<Badge>(context); - ProvideTo(*context, supplement); - } - return supplement; -} - -// static -void Badge::set(ScriptState* script_state, ExceptionState& exception_state) { - Badge::set(script_state, BadgeOptions::Create(), exception_state); -} - -// static -void Badge::set(ScriptState* script_state, - const BadgeOptions* options, - ExceptionState& exception_state) { - BadgeFromState(script_state) - ->SetBadge(options->scope(), mojom::blink::BadgeValue::NewFlag(0)); -} - -// static -void Badge::set(ScriptState* script_state, - uint64_t content, - ExceptionState& exception_state) { - Badge::set(script_state, content, BadgeOptions::Create(), exception_state); -} - -// static -void Badge::set(ScriptState* script_state, - uint64_t content, - const BadgeOptions* options, - ExceptionState& exception_state) { - if (content == 0) { - Badge::clear(script_state, options); - } else { - BadgeFromState(script_state) - ->SetBadge(options->scope(), - mojom::blink::BadgeValue::NewNumber(content)); - } -} - -// static -void Badge::clear(ScriptState* script_state, const BadgeOptions* options) { - BadgeFromState(script_state)->ClearBadge(options->scope()); -} - -void Badge::SetBadge(WTF::String scope, mojom::blink::BadgeValuePtr value) { - // Resolve |scope| against the URL of the current document/worker. - KURL scope_url = KURL(execution_context_->Url(), scope); - badge_service_->SetBadge(scope_url, std::move(value)); -} - -void Badge::ClearBadge(WTF::String scope) { - // Resolve |scope| against the URL of the current document/worker. - badge_service_->ClearBadge(KURL(execution_context_->Url(), scope)); -} - -void Badge::Trace(blink::Visitor* visitor) { - Supplement<ExecutionContext>::Trace(visitor); - ScriptWrappable::Trace(visitor); - - visitor->Trace(execution_context_); -} - -Badge::Badge(ExecutionContext* context) : execution_context_(context) { - context->GetInterfaceProvider()->GetInterface( - badge_service_.BindNewPipeAndPassReceiver()); - DCHECK(badge_service_); -} - -// static -Badge* Badge::BadgeFromState(ScriptState* script_state) { - return Badge::From(ExecutionContext::From(script_state)); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/badging/badge.h b/chromium/third_party/blink/renderer/modules/badging/badge.h deleted file mode 100644 index 02658859f20..00000000000 --- a/chromium/third_party/blink/renderer/modules/badging/badge.h +++ /dev/null @@ -1,58 +0,0 @@ -// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_ - -#include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/mojom/badging/badging.mojom-blink.h" -#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" -#include "third_party/blink/renderer/platform/supplementable.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -namespace blink { - -class BadgeOptions; -class ExceptionState; -class ExecutionContext; -class ScriptState; - -class Badge final : public ScriptWrappable, - public Supplement<ExecutionContext> { - DEFINE_WRAPPERTYPEINFO(); - USING_GARBAGE_COLLECTED_MIXIN(Badge); - - public: - static const char kSupplementName[]; - - static Badge* From(ExecutionContext*); - - explicit Badge(ExecutionContext*); - ~Badge() override; - - // Badge IDL interface. - static void set(ScriptState*, const BadgeOptions*, ExceptionState&); - static void set(ScriptState*, - uint64_t content, - const BadgeOptions*, - ExceptionState&); - static void set(ScriptState*, ExceptionState&); - static void set(ScriptState*, uint64_t content, ExceptionState&); - static void clear(ScriptState*, const BadgeOptions*); - - void SetBadge(WTF::String scope, mojom::blink::BadgeValuePtr value); - void ClearBadge(WTF::String scope); - - void Trace(blink::Visitor*) override; - - private: - static Badge* BadgeFromState(ScriptState* script_state); - - mojo::Remote<blink::mojom::blink::BadgeService> badge_service_; - Member<ExecutionContext> execution_context_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_ diff --git a/chromium/third_party/blink/renderer/modules/badging/badge_options.idl b/chromium/third_party/blink/renderer/modules/badging/badge_options.idl deleted file mode 100644 index 279519c2199..00000000000 --- a/chromium/third_party/blink/renderer/modules/badging/badge_options.idl +++ /dev/null @@ -1,12 +0,0 @@ -// 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. - -// The options used to decide how to apply a badge. -// See the explainer https://github.com/WICG/badging/blob/master/explainer.md -dictionary BadgeOptions { - // The scope of the badge. This is resolved against the URL of the current - // page. - // https://github.com/WICG/badging/blob/master/explainer.md#badge-scope - DOMString scope = "/"; -};
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/modules/badging/experimental_badge.idl b/chromium/third_party/blink/renderer/modules/badging/experimental_badge.idl deleted file mode 100644 index 3e84590f40e..00000000000 --- a/chromium/third_party/blink/renderer/modules/badging/experimental_badge.idl +++ /dev/null @@ -1,17 +0,0 @@ -// 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. - -// TODO(estevenson): Add link to spec once complete. -// https://github.com/WICG/badging/blob/master/explainer.md - -[ - RuntimeEnabled=Badging, - // TODO(estevenson): Expose the Badge interface to Worker. - Exposed=Window, - ImplementedAs=Badge -] interface ExperimentalBadge { - [CallWith=ScriptState, RaisesException, MeasureAs=BadgeSet] - static void set(optional [EnforceRange] unsigned long long contents, optional BadgeOptions options); - [CallWith=ScriptState, MeasureAs=BadgeClear] static void clear(optional BadgeOptions options); -}; diff --git a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc new file mode 100644 index 00000000000..a6f540dcc9b --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc @@ -0,0 +1,65 @@ +// 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 "third_party/blink/renderer/modules/badging/navigator_badge.h" + +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" + +namespace blink { + +const char NavigatorBadge::kSupplementName[] = "NavigatorBadge"; + +// static +NavigatorBadge& NavigatorBadge::From(ScriptState* script_state) { + ExecutionContext* context = ExecutionContext::From(script_state); + NavigatorBadge* supplement = + Supplement<ExecutionContext>::From<NavigatorBadge>(context); + if (!supplement) { + supplement = MakeGarbageCollected<NavigatorBadge>(context); + ProvideTo(*context, supplement); + } + return *supplement; +} + +NavigatorBadge::NavigatorBadge(ExecutionContext* context) { + context->GetBrowserInterfaceBroker().GetInterface( + badge_service_.BindNewPipeAndPassReceiver()); + DCHECK(badge_service_); +} + +// static +ScriptPromise NavigatorBadge::setAppBadge(ScriptState* script_state, + Navigator& /*navigator*/) { + From(script_state) + .badge_service_->SetBadge(mojom::blink::BadgeValue::NewFlag(0)); + return ScriptPromise::CastUndefined(script_state); +} + +// static +ScriptPromise NavigatorBadge::setAppBadge(ScriptState* script_state, + Navigator& navigator, + uint64_t content) { + if (content == 0) + return NavigatorBadge::clearAppBadge(script_state, navigator); + + From(script_state) + .badge_service_->SetBadge(mojom::blink::BadgeValue::NewNumber(content)); + return ScriptPromise::CastUndefined(script_state); +} + +// static +ScriptPromise NavigatorBadge::clearAppBadge(ScriptState* script_state, + Navigator& /*navigator*/) { + From(script_state).badge_service_->ClearBadge(); + return ScriptPromise::CastUndefined(script_state); +} + +void NavigatorBadge::Trace(blink::Visitor* visitor) { + Supplement<ExecutionContext>::Trace(visitor); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h new file mode 100644 index 00000000000..e806dce5df3 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h @@ -0,0 +1,40 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_NAVIGATOR_BADGE_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_NAVIGATOR_BADGE_H_ + +#include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/mojom/badging/badging.mojom-blink.h" +#include "third_party/blink/renderer/core/frame/navigator.h" +#include "third_party/blink/renderer/platform/supplementable.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { +class ScriptPromise; + +class NavigatorBadge final : public GarbageCollected<NavigatorBadge>, + public Supplement<ExecutionContext> { + USING_GARBAGE_COLLECTED_MIXIN(NavigatorBadge); + + public: + static const char kSupplementName[]; + + static NavigatorBadge& From(ScriptState*); + explicit NavigatorBadge(ExecutionContext*); + + // Badge IDL interface. + static ScriptPromise setAppBadge(ScriptState*, Navigator&); + static ScriptPromise setAppBadge(ScriptState*, Navigator&, uint64_t content); + static ScriptPromise clearAppBadge(ScriptState*, Navigator&); + + void Trace(blink::Visitor*) override; + + private: + mojo::Remote<blink::mojom::blink::BadgeService> badge_service_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_NAVIGATOR_BADGE_H_ diff --git a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.idl b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.idl new file mode 100644 index 00000000000..a115a8e06a0 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.idl @@ -0,0 +1,16 @@ +// 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://wicg.github.io/badging/ +[ + SecureContext, + RuntimeEnabled=Badging, + ImplementedAs=NavigatorBadge +] partial interface Navigator { + [CallWith=ScriptState, MeasureAs=BadgeSet, ImplementedAs=setAppBadge] + Promise<void> setExperimentalAppBadge(optional [EnforceRange] unsigned long long contents); + + [CallWith=ScriptState, MeasureAs=BadgeClear, ImplementedAs=clearAppBadge] + Promise<void> clearExperimentalAppBadge(); +};
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc index 9f0dc995b00..83c547016a7 100644 --- a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc +++ b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc @@ -47,8 +47,9 @@ void BatteryDispatcher::UpdateBatteryStatus( void BatteryDispatcher::StartListening(LocalFrame* frame) { DCHECK(!monitor_.is_bound()); // See https://bit.ly/2S0zRAS for task types. - Platform::Current()->GetInterfaceProvider()->GetInterface(mojo::MakeRequest( - &monitor_, frame->GetTaskRunner(TaskType::kMiscPlatformAPI))); + Platform::Current()->GetInterfaceProvider()->GetInterface( + monitor_.BindNewPipeAndPassReceiver( + frame->GetTaskRunner(TaskType::kMiscPlatformAPI))); QueryNextStatus(); } diff --git a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.h b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.h index 3d6a057f1de..20a75a80ccd 100644 --- a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.h +++ b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BATTERY_BATTERY_DISPATCHER_H_ #include "base/macros.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/device/public/mojom/battery_monitor.mojom-blink.h" #include "third_party/blink/renderer/core/frame/platform_event_dispatcher.h" #include "third_party/blink/renderer/modules/battery/battery_manager.h" @@ -15,7 +16,7 @@ namespace blink { class MODULES_EXPORT BatteryDispatcher final - : public GarbageCollectedFinalized<BatteryDispatcher>, + : public GarbageCollected<BatteryDispatcher>, public PlatformEventDispatcher { USING_GARBAGE_COLLECTED_MIXIN(BatteryDispatcher); @@ -37,7 +38,7 @@ class MODULES_EXPORT BatteryDispatcher final void StartListening(LocalFrame* frame) override; void StopListening() override; - device::mojom::blink::BatteryMonitorPtr monitor_; + mojo::Remote<device::mojom::blink::BatteryMonitor> monitor_; BatteryStatus battery_status_; bool has_latest_data_; diff --git a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h index 57ba79dcb88..45482512bbd 100644 --- a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h +++ b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h @@ -16,7 +16,7 @@ class ExceptionState; class KURL; class ArrayBufferViewOrBlobOrStringOrFormData; -class NavigatorBeacon final : public GarbageCollectedFinalized<NavigatorBeacon>, +class NavigatorBeacon final : public GarbageCollected<NavigatorBeacon>, public Supplement<Navigator> { USING_GARBAGE_COLLECTED_MIXIN(NavigatorBeacon); diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc index 5cdce3a8c4a..44fb0989676 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc @@ -6,7 +6,12 @@ #include <utility> -#include "services/service_manager/public/cpp/interface_provider.h" +#include "mojo/public/cpp/bindings/associated_receiver_set.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -149,7 +154,7 @@ ScriptPromise Bluetooth::getAvailability(ScriptState* script_state) { } CHECK(context->IsSecureContext()); - EnsureServiceConnection(); + EnsureServiceConnection(context); // Subsequent steps are handled in the browser process. auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); @@ -183,7 +188,12 @@ void Bluetooth::RequestDeviceCallback( ScriptPromise Bluetooth::requestDevice(ScriptState* script_state, const RequestDeviceOptions* options, ExceptionState& exception_state) { - ExecutionContext* context = ExecutionContext::From(script_state); + ExecutionContext* context = GetExecutionContext(); + if (!context) { + return ScriptPromise::Reject( + script_state, V8ThrowException::CreateTypeError( + script_state->GetIsolate(), kInactiveDocumentError)); + } // Remind developers when they are using Web Bluetooth on unsupported platforms. #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) && !defined(OS_MACOSX) && \ @@ -216,7 +226,7 @@ ScriptPromise Bluetooth::requestDevice(ScriptState* script_state, "Must be handling a user gesture to show a permission request.")); } - EnsureServiceConnection(); + EnsureServiceConnection(context); // In order to convert the arguments from service names and aliases to just // UUIDs, do the following substeps: @@ -278,7 +288,7 @@ static void ConvertRequestLEScanOptions( void Bluetooth::RequestScanningCallback( ScriptPromiseResolver* resolver, - mojo::BindingId id, + mojo::ReceiverId id, mojom::blink::RequestScanningStartResultPtr result) { if (!resolver->GetExecutionContext() || resolver->GetExecutionContext()->IsContextDestroyed()) { @@ -300,8 +310,12 @@ void Bluetooth::RequestScanningCallback( ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state, const BluetoothLEScanOptions* options, ExceptionState& exception_state) { - ExecutionContext* context = ExecutionContext::From(script_state); - DCHECK(context); + ExecutionContext* context = GetExecutionContext(); + if (!context) { + return ScriptPromise::Reject( + script_state, V8ThrowException::CreateTypeError( + script_state->GetIsolate(), kInactiveDocumentError)); + } // Remind developers when they are using Web Bluetooth on unsupported // platforms. @@ -332,7 +346,7 @@ ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state, "Must be handling a user gesture to show a permission request.")); } - EnsureServiceConnection(); + EnsureServiceConnection(context); auto scan_options = mojom::blink::WebBluetoothRequestLEScanOptions::New(); ConvertRequestLEScanOptions(options, scan_options, exception_state); @@ -347,11 +361,11 @@ ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state, auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); - mojom::blink::WebBluetoothScanClientAssociatedPtrInfo client; + mojo::PendingAssociatedRemote<mojom::blink::WebBluetoothScanClient> client; // See https://bit.ly/2S0zRAS for task types. - mojo::BindingId id = client_bindings_.AddBinding( - this, mojo::MakeRequest(&client), - context->GetTaskRunner(TaskType::kMiscPlatformAPI)); + mojo::ReceiverId id = + client_receivers_.Add(this, client.InitWithNewEndpointAndPassReceiver(), + context->GetTaskRunner(TaskType::kMiscPlatformAPI)); service_->RequestScanningStart( std::move(client), std::move(scan_options), @@ -399,15 +413,15 @@ void Bluetooth::ScanEvent(mojom::blink::WebBluetoothScanResultPtr result) { } void Bluetooth::PageVisibilityChanged() { - client_bindings_.CloseAllBindings(); + client_receivers_.Clear(); } -void Bluetooth::CancelScan(mojo::BindingId id) { - client_bindings_.RemoveBinding(id); +void Bluetooth::CancelScan(mojo::ReceiverId id) { + client_receivers_.Remove(id); } -bool Bluetooth::IsScanActive(mojo::BindingId id) const { - return client_bindings_.HasBinding(id); +bool Bluetooth::IsScanActive(mojo::ReceiverId id) const { + return client_receivers_.HasReceiver(id); } const WTF::AtomicString& Bluetooth::InterfaceName() const { @@ -419,7 +433,7 @@ ExecutionContext* Bluetooth::GetExecutionContext() const { } void Bluetooth::ContextDestroyed(ExecutionContext*) { - client_bindings_.CloseAllBindings(); + client_receivers_.Clear(); } void Bluetooth::Trace(blink::Visitor* visitor) { @@ -434,7 +448,7 @@ Bluetooth::Bluetooth(ExecutionContext* context) PageVisibilityObserver(To<Document>(context)->GetPage()) {} Bluetooth::~Bluetooth() { - DCHECK(client_bindings_.empty()); + DCHECK(client_receivers_.empty()); } BluetoothDevice* Bluetooth::GetBluetoothDeviceRepresentingDevice( @@ -451,15 +465,12 @@ BluetoothDevice* Bluetooth::GetBluetoothDeviceRepresentingDevice( return device; } -void Bluetooth::EnsureServiceConnection() { +void Bluetooth::EnsureServiceConnection(ExecutionContext* context) { if (!service_) { // See https://bit.ly/2S0zRAS for task types. - auto* context = GetExecutionContext(); - DCHECK(context); - auto task_runner = context->GetTaskRunner(TaskType::kMiscPlatformAPI); - context->GetInterfaceProvider()->GetInterface( - mojo::MakeRequest(&service_, task_runner)); + context->GetBrowserInterfaceBroker().GetInterface( + service_.BindNewPipeAndPassReceiver(task_runner)); } } diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h index ac568359bfb..2162844de66 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h @@ -5,8 +5,10 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_H_ -#include <memory> -#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h" +#include "mojo/public/cpp/bindings/associated_receiver_set.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/page/page_visibility_observer.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth_device.h" @@ -61,8 +63,8 @@ class Bluetooth final : public EventTargetWithInlineData, // PageVisibilityObserver void PageVisibilityChanged() override; - void CancelScan(mojo::BindingId); - bool IsScanActive(mojo::BindingId) const; + void CancelScan(mojo::ReceiverId); + bool IsScanActive(mojo::ReceiverId) const; private: BluetoothDevice* GetBluetoothDeviceRepresentingDevice( @@ -74,20 +76,20 @@ class Bluetooth final : public EventTargetWithInlineData, mojom::blink::WebBluetoothDevicePtr); void RequestScanningCallback(ScriptPromiseResolver*, - mojo::BindingId id, + mojo::ReceiverId id, mojom::blink::RequestScanningStartResultPtr); - void EnsureServiceConnection(); + void EnsureServiceConnection(ExecutionContext*); // Map of device ids to BluetoothDevice objects. // Ensures only one BluetoothDevice instance represents each // Bluetooth device inside a single global object. HeapHashMap<String, Member<BluetoothDevice>> device_instance_map_; - mojo::AssociatedBindingSet<mojom::blink::WebBluetoothScanClient> - client_bindings_; + mojo::AssociatedReceiverSet<mojom::blink::WebBluetoothScanClient> + client_receivers_; - mojom::blink::WebBluetoothServicePtr service_; + mojo::Remote<mojom::blink::WebBluetoothService> service_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h index 985e4b43d98..8daeae6fd0e 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_DEVICE_H_ #include <memory> -#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h" +#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h" #include "third_party/blink/renderer/modules/event_target_modules.h" diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc index a4027a7eca5..842bc68ed05 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/bluetooth/bluetooth_error.h" +#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/platform/heap/heap.h" diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.h index a88450063b5..2a6ba1e1fdf 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_ERROR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_ERROR_H_ -#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h" +#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.cc index 8f3edbbe322..017c0d3e6ae 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.cc @@ -4,10 +4,12 @@ #include "third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h" +#include "mojo/public/cpp/bindings/receiver_set.h" + namespace blink { BluetoothLEScan::BluetoothLEScan( - mojo::BindingId id, + mojo::ReceiverId id, Bluetooth* bluetooth, mojom::blink::WebBluetoothRequestLEScanOptionsPtr options) : id_(id), diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h index 943627140a7..0fb2bf26b1d 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_LE_SCAN_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_LE_SCAN_H_ +#include "mojo/public/cpp/bindings/receiver_set.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan_filter_init.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -16,7 +17,7 @@ class BluetoothLEScan final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - BluetoothLEScan(mojo::BindingId, + BluetoothLEScan(mojo::ReceiverId, Bluetooth*, mojom::blink::WebBluetoothRequestLEScanOptionsPtr); @@ -31,7 +32,7 @@ class BluetoothLEScan final : public ScriptWrappable { void Trace(blink::Visitor*) override; private: - mojo::BindingId id_; + mojo::ReceiverId id_; HeapVector<Member<BluetoothLEScanFilterInit>> filters_; Member<Bluetooth> bluetooth_; const bool keep_repeated_devices_; diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc index e73dc5f8ad8..0eb9959573c 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc @@ -6,7 +6,9 @@ #include <utility> -#include "mojo/public/cpp/bindings/associated_interface_ptr.h" +#include "mojo/public/cpp/bindings/associated_receiver_set.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" +#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -55,7 +57,7 @@ void BluetoothRemoteGATTCharacteristic::ContextDestroyed(ExecutionContext*) { } void BluetoothRemoteGATTCharacteristic::Dispose() { - client_bindings_.CloseAllBindings(); + receivers_.Clear(); } const WTF::AtomicString& BluetoothRemoteGATTCharacteristic::InterfaceName() @@ -255,15 +257,15 @@ ScriptPromise BluetoothRemoteGATTCharacteristic::startNotifications( mojom::blink::WebBluetoothService* service = device_->GetBluetooth()->Service(); - mojom::blink::WebBluetoothCharacteristicClientAssociatedPtrInfo ptr_info; - auto request = mojo::MakeRequest(&ptr_info); + mojo::PendingAssociatedRemote<mojom::blink::WebBluetoothCharacteristicClient> + client; // See https://bit.ly/2S0zRAS for task types. - client_bindings_.AddBinding( - this, std::move(request), + receivers_.Add( + this, client.InitWithNewEndpointAndPassReceiver(), GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI)); service->RemoteCharacteristicStartNotifications( - characteristic_->instance_id, std::move(ptr_info), + characteristic_->instance_id, std::move(client), WTF::Bind(&BluetoothRemoteGATTCharacteristic::NotificationsCallback, WrapPersistent(this), WrapPersistent(resolver))); diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h index ef53c8cc697..fbe7df6c7ce 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h @@ -5,8 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_REMOTE_GATT_CHARACTERISTIC_H_ -#include "mojo/public/cpp/bindings/associated_binding_set.h" -#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h" +#include "mojo/public/cpp/bindings/associated_receiver_set.h" +#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_piece.h" @@ -133,8 +133,8 @@ class BluetoothRemoteGATTCharacteristic final Member<BluetoothCharacteristicProperties> properties_; Member<DOMDataView> value_; Member<BluetoothDevice> device_; - mojo::AssociatedBindingSet<mojom::blink::WebBluetoothCharacteristicClient> - client_bindings_; + mojo::AssociatedReceiverSet<mojom::blink::WebBluetoothCharacteristicClient> + receivers_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc index dc809116964..a74a57460da 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc @@ -5,7 +5,10 @@ #include "third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h" #include <utility> -#include "mojo/public/cpp/bindings/associated_interface_ptr.h" + +#include "mojo/public/cpp/bindings/associated_receiver_set.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" +#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -75,7 +78,7 @@ void BluetoothRemoteGATTServer::Dispose() { DisconnectIfConnected(); // The pipe to this object must be closed when is marked unreachable to // prevent messages from being dispatched before lazy sweeping. - client_bindings_.CloseAllBindings(); + client_receivers_.Clear(); } void BluetoothRemoteGATTServer::Trace(blink::Visitor* visitor) { @@ -106,15 +109,15 @@ ScriptPromise BluetoothRemoteGATTServer::connect(ScriptState* script_state) { mojom::blink::WebBluetoothService* service = device_->GetBluetooth()->Service(); - mojom::blink::WebBluetoothServerClientAssociatedPtrInfo ptr_info; + mojo::PendingAssociatedRemote<mojom::blink::WebBluetoothServerClient> client; // See https://bit.ly/2S0zRAS for task types. scoped_refptr<base::SingleThreadTaskRunner> task_runner = GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI); - auto request = mojo::MakeRequest(&ptr_info); - client_bindings_.AddBinding(this, std::move(request), std::move(task_runner)); + client_receivers_.Add(this, client.InitWithNewEndpointAndPassReceiver(), + std::move(task_runner)); service->RemoteServerConnect( - device_->id(), std::move(ptr_info), + device_->id(), std::move(client), WTF::Bind(&BluetoothRemoteGATTServer::ConnectCallback, WrapPersistent(this), WrapPersistent(resolver))); @@ -125,7 +128,7 @@ void BluetoothRemoteGATTServer::disconnect(ScriptState* script_state) { if (!connected_) return; CleanupDisconnectedDeviceAndFireEvent(); - client_bindings_.CloseAllBindings(); + client_receivers_.Clear(); mojom::blink::WebBluetoothService* service = device_->GetBluetooth()->Service(); service->RemoteServerDisconnect(device_->id()); diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h index 62d24b336d6..73c60c1f90f 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVER_H_ -#include "mojo/public/cpp/bindings/associated_binding_set.h" +#include "mojo/public/cpp/bindings/associated_receiver_set.h" #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h" #include "third_party/blink/renderer/bindings/modules/v8/string_or_unsigned_long.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" @@ -108,8 +108,8 @@ class BluetoothRemoteGATTServer // using this server’s connection. HeapHashSet<Member<ScriptPromiseResolver>> active_algorithms_; - mojo::AssociatedBindingSet<mojom::blink::WebBluetoothServerClient> - client_bindings_; + mojo::AssociatedReceiverSet<mojom::blink::WebBluetoothServerClient> + client_receivers_; Member<BluetoothDevice> device_; bool connected_; @@ -117,4 +117,4 @@ class BluetoothRemoteGATTServer } // namespace blink -#endif // BluetoothDevice_h +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVER_H_ diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h index 9feec686021..4b351c0cf85 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_H_ #include <memory> -#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h" +#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/modules/v8/string_or_unsigned_long.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth_device.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" diff --git a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc index e963f704969..683099a37e8 100644 --- a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc +++ b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc @@ -5,9 +5,11 @@ #include "third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h" #include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-shared.h" #include "third_party/blink/public/platform/interface_provider.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" +#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/events/message_event.h" #include "third_party/blink/renderer/platform/mojo/mojo_helper.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -39,6 +41,15 @@ GetThreadSpecificProvider() { BroadcastChannel* BroadcastChannel::Create(ExecutionContext* execution_context, const String& name, ExceptionState& exception_state) { + // Record BroadcastChannel usage in third party context. Don't record if the + // frame is same-origin to the top frame, or if we can't tell whether the + // frame was ever cross-origin or not. + Document* document = DynamicTo<Document>(execution_context); + if (document && document->TopFrameOrigin() && + !document->TopFrameOrigin()->CanAccess(document->GetSecurityOrigin())) { + UseCounter::Count(document, WebFeature::kThirdPartyBroadcastChannel); + } + if (execution_context->GetSecurityOrigin()->IsOpaque()) { // TODO(mek): Decide what to do here depending on // https://github.com/whatwg/html/issues/1319 diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/BUILD.gn b/chromium/third_party/blink/renderer/modules/cache_storage/BUILD.gn index b221c1559e9..af99e71f534 100644 --- a/chromium/third_party/blink/renderer/modules/cache_storage/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/cache_storage/BUILD.gn @@ -10,10 +10,14 @@ blink_modules_sources("cache_storage") { "cache.h", "cache_storage.cc", "cache_storage.h", + "cache_storage_blob_client_list.cc", + "cache_storage_blob_client_list.h", "cache_storage_error.cc", "cache_storage_error.h", "cache_storage_trace_utils.cc", "cache_storage_trace_utils.h", + "cache_utils.cc", + "cache_utils.h", "global_cache_storage.cc", "global_cache_storage.h", "inspector_cache_storage_agent.cc", diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc index 35a05fea672..ff092dcb411 100644 --- a/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc +++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc @@ -7,12 +7,9 @@ #include <memory> #include <utility> -#include "base/feature_list.h" #include "base/optional.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "third_party/blink/public/common/cache_storage/cache_storage_utils.h" -#include "third_party/blink/public/common/features.h" -#include "third_party/blink/public/common/service_worker/service_worker_utils.h" #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h" #include "third_party/blink/renderer/bindings/core/v8/idl_types.h" @@ -33,8 +30,10 @@ #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/modules/cache_storage/cache_storage.h" +#include "third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h" #include "third_party/blink/renderer/modules/cache_storage/cache_storage_error.h" #include "third_party/blink/renderer/modules/cache_storage/cache_storage_trace_utils.h" +#include "third_party/blink/renderer/modules/cache_storage/cache_utils.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" @@ -44,11 +43,11 @@ #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h" #include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h" +#include "third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h" #include "third_party/blink/renderer/platform/network/http_names.h" #include "third_party/blink/renderer/platform/network/http_parsers.h" #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" namespace blink { @@ -76,38 +75,22 @@ bool HasJavascriptMimeType(const Response* response) { return MIMETypeRegistry::IsSupportedJavaScriptMIMEType(mime_type); } -enum class CodeCacheGenerateTiming { - kDontGenerate, - kGenerateNow, - kGenerateWhenIdle, -}; - -CodeCacheGenerateTiming ShouldGenerateV8CodeCache(ScriptState* script_state, - const Response* response) { - EagerCodeCacheStrategy strategy = - ServiceWorkerUtils::GetEagerCodeCacheStrategy(); - if (strategy == EagerCodeCacheStrategy::kDontGenerate) - return CodeCacheGenerateTiming::kDontGenerate; - +bool ShouldGenerateV8CodeCache(ScriptState* script_state, + const Response* response) { ExecutionContext* context = ExecutionContext::From(script_state); auto* global_scope = DynamicTo<ServiceWorkerGlobalScope>(context); if (!global_scope) - return CodeCacheGenerateTiming::kDontGenerate; + return false; + + if (!global_scope->IsInstalling()) + return false; if (!HasJavascriptMimeType(response)) - return CodeCacheGenerateTiming::kDontGenerate; + return false; if (!response->InternalBodyBuffer()) - return CodeCacheGenerateTiming::kDontGenerate; - - if (global_scope->IsInstalling()) - return CodeCacheGenerateTiming::kGenerateNow; - - if (strategy == EagerCodeCacheStrategy::kOnIdleTask) { - return CodeCacheGenerateTiming::kGenerateWhenIdle; - } - - return CodeCacheGenerateTiming::kDontGenerate; + return false; + return true; } } // namespace @@ -161,7 +144,7 @@ class Cache::FetchResolvedForAdd final : public ScriptFunction { if (exception_state.HadException()) { ScriptPromise rejection = ScriptPromise::Reject(GetScriptState(), exception_state); - return ScriptValue(GetScriptState(), rejection.V8Value()); + return ScriptValue(GetScriptState()->GetIsolate(), rejection.V8Value()); } for (const auto& response : responses) { @@ -170,21 +153,21 @@ class Cache::FetchResolvedForAdd final : public ScriptFunction { GetScriptState(), V8ThrowException::CreateTypeError(GetScriptState()->GetIsolate(), "Request failed")); - return ScriptValue(GetScriptState(), rejection.V8Value()); + return ScriptValue(GetScriptState()->GetIsolate(), rejection.V8Value()); } if (VaryHeaderContainsAsterisk(response)) { ScriptPromise rejection = ScriptPromise::Reject( GetScriptState(), V8ThrowException::CreateTypeError(GetScriptState()->GetIsolate(), "Vary header contains *")); - return ScriptValue(GetScriptState(), rejection.V8Value()); + return ScriptValue(GetScriptState()->GetIsolate(), rejection.V8Value()); } } ScriptPromise put_promise = cache_->PutImpl(GetScriptState(), method_name_, requests_, responses, exception_state, trace_id_); - return ScriptValue(GetScriptState(), put_promise.V8Value()); + return ScriptValue(GetScriptState()->GetIsolate(), put_promise.V8Value()); } void Trace(blink::Visitor* visitor) override { @@ -204,7 +187,7 @@ class Cache::FetchResolvedForAdd final : public ScriptFunction { }; class Cache::BarrierCallbackForPut final - : public GarbageCollectedFinalized<BarrierCallbackForPut> { + : public GarbageCollected<BarrierCallbackForPut> { public: BarrierCallbackForPut(wtf_size_t number_of_operations, Cache* cache, @@ -236,10 +219,10 @@ class Cache::BarrierCallbackForPut final MaybeReportInstalledScripts(); int operation_count = batch_operations_.size(); DCHECK_GE(operation_count, 1); - // Make sure to bind the Cache object to keep the mojo interface pointer - // alive during the operation. Otherwise GC might prevent the callback - // from ever being executed. - cache_->cache_ptr_->Batch( + // Make sure to bind the Cache object to keep the mojo remote alive during + // the operation. Otherwise GC might prevent the callback from ever being + // executed. + cache_->cache_remote_->Batch( std::move(batch_operations_), trace_id_, WTF::Bind( [](const String& method_name, ScriptPromiseResolver* resolver, @@ -336,8 +319,8 @@ class Cache::BarrierCallbackForPut final continue; } uint64_t side_data_blob_size = - operation->response->side_data_blob - ? operation->response->side_data_blob->size() + operation->response->side_data_blob_for_cache_put + ? operation->response->side_data_blob_for_cache_put->size() : 0; global_scope->CountCacheStorageInstalledScript(blob_data_handle->size(), side_data_blob_size); @@ -354,7 +337,7 @@ class Cache::BarrierCallbackForPut final }; class Cache::BlobHandleCallbackForPut final - : public GarbageCollectedFinalized<BlobHandleCallbackForPut>, + : public GarbageCollected<BlobHandleCallbackForPut>, public FetchDataLoader::Client { USING_GARBAGE_COLLECTED_MIXIN(BlobHandleCallbackForPut); @@ -400,33 +383,25 @@ class Cache::BlobHandleCallbackForPut final }; class Cache::CodeCacheHandleCallbackForPut final - : public GarbageCollectedFinalized<CodeCacheHandleCallbackForPut>, + : public GarbageCollected<CodeCacheHandleCallbackForPut>, public FetchDataLoader::Client { USING_GARBAGE_COLLECTED_MIXIN(CodeCacheHandleCallbackForPut); public: CodeCacheHandleCallbackForPut(ScriptState* script_state, - Cache* cache, wtf_size_t index, BarrierCallbackForPut* barrier_callback, Request* request, Response* response, - CodeCacheGenerateTiming timing, int64_t trace_id) : script_state_(script_state), - cache_(cache), index_(index), barrier_callback_(barrier_callback), mime_type_(response->InternalMIMEType()), - timing_(timing), trace_id_(trace_id) { fetch_api_request_ = request->CreateFetchAPIRequest(); fetch_api_response_ = response->PopulateFetchAPIResponse(); url_ = fetch_api_request_->url; - opaque_mode_ = fetch_api_response_->response_type == - network::mojom::FetchResponseType::kOpaque - ? V8CodeCache::OpaqueMode::kOpaque - : V8CodeCache::OpaqueMode::kNotOpaque; } ~CodeCacheHandleCallbackForPut() override = default; @@ -437,7 +412,6 @@ class Cache::CodeCacheHandleCallbackForPut final TRACE_ID_GLOBAL(trace_id_), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "url", CacheStorageTracedValue(url_.GetString())); - base::Time response_time = fetch_api_response_->response_time; mojom::blink::BatchOperationPtr batch_operation = mojom::blink::BatchOperation::New(); batch_operation->operation_type = mojom::blink::OperationType::kPut; @@ -450,33 +424,18 @@ class Cache::CodeCacheHandleCallbackForPut final batch_operation->response->blob = BlobDataHandle::Create( std::move(blob_data), array_buffer->ByteLength()); - if (timing_ == CodeCacheGenerateTiming::kGenerateNow) { - scoped_refptr<CachedMetadata> cached_metadata = - GenerateFullCodeCache(array_buffer); - if (cached_metadata) { - base::span<const uint8_t> serialized_data = - cached_metadata->SerializedData(); - auto side_data_blob_data = std::make_unique<BlobData>(); - side_data_blob_data->AppendBytes(serialized_data.data(), - serialized_data.size()); - - batch_operation->response->side_data_blob = BlobDataHandle::Create( - std::move(side_data_blob_data), serialized_data.size()); - } - } else { - // Schedule an idle task to generate code cache later. - ServiceWorkerGlobalScope* global_scope = GetServiceWorkerGlobalScope(); - if (global_scope) { - auto* thread_scheduler = - global_scope->GetScheduler()->GetWorkerThreadScheduler(); - DCHECK(thread_scheduler); - int task_id = global_scope->WillStartTask(); - thread_scheduler->IdleTaskRunner()->PostIdleTask( - FROM_HERE, WTF::Bind(&Cache::CodeCacheHandleCallbackForPut:: - GenerateCodeCacheOnIdleTask, - WrapPersistent(this), task_id, - WrapPersistent(array_buffer), response_time)); - } + scoped_refptr<CachedMetadata> cached_metadata = + GenerateFullCodeCache(array_buffer); + if (cached_metadata) { + base::span<const uint8_t> serialized_data = + cached_metadata->SerializedData(); + auto side_data_blob_data = std::make_unique<BlobData>(); + side_data_blob_data->AppendBytes(serialized_data.data(), + serialized_data.size()); + + batch_operation->response->side_data_blob_for_cache_put = + BlobDataHandle::Create(std::move(side_data_blob_data), + serialized_data.size()); } barrier_callback_->OnSuccess(index_, std::move(batch_operation)); @@ -490,7 +449,6 @@ class Cache::CodeCacheHandleCallbackForPut final void Trace(blink::Visitor* visitor) override { visitor->Trace(script_state_); - visitor->Trace(cache_); visitor->Trace(barrier_callback_); FetchDataLoader::Client::Trace(visitor); } @@ -528,45 +486,12 @@ class Cache::CodeCacheHandleCallbackForPut final url_, text_decoder->Encoding(), opaque_mode_); } - void GenerateCodeCacheOnIdleTask(int task_id, - DOMArrayBuffer* array_buffer, - base::Time response_time, - base::TimeTicks) { - TRACE_EVENT_WITH_FLOW1( - "CacheStorage", - "Cache::CodeCacheHandleCallbackForPut::GenerateCodeCacheOnIdleTask", - TRACE_ID_GLOBAL(trace_id_), - TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "url", - CacheStorageTracedValue(url_.GetString())); - - ServiceWorkerGlobalScope* global_scope = GetServiceWorkerGlobalScope(); - if (!global_scope) - return; - - scoped_refptr<CachedMetadata> cached_metadata = - GenerateFullCodeCache(array_buffer); - if (!cached_metadata) { - global_scope->DidEndTask(task_id); - return; - } - cache_->cache_ptr_->SetSideData( - url_, response_time, cached_metadata->SerializedData(), trace_id_, - WTF::Bind( - [](ServiceWorkerGlobalScope* global_scope, int task_id, - mojom::blink::CacheStorageError error) { - global_scope->DidEndTask(task_id); - }, - WrapPersistent(global_scope), task_id)); - } - const Member<ScriptState> script_state_; - const Member<Cache> cache_; const wtf_size_t index_; Member<BarrierCallbackForPut> barrier_callback_; const String mime_type_; KURL url_; V8CodeCache::OpaqueMode opaque_mode_; - CodeCacheGenerateTiming timing_; const int64_t trace_id_; mojom::blink::FetchAPIRequestPtr fetch_api_request_; @@ -697,14 +622,17 @@ ScriptPromise Cache::keys(ScriptState* script_state, } Cache::Cache(GlobalFetch::ScopedFetcher* fetcher, - mojom::blink::CacheStorageCacheAssociatedPtrInfo cache_ptr_info, + mojo::PendingAssociatedRemote<mojom::blink::CacheStorageCache> + cache_pending_remote, scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : scoped_fetcher_(fetcher) { - cache_ptr_.Bind(std::move(cache_ptr_info), std::move(task_runner)); + : scoped_fetcher_(fetcher), + blob_client_list_(MakeGarbageCollected<CacheStorageBlobClientList>()) { + cache_remote_.Bind(std::move(cache_pending_remote), std::move(task_runner)); } void Cache::Trace(blink::Visitor* visitor) { visitor->Trace(scoped_fetcher_); + visitor->Trace(blob_client_list_); ScriptWrappable::Trace(visitor); } @@ -729,14 +657,20 @@ ScriptPromise Cache::MatchImpl(ScriptState* script_state, return promise; } - // Make sure to bind the Cache object to keep the mojo interface pointer - // alive during the operation. Otherwise GC might prevent the callback - // from ever being executed. - cache_ptr_->Match( - std::move(mojo_request), std::move(mojo_options), trace_id, + bool in_related_fetch_event = false; + ExecutionContext* context = ExecutionContext::From(script_state); + if (auto* global_scope = DynamicTo<ServiceWorkerGlobalScope>(context)) + in_related_fetch_event = global_scope->HasRelatedFetchEvent(request->url()); + + // Make sure to bind the Cache object to keep the mojo remote alive during + // the operation. Otherwise GC might prevent the callback from ever being + // executed. + cache_remote_->Match( + std::move(mojo_request), std::move(mojo_options), in_related_fetch_event, + trace_id, WTF::Bind( [](ScriptPromiseResolver* resolver, base::TimeTicks start_time, - const CacheQueryOptions* options, int64_t trace_id, Cache* _, + const CacheQueryOptions* options, int64_t trace_id, Cache* self, mojom::blink::MatchResultPtr result) { base::TimeDelta elapsed = base::TimeTicks::Now() - start_time; UMA_HISTOGRAM_LONG_TIMES("ServiceWorkerCache.Cache.Renderer.Match", @@ -766,15 +700,29 @@ ScriptPromise Cache::MatchImpl(ScriptState* script_state, break; } } else { - TRACE_EVENT_WITH_FLOW1( - "CacheStorage", "Cache::MatchImpl::Callback", - TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, - "response", CacheStorageTracedValue(result->get_response())); UMA_HISTOGRAM_LONG_TIMES( "ServiceWorkerCache.Cache.Renderer.Match.Hit", elapsed); ScriptState::Scope scope(resolver->GetScriptState()); - resolver->Resolve(Response::Create(resolver->GetScriptState(), - *result->get_response())); + if (result->is_eager_response()) { + TRACE_EVENT_WITH_FLOW1( + "CacheStorage", "Cache::MatchImpl::Callback", + TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, + "eager_response", + CacheStorageTracedValue( + result->get_eager_response()->response)); + resolver->Resolve( + CreateEagerResponse(resolver->GetScriptState(), + std::move(result->get_eager_response()), + self->blob_client_list_)); + } else { + TRACE_EVENT_WITH_FLOW1( + "CacheStorage", "Cache::MatchImpl::Callback", + TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, + "response", + CacheStorageTracedValue(result->get_response())); + resolver->Resolve(Response::Create(resolver->GetScriptState(), + *result->get_response())); + } } }, WrapPersistent(resolver), base::TimeTicks::Now(), @@ -808,10 +756,10 @@ ScriptPromise Cache::MatchAllImpl(ScriptState* script_state, return promise; } - // Make sure to bind the Cache object to keep the mojo interface pointer - // alive during the operation. Otherwise GC might prevent the callback - // from ever being executed. - cache_ptr_->MatchAll( + // Make sure to bind the Cache object to keep the mojo remote alive during + // the operation. Otherwise GC might prevent the callback from ever being + // executed. + cache_remote_->MatchAll( std::move(fetch_api_request), std::move(mojo_options), trace_id, WTF::Bind( [](ScriptPromiseResolver* resolver, base::TimeTicks start_time, @@ -864,7 +812,7 @@ ScriptPromise Cache::AddAllImpl(ScriptState* script_state, HeapVector<RequestInfo> request_infos; request_infos.resize(requests.size()); - Vector<ScriptPromise> promises; + HeapVector<ScriptPromise> promises; promises.resize(requests.size()); for (wtf_size_t i = 0; i < requests.size(); ++i) { if (!requests[i]->url().ProtocolIsInHTTPFamily()) { @@ -917,10 +865,10 @@ ScriptPromise Cache::DeleteImpl(ScriptState* script_state, return promise; } - // Make sure to bind the Cache object to keep the mojo interface pointer - // alive during the operation. Otherwise GC might prevent the callback - // from ever being executed. - cache_ptr_->Batch( + // Make sure to bind the Cache object to keep the mojo remote alive during + // the operation. Otherwise GC might prevent the callback from ever being + // executed. + cache_remote_->Batch( std::move(batch_operations), trace_id, WTF::Bind( [](ScriptPromiseResolver* resolver, base::TimeTicks start_time, @@ -1013,16 +961,13 @@ ScriptPromise Cache::PutImpl(ScriptState* script_state, BodyStreamBuffer* buffer = responses[i]->InternalBodyBuffer(); - CodeCacheGenerateTiming cache_generate_timing = - ShouldGenerateV8CodeCache(script_state, responses[i]); - if (cache_generate_timing != CodeCacheGenerateTiming::kDontGenerate) { + if (ShouldGenerateV8CodeCache(script_state, responses[i])) { FetchDataLoader* loader = FetchDataLoader::CreateLoaderAsArrayBuffer(); - buffer->StartLoading( - loader, - MakeGarbageCollected<CodeCacheHandleCallbackForPut>( - script_state, this, i, barrier_callback, requests[i], - responses[i], cache_generate_timing, trace_id), - exception_state); + buffer->StartLoading(loader, + MakeGarbageCollected<CodeCacheHandleCallbackForPut>( + script_state, i, barrier_callback, requests[i], + responses[i], trace_id), + exception_state); if (exception_state.HadException()) { barrier_callback->OnError("Could not inspect response body state"); return promise; @@ -1082,10 +1027,10 @@ ScriptPromise Cache::KeysImpl(ScriptState* script_state, return promise; } - // Make sure to bind the Cache object to keep the mojo interface pointer - // alive during the operation. Otherwise GC might prevent the callback - // from ever being executed. - cache_ptr_->Keys( + // Make sure to bind the Cache object to keep the mojo remote alive during + // the operation. Otherwise GC might prevent the callback from ever being + // executed. + cache_remote_->Keys( std::move(fetch_api_request), std::move(mojo_options), trace_id, WTF::Bind( [](ScriptPromiseResolver* resolver, base::TimeTicks start_time, diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache.h b/chromium/third_party/blink/renderer/modules/cache_storage/cache.h index d3f75893c99..b386ecdb55a 100644 --- a/chromium/third_party/blink/renderer/modules/cache_storage/cache.h +++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache.h @@ -8,6 +8,8 @@ #include <memory> #include "base/macros.h" +#include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/fetch/global_fetch.h" @@ -38,6 +40,7 @@ struct TypeConverter<CacheQueryOptionsPtr, const blink::CacheQueryOptions*> { namespace blink { +class CacheStorageBlobClientList; class ExceptionState; class Response; class Request; @@ -50,7 +53,7 @@ class MODULES_EXPORT Cache final : public ScriptWrappable { public: Cache(GlobalFetch::ScopedFetcher*, - mojom::blink::CacheStorageCacheAssociatedPtrInfo, + mojo::PendingAssociatedRemote<mojom::blink::CacheStorageCache>, scoped_refptr<base::SingleThreadTaskRunner>); // From Cache.idl: @@ -114,8 +117,9 @@ class MODULES_EXPORT Cache final : public ScriptWrappable { const CacheQueryOptions*); Member<GlobalFetch::ScopedFetcher> scoped_fetcher_; + Member<CacheStorageBlobClientList> blob_client_list_; - mojom::blink::CacheStorageCacheAssociatedPtr cache_ptr_; + mojo::AssociatedRemote<mojom::blink::CacheStorageCache> cache_remote_; DISALLOW_COPY_AND_ASSIGN(Cache); }; diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.cc index 60a2e5313a3..2122c8c17b9 100644 --- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.cc +++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.cc @@ -20,8 +20,10 @@ #include "third_party/blink/renderer/core/fetch/response.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h" #include "third_party/blink/renderer/modules/cache_storage/cache_storage_error.h" #include "third_party/blink/renderer/modules/cache_storage/cache_storage_trace_utils.h" +#include "third_party/blink/renderer/modules/cache_storage/cache_utils.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -100,12 +102,20 @@ ScriptPromise CacheStorage::open(ScriptState* script_state, return promise; } + // The context may be destroyed and the mojo connection unbound. However the + // object may live on, reject any requests after the context is destroyed. + if (!cache_storage_remote_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError)); + return promise; + } + ever_used_ = true; // Make sure to bind the CacheStorage object to keep the mojo interface // pointer alive during the operation. Otherwise GC might prevent the // callback from ever being executed. - cache_storage_ptr_->Open( + cache_storage_remote_->Open( cache_name, trace_id, WTF::Bind( [](ScriptPromiseResolver* resolver, @@ -166,12 +176,20 @@ ScriptPromise CacheStorage::has(ScriptState* script_state, return promise; } + // The context may be destroyed and the mojo connection unbound. However the + // object may live on, reject any requests after the context is destroyed. + if (!cache_storage_remote_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError)); + return promise; + } + ever_used_ = true; // Make sure to bind the CacheStorage object to keep the mojo interface // pointer alive during the operation. Otherwise GC might prevent the // callback from ever being executed. - cache_storage_ptr_->Has( + cache_storage_remote_->Has( cache_name, trace_id, WTF::Bind( [](ScriptPromiseResolver* resolver, base::TimeTicks start_time, @@ -218,12 +236,20 @@ ScriptPromise CacheStorage::Delete(ScriptState* script_state, return promise; } + // The context may be destroyed and the mojo connection unbound. However the + // object may live on, reject any requests after the context is destroyed. + if (!cache_storage_remote_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError)); + return promise; + } + ever_used_ = true; // Make sure to bind the CacheStorage object to keep the mojo interface // pointer alive during the operation. Otherwise GC might prevent the // callback from ever being executed. - cache_storage_ptr_->Delete( + cache_storage_remote_->Delete( cache_name, trace_id, WTF::Bind( [](ScriptPromiseResolver* resolver, base::TimeTicks start_time, @@ -270,12 +296,20 @@ ScriptPromise CacheStorage::keys(ScriptState* script_state) { return promise; } + // The context may be destroyed and the mojo connection unbound. However the + // object may live on, reject any requests after the context is destroyed. + if (!cache_storage_remote_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError)); + return promise; + } + ever_used_ = true; // Make sure to bind the CacheStorage object to keep the mojo interface // pointer alive during the operation. Otherwise GC might prevent the // callback from ever being executed. - cache_storage_ptr_->Keys( + cache_storage_remote_->Keys( trace_id, WTF::Bind( [](ScriptPromiseResolver* resolver, base::TimeTicks start_time, @@ -319,6 +353,12 @@ ScriptPromise CacheStorage::MatchImpl(ScriptState* script_state, request->CreateFetchAPIRequest(); mojom::blink::MultiCacheQueryOptionsPtr mojo_options = mojom::blink::MultiCacheQueryOptions::From(options); + + ExecutionContext* context = ExecutionContext::From(script_state); + bool in_related_fetch_event = false; + if (auto* global_scope = DynamicTo<ServiceWorkerGlobalScope>(context)) + in_related_fetch_event = global_scope->HasRelatedFetchEvent(request->url()); + TRACE_EVENT_WITH_FLOW2("CacheStorage", "CacheStorage::MatchImpl", TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT, "request", CacheStorageTracedValue(mojo_request), @@ -333,6 +373,14 @@ ScriptPromise CacheStorage::MatchImpl(ScriptState* script_state, return promise; } + // The context may be destroyed and the mojo connection unbound. However the + // object may live on, reject any requests after the context is destroyed. + if (!cache_storage_remote_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError)); + return promise; + } + if (request->method() != http_names::kGET && !options->ignoreMethod()) { resolver->Resolve(); return promise; @@ -343,12 +391,13 @@ ScriptPromise CacheStorage::MatchImpl(ScriptState* script_state, // Make sure to bind the CacheStorage object to keep the mojo interface // pointer alive during the operation. Otherwise GC might prevent the // callback from ever being executed. - cache_storage_ptr_->Match( - std::move(mojo_request), std::move(mojo_options), trace_id, + cache_storage_remote_->Match( + std::move(mojo_request), std::move(mojo_options), in_related_fetch_event, + trace_id, WTF::Bind( [](ScriptPromiseResolver* resolver, base::TimeTicks start_time, const MultiCacheQueryOptions* options, int64_t trace_id, - mojom::blink::MatchResultPtr result) { + CacheStorage* self, mojom::blink::MatchResultPtr result) { base::TimeDelta elapsed = base::TimeTicks::Now() - start_time; if (!options->hasCacheName() || options->cacheName().IsEmpty()) { UMA_HISTOGRAM_LONG_TIMES( @@ -379,24 +428,41 @@ ScriptPromise CacheStorage::MatchImpl(ScriptState* script_state, break; } } else { - TRACE_EVENT_WITH_FLOW1( - "CacheStorage", "CacheStorage::MatchImpl::Callback", - TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, - "response", CacheStorageTracedValue(result->get_response())); ScriptState::Scope scope(resolver->GetScriptState()); - resolver->Resolve(Response::Create(resolver->GetScriptState(), - *result->get_response())); + if (result->is_eager_response()) { + TRACE_EVENT_WITH_FLOW1( + "CacheStorage", "CacheStorage::MatchImpl::Callback", + TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, + "eager_response", + CacheStorageTracedValue( + result->get_eager_response()->response)); + resolver->Resolve( + CreateEagerResponse(resolver->GetScriptState(), + std::move(result->get_eager_response()), + self->blob_client_list_)); + } else { + TRACE_EVENT_WITH_FLOW1( + "CacheStorage", "CacheStorage::MatchImpl::Callback", + TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_IN, + "response", + CacheStorageTracedValue(result->get_response())); + resolver->Resolve(Response::Create(resolver->GetScriptState(), + *result->get_response())); + } } }, WrapPersistent(resolver), base::TimeTicks::Now(), - WrapPersistent(options), trace_id)); + WrapPersistent(options), trace_id, WrapPersistent(this))); return promise; } CacheStorage::CacheStorage(ExecutionContext* context, GlobalFetch::ScopedFetcher* fetcher) - : ContextClient(context), scoped_fetcher_(fetcher), ever_used_(false) { + : ContextLifecycleObserver(context), + scoped_fetcher_(fetcher), + blob_client_list_(MakeGarbageCollected<CacheStorageBlobClientList>()), + ever_used_(false) { // See https://bit.ly/2S0zRAS for task types. scoped_refptr<base::SingleThreadTaskRunner> task_runner = context->GetTaskRunner(blink::TaskType::kMiscPlatformAPI); @@ -404,16 +470,17 @@ CacheStorage::CacheStorage(ExecutionContext* context, // Service workers may already have a CacheStoragePtr provided as an // optimization. if (auto* service_worker = DynamicTo<ServiceWorkerGlobalScope>(context)) { - mojom::blink::CacheStoragePtrInfo info = service_worker->TakeCacheStorage(); + mojo::PendingRemote<mojom::blink::CacheStorage> info = + service_worker->TakeCacheStorage(); if (info) { - cache_storage_ptr_ = RevocableInterfacePtr<mojom::blink::CacheStorage>( - std::move(info), context->GetInterfaceInvalidator(), task_runner); + cache_storage_remote_ = mojo::Remote<mojom::blink::CacheStorage>( + std::move(info), task_runner); return; } } - context->GetInterfaceProvider()->GetInterface(MakeRequest( - &cache_storage_ptr_, context->GetInterfaceInvalidator(), task_runner)); + context->GetInterfaceProvider()->GetInterface( + cache_storage_remote_.BindNewPipeAndPassReceiver(task_runner)); } CacheStorage::~CacheStorage() = default; @@ -431,8 +498,9 @@ bool CacheStorage::HasPendingActivity() const { void CacheStorage::Trace(blink::Visitor* visitor) { visitor->Trace(scoped_fetcher_); + visitor->Trace(blob_client_list_); ScriptWrappable::Trace(visitor); - ContextClient::Trace(visitor); + ContextLifecycleObserver::Trace(visitor); } bool CacheStorage::IsAllowed(ScriptState* script_state) { @@ -443,4 +511,8 @@ bool CacheStorage::IsAllowed(ScriptState* script_state) { return allowed_.value(); } +void CacheStorage::ContextDestroyed(ExecutionContext*) { + cache_storage_remote_.reset(); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.h b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.h index 4e5ae78cd89..b545f83665b 100644 --- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.h +++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage.h @@ -8,7 +8,8 @@ #include <memory> #include "base/macros.h" #include "base/optional.h" -#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" @@ -17,15 +18,16 @@ #include "third_party/blink/renderer/modules/cache_storage/multi_cache_query_options.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" -#include "third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h" #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" namespace blink { +class CacheStorageBlobClientList; + class CacheStorage final : public ScriptWrappable, public ActiveScriptWrappable<CacheStorage>, - public ContextClient { + public ContextLifecycleObserver { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(CacheStorage); @@ -44,6 +46,7 @@ class CacheStorage final : public ScriptWrappable, bool HasPendingActivity() const override; void Trace(blink::Visitor*) override; + void ContextDestroyed(ExecutionContext*) override; private: ScriptPromise MatchImpl(ScriptState*, @@ -53,8 +56,9 @@ class CacheStorage final : public ScriptWrappable, bool IsAllowed(ScriptState*); Member<GlobalFetch::ScopedFetcher> scoped_fetcher_; + Member<CacheStorageBlobClientList> blob_client_list_; - RevocableInterfacePtr<mojom::blink::CacheStorage> cache_storage_ptr_; + mojo::Remote<mojom::blink::CacheStorage> cache_storage_remote_; base::Optional<bool> allowed_; bool ever_used_; diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.cc new file mode 100644 index 00000000000..b46756aa2fd --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.cc @@ -0,0 +1,87 @@ +// 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. + +#include "third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h" + +namespace blink { + +// Class implementing the BlobReaderClient interface. This is used to +// propagate the completion of an eager body blob read to the +// DataPipeBytesConsumer. +class CacheStorageBlobClientList::Client + : public GarbageCollected<CacheStorageBlobClientList::Client>, + public mojom::blink::BlobReaderClient { + // We must prevent any mojo messages from coming in after this object + // starts getting garbage collected. + USING_PRE_FINALIZER(CacheStorageBlobClientList::Client, Dispose); + + public: + Client(CacheStorageBlobClientList* owner, + mojo::PendingReceiver<mojom::blink::BlobReaderClient> + client_pending_receiver, + DataPipeBytesConsumer::CompletionNotifier* completion_notifier) + : owner_(owner), + client_receiver_(this, std::move(client_pending_receiver)), + completion_notifier_(completion_notifier) {} + + void OnCalculatedSize(uint64_t total_size, + uint64_t expected_content_size) override {} + + void OnComplete(int32_t status, uint64_t data_length) override { + client_receiver_.reset(); + + // 0 is net::OK + if (status == 0) + completion_notifier_->SignalComplete(); + else + completion_notifier_->SignalError(BytesConsumer::Error()); + + if (owner_) + owner_->RevokeClient(this); + } + + void Trace(blink::Visitor* visitor) { + visitor->Trace(owner_); + visitor->Trace(completion_notifier_); + } + + private: + void Dispose() { + // Use the existence of the client_receiver_ binding to see if this + // client has already completed. + if (!client_receiver_.is_bound()) + return; + + client_receiver_.reset(); + completion_notifier_->SignalError(BytesConsumer::Error("aborted")); + + // If we are already being garbage collected its not necessary to + // call RevokeClient() on the owner. + } + + WeakMember<CacheStorageBlobClientList> owner_; + mojo::Receiver<mojom::blink::BlobReaderClient> client_receiver_; + Member<DataPipeBytesConsumer::CompletionNotifier> completion_notifier_; + + DISALLOW_COPY_AND_ASSIGN(Client); +}; + +void CacheStorageBlobClientList::AddClient( + mojo::PendingReceiver<mojom::blink::BlobReaderClient> + client_pending_receiver, + DataPipeBytesConsumer::CompletionNotifier* completion_notifier) { + clients.emplace_back(MakeGarbageCollected<Client>( + this, std::move(client_pending_receiver), completion_notifier)); +} + +void CacheStorageBlobClientList::Trace(blink::Visitor* visitor) { + visitor->Trace(clients); +} + +void CacheStorageBlobClientList::RevokeClient(Client* client) { + auto index = clients.Find(client); + clients.EraseAt(index); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h new file mode 100644 index 00000000000..23b0452dadc --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h @@ -0,0 +1,39 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CACHE_STORAGE_CACHE_STORAGE_BLOB_CLIENT_LIST_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_CACHE_STORAGE_CACHE_STORAGE_BLOB_CLIENT_LIST_H_ + +#include "mojo/public/cpp/bindings/receiver.h" +#include "third_party/blink/public/mojom/blob/blob.mojom-blink.h" +#include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h" + +namespace blink { + +// This class holds a list of BlobReaderClient implementations alive until +// they complete or the entire list is garbage collected. +class CacheStorageBlobClientList + : public GarbageCollected<CacheStorageBlobClientList> { + public: + CacheStorageBlobClientList() = default; + void AddClient( + mojo::PendingReceiver<mojom::blink::BlobReaderClient> + client_pending_receiver, + DataPipeBytesConsumer::CompletionNotifier* completion_notifier); + + void Trace(blink::Visitor* visitor); + + private: + class Client; + + void RevokeClient(Client* client); + + HeapVector<Member<Client>> clients; + DISALLOW_COPY_AND_ASSIGN(CacheStorageBlobClientList); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CACHE_STORAGE_CACHE_STORAGE_BLOB_CLIENT_LIST_H_ diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc index a9abf23d371..707c7592e49 100644 --- a/chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc +++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_test.cc @@ -10,7 +10,8 @@ #include "base/memory/ptr_util.h" #include "base/optional.h" -#include "mojo/public/cpp/bindings/associated_binding.h" +#include "mojo/public/cpp/bindings/associated_receiver.h" +#include "mojo/public/cpp/bindings/associated_remote.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" @@ -21,6 +22,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_request.h" @@ -50,7 +52,7 @@ const char kNotImplementedString[] = "NotSupportedError: Method is not implemented."; class ScopedFetcherForTests final - : public GarbageCollectedFinalized<ScopedFetcherForTests>, + : public GarbageCollected<ScopedFetcherForTests>, public GlobalFetch::ScopedFetcher { USING_GARBAGE_COLLECTED_MIXIN(ScopedFetcherForTests); @@ -139,6 +141,7 @@ class ErrorCacheForTests : public mojom::blink::CacheStorageCache { void Match(mojom::blink::FetchAPIRequestPtr fetch_api_request, mojom::blink::CacheQueryOptionsPtr query_options, + bool in_related_fetch_event, int64_t trace_id, MatchCallback callback) override { last_error_web_cache_method_called_ = "dispatchMatch"; @@ -182,14 +185,6 @@ class ErrorCacheForTests : public mojom::blink::CacheStorageCache { CheckBatchOperationsIfProvided(batch_operations); std::move(callback).Run(CacheStorageVerboseError::New(error_, String())); } - void SetSideData(const KURL& url, - base::Time response_time, - base::span<const uint8_t> side_data, - int64_t trace_id, - SetSideDataCallback callback) override { - std::move(callback).Run( - blink::mojom::CacheStorageError::kErrorNotImplemented); - } protected: void CheckUrlIfProvided(const KURL& url) { @@ -271,14 +266,14 @@ class CacheStorageTest : public PageTestBase { Cache* CreateCache(ScopedFetcherForTests* fetcher, std::unique_ptr<ErrorCacheForTests> cache) { - mojom::blink::CacheStorageCacheAssociatedPtr cache_ptr; - auto request = mojo::MakeRequestAssociatedWithDedicatedPipe(&cache_ptr); + mojo::AssociatedRemote<mojom::blink::CacheStorageCache> cache_remote; cache_ = std::move(cache); - binding_ = std::make_unique< - mojo::AssociatedBinding<mojom::blink::CacheStorageCache>>( - cache_.get(), std::move(request)); + receiver_ = std::make_unique< + mojo::AssociatedReceiver<mojom::blink::CacheStorageCache>>( + cache_.get(), + cache_remote.BindNewEndpointAndPassDedicatedReceiverForTesting()); return MakeGarbageCollected<Cache>( - fetcher, cache_ptr.PassInterface(), + fetcher, cache_remote.Unbind(), blink::scheduler::GetSingleThreadTaskRunnerForTesting()); } @@ -302,12 +297,10 @@ class CacheStorageTest : public PageTestBase { // Convenience methods for testing the returned promises. ScriptValue GetRejectValue(ScriptPromise& promise) { - ScriptValue on_reject; - promise.Then(UnreachableFunction::Create(GetScriptState()), - TestFunction::Create(GetScriptState(), &on_reject)); - v8::MicrotasksScope::PerformCheckpoint(GetIsolate()); - test::RunPendingTasks(); - return on_reject; + ScriptPromiseTester tester(GetScriptState(), promise); + tester.WaitUntilSettled(); + EXPECT_TRUE(tester.IsRejected()); + return tester.Value(); } std::string GetRejectString(ScriptPromise& promise) { @@ -319,12 +312,10 @@ class CacheStorageTest : public PageTestBase { } ScriptValue GetResolveValue(ScriptPromise& promise) { - ScriptValue on_resolve; - promise.Then(TestFunction::Create(GetScriptState(), &on_resolve), - UnreachableFunction::Create(GetScriptState())); - v8::MicrotasksScope::PerformCheckpoint(GetIsolate()); - test::RunPendingTasks(); - return on_resolve; + ScriptPromiseTester tester(GetScriptState(), promise); + tester.WaitUntilSettled(); + EXPECT_TRUE(tester.IsFulfilled()); + return tester.Value(); } std::string GetResolveString(ScriptPromise& promise) { @@ -336,51 +327,9 @@ class CacheStorageTest : public PageTestBase { } private: - // A ScriptFunction that creates a test failure if it is ever called. - class UnreachableFunction : public ScriptFunction { - public: - static v8::Local<v8::Function> Create(ScriptState* script_state) { - UnreachableFunction* self = - MakeGarbageCollected<UnreachableFunction>(script_state); - return self->BindToV8Function(); - } - - UnreachableFunction(ScriptState* script_state) - : ScriptFunction(script_state) {} - - ScriptValue Call(ScriptValue value) override { - ADD_FAILURE() << "Unexpected call to a null ScriptFunction."; - return value; - } - }; - - // A ScriptFunction that saves its parameter; used by tests to assert on - // correct values being passed. - class TestFunction : public ScriptFunction { - public: - static v8::Local<v8::Function> Create(ScriptState* script_state, - ScriptValue* out_value) { - TestFunction* self = - MakeGarbageCollected<TestFunction>(script_state, out_value); - return self->BindToV8Function(); - } - - TestFunction(ScriptState* script_state, ScriptValue* out_value) - : ScriptFunction(script_state), value_(out_value) {} - - ScriptValue Call(ScriptValue value) override { - DCHECK(!value.IsEmpty()); - *value_ = value; - return value; - } - - private: - ScriptValue* value_; - }; - std::unique_ptr<ErrorCacheForTests> cache_; - std::unique_ptr<mojo::AssociatedBinding<mojom::blink::CacheStorageCache>> - binding_; + std::unique_ptr<mojo::AssociatedReceiver<mojom::blink::CacheStorageCache>> + receiver_; }; RequestInfo StringToRequestInfo(const String& value) { @@ -589,6 +538,7 @@ class MatchTestCache : public NotImplementedErrorCache { // From WebServiceWorkerCache: void Match(mojom::blink::FetchAPIRequestPtr fetch_api_request, mojom::blink::CacheQueryOptionsPtr query_options, + bool in_related_fetch_event, int64_t trace_id, MatchCallback callback) override { mojom::blink::MatchResultPtr result = mojom::blink::MatchResult::New(); diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_utils.cc b/chromium/third_party/blink/renderer/modules/cache_storage/cache_utils.cc new file mode 100644 index 00000000000..f70202288b4 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_utils.cc @@ -0,0 +1,47 @@ +// 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. + +#include "third_party/blink/renderer/modules/cache_storage/cache_utils.h" + +#include "third_party/blink/renderer/core/fetch/fetch_response_data.h" +#include "third_party/blink/renderer/core/fetch/response.h" +#include "third_party/blink/renderer/modules/cache_storage/cache_storage_blob_client_list.h" +#include "third_party/blink/renderer/platform/loader/fetch/data_pipe_bytes_consumer.h" + +namespace blink { + +Response* CreateEagerResponse(ScriptState* script_state, + mojom::blink::EagerResponsePtr eager_response, + CacheStorageBlobClientList* client_list) { + auto& response = eager_response->response; + DCHECK(!response->blob); + + ExecutionContext* context = ExecutionContext::From(script_state); + + FetchResponseData* fetch_data = + Response::CreateUnfilteredFetchResponseDataWithoutBody(script_state, + *response); + + DataPipeBytesConsumer::CompletionNotifier* completion_notifier = nullptr; + fetch_data->ReplaceBodyStreamBuffer(MakeGarbageCollected<BodyStreamBuffer>( + script_state, + MakeGarbageCollected<DataPipeBytesConsumer>( + context->GetTaskRunner(TaskType::kNetworking), + std::move(eager_response->pipe), &completion_notifier), + nullptr /* AbortSignal */)); + + // Create a BlobReaderClient in the provided list. This will track the + // completion of the eagerly read blob and propagate it to the given + // DataPipeBytesConsumer::CompletionNotifier. The list will also hold + // the client alive. + client_list->AddClient(std::move(eager_response->client_receiver), + std::move(completion_notifier)); + + fetch_data = Response::FilterResponseData( + response->response_type, fetch_data, response->cors_exposed_header_names); + + return Response::Create(context, fetch_data); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/cache_utils.h b/chromium/third_party/blink/renderer/modules/cache_storage/cache_utils.h new file mode 100644 index 00000000000..2c80bed0624 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache_utils.h @@ -0,0 +1,26 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CACHE_STORAGE_CACHE_UTILS_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_CACHE_STORAGE_CACHE_UTILS_H_ + +#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" + +namespace blink { + +class CacheStorageBlobClientList; +class Response; +class ScriptState; + +// A utility function to deserialize an eagerly read cache_storage response +// into a web-exposed fetch Response object. The resulting Response will +// have a DataPipeBytesConsumer body and a side_data_blob which can be used +// to read any code cache. +Response* CreateEagerResponse(ScriptState* script_state, + mojom::blink::EagerResponsePtr eager_response, + CacheStorageBlobClientList* client_list); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CACHE_STORAGE_CACHE_UTILS_H_ diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc b/chromium/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc index fd9d7a905e3..483b7a321fc 100644 --- a/chromium/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc +++ b/chromium/third_party/blink/renderer/modules/cache_storage/global_cache_storage.cc @@ -19,7 +19,7 @@ namespace { template <typename T> class GlobalCacheStorageImpl final - : public GarbageCollectedFinalized<GlobalCacheStorageImpl<T>>, + : public GarbageCollected<GlobalCacheStorageImpl<T>>, public Supplement<T> { USING_GARBAGE_COLLECTED_MIXIN(GlobalCacheStorageImpl); diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc b/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc index d67b04c1a71..ccc8ceec252 100644 --- a/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc +++ b/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc @@ -9,6 +9,8 @@ #include <utility> #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/cache_storage/cache_storage_utils.h" @@ -213,13 +215,15 @@ struct RequestResponse { class ResponsesAccumulator : public RefCounted<ResponsesAccumulator> { public: - ResponsesAccumulator(wtf_size_t num_responses, - const DataRequestParams& params, - mojom::blink::CacheStorageCacheAssociatedPtr cache_ptr, - std::unique_ptr<RequestEntriesCallback> callback) + ResponsesAccumulator( + wtf_size_t num_responses, + const DataRequestParams& params, + mojo::PendingAssociatedRemote<mojom::blink::CacheStorageCache> + cache_pending_remote, + std::unique_ptr<RequestEntriesCallback> callback) : params_(params), num_responses_left_(num_responses), - cache_ptr_(std::move(cache_ptr)), + cache_remote_(std::move(cache_pending_remote)), callback_(std::move(callback)) {} void Dispatch(Vector<mojom::blink::FetchAPIRequestPtr> old_requests) { @@ -261,21 +265,22 @@ class ResponsesAccumulator : public RefCounted<ResponsesAccumulator> { request->redirect_mode, request->integrity, request->priority, request->fetch_window_id, request->keepalive, request->is_reload, request->is_history_navigation); - cache_ptr_->Match(std::move(request), - mojom::blink::CacheQueryOptions::New(), trace_id, - WTF::Bind( - [](scoped_refptr<ResponsesAccumulator> accumulator, - mojom::blink::FetchAPIRequestPtr request, - mojom::blink::MatchResultPtr result) { - if (result->is_status()) { - accumulator->SendFailure(result->get_status()); - } else { - accumulator->AddRequestResponsePair( - request, result->get_response()); - } - }, - scoped_refptr<ResponsesAccumulator>(this), - std::move(request_clone_without_body))); + cache_remote_->Match( + std::move(request), mojom::blink::CacheQueryOptions::New(), + false /* in_related_fetch_event */, trace_id, + WTF::Bind( + [](scoped_refptr<ResponsesAccumulator> accumulator, + mojom::blink::FetchAPIRequestPtr request, + mojom::blink::MatchResultPtr result) { + if (result->is_status()) { + accumulator->SendFailure(result->get_status()); + } else { + accumulator->AddRequestResponsePair(request, + result->get_response()); + } + }, + scoped_refptr<ResponsesAccumulator>(this), + std::move(request_clone_without_body))); } } @@ -362,7 +367,7 @@ class ResponsesAccumulator : public RefCounted<ResponsesAccumulator> { DataRequestParams params_; int num_responses_left_; Vector<RequestResponse> responses_; - mojom::blink::CacheStorageCacheAssociatedPtr cache_ptr_; + mojo::AssociatedRemote<mojom::blink::CacheStorageCache> cache_remote_; std::unique_ptr<RequestEntriesCallback> callback_; DISALLOW_COPY_AND_ASSIGN(ResponsesAccumulator); @@ -374,10 +379,11 @@ class GetCacheKeysForRequestData { public: GetCacheKeysForRequestData( const DataRequestParams& params, - mojom::blink::CacheStorageCacheAssociatedPtrInfo cache_ptr_info, + mojo::PendingAssociatedRemote<mojom::blink::CacheStorageCache> + cache_pending_remote, std::unique_ptr<RequestEntriesCallback> callback) : params_(params), callback_(std::move(callback)) { - cache_ptr_.Bind(std::move(cache_ptr_info)); + cache_remote_.Bind(std::move(cache_pending_remote)); } void Dispatch(std::unique_ptr<GetCacheKeysForRequestData> self) { @@ -385,7 +391,7 @@ class GetCacheKeysForRequestData { TRACE_EVENT_WITH_FLOW0( "CacheStorage", "GetCacheKeysForRequestData::Dispatch", TRACE_ID_GLOBAL(trace_id), TRACE_EVENT_FLAG_FLOW_OUT); - cache_ptr_->Keys( + cache_remote_->Keys( nullptr /* request */, mojom::blink::CacheQueryOptions::New(), trace_id, WTF::Bind( [](DataRequestParams params, @@ -406,7 +412,7 @@ class GetCacheKeysForRequestData { scoped_refptr<ResponsesAccumulator> accumulator = base::AdoptRef(new ResponsesAccumulator( result->get_keys().size(), params, - std::move(self->cache_ptr_), + self->cache_remote_.Unbind(), std::move(self->callback_))); accumulator->Dispatch(std::move(result->get_keys())); } @@ -416,7 +422,7 @@ class GetCacheKeysForRequestData { private: DataRequestParams params_; - mojom::blink::CacheStorageCacheAssociatedPtr cache_ptr_; + mojo::AssociatedRemote<mojom::blink::CacheStorageCache> cache_remote_; std::unique_ptr<RequestEntriesCallback> callback_; DISALLOW_COPY_AND_ASSIGN(GetCacheKeysForRequestData); @@ -653,13 +659,15 @@ void InspectorCacheStorageAgent::deleteEntry( operation->request->url = KURL(request); operation->request->method = String("GET"); - mojom::blink::CacheStorageCacheAssociatedPtr cache_ptr; - cache_ptr.Bind(std::move(result->get_cache())); - auto* cache = cache_ptr.get(); + mojo::AssociatedRemote<mojom::blink::CacheStorageCache> + cache_remote; + cache_remote.Bind(std::move(result->get_cache())); + auto* cache = cache_remote.get(); cache->Batch( std::move(batch_operations), trace_id, WTF::Bind( - [](mojom::blink::CacheStorageCacheAssociatedPtr cache_ptr, + [](mojo::AssociatedRemote<mojom::blink::CacheStorageCache> + cache_remote, std::unique_ptr<DeleteEntryCallback> callback, mojom::blink::CacheStorageVerboseErrorPtr error) { if (error->value != @@ -673,7 +681,7 @@ void InspectorCacheStorageAgent::deleteEntry( callback->sendSuccess(); } }, - std::move(cache_ptr), std::move(callback))); + std::move(cache_remote), std::move(callback))); } }, cache_name, request, trace_id, std::move(callback))); @@ -711,7 +719,8 @@ void InspectorCacheStorageAgent::requestCachedResponse( multi_query_options->cache_name = cache_name; cache_storage->Match( - std::move(request), std::move(multi_query_options), trace_id, + std::move(request), std::move(multi_query_options), + false /* in_related_fetch_event */, trace_id, WTF::Bind( [](std::unique_ptr<RequestCachedResponseCallback> callback, mojom::blink::MatchResultPtr result) { diff --git a/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h b/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h index b75220c895e..52681c295a8 100644 --- a/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h +++ b/chromium/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h @@ -9,7 +9,7 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" +#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink-forward.h" #include "third_party/blink/renderer/core/inspector/inspector_base_agent.h" #include "third_party/blink/renderer/core/inspector/protocol/CacheStorage.h" #include "third_party/blink/renderer/modules/modules_export.h" diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS index aaee473139e..11fa35c31af 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS @@ -1,3 +1,10 @@ include_rules = [ "+third_party/skia/include", -]
\ No newline at end of file +] + +specific_include_rules = { + # Additional allowed includes for tests. + ".*_test(_.*)?\.(cc|h)" : [ + "+components/viz", + ] +}
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc index b54d60ee2d0..fbbd98d2f7d 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc @@ -1597,6 +1597,9 @@ ImageData* BaseRenderingContext2D::getImageData( WTF::ArrayBufferContents contents; const CanvasColorParams& color_params = ColorParams(); + // Deferred offscreen canvases might have recorded commands, make sure + // that those get drawn here + FinalizeFrame(); scoped_refptr<StaticBitmapImage> snapshot = GetImage(kPreferNoAcceleration); // GetImagedata is faster in Unaccelerated canvases @@ -1609,8 +1612,6 @@ ImageData* BaseRenderingContext2D::getImageData( return nullptr; } - NeedsFinalizeFrame(); - // Convert pixels to proper storage format if needed if (PixelFormat() != kRGBA8CanvasPixelFormat) { ImageDataStorageFormat storage_format = diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h index 112f4aa0c10..5ad18e2ea4e 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h @@ -193,6 +193,8 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, ImageDataColorSettings*, ExceptionState&) const; + // For deferred canvases this will have the side effect of drawing recorded + // commands in order to finalize the frame ImageData* getImageData(int sx, int sy, int sw, int sh, ExceptionState&); void putImageData(ImageData*, int dx, int dy, ExceptionState&); void putImageData(ImageData*, @@ -341,7 +343,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, NOTREACHED(); return false; } - virtual scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) const { + virtual scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) { NOTREACHED(); return nullptr; } @@ -361,7 +363,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, mutable UsageCounters usage_counters_; - virtual void NeedsFinalizeFrame() {} + virtual void FinalizeFrame() {} float GetFontBaseline(const SimpleFontData&) const; diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc index 5df98e9f9b6..e2c68071542 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc @@ -317,7 +317,7 @@ CanvasPixelFormat CanvasRenderingContext2D::PixelFormat() const { } void CanvasRenderingContext2D::Reset() { - // This is a multiple inherritance bootstrap + // This is a multiple inheritance bootstrap BaseRenderingContext2D::Reset(); } @@ -665,12 +665,19 @@ bool CanvasRenderingContext2D::CanCreateCanvas2dResourceProvider() const { } scoped_refptr<StaticBitmapImage> blink::CanvasRenderingContext2D::GetImage( - AccelerationHint hint) const { + AccelerationHint hint) { if (!IsPaintable()) return nullptr; return canvas()->GetCanvas2DLayerBridge()->NewImageSnapshot(hint); } +void CanvasRenderingContext2D::FinalizeFrame() { + TRACE_EVENT0("blink", "CanvasRenderingContext2D::FinalizeFrame"); + if (canvas() && canvas()->GetCanvas2DLayerBridge()) + canvas()->GetCanvas2DLayerBridge()->FinalizeFrame(); + usage_counters_.num_frames_since_reset++; +} + bool CanvasRenderingContext2D::ParseColorOrCurrentColor( Color& color, const String& color_string) const { @@ -1132,4 +1139,11 @@ bool CanvasRenderingContext2D::IsCanvas2DBufferValid() const { return false; } +bool CanvasRenderingContext2D::IsDeferralEnabled() const { + Canvas2DLayerBridge* layer_bridge = canvas()->GetCanvas2DLayerBridge(); + if (!layer_bridge) + return false; + return layer_bridge->IsDeferralEnabled(); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h index 4f26dd20247..d0e157a83c3 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h @@ -87,7 +87,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final static_cast<HTMLCanvasElement*>(host), attrs); } CanvasRenderingContext::ContextType GetContextType() const override { - return CanvasRenderingContext::kContext2d; + return CanvasRenderingContext::kContext2D; } private: @@ -182,7 +182,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final cc::PaintCanvas* ExistingDrawingCanvas() const final; void DidDraw(const SkIRect& dirty_rect) final; - scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) const final; + scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final; bool StateHasFilter() final; sk_sp<PaintFilter> StateGetFilter() final; @@ -190,7 +190,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final void ValidateStateStack() const final; - void FinalizeFrame() override { usage_counters_.num_frames_since_reset++; } + void FinalizeFrame() override; bool IsPaintable() const final { return canvas()->GetCanvas2DLayerBridge(); } @@ -200,11 +200,9 @@ class MODULES_EXPORT CanvasRenderingContext2D final CanvasColorParams ColorParamsForTest() const { return ColorParams(); } - protected: - void NeedsFinalizeFrame() override { - CanvasRenderingContext::NeedsFinalizeFrame(); - } + bool IsDeferralEnabled() const final; + protected: CanvasColorParams ColorParams() const override; bool WritePixels(const SkImageInfo& orig_info, const void* pixels, @@ -238,7 +236,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final void UpdateElementAccessibility(const Path&, Element*); CanvasRenderingContext::ContextType GetContextType() const override { - return CanvasRenderingContext::kContext2d; + return CanvasRenderingContext::kContext2D; } String ColorSpaceAsString() const override; diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc index 9e7f31e88be..f7f5fd9ab31 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_api_test.cc @@ -32,7 +32,7 @@ class CanvasRenderingContext2DAPITest : public PageTestBase { void SetUp() override; HTMLCanvasElement& CanvasElement() const { return *canvas_element_; } - CanvasRenderingContext2D* Context2d() const; + CanvasRenderingContext2D* Context2D() const; void CreateContext(OpacityMode); @@ -42,7 +42,7 @@ class CanvasRenderingContext2DAPITest : public PageTestBase { CanvasRenderingContext2DAPITest::CanvasRenderingContext2DAPITest() = default; -CanvasRenderingContext2D* CanvasRenderingContext2DAPITest::Context2d() const { +CanvasRenderingContext2D* CanvasRenderingContext2DAPITest::Context2D() const { // If the following check fails, perhaps you forgot to call createContext // in your test? EXPECT_NE(nullptr, CanvasElement().RenderingContext()); @@ -56,7 +56,7 @@ void CanvasRenderingContext2DAPITest::CreateContext(OpacityMode opacity_mode) { CanvasContextCreationAttributesCore attributes; attributes.alpha = opacity_mode == kNonOpaque; canvas_element_->GetCanvasRenderingContext(canvas_type, attributes); - Context2d(); // Calling this for the checks + Context2D(); // Calling this for the checks } void CanvasRenderingContext2DAPITest::SetUp() { @@ -70,13 +70,13 @@ void CanvasRenderingContext2DAPITest::SetUp() { TEST_F(CanvasRenderingContext2DAPITest, SetShadowColor_Clamping) { CreateContext(kNonOpaque); - Context2d()->setShadowColor("rgba(0,0,0,0)"); - EXPECT_EQ(String("rgba(0, 0, 0, 0)"), Context2d()->shadowColor()); - Context2d()->setShadowColor("rgb(0,0,0)"); - EXPECT_EQ(String("#000000"), Context2d()->shadowColor()); - Context2d()->setShadowColor("rgb(0,999,0)"); - EXPECT_EQ(String("#00ff00"), Context2d()->shadowColor()); - Context2d()->setShadowColor( + Context2D()->setShadowColor("rgba(0,0,0,0)"); + EXPECT_EQ(String("rgba(0, 0, 0, 0)"), Context2D()->shadowColor()); + Context2D()->setShadowColor("rgb(0,0,0)"); + EXPECT_EQ(String("#000000"), Context2D()->shadowColor()); + Context2D()->setShadowColor("rgb(0,999,0)"); + EXPECT_EQ(String("#00ff00"), Context2D()->shadowColor()); + Context2D()->setShadowColor( "rgb(0," "999999999999999999999999999999999999999999999999999999999999999999999999" "999999999999999999999999999999999999999999999999999999999999999999999999" @@ -86,23 +86,23 @@ TEST_F(CanvasRenderingContext2DAPITest, SetShadowColor_Clamping) { "999999999999999999999999999999999999999999999999999999999999999999999999" "999999999999999999999999999999999999999999999999999999999999999999999999" ",0)"); - EXPECT_EQ(String("#00ff00"), Context2d()->shadowColor()); - Context2d()->setShadowColor("rgb(0,0,256)"); - EXPECT_EQ(String("#0000ff"), Context2d()->shadowColor()); - Context2d()->setShadowColor( + EXPECT_EQ(String("#00ff00"), Context2D()->shadowColor()); + Context2D()->setShadowColor("rgb(0,0,256)"); + EXPECT_EQ(String("#0000ff"), Context2D()->shadowColor()); + Context2D()->setShadowColor( "rgb(999999999999999999999999,0,-9999999999999999999999999999)"); - EXPECT_EQ(String("#ff0000"), Context2d()->shadowColor()); - Context2d()->setShadowColor( + EXPECT_EQ(String("#ff0000"), Context2D()->shadowColor()); + Context2D()->setShadowColor( "rgba(" "999999999999999999999999999999999999999999999999999999999999999999999999" "9999999999,9,0,1)"); - EXPECT_EQ(String("#ff0900"), Context2d()->shadowColor()); - Context2d()->setShadowColor( + EXPECT_EQ(String("#ff0900"), Context2D()->shadowColor()); + Context2D()->setShadowColor( "rgba(" "999999999999999999999999999999999999999999999999999999999999999999999999" "9999999999,9,0,-99999999999999999999999999999999999999)"); - EXPECT_EQ(String("rgba(255, 9, 0, 0)"), Context2d()->shadowColor()); - Context2d()->setShadowColor( + EXPECT_EQ(String("rgba(255, 9, 0, 0)"), Context2D()->shadowColor()); + Context2D()->setShadowColor( "rgba(7," "999999999999999999999999999999999999999999999999999999999999999999999999" "9999999999,0," @@ -114,8 +114,8 @@ TEST_F(CanvasRenderingContext2DAPITest, SetShadowColor_Clamping) { "999999999999999999999999999999999999999999999999999999999999999999999999" "999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999)"); - EXPECT_EQ(String("#07ff00"), Context2d()->shadowColor()); - Context2d()->setShadowColor( + EXPECT_EQ(String("#07ff00"), Context2D()->shadowColor()); + Context2D()->setShadowColor( "rgba(-7," "999999999999999999999999999999999999999999999999999999999999999999999999" "9999999999,0," @@ -127,9 +127,9 @@ TEST_F(CanvasRenderingContext2DAPITest, SetShadowColor_Clamping) { "999999999999999999999999999999999999999999999999999999999999999999999999" "999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999)"); - EXPECT_EQ(String("#00ff00"), Context2d()->shadowColor()); - Context2d()->setShadowColor("rgba(0%,100%,0%,0.4)"); - EXPECT_EQ(String("rgba(0, 255, 0, 0.4)"), Context2d()->shadowColor()); + EXPECT_EQ(String("#00ff00"), Context2D()->shadowColor()); + Context2D()->setShadowColor("rgba(0%,100%,0%,0.4)"); + EXPECT_EQ(String("rgba(0, 255, 0, 0.4)"), Context2D()->shadowColor()); } String TrySettingStrokeStyle(CanvasRenderingContext2D* ctx, @@ -173,15 +173,15 @@ void TrySettingColor(CanvasRenderingContext2D* ctx, TEST_F(CanvasRenderingContext2DAPITest, ColorSerialization) { CreateContext(kNonOpaque); // Check round trips - TrySettingColor(Context2d(), "transparent", "rgba(0, 0, 0, 0)"); - TrySettingColor(Context2d(), "red", "#ff0000"); - TrySettingColor(Context2d(), "white", "#ffffff"); - TrySettingColor(Context2d(), "", "#666666"); - TrySettingColor(Context2d(), "RGBA(0, 0, 0, 0)", "rgba(0, 0, 0, 0)"); - TrySettingColor(Context2d(), "rgba(0,255,0,1.0)", "#00ff00"); - TrySettingColor(Context2d(), "rgba(1,2,3,0.4)", "rgba(1, 2, 3, 0.4)"); - TrySettingColor(Context2d(), "RgB(1,2,3)", "#010203"); - TrySettingColor(Context2d(), "rGbA(1,2,3,0)", "rgba(1, 2, 3, 0)"); + TrySettingColor(Context2D(), "transparent", "rgba(0, 0, 0, 0)"); + TrySettingColor(Context2D(), "red", "#ff0000"); + TrySettingColor(Context2D(), "white", "#ffffff"); + TrySettingColor(Context2D(), "", "#666666"); + TrySettingColor(Context2D(), "RGBA(0, 0, 0, 0)", "rgba(0, 0, 0, 0)"); + TrySettingColor(Context2D(), "rgba(0,255,0,1.0)", "#00ff00"); + TrySettingColor(Context2D(), "rgba(1,2,3,0.4)", "rgba(1, 2, 3, 0.4)"); + TrySettingColor(Context2D(), "RgB(1,2,3)", "#010203"); + TrySettingColor(Context2D(), "rGbA(1,2,3,0)", "rgba(1, 2, 3, 0)"); } TEST_F(CanvasRenderingContext2DAPITest, DefaultAttributeValues) { @@ -189,19 +189,19 @@ TEST_F(CanvasRenderingContext2DAPITest, DefaultAttributeValues) { { StringOrCanvasGradientOrCanvasPattern value; - Context2d()->strokeStyle(value); + Context2D()->strokeStyle(value); EXPECT_TRUE(value.IsString()); EXPECT_EQ(String("#000000"), value.GetAsString()); } { StringOrCanvasGradientOrCanvasPattern value; - Context2d()->fillStyle(value); + Context2D()->fillStyle(value); EXPECT_TRUE(value.IsString()); EXPECT_EQ(String("#000000"), value.GetAsString()); } - EXPECT_EQ(String("rgba(0, 0, 0, 0)"), Context2d()->shadowColor()); + EXPECT_EQ(String("rgba(0, 0, 0, 0)"), Context2D()->shadowColor()); } TEST_F(CanvasRenderingContext2DAPITest, LineDashStateSave) { @@ -211,14 +211,14 @@ TEST_F(CanvasRenderingContext2DAPITest, LineDashStateSave) { simple_dash.push_back(4); simple_dash.push_back(2); - Context2d()->setLineDash(simple_dash); - EXPECT_EQ(simple_dash, Context2d()->getLineDash()); - Context2d()->save(); + Context2D()->setLineDash(simple_dash); + EXPECT_EQ(simple_dash, Context2D()->getLineDash()); + Context2D()->save(); // Realize the save. - Context2d()->scale(2, 2); - EXPECT_EQ(simple_dash, Context2d()->getLineDash()); - Context2d()->restore(); - EXPECT_EQ(simple_dash, Context2d()->getLineDash()); + Context2D()->scale(2, 2); + EXPECT_EQ(simple_dash, Context2D()->getLineDash()); + Context2D()->restore(); + EXPECT_EQ(simple_dash, Context2D()->getLineDash()); } TEST_F(CanvasRenderingContext2DAPITest, CreateImageData) { @@ -228,7 +228,7 @@ TEST_F(CanvasRenderingContext2DAPITest, CreateImageData) { // create a 100x50 imagedata and fill it with white pixels ImageData* image_data = - Context2d()->createImageData(100, 50, exception_state); + Context2D()->createImageData(100, 50, exception_state); EXPECT_FALSE(exception_state.HadException()); EXPECT_EQ(100, image_data->width()); EXPECT_EQ(50, image_data->height()); @@ -242,7 +242,7 @@ TEST_F(CanvasRenderingContext2DAPITest, CreateImageData) { // as 'imageData' but filled with transparent black ImageData* same_size_image_data = - Context2d()->createImageData(image_data, exception_state); + Context2D()->createImageData(image_data, exception_state); EXPECT_FALSE(exception_state.HadException()); EXPECT_EQ(100, same_size_image_data->width()); EXPECT_EQ(50, same_size_image_data->height()); @@ -251,13 +251,13 @@ TEST_F(CanvasRenderingContext2DAPITest, CreateImageData) { // createImageData(width, height) takes the absolute magnitude of the size // arguments - ImageData* imgdata1 = Context2d()->createImageData(10, 20, exception_state); + ImageData* imgdata1 = Context2D()->createImageData(10, 20, exception_state); EXPECT_FALSE(exception_state.HadException()); - ImageData* imgdata2 = Context2d()->createImageData(-10, 20, exception_state); + ImageData* imgdata2 = Context2D()->createImageData(-10, 20, exception_state); EXPECT_FALSE(exception_state.HadException()); - ImageData* imgdata3 = Context2d()->createImageData(10, -20, exception_state); + ImageData* imgdata3 = Context2D()->createImageData(10, -20, exception_state); EXPECT_FALSE(exception_state.HadException()); - ImageData* imgdata4 = Context2d()->createImageData(-10, -20, exception_state); + ImageData* imgdata4 = Context2D()->createImageData(-10, -20, exception_state); EXPECT_FALSE(exception_state.HadException()); EXPECT_EQ((unsigned)800, imgdata1->data()->length()); @@ -270,7 +270,7 @@ TEST_F(CanvasRenderingContext2DAPITest, CreateImageDataTooBig) { CreateContext(kNonOpaque); DummyExceptionStateForTesting exception_state; ImageData* too_big_image_data = - Context2d()->createImageData(1000000, 1000000, exception_state); + Context2D()->createImageData(1000000, 1000000, exception_state); EXPECT_EQ(nullptr, too_big_image_data); EXPECT_TRUE(exception_state.HadException()); EXPECT_EQ(ESErrorType::kRangeError, exception_state.CodeAs<ESErrorType>()); @@ -280,7 +280,7 @@ TEST_F(CanvasRenderingContext2DAPITest, GetImageDataTooBig) { CreateContext(kNonOpaque); DummyExceptionStateForTesting exception_state; ImageData* image_data = - Context2d()->getImageData(0, 0, 1000000, 1000000, exception_state); + Context2D()->getImageData(0, 0, 1000000, 1000000, exception_state); EXPECT_EQ(nullptr, image_data); EXPECT_TRUE(exception_state.HadException()); EXPECT_EQ(ESErrorType::kRangeError, exception_state.CodeAs<ESErrorType>()); @@ -290,14 +290,14 @@ TEST_F(CanvasRenderingContext2DAPITest, GetImageDataIntegerOverflowNegativeParams) { CreateContext(kNonOpaque); DummyExceptionStateForTesting exception_state; - ImageData* image_data = Context2d()->getImageData( + ImageData* image_data = Context2D()->getImageData( 1, -2147483647, 1, -2147483647, exception_state); EXPECT_EQ(nullptr, image_data); EXPECT_TRUE(exception_state.HadException()); EXPECT_EQ(ESErrorType::kRangeError, exception_state.CodeAs<ESErrorType>()); exception_state.ClearException(); - image_data = Context2d()->getImageData(-2147483647, 1, -2147483647, 1, + image_data = Context2D()->getImageData(-2147483647, 1, -2147483647, 1, exception_state); EXPECT_EQ(nullptr, image_data); EXPECT_TRUE(exception_state.HadException()); diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc index 8c99835e7e0..b670fe73bca 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.cc @@ -8,6 +8,7 @@ #include "third_party/blink/renderer/core/css/resolver/filter_operation_resolver.h" #include "third_party/blink/renderer/core/css/resolver/style_builder.h" #include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" #include "third_party/blink/renderer/core/paint/filter_effect_builder.h" #include "third_party/blink/renderer/core/style/computed_style.h" @@ -334,8 +335,18 @@ sk_sp<PaintFilter> CanvasRenderingContext2DState::GetFilter( scoped_refptr<ComputedStyle> filter_style = ComputedStyle::Create(); // Must set font in case the filter uses any font-relative units (em, ex) - filter_style->SetFont(font_for_filter_); - + // If font_for_filter_ was never set (ie frame-less documents) use base font + if (LIKELY(font_for_filter_.GetFontSelector())) { + filter_style->SetFont(font_for_filter_); + } else { + const ComputedStyle* computed_style = + style_resolution_host->GetDocument().GetComputedStyle(); + if (computed_style) { + filter_style->SetFont(computed_style->GetFont()); + } else { + return nullptr; + } + } StyleResolverState resolver_state(style_resolution_host->GetDocument(), *style_resolution_host, filter_style.get(), filter_style.get()); @@ -617,7 +628,7 @@ bool CanvasRenderingContext2DState::HasPattern() const { FillStyle()->GetCanvasPattern()->GetPattern(); } -// Only to be used if the CanvasRenderingContext2dState has Pattern +// Only to be used if the CanvasRenderingContext2DState has Pattern bool CanvasRenderingContext2DState::PatternIsAccelerated() const { DCHECK(HasPattern()); return FillStyle()->GetCanvasPattern()->GetPattern()->IsTextureBacked(); diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h index 0e164085d7b..eaf5b21390c 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h @@ -25,7 +25,7 @@ class CSSValue; class Element; class CanvasRenderingContext2DState final - : public GarbageCollectedFinalized<CanvasRenderingContext2DState>, + : public GarbageCollected<CanvasRenderingContext2DState>, public FontSelectorClient { USING_GARBAGE_COLLECTED_MIXIN(CanvasRenderingContext2DState); @@ -119,7 +119,7 @@ class CanvasRenderingContext2DState final bool HasPattern() const; - // Only to be used if the CanvasRenderingContext2dState has Pattern + // Only to be used if the CanvasRenderingContext2DState has Pattern bool PatternIsAccelerated() const; enum Direction { kDirectionInherit, kDirectionRTL, kDirectionLTR }; diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc index 4f9835f30d4..4a33e8cf1a8 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc @@ -6,6 +6,7 @@ #include <memory> #include "build/build_config.h" +#include "components/viz/test/test_context_provider.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" @@ -35,8 +36,7 @@ #include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/test/fake_canvas_resource_host.h" -#include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h" -#include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h" +#include "third_party/blink/renderer/platform/graphics/test/gpu_test_utils.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" @@ -110,13 +110,15 @@ class CanvasRenderingContext2DTest : public ::testing::Test { bool IsCanvasResourceHostSet(Canvas2DLayerBridge* bridge) { return !!bridge->resource_host_; } - CanvasRenderingContext2D* Context2d() const { + CanvasRenderingContext2D* Context2D() const { return static_cast<CanvasRenderingContext2D*>( CanvasElement().RenderingContext()); } void DrawSomething() { CanvasElement().DidDraw(); - CanvasElement().FinalizeFrame(); + CanvasElement().PreFinalizeFrame(); + Context2D()->FinalizeFrame(); + CanvasElement().PostFinalizeFrame(); // Grabbing an image forces a flush CanvasElement().Snapshot(kBackBuffer, kPreferAcceleration); } @@ -155,7 +157,7 @@ class CanvasRenderingContext2DTest : public ::testing::Test { Persistent<MemoryCache> global_memory_cache_; std::unique_ptr<ScopedAccelerated2dCanvasForTest> allow_accelerated_; - class WrapGradients final : public GarbageCollectedFinalized<WrapGradients> { + class WrapGradients final : public GarbageCollected<WrapGradients> { public: void Trace(blink::Visitor* visitor) { visitor->Trace(opaque_gradient_); @@ -176,7 +178,7 @@ class CanvasRenderingContext2DTest : public ::testing::Test { Persistent<ImageData> partial_image_data_; FakeImageSource opaque_bitmap_; FakeImageSource alpha_bitmap_; - FakeGLES2Interface gl_; + scoped_refptr<viz::TestContextProvider> test_context_provider_; StringOrCanvasGradientOrCanvasPattern& OpaqueGradient() { return wrap_gradients_->opaque_gradient_; @@ -201,15 +203,8 @@ void CanvasRenderingContext2DTest::CreateContext(OpacityMode opacity_mode, } void CanvasRenderingContext2DTest::SetUp() { - auto factory = [](FakeGLES2Interface* gl, bool* gpu_compositing_disabled) - -> std::unique_ptr<WebGraphicsContext3DProvider> { - *gpu_compositing_disabled = false; - gl->SetIsContextLost(false); - return std::make_unique<FakeWebGraphicsContext3DProvider>(gl); - }; - SharedGpuContext::SetContextProviderFactoryForTesting( - WTF::BindRepeating(factory, WTF::Unretained(&gl_))); - + test_context_provider_ = viz::TestContextProvider::Create(); + InitializeSharedGpuContext(test_context_provider_.get()); allow_accelerated_.reset( new ScopedAccelerated2dCanvasForTest(AllowsAcceleration())); web_view_helper_ = std::make_unique<frame_test_helpers::WebViewHelper>(); @@ -350,43 +345,43 @@ class MockImageBufferSurfaceForOverwriteTesting : public Canvas2DLayerBridge { CanvasElement().SetResourceProviderForTesting( \ nullptr, std::move(mock_surface), size); \ EXPECT_CALL(*surface_ptr, WillOverwriteCanvas()).Times(EXPECTED_OVERDRAWS); \ - Context2d()->save(); + Context2D()->save(); #define TEST_OVERDRAW_FINALIZE \ - Context2d()->restore(); \ + Context2D()->restore(); \ Mock::VerifyAndClearExpectations(surface_ptr); #define TEST_OVERDRAW_1(EXPECTED_OVERDRAWS, CALL1) \ do { \ TEST_OVERDRAW_SETUP(EXPECTED_OVERDRAWS) \ - Context2d()->CALL1; \ + Context2D()->CALL1; \ TEST_OVERDRAW_FINALIZE \ } while (0) #define TEST_OVERDRAW_2(EXPECTED_OVERDRAWS, CALL1, CALL2) \ do { \ TEST_OVERDRAW_SETUP(EXPECTED_OVERDRAWS) \ - Context2d()->CALL1; \ - Context2d()->CALL2; \ + Context2D()->CALL1; \ + Context2D()->CALL2; \ TEST_OVERDRAW_FINALIZE \ } while (0) #define TEST_OVERDRAW_3(EXPECTED_OVERDRAWS, CALL1, CALL2, CALL3) \ do { \ TEST_OVERDRAW_SETUP(EXPECTED_OVERDRAWS) \ - Context2d()->CALL1; \ - Context2d()->CALL2; \ - Context2d()->CALL3; \ + Context2D()->CALL1; \ + Context2D()->CALL2; \ + Context2D()->CALL3; \ TEST_OVERDRAW_FINALIZE \ } while (0) #define TEST_OVERDRAW_4(EXPECTED_OVERDRAWS, CALL1, CALL2, CALL3, CALL4) \ do { \ TEST_OVERDRAW_SETUP(EXPECTED_OVERDRAWS) \ - Context2d()->CALL1; \ - Context2d()->CALL2; \ - Context2d()->CALL3; \ - Context2d()->CALL4; \ + Context2D()->CALL1; \ + Context2D()->CALL2; \ + Context2D()->CALL3; \ + Context2D()->CALL4; \ TEST_OVERDRAW_FINALIZE \ } while (0) @@ -644,14 +639,14 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) { TEST_F(CanvasRenderingContext2DTest, CanvasDisposedBeforeContext) { CreateContext(kNonOpaque); - Context2d()->fillRect(0, 0, 1, 1); // results in task observer registration + Context2D()->fillRect(0, 0, 1, 1); // results in task observer registration - Context2d()->DetachHost(); + Context2D()->DetachHost(); // This is the only method that is callable after DetachHost // Test passes by not crashing. base::PendingTask dummy_pending_task(FROM_HERE, base::Closure()); - Context2d()->DidProcessTask(dummy_pending_task); + Context2D()->DidProcessTask(dummy_pending_task); // Test passes by not crashing during teardown } @@ -691,7 +686,7 @@ TEST_F(CanvasRenderingContext2DTest, size, CanvasColorParams(), kPreferAcceleration); CanvasElement().SetResourceProviderForTesting( nullptr, std::move(fake_accelerate_surface), size); - CanvasRenderingContext2D* context = Context2d(); + CanvasRenderingContext2D* context = Context2D(); // 800 = 10 * 10 * 4 * 2 where 10*10 is canvas size, 4 is num of bytes per // pixel per buffer, and 2 is an estimate of num of gpu buffers required diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h index d581278e224..909768d929b 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.h @@ -15,7 +15,7 @@ namespace blink { -class HitRegion final : public GarbageCollectedFinalized<HitRegion> { +class HitRegion final : public GarbageCollected<HitRegion> { public: HitRegion(const Path&, const HitRegionOptions*); virtual ~HitRegion() = default; @@ -37,8 +37,7 @@ class HitRegion final : public GarbageCollectedFinalized<HitRegion> { WindRule fill_rule_; }; -class HitRegionManager final - : public GarbageCollectedFinalized<HitRegionManager> { +class HitRegionManager final : public GarbageCollected<HitRegionManager> { public: HitRegionManager() = default; ~HitRegionManager() {} diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc index c064aa71a5d..66271ef4cc5 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" #include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h" #include "third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.h" @@ -36,6 +37,7 @@ void HTMLCanvasElementModule::getContext( } OffscreenCanvas* HTMLCanvasElementModule::transferControlToOffscreen( + ExecutionContext* execution_context, HTMLCanvasElement& canvas, ExceptionState& exception_state) { OffscreenCanvas* offscreen_canvas = nullptr; @@ -45,8 +47,8 @@ OffscreenCanvas* HTMLCanvasElementModule::transferControlToOffscreen( "Cannot transfer control from a canvas for more than one time."); } else { canvas.CreateLayer(); - offscreen_canvas = - TransferControlToOffscreenInternal(canvas, exception_state); + offscreen_canvas = TransferControlToOffscreenInternal( + execution_context, canvas, exception_state); } UMA_HISTOGRAM_BOOLEAN("Blink.OffscreenCanvas.TransferControlToOffscreen", @@ -55,6 +57,7 @@ OffscreenCanvas* HTMLCanvasElementModule::transferControlToOffscreen( } OffscreenCanvas* HTMLCanvasElementModule::TransferControlToOffscreenInternal( + ExecutionContext* execution_context, HTMLCanvasElement& canvas, ExceptionState& exception_state) { if (canvas.RenderingContext()) { @@ -63,10 +66,16 @@ OffscreenCanvas* HTMLCanvasElementModule::TransferControlToOffscreenInternal( "Cannot transfer control from a canvas that has a rendering context."); return nullptr; } - OffscreenCanvas* offscreen_canvas = - OffscreenCanvas::Create(canvas.width(), canvas.height()); + OffscreenCanvas* offscreen_canvas = OffscreenCanvas::Create( + execution_context, canvas.width(), canvas.height()); offscreen_canvas->SetFilterQuality(canvas.FilterQuality()); + // If this canvas is cross-origin, then the associated offscreen canvas + // should prefer using the low-power GPU. + LocalFrame* frame = canvas.GetDocument().GetFrame(); + if (!(frame && frame->IsCrossOriginSubframe())) + offscreen_canvas->AllowHighPerformancePowerPreference(); + DOMNodeId canvas_id = DOMNodeIds::IdForNode(&canvas); offscreen_canvas->SetPlaceholderCanvasId(canvas_id); canvas.RegisterPlaceholderCanvas(static_cast<int>(canvas_id)); diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h index 2752cff6ec0..85dff7093da 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.h @@ -26,11 +26,13 @@ class MODULES_EXPORT HTMLCanvasElementModule { const CanvasContextCreationAttributesModule*, ExceptionState&, RenderingContext&); - static OffscreenCanvas* transferControlToOffscreen(HTMLCanvasElement&, + static OffscreenCanvas* transferControlToOffscreen(ExecutionContext*, + HTMLCanvasElement&, ExceptionState&); private: - static OffscreenCanvas* TransferControlToOffscreenInternal(HTMLCanvasElement&, + static OffscreenCanvas* TransferControlToOffscreenInternal(ExecutionContext*, + HTMLCanvasElement&, ExceptionState&); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.idl b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.idl index c342789f3c5..1c40f9aef68 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.idl +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.idl @@ -24,6 +24,6 @@ typedef (CanvasRenderingContext2D or // Related spec issue: https://github.com/whatwg/html/issues/595 [RaisesException] RenderingContext? getContext(DOMString contextId, [PermissiveDictionaryConversion] optional CanvasContextCreationAttributesModule attributes); - [RuntimeEnabled=SurfaceEmbeddingFeatures, + [CallWith=ExecutionContext, RuntimeEnabled=SurfaceEmbeddingFeatures, RaisesException, MeasureAs=OffscreenCanvas] OffscreenCanvas transferControlToOffscreen(); }; diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl index 60d6efdc2da..3ca7190541e 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_support_webgl2_compute.idl @@ -24,5 +24,5 @@ typedef (CanvasRenderingContext2D or // (and is not undefined or null). The binding must ignore this. // Related spec issue: https://github.com/whatwg/html/issues/595 [RaisesException] RenderingContext? getContext(DOMString contextId, [PermissiveDictionaryConversion] optional CanvasContextCreationAttributesModule attributes); - [RaisesException, MeasureAs=OffscreenCanvas, RuntimeEnabled=SurfaceEmbeddingFeatures] OffscreenCanvas transferControlToOffscreen(); + [CallWith=ExecutionContext, RaisesException, MeasureAs=OffscreenCanvas, RuntimeEnabled=SurfaceEmbeddingFeatures] OffscreenCanvas transferControlToOffscreen(); }; diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc index d2562abcddc..7ba7ea2d500 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc @@ -10,6 +10,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/frame_sinks/embedded_frame_sink.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" @@ -67,7 +68,7 @@ class HTMLCanvasElementModuleTest : public ::testing::Test, HTMLCanvasElement& canvas_element() const { return *canvas_element_; } OffscreenCanvas* TransferControlToOffscreen(ExceptionState& exception_state) { return HTMLCanvasElementModule::TransferControlToOffscreenInternal( - canvas_element(), exception_state); + &GetDocument(), canvas_element(), exception_state); } frame_test_helpers::WebViewHelper web_view_helper_; @@ -144,7 +145,9 @@ TEST_P(HTMLCanvasElementModuleTest, LowLatencyCanvasCompositorFrameOpacity) { EXPECT_NE(shared_quad_state_list.front()->are_contents_opaque, context_alpha); }))); - canvas_element().FinalizeFrame(); + canvas_element().PreFinalizeFrame(); + context_->FinalizeFrame(); + canvas_element().PostFinalizeFrame(); platform->RunUntilIdle(); } diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc index 801b9140d0f..99ba3fc72c2 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.cc @@ -51,7 +51,7 @@ void ImageBitmapRenderingContextBase::SetImage(ImageBitmap* image_bitmap) { } scoped_refptr<StaticBitmapImage> ImageBitmapRenderingContextBase::GetImage( - AccelerationHint) const { + AccelerationHint) { return image_layer_bridge_->GetImage(); } @@ -63,7 +63,7 @@ ImageBitmapRenderingContextBase::GetImageAndResetInternal() { SkBitmap black_bitmap; black_bitmap.allocN32Pixels(copy_image->width(), copy_image->height()); - black_bitmap.eraseColor(SkColorSetRGB(0, 0, 0)); + black_bitmap.eraseARGB(0, 0, 0, 0); image_layer_bridge_->SetImage( StaticBitmapImage::Create(SkImage::MakeFromBitmap(black_bitmap))); @@ -99,11 +99,11 @@ bool ImageBitmapRenderingContextBase::CanCreateCanvas2dResourceProvider() return !!static_cast<OffscreenCanvas*>(Host())->GetOrCreateResourceProvider(); } -void ImageBitmapRenderingContextBase::PushFrame() { +bool ImageBitmapRenderingContextBase::PushFrame() { DCHECK(Host()); DCHECK(Host()->IsOffscreenCanvas()); if (!CanCreateCanvas2dResourceProvider()) - return; + return false; scoped_refptr<StaticBitmapImage> image = image_layer_bridge_->GetImage(); cc::PaintFlags paint_flags; @@ -116,6 +116,7 @@ void ImageBitmapRenderingContextBase::PushFrame() { std::move(resource), SkIRect::MakeWH(image_layer_bridge_->GetImage()->Size().Width(), image_layer_bridge_->GetImage()->Size().Height())); + return true; } bool ImageBitmapRenderingContextBase::IsOriginTopLeft() const { diff --git a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h index 7cb61cd9c5e..7f6ce8530d6 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h +++ b/chromium/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h @@ -43,9 +43,9 @@ class MODULES_EXPORT ImageBitmapRenderingContextBase void SetIsHidden(bool) override {} bool isContextLost() const override { return false; } void SetImage(ImageBitmap*); - // The acceleration hing here is ignored as GetImage(AccelerationHint) only + // The acceleration hint here is ignored as GetImage(AccelerationHint) only // calls to image_layer_bridge->GetImage(), without giving it a hint - scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) const final; + scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final; // This function resets the internal image resource to a image of the same // size than the original, with the same properties, but completely black. // This is used to follow the standard regarding transferToBitmap @@ -53,7 +53,7 @@ class MODULES_EXPORT ImageBitmapRenderingContextBase void SetUV(const FloatPoint& left_top, const FloatPoint& right_bottom); bool IsComposited() const final { return true; } bool IsAccelerated() const final; - void PushFrame() override; + bool PushFrame() override; bool IsOriginTopLeft() const override; diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc index 3c90dfbb7e1..025d75da414 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_test.cc @@ -92,7 +92,7 @@ void OffscreenCanvasTest::SetUp() { DummyExceptionStateForTesting exception_state; offscreen_canvas_ = HTMLCanvasElementModule::transferControlToOffscreen( - *canvas_element, exception_state); + &GetDocument(), *canvas_element, exception_state); // |offscreen_canvas_| should inherit the FrameSinkId from |canvas_element|s // SurfaceLayerBridge, but in tests this id is zero; fill it up by hand. offscreen_canvas_->SetFrameSinkId(kClientId, kSinkId); diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc index 8fc6edaec56..bd9d23f974a 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h" #include "base/metrics/histogram_functions.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/renderer/bindings/modules/v8/offscreen_rendering_context.h" #include "third_party/blink/renderer/core/css/offscreen_font_selector.h" #include "third_party/blink/renderer/core/css/parser/css_parser.h" @@ -19,6 +20,7 @@ #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" +#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/text/bidi_text_run.h" @@ -79,8 +81,26 @@ OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D( OffscreenCanvas* canvas, const CanvasContextCreationAttributesCore& attrs) : CanvasRenderingContext(canvas, attrs), + is_deferral_enabled_( + base::FeatureList::IsEnabled(features::kCanvasAlwaysDeferral)), random_generator_((uint32_t)base::RandUint64()), bernoulli_distribution_(kUMASampleProbability) { + is_valid_size_ = IsValidImageSize(Host()->Size()); + + if (is_deferral_enabled_) { + StartRecording(); + + // Clear the background transparent or opaque. Similar code at + // CanvasResourceProvider::Clear(). + if (IsCanvas2DBufferValid()) { + DCHECK(recorder_); + recorder_->getRecordingCanvas()->clear( + ColorParams().GetOpacityMode() == kOpaque ? SK_ColorBLACK + : SK_ColorTRANSPARENT); + DidDraw(); + } + } + ExecutionContext* execution_context = canvas->GetTopExecutionContext(); if (auto* document = DynamicTo<Document>(execution_context)) { Settings* settings = document->GetSettings(); @@ -104,10 +124,50 @@ void OffscreenCanvasRenderingContext2D::commit() { // TODO(fserb): consolidate this with PushFrame SkIRect damage_rect(dirty_rect_for_commit_); dirty_rect_for_commit_.setEmpty(); + FinalizeFrame(); Host()->Commit(ProduceCanvasResource(), damage_rect); GetOffscreenFontCache().PruneLocalFontCache(kMaxCachedFonts); } +void OffscreenCanvasRenderingContext2D::StartRecording() { + DCHECK(is_deferral_enabled_); + recorder_ = std::make_unique<PaintRecorder>(); + + cc::PaintCanvas* canvas = recorder_->beginRecording(Width(), Height()); + // Always save an initial frame, to support resetting the top level matrix + // and clip. + canvas->save(); + + RestoreMatrixClipStack(canvas); +} + +void OffscreenCanvasRenderingContext2D::FlushRecording() { + if (!have_recorded_draw_commands_) + return; + + { // Make a new scope so that PaintRecord gets deleted and that gets timed + CanvasResourceProvider* resource_provider = GetCanvasResourceProvider(); + cc::PaintCanvas* canvas = resource_provider->Canvas(); + canvas->drawPicture(recorder_->finishRecordingAsPicture()); + resource_provider->FlushSkia(); + } + GetCanvasResourceProvider()->ReleaseLockedImages(); + + if (is_deferral_enabled_) + StartRecording(); + have_recorded_draw_commands_ = false; +} + +void OffscreenCanvasRenderingContext2D::FinalizeFrame() { + TRACE_EVENT0("blink", "OffscreenCanvasRenderingContext2D::FinalizeFrame"); + + // Make sure surface is ready for painting: fix the rendering mode now + // because it will be too late during the paint invalidation phase. + if (!GetOrCreateCanvasResourceProvider()) + return; + FlushRecording(); +} + // BaseRenderingContext2D implementation bool OffscreenCanvasRenderingContext2D::OriginClean() const { return Host()->OriginClean(); @@ -134,7 +194,13 @@ bool OffscreenCanvasRenderingContext2D::CanCreateCanvas2dResourceProvider() const { if (!Host() || Host()->Size().IsEmpty()) return false; - return !!offscreenCanvasForBinding()->GetOrCreateResourceProvider(); + return !!GetOrCreateCanvasResourceProvider(); +} + +CanvasResourceProvider* +OffscreenCanvasRenderingContext2D::GetOrCreateCanvasResourceProvider() const { + // TODO(aaronhk) use Host() instead of offscreenCanvasForBinding() here + return offscreenCanvasForBinding()->GetOrCreateResourceProvider(); } CanvasResourceProvider* @@ -144,11 +210,15 @@ OffscreenCanvasRenderingContext2D::GetCanvasResourceProvider() const { void OffscreenCanvasRenderingContext2D::Reset() { Host()->DiscardResourceProvider(); BaseRenderingContext2D::Reset(); + if (is_deferral_enabled_) + StartRecording(); + // Because the host may have changed to a zero size + is_valid_size_ = IsValidImageSize(Host()->Size()); } scoped_refptr<CanvasResource> OffscreenCanvasRenderingContext2D::ProduceCanvasResource() { - if (!CanCreateCanvas2dResourceProvider()) + if (!GetOrCreateCanvasResourceProvider()) return nullptr; scoped_refptr<CanvasResource> frame = GetCanvasResourceProvider()->ProduceCanvasResource(); @@ -159,14 +229,16 @@ OffscreenCanvasRenderingContext2D::ProduceCanvasResource() { return frame; } -void OffscreenCanvasRenderingContext2D::PushFrame() { +bool OffscreenCanvasRenderingContext2D::PushFrame() { if (dirty_rect_for_commit_.isEmpty()) - return; + return false; SkIRect damage_rect(dirty_rect_for_commit_); - Host()->PushFrame(ProduceCanvasResource(), damage_rect); + FinalizeFrame(); + bool ret = Host()->PushFrame(ProduceCanvasResource(), damage_rect); dirty_rect_for_commit_.setEmpty(); GetOffscreenFontCache().PruneLocalFontCache(kMaxCachedFonts); + return ret; } ImageBitmap* OffscreenCanvasRenderingContext2D::TransferToImageBitmap( @@ -174,25 +246,39 @@ ImageBitmap* OffscreenCanvasRenderingContext2D::TransferToImageBitmap( WebFeature feature = WebFeature::kOffscreenCanvasTransferToImageBitmap2D; UseCounter::Count(ExecutionContext::From(script_state), feature); - if (!CanCreateCanvas2dResourceProvider()) + if (!GetOrCreateCanvasResourceProvider()) return nullptr; - scoped_refptr<StaticBitmapImage> image = - GetCanvasResourceProvider()->Snapshot(); + scoped_refptr<StaticBitmapImage> image = GetImage(kPreferAcceleration); if (!image) return nullptr; image->SetOriginClean(this->OriginClean()); if (image->IsTextureBacked()) { // Before discarding the image resource, we need to flush pending render ops // to fully resolve the snapshot. - image->PaintImageForCurrentFrame().GetSkImage()->getBackendTexture( - true); // Flush pending ops. + // We can only do this if the skImage is not null + if (auto skImage = image->PaintImageForCurrentFrame().GetSkImage()) { + skImage->getBackendTexture(true); // Flush pending ops. + } else { + // If the SkImage was null, we better return a null ImageBitmap + return nullptr; + } } - Host()->DiscardResourceProvider(); // "Transfer" means no retained buffer. + + // "Transfer" means no retained buffer. Matrix transformations need to be + // preserved though. + Host()->DiscardResourceProvider(); + if (is_deferral_enabled_) { + recorder_->getRecordingCanvas()->restore(); + recorder_->getRecordingCanvas()->save(); + Host()->SetNeedsMatrixClipRestore(); + } + return ImageBitmap::Create(std::move(image)); } scoped_refptr<StaticBitmapImage> OffscreenCanvasRenderingContext2D::GetImage( - AccelerationHint hint) const { + AccelerationHint hint) { + FinalizeFrame(); if (!IsPaintable()) return nullptr; scoped_refptr<StaticBitmapImage> image = @@ -213,6 +299,10 @@ bool OffscreenCanvasRenderingContext2D::ParseColorOrCurrentColor( } cc::PaintCanvas* OffscreenCanvasRenderingContext2D::DrawingCanvas() const { + if (!is_valid_size_) + return nullptr; + if (is_deferral_enabled_) + return recorder_->getRecordingCanvas(); if (!CanCreateCanvas2dResourceProvider()) return nullptr; return GetCanvasResourceProvider()->Canvas(); @@ -220,17 +310,25 @@ cc::PaintCanvas* OffscreenCanvasRenderingContext2D::DrawingCanvas() const { cc::PaintCanvas* OffscreenCanvasRenderingContext2D::ExistingDrawingCanvas() const { + if (!is_valid_size_) + return nullptr; + if (is_deferral_enabled_) + return recorder_->getRecordingCanvas(); if (!IsPaintable()) return nullptr; return GetCanvasResourceProvider()->Canvas(); } void OffscreenCanvasRenderingContext2D::DidDraw() { + if (is_deferral_enabled_) + have_recorded_draw_commands_ = true; Host()->DidDraw(); dirty_rect_for_commit_.setWH(Width(), Height()); } void OffscreenCanvasRenderingContext2D::DidDraw(const SkIRect& dirty_rect) { + if (is_deferral_enabled_) + have_recorded_draw_commands_ = true; dirty_rect_for_commit_.join(dirty_rect); Host()->DidDraw(SkRect::Make(dirty_rect_for_commit_)); } @@ -283,6 +381,17 @@ bool OffscreenCanvasRenderingContext2D::WritePixels( int x, int y) { DCHECK(IsPaintable()); + + FinalizeFrame(); + // WritePixels is not supported by deferral. Since we are directly rendering, + // we can't do deferral on top of the canvas. Disable deferral completely. + is_deferral_enabled_ = false; + have_recorded_draw_commands_ = false; + recorder_.reset(); + // install the current matrix/clip stack onto the immediate canvas + if (GetOrCreateCanvasResourceProvider()) + RestoreMatrixClipStack(GetCanvasResourceProvider()->Canvas()); + return offscreenCanvasForBinding()->ResourceProvider()->WritePixels( orig_info, pixels, row_bytes, x, y); } @@ -513,8 +622,7 @@ void OffscreenCanvasRenderingContext2D::DrawTextInternal( Draw( [&font, &text_run_paint_info, &location]( - cc::PaintCanvas* c, const PaintFlags* flags) // draw lambda - { + cc::PaintCanvas* c, const PaintFlags* flags) /* draw lambda */ { font.DrawBidiText(c, text_run_paint_info, location, Font::kUseFallbackIfFontNotReady, kCDeviceScaleFactor, *flags); diff --git a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h index 89270c56caa..eff614da236 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h +++ b/chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h @@ -12,6 +12,7 @@ #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_factory.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h" +#include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h" namespace blink { @@ -40,7 +41,7 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final } CanvasRenderingContext::ContextType GetContextType() const override { - return CanvasRenderingContext::kContext2d; + return CanvasRenderingContext::kContext2D; } }; @@ -57,7 +58,7 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final // CanvasRenderingContext implementation ~OffscreenCanvasRenderingContext2D() override; - ContextType GetContextType() const override { return kContext2d; } + ContextType GetContextType() const override { return kContext2D; } bool Is2d() const override { return true; } bool IsComposited() const override { return false; } bool IsAccelerated() const override; @@ -68,7 +69,7 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final void ClearRect(double x, double y, double width, double height) override { BaseRenderingContext2D::clearRect(x, y, width, height); } - scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) const final; + scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final; void Reset() override; void RestoreCanvasMatrixClipStack(cc::PaintCanvas* c) const override { RestoreMatrixClipStack(c); @@ -95,6 +96,7 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final int Height() const final; bool CanCreateCanvas2dResourceProvider() const final; + CanvasResourceProvider* GetOrCreateCanvasResourceProvider() const; CanvasResourceProvider* GetCanvasResourceProvider() const; bool ParseColorOrCurrentColor(Color&, const String& color_string) const final; @@ -118,13 +120,12 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final void Trace(blink::Visitor*) override; - void PushFrame() override; + bool PushFrame() override; - protected: - void NeedsFinalizeFrame() override { - CanvasRenderingContext::NeedsFinalizeFrame(); - } + bool HasRecordedDrawCommands() { return have_recorded_draw_commands_; } + bool IsDeferralEnabled() const final { return is_deferral_enabled_; } + protected: CanvasColorParams ColorParams() const override; bool WritePixels(const SkImageInfo& orig_info, const void* pixels, @@ -133,6 +134,13 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final int y) override; private: + void StartRecording(); + bool is_deferral_enabled_; + std::unique_ptr<PaintRecorder> recorder_; + bool have_recorded_draw_commands_; + void FinalizeFrame() final; + void FlushRecording(); + bool IsPaintable() const final; bool IsCanvas2DBufferValid() const override; @@ -149,6 +157,8 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final CanvasPixelFormat PixelFormat() const override; SkIRect dirty_rect_for_commit_; + bool is_valid_size_ = false; + std::mt19937 random_generator_; std::bernoulli_distribution bernoulli_distribution_; }; diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h index 9867510ac72..c4191eb0b65 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h +++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h @@ -21,9 +21,8 @@ namespace blink { class ScriptPromiseResolver; -class ClipboardPromise final - : public GarbageCollectedFinalized<ClipboardPromise>, - public ContextLifecycleObserver { +class ClipboardPromise final : public GarbageCollected<ClipboardPromise>, + public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(ClipboardPromise); public: diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc index ef4542d3e1e..496ad215663 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc +++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc @@ -31,8 +31,12 @@ class ClipboardImageReader final : public ClipboardReader { SkPixmap pixmap; bitmap.peekPixels(&pixmap); - Vector<uint8_t> png_data; + // Set encoding options to favor speed over size. SkPngEncoder::Options options; + options.fZLibLevel = 1; + options.fFilterFlags = SkPngEncoder::FilterFlag::kNone; + + Vector<uint8_t> png_data; if (!ImageEncoder::Encode(&png_data, pixmap, options)) return nullptr; diff --git a/chromium/third_party/blink/renderer/modules/compression/BUILD.gn b/chromium/third_party/blink/renderer/modules/compression/BUILD.gn new file mode 100644 index 00000000000..b5a2071fa96 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/BUILD.gn @@ -0,0 +1,16 @@ +import("//third_party/blink/renderer/modules/modules.gni") + +blink_modules_sources("compression") { + sources = [ + "compression_stream.cc", + "compression_stream.h", + "decompression_stream.cc", + "decompression_stream.h", + "deflate_transformer.cc", + "deflate_transformer.h", + "inflate_transformer.cc", + "inflate_transformer.h", + "zlib_partition_alloc.cc", + "zlib_partition_alloc.h", + ] +} diff --git a/chromium/third_party/blink/renderer/modules/compression/OWNERS b/chromium/third_party/blink/renderer/modules/compression/OWNERS new file mode 100644 index 00000000000..b63f88130bc --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/OWNERS @@ -0,0 +1,5 @@ +yhirano@chromium.org +ricea@chromium.org + +# TEAM: blink-network-dev@chromium.org +# COMPONENT: Blink>Network>StreamsAPI diff --git a/chromium/third_party/blink/renderer/modules/compression/README.md b/chromium/third_party/blink/renderer/modules/compression/README.md new file mode 100644 index 00000000000..3a65da92f28 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/README.md @@ -0,0 +1,8 @@ +# CompressionStreams API + +This directory contains the implementation of CompressionStream and +DecompressionStream. + +## Design docs + +See [DecompressionStream Design Docs](https://docs.google.com/document/d/1TovyqqeC3HoO0A4UUBKiCyhZlQSl7jM_F7KbWjK2Gcs/edit). diff --git a/chromium/third_party/blink/renderer/modules/compression/compression_stream.cc b/chromium/third_party/blink/renderer/modules/compression/compression_stream.cc new file mode 100644 index 00000000000..5959a7bbea2 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/compression_stream.cc @@ -0,0 +1,53 @@ +// 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. + +#include "third_party/blink/renderer/modules/compression/compression_stream.h" + +#include "third_party/blink/renderer/modules/compression/deflate_transformer.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" + +namespace blink { + +CompressionStream* CompressionStream::Create(ScriptState* script_state, + const AtomicString& format, + ExceptionState& exception_state) { + return MakeGarbageCollected<CompressionStream>(script_state, format, + exception_state); +} + +ReadableStream* CompressionStream::readable() const { + return transform_->Readable(); +} + +WritableStream* CompressionStream::writable() const { + return transform_->Writable(); +} + +void CompressionStream::Trace(Visitor* visitor) { + visitor->Trace(transform_); + ScriptWrappable::Trace(visitor); +} + +CompressionStream::CompressionStream(ScriptState* script_state, + const AtomicString& format, + ExceptionState& exception_state) + : transform_(MakeGarbageCollected<TransformStream>()) { + DeflateTransformer::Format deflate_format = + DeflateTransformer::Format::kDeflate; + if (format == "gzip") { + deflate_format = DeflateTransformer::Format::kGzip; + } else if (format != "deflate") { + exception_state.ThrowTypeError("Unsupported format"); + return; + } + + // default level is hardcoded for now. + // TODO(arenevier): Make level configurable + const int deflate_level = 6; + transform_->Init(MakeGarbageCollected<DeflateTransformer>( + script_state, deflate_format, deflate_level), + script_state, exception_state); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/compression/compression_stream.h b/chromium/third_party/blink/renderer/modules/compression/compression_stream.h new file mode 100644 index 00000000000..4a96737539c --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/compression_stream.h @@ -0,0 +1,36 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_COMPRESSION_STREAM_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_COMPRESSION_STREAM_H_ + +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/core/streams/transform_stream.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class CompressionStream final : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + static CompressionStream* Create(ScriptState*, + const AtomicString&, + ExceptionState&); + CompressionStream(ScriptState*, const AtomicString&, ExceptionState&); + + ReadableStream* readable() const; + WritableStream* writable() const; + + void Trace(Visitor*) override; + + private: + const Member<TransformStream> transform_; + + DISALLOW_COPY_AND_ASSIGN(CompressionStream); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_COMPRESSION_STREAM_H_ diff --git a/chromium/third_party/blink/renderer/modules/compression/compression_stream.idl b/chromium/third_party/blink/renderer/modules/compression/compression_stream.idl new file mode 100644 index 00000000000..475b817bacc --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/compression_stream.idl @@ -0,0 +1,11 @@ +[ + Exposed=(Window,Worker), + Constructor(DOMString format), + ConstructorCallWith=ScriptState, + RuntimeEnabled=CompressionStreams, + RaisesException=Constructor, + MeasureAs=CompressionStreamConstructor +] interface CompressionStream { + readonly attribute ReadableStream readable; + readonly attribute WritableStream writable; +}; diff --git a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.cc b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.cc new file mode 100644 index 00000000000..cb1fbc4bbd6 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.cc @@ -0,0 +1,46 @@ +#include "third_party/blink/renderer/modules/compression/decompression_stream.h" +#include "third_party/blink/renderer/modules/compression/inflate_transformer.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" + +namespace blink { + +DecompressionStream* DecompressionStream::Create( + ScriptState* script_state, + const AtomicString& format, + ExceptionState& exception_state) { + return MakeGarbageCollected<DecompressionStream>(script_state, format, + exception_state); +} + +ReadableStream* DecompressionStream::readable() const { + return transform_->Readable(); +} + +WritableStream* DecompressionStream::writable() const { + return transform_->Writable(); +} + +void DecompressionStream::Trace(Visitor* visitor) { + visitor->Trace(transform_); + ScriptWrappable::Trace(visitor); +} + +DecompressionStream::DecompressionStream(ScriptState* script_state, + const AtomicString& format, + ExceptionState& exception_state) + : transform_(MakeGarbageCollected<TransformStream>()) { + InflateTransformer::Format deflate_format = + InflateTransformer::Format::kDeflate; + if (format == "gzip") { + deflate_format = InflateTransformer::Format::kGzip; + } else if (format != "deflate") { + exception_state.ThrowTypeError("Unsupported format"); + return; + } + + transform_->Init( + MakeGarbageCollected<InflateTransformer>(script_state, deflate_format), + script_state, exception_state); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.h b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.h new file mode 100644 index 00000000000..3e2495fb416 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.h @@ -0,0 +1,32 @@ +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_DECOMPRESSION_STREAM_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_DECOMPRESSION_STREAM_H_ + +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/core/streams/transform_stream.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class DecompressionStream final : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + static DecompressionStream* Create(ScriptState*, + const AtomicString&, + ExceptionState&); + DecompressionStream(ScriptState*, const AtomicString&, ExceptionState&); + + ReadableStream* readable() const; + WritableStream* writable() const; + + void Trace(Visitor* visitor) override; + + private: + const Member<TransformStream> transform_; + + DISALLOW_COPY_AND_ASSIGN(DecompressionStream); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_DECOMPRESSION_STREAM_H_ diff --git a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.idl b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.idl new file mode 100644 index 00000000000..b22d90410f9 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.idl @@ -0,0 +1,11 @@ +[ + Exposed=(Window,Worker), + Constructor(DOMString format), + ConstructorCallWith=ScriptState, + RaisesException=Constructor, + RuntimeEnabled=CompressionStreams, + MeasureAs=DecompressionStreamConstructor +] interface DecompressionStream { + readonly attribute ReadableStream readable; + readonly attribute WritableStream writable; +}; diff --git a/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc new file mode 100644 index 00000000000..f8ee728c486 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc @@ -0,0 +1,121 @@ +// 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. + +#include "third_party/blink/renderer/modules/compression/deflate_transformer.h" + +#include <string.h> +#include <algorithm> +#include <limits> + +#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_uint8_array.h" +#include "third_party/blink/renderer/core/streams/transform_stream_default_controller_interface.h" +#include "third_party/blink/renderer/core/streams/transform_stream_transformer.h" +#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h" +#include "third_party/blink/renderer/modules/compression/zlib_partition_alloc.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/bindings/to_v8.h" +#include "v8/include/v8.h" + +namespace blink { + +DeflateTransformer::DeflateTransformer(ScriptState* script_state, + Format format, + int level) + : script_state_(script_state), out_buffer_(kBufferSize) { + DCHECK(level >= 1 && level <= 9); + memset(&stream_, 0, sizeof(z_stream)); + ZlibPartitionAlloc::Configure(&stream_); + constexpr int kWindowBits = 15; + constexpr int kUseGzip = 16; + int err; + switch (format) { + case Format::kDeflate: + err = deflateInit2(&stream_, level, Z_DEFLATED, kWindowBits, 8, + Z_DEFAULT_STRATEGY); + break; + case Format::kGzip: + err = deflateInit2(&stream_, level, Z_DEFLATED, kWindowBits + kUseGzip, 8, + Z_DEFAULT_STRATEGY); + break; + } + DCHECK_EQ(Z_OK, err); +} + +DeflateTransformer::~DeflateTransformer() { + if (!was_flush_called_) { + deflateEnd(&stream_); + } +} + +void DeflateTransformer::Transform( + v8::Local<v8::Value> chunk, + TransformStreamDefaultControllerInterface* controller, + ExceptionState& exception_state) { + ArrayBufferOrArrayBufferView buffer_source; + V8ArrayBufferOrArrayBufferView::ToImpl( + script_state_->GetIsolate(), chunk, buffer_source, + UnionTypeConversionMode::kNotNullable, exception_state); + if (exception_state.HadException()) { + return; + } + if (buffer_source.IsArrayBufferView()) { + const auto* view = buffer_source.GetAsArrayBufferView().View(); + const uint8_t* start = static_cast<const uint8_t*>(view->BaseAddress()); + wtf_size_t length = view->byteLength(); + Deflate(start, length, IsFinished(false), controller, exception_state); + return; + } + DCHECK(buffer_source.IsArrayBuffer()); + const auto* array_buffer = buffer_source.GetAsArrayBuffer(); + const uint8_t* start = static_cast<const uint8_t*>(array_buffer->Data()); + wtf_size_t length = array_buffer->ByteLength(); + Deflate(start, length, IsFinished(false), controller, exception_state); +} + +void DeflateTransformer::Flush( + TransformStreamDefaultControllerInterface* controller, + ExceptionState& exception_state) { + Deflate(nullptr, 0u, IsFinished(true), controller, exception_state); + was_flush_called_ = true; + deflateEnd(&stream_); + out_buffer_.clear(); +} + +void DeflateTransformer::Deflate( + const uint8_t* start, + wtf_size_t length, + IsFinished finished, + TransformStreamDefaultControllerInterface* controller, + ExceptionState& exception_state) { + stream_.avail_in = length; + // Zlib treats this pointer as const, so this cast is safe. + stream_.next_in = const_cast<uint8_t*>(start); + + do { + stream_.avail_out = out_buffer_.size(); + stream_.next_out = out_buffer_.data(); + int err = deflate(&stream_, finished ? Z_FINISH : Z_NO_FLUSH); + DCHECK((finished && err == Z_STREAM_END) || err == Z_OK || + err == Z_BUF_ERROR); + + wtf_size_t bytes = out_buffer_.size() - stream_.avail_out; + if (bytes) { + controller->Enqueue( + ToV8(DOMUint8Array::Create(out_buffer_.data(), bytes), script_state_), + exception_state); + if (exception_state.HadException()) { + return; + } + } + } while (stream_.avail_out == 0); +} + +void DeflateTransformer::Trace(Visitor* visitor) { + visitor->Trace(script_state_); + TransformStreamTransformer::Trace(visitor); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.h b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.h new file mode 100644 index 00000000000..c3b93c0c7ca --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.h @@ -0,0 +1,60 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_DEFLATE_TRANSFORMER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_DEFLATE_TRANSFORMER_H_ + +#include "base/util/type_safety/strong_alias.h" + +#include "third_party/blink/renderer/core/streams/transform_stream_transformer.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" +#include "third_party/zlib/zlib.h" + +namespace blink { + +class DeflateTransformer final : public TransformStreamTransformer { + public: + enum class Format { kGzip, kDeflate }; + + DeflateTransformer(ScriptState*, Format, int level); + ~DeflateTransformer() override; + + void Transform(v8::Local<v8::Value> chunk, + TransformStreamDefaultControllerInterface*, + ExceptionState&) override; + + void Flush(TransformStreamDefaultControllerInterface*, + ExceptionState&) override; + + ScriptState* GetScriptState() override { return script_state_; } + + void Trace(Visitor*) override; + + private: + using IsFinished = util::StrongAlias<class IsFinishedTag, bool>; + + void Deflate(const uint8_t*, + wtf_size_t, + IsFinished, + TransformStreamDefaultControllerInterface*, + ExceptionState&); + + Member<ScriptState> script_state_; + + Vector<uint8_t> out_buffer_; + + z_stream stream_; + + bool was_flush_called_ = false; + + // This buffer size has been experimentally verified to be optimal. + static constexpr wtf_size_t kBufferSize = 16384; + + DISALLOW_COPY_AND_ASSIGN(DeflateTransformer); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_DEFLATE_TRANSFORMER_H_ diff --git a/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc new file mode 100644 index 00000000000..372a56b410d --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc @@ -0,0 +1,116 @@ +#include "third_party/blink/renderer/modules/compression/inflate_transformer.h" + +#include <string.h> +#include <algorithm> +#include <limits> + +#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_uint8_array.h" +#include "third_party/blink/renderer/core/streams/transform_stream_default_controller_interface.h" +#include "third_party/blink/renderer/core/streams/transform_stream_transformer.h" +#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h" +#include "third_party/blink/renderer/modules/compression/zlib_partition_alloc.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/bindings/to_v8.h" +#include "v8/include/v8.h" + +namespace blink { + +InflateTransformer::InflateTransformer(ScriptState* script_state, Format format) + : script_state_(script_state), out_buffer_(kBufferSize) { + memset(&stream_, 0, sizeof(z_stream)); + ZlibPartitionAlloc::Configure(&stream_); + constexpr int kWindowBits = 15; + constexpr int kUseGzip = 16; + int err; + switch (format) { + case Format::kDeflate: + err = inflateInit2(&stream_, kWindowBits); + break; + case Format::kGzip: + err = inflateInit2(&stream_, kWindowBits + kUseGzip); + break; + } + DCHECK_EQ(Z_OK, err); +} + +InflateTransformer::~InflateTransformer() { + if (!was_flush_called_) { + inflateEnd(&stream_); + } +} + +void InflateTransformer::Transform( + v8::Local<v8::Value> chunk, + TransformStreamDefaultControllerInterface* controller, + ExceptionState& exception_state) { + // TODO(canonmukai): Support SharedArrayBuffer. + ArrayBufferOrArrayBufferView buffer_source; + V8ArrayBufferOrArrayBufferView::ToImpl( + script_state_->GetIsolate(), chunk, buffer_source, + UnionTypeConversionMode::kNotNullable, exception_state); + if (exception_state.HadException()) { + return; + } + if (buffer_source.IsArrayBufferView()) { + const auto* view = buffer_source.GetAsArrayBufferView().View(); + const uint8_t* start = static_cast<const uint8_t*>(view->BaseAddress()); + wtf_size_t length = view->byteLength(); + Inflate(start, length, IsFinished(false), controller, exception_state); + return; + } + DCHECK(buffer_source.IsArrayBuffer()); + const auto* array_buffer = buffer_source.GetAsArrayBuffer(); + const uint8_t* start = static_cast<const uint8_t*>(array_buffer->Data()); + wtf_size_t length = array_buffer->ByteLength(); + Inflate(start, length, IsFinished(false), controller, exception_state); +} + +void InflateTransformer::Flush( + TransformStreamDefaultControllerInterface* controller, + ExceptionState& exception_state) { + DCHECK(!was_flush_called_); + Inflate(nullptr, 0u, IsFinished(true), controller, exception_state); + inflateEnd(&stream_); + was_flush_called_ = true; + out_buffer_.clear(); +} + +void InflateTransformer::Inflate( + const uint8_t* start, + wtf_size_t length, + IsFinished finished, + TransformStreamDefaultControllerInterface* controller, + ExceptionState& exception_state) { + stream_.avail_in = length; + // Zlib treats this pointer as const, so this cast is safe. + stream_.next_in = const_cast<uint8_t*>(start); + + do { + stream_.avail_out = out_buffer_.size(); + stream_.next_out = out_buffer_.data(); + int err = inflate(&stream_, finished ? Z_FINISH : Z_NO_FLUSH); + if (err != Z_OK && err != Z_STREAM_END && err != Z_BUF_ERROR) { + exception_state.ThrowTypeError("The compressed data was not valid."); + return; + } + + wtf_size_t bytes = out_buffer_.size() - stream_.avail_out; + if (bytes) { + controller->Enqueue( + ToV8(DOMUint8Array::Create(out_buffer_.data(), bytes), script_state_), + exception_state); + if (exception_state.HadException()) { + return; + } + } + } while (stream_.avail_out == 0); +} + +void InflateTransformer::Trace(Visitor* visitor) { + visitor->Trace(script_state_); + TransformStreamTransformer::Trace(visitor); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.h b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.h new file mode 100644 index 00000000000..b76f2c92be2 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.h @@ -0,0 +1,56 @@ +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_INFLATE_TRANSFORMER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_INFLATE_TRANSFORMER_H_ + +#include "base/util/type_safety/strong_alias.h" + +#include "third_party/blink/renderer/core/streams/transform_stream_transformer.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" +#include "third_party/zlib/zlib.h" + +namespace blink { + +class InflateTransformer final : public TransformStreamTransformer { + public: + enum class Format { kDeflate, kGzip }; + + InflateTransformer(ScriptState*, Format format); + ~InflateTransformer() override; + + void Transform(v8::Local<v8::Value> chunk, + TransformStreamDefaultControllerInterface*, + ExceptionState&) override; + + void Flush(TransformStreamDefaultControllerInterface*, + ExceptionState&) override; + + ScriptState* GetScriptState() override { return script_state_; } + + void Trace(Visitor*) override; + + private: + using IsFinished = util::StrongAlias<class IsFinishedTag, bool>; + + void Inflate(const uint8_t*, + wtf_size_t, + IsFinished, + TransformStreamDefaultControllerInterface*, + ExceptionState&); + + Member<ScriptState> script_state_; + + z_stream stream_; + + Vector<uint8_t> out_buffer_; + + bool was_flush_called_ = false; + + // This buffer size has been experimentally verified to be optimal. + static constexpr wtf_size_t kBufferSize = 65536; + + DISALLOW_COPY_AND_ASSIGN(InflateTransformer); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_INFLATE_TRANSFORMER_H_ diff --git a/chromium/third_party/blink/renderer/modules/compression/zlib_partition_alloc.cc b/chromium/third_party/blink/renderer/modules/compression/zlib_partition_alloc.cc new file mode 100644 index 00000000000..99297631878 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/zlib_partition_alloc.cc @@ -0,0 +1,20 @@ +#include "third_party/blink/renderer/modules/compression/zlib_partition_alloc.h" +#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h" + +namespace blink { + +void ZlibPartitionAlloc::Configure(z_stream* stream) { + stream->zalloc = Alloc; + stream->zfree = Free; +} + +void* ZlibPartitionAlloc::Alloc(void*, uint32_t items, uint32_t size) { + // BufferMalloc is safer than FastMalloc when handling untrusted data. + return WTF::Partitions::BufferMalloc(items * size, "zlib"); +} + +void ZlibPartitionAlloc::Free(void*, void* address) { + WTF::Partitions::BufferFree(address); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/compression/zlib_partition_alloc.h b/chromium/third_party/blink/renderer/modules/compression/zlib_partition_alloc.h new file mode 100644 index 00000000000..f013f1a489e --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/compression/zlib_partition_alloc.h @@ -0,0 +1,24 @@ +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_ZLIB_PARTITION_ALLOC_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_ZLIB_PARTITION_ALLOC_H_ + +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/zlib/zlib.h" + +namespace blink { + +// Use partition alloc for zlib allocations. +class ZlibPartitionAlloc { + STATIC_ONLY(ZlibPartitionAlloc); + + public: + static void Configure(z_stream* s); + + private: + static void* Alloc(void*, uint32_t items, uint32_t size); + + static void Free(void*, void*); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_ZLIB_PARTITION_ALLOC_H_ diff --git a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc index 9181ed759bb..2240b7eb224 100644 --- a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc +++ b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc @@ -4,7 +4,8 @@ #include "third_party/blink/renderer/modules/contacts_picker/contacts_manager.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "base/stl_util.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -64,16 +65,31 @@ TypeConverter<blink::ContactInfo*, blink::mojom::blink::ContactInfoPtr>:: } // namespace mojo namespace blink { +namespace { + +// ContactProperty enum strings. +constexpr char kAddress[] = "address"; +constexpr char kEmail[] = "email"; +constexpr char kName[] = "name"; +constexpr char kTel[] = "tel"; + +} // namespace + +ContactsManager::ContactsManager() { + properties_ = {kEmail, kName, kTel}; + + if (RuntimeEnabledFeatures::ContactsManagerAddressesEnabled()) + properties_.push_back(kAddress); +} -ContactsManager::ContactsManager() = default; ContactsManager::~ContactsManager() = default; mojo::Remote<mojom::blink::ContactsManager>& ContactsManager::GetContactsManager(ScriptState* script_state) { if (!contacts_manager_) { ExecutionContext::From(script_state) - ->GetInterfaceProvider() - ->GetInterface(contacts_manager_.BindNewPipeAndPassReceiver()); + ->GetBrowserInterfaceBroker() + .GetInterface(contacts_manager_.BindNewPipeAndPassReceiver()); } return contacts_manager_; } @@ -113,22 +129,31 @@ ScriptPromise ContactsManager::select(ScriptState* script_state, "Contacts Picker is already in use.")); } - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - bool include_names = false; bool include_emails = false; bool include_tel = false; for (const String& property : properties) { - if (property == "name") + if (!base::Contains(properties_, property)) { + return ScriptPromise::Reject( + script_state, + V8ThrowException::CreateTypeError( + script_state->GetIsolate(), + "The provided value '" + property + + "' is not a valid enum value of type ContactProperty")); + } + + if (property == kName) include_names = true; - else if (property == "email") + else if (property == kEmail) include_emails = true; - else if (property == "tel") + else if (property == kTel) include_tel = true; } + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + contact_picker_in_use_ = true; GetContactsManager(script_state) ->Select(options->multiple(), include_names, include_emails, include_tel, @@ -166,4 +191,8 @@ void ContactsManager::OnContactsSelected( resolver->Resolve(contacts_list); } +ScriptPromise ContactsManager::getProperties(ScriptState* script_state) { + return ScriptPromise::Cast(script_state, ToV8(properties_, script_state)); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.h b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.h index 07ff327049e..b8b622016a9 100644 --- a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.h +++ b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.h @@ -30,6 +30,7 @@ class ContactsManager final : public ScriptWrappable { ScriptPromise select(ScriptState* script_state, const Vector<String>& properties, ContactsSelectOptions* options); + ScriptPromise getProperties(ScriptState* script_state); private: mojo::Remote<mojom::blink::ContactsManager>& GetContactsManager( @@ -42,6 +43,7 @@ class ContactsManager final : public ScriptWrappable { // Created lazily. mojo::Remote<mojom::blink::ContactsManager> contacts_manager_; bool contact_picker_in_use_ = false; + Vector<String> properties_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.idl b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.idl index fb3cdd586ed..697fa3a34a1 100644 --- a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.idl +++ b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_manager.idl @@ -9,5 +9,6 @@ SecureContext, RuntimeEnabled=ContactsManager ] interface ContactsManager { + [CallWith=ScriptState, MeasureAs=ContactsManagerGetProperties] Promise<sequence<ContactProperty>> getProperties(); [CallWith=ScriptState, MeasureAs=ContactsManagerSelect] Promise<sequence<ContactInfo>> select(sequence<ContactProperty> properties, optional ContactsSelectOptions options); }; diff --git a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_select_options.idl b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_select_options.idl index f53294142af..279c5a385f7 100644 --- a/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_select_options.idl +++ b/chromium/third_party/blink/renderer/modules/contacts_picker/contacts_select_options.idl @@ -4,7 +4,7 @@ // https://wicg.github.io/contact-api/spec/#contacts-manager -enum ContactProperty { "email", "name", "tel" }; +enum ContactProperty { "address", "email", "name", "tel" }; dictionary ContactsSelectOptions { boolean multiple = false; diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_description.idl b/chromium/third_party/blink/renderer/modules/content_index/content_description.idl index c32a824f00b..93b2652aa1e 100644 --- a/chromium/third_party/blink/renderer/modules/content_index/content_description.idl +++ b/chromium/third_party/blink/renderer/modules/content_index/content_description.idl @@ -5,6 +5,7 @@ // https://github.com/rknoll/content-index enum ContentCategory { + "", "homepage", "article", "video", @@ -15,7 +16,7 @@ dictionary ContentDescription { required DOMString id; required DOMString title; required DOMString description; - required ContentCategory category; + ContentCategory category = ""; sequence<ContentIconDefinition> icons = []; required USVString launchUrl; }; diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.cc b/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.cc index 6a277033a47..889588ec042 100644 --- a/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.cc +++ b/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter.cc @@ -13,6 +13,8 @@ namespace mojo { namespace { blink::mojom::ContentCategory GetContentCategory(const WTF::String& category) { + if (category == "") + return blink::mojom::ContentCategory::NONE; if (category == "homepage") return blink::mojom::ContentCategory::HOME_PAGE; if (category == "article") @@ -23,11 +25,13 @@ blink::mojom::ContentCategory GetContentCategory(const WTF::String& category) { return blink::mojom::ContentCategory::AUDIO; NOTREACHED(); - return blink::mojom::ContentCategory::ARTICLE; + return blink::mojom::ContentCategory::NONE; } WTF::String GetContentCategory(blink::mojom::ContentCategory category) { switch (category) { + case blink::mojom::ContentCategory::NONE: + return ""; case blink::mojom::ContentCategory::HOME_PAGE: return "homepage"; case blink::mojom::ContentCategory::ARTICLE: diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index.cc b/chromium/third_party/blink/renderer/modules/content_index/content_index.cc index a8b4d6f722f..3e0afe7332e 100644 --- a/chromium/third_party/blink/renderer/modules/content_index/content_index.cc +++ b/chromium/third_party/blink/renderer/modules/content_index/content_index.cc @@ -5,7 +5,7 @@ #include "third_party/blink/renderer/modules/content_index/content_index.h" #include "base/optional.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -279,8 +279,10 @@ void ContentIndex::Trace(blink::Visitor* visitor) { mojom::blink::ContentIndexService* ContentIndex::GetService() { if (!content_index_service_) { - registration_->GetExecutionContext()->GetInterfaceProvider()->GetInterface( - content_index_service_.BindNewPipeAndPassReceiver(task_runner_)); + registration_->GetExecutionContext() + ->GetBrowserInterfaceBroker() + .GetInterface( + content_index_service_.BindNewPipeAndPassReceiver(task_runner_)); } return content_index_service_.get(); } diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index.idl b/chromium/third_party/blink/renderer/modules/content_index/content_index.idl index fd8f1f8450b..8a116d02860 100644 --- a/chromium/third_party/blink/renderer/modules/content_index/content_index.idl +++ b/chromium/third_party/blink/renderer/modules/content_index/content_index.idl @@ -10,5 +10,5 @@ ] interface ContentIndex { [CallWith=ScriptState, MeasureAs=ContentIndexAdd] Promise<void> add(ContentDescription description); [CallWith=ScriptState, MeasureAs=ContentIndexDelete, ImplementedAs=deleteDescription] Promise<void> delete(DOMString id); - [CallWith=ScriptState, MeasureAs=ContentIndexGet] Promise<sequence<ContentDescription>> getDescriptions(); + [CallWith=ScriptState, MeasureAs=ContentIndexGet, ImplementedAs=getDescriptions] Promise<sequence<ContentDescription>> getAll(); };
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc b/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc index 0cc3c05e4f7..cd1ea626f1d 100644 --- a/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc +++ b/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.cc @@ -8,6 +8,7 @@ #include "base/time/time.h" #include "third_party/blink/public/common/manifest/manifest.h" #include "third_party/blink/public/common/manifest/manifest_icon_selector.h" +#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/public/platform/web_icon_sizes_parser.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_vector.h" diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.h b/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.h index d49fc1db3c8..2643f0666ca 100644 --- a/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.h +++ b/chromium/third_party/blink/renderer/modules/content_index/content_index_icon_loader.h @@ -17,7 +17,7 @@ namespace blink { class ExecutionContext; class MODULES_EXPORT ContentIndexIconLoader final - : public GarbageCollectedFinalized<ContentIndexIconLoader> { + : public GarbageCollected<ContentIndexIconLoader> { public: using IconsCallback = base::OnceCallback<void(mojom::blink::ContentDescriptionPtr description, diff --git a/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.h b/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.h index 5276c310bc0..7852ebacc0f 100644 --- a/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.h +++ b/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.h @@ -16,7 +16,7 @@ namespace blink { class ContentIndex; class ServiceWorkerRegistrationContentIndex final - : public GarbageCollectedFinalized<ServiceWorkerRegistrationContentIndex>, + : public GarbageCollected<ServiceWorkerRegistrationContentIndex>, public Supplement<ServiceWorkerRegistration> { USING_GARBAGE_COLLECTED_MIXIN(ServiceWorkerRegistrationContentIndex); diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc index 3585a840a94..adb0c2f93f0 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc +++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.cc @@ -424,10 +424,9 @@ void CookieStore::RemoveAllEventListeners() { } void CookieStore::OnCookieChange( - const WebCanonicalCookie& backend_cookie, - network::mojom::blink::CookieChangeCause change_cause) { + network::mojom::blink::CookieChangeInfoPtr change) { HeapVector<Member<CookieListItem>> changed, deleted; - CookieChangeEvent::ToEventInfo(backend_cookie, change_cause, changed, + CookieChangeEvent::ToEventInfo(change->cookie, change->cause, changed, deleted); if (changed.IsEmpty() && deleted.IsEmpty()) { // The backend only reported OVERWRITE events, which are dropped. diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.h b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.h index d85631fe163..031eeda80f9 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.h +++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.h @@ -7,7 +7,7 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/network/public/mojom/restricted_cookie_manager.mojom-blink.h" +#include "services/network/public/mojom/restricted_cookie_manager.mojom-blink-forward.h" #include "third_party/blink/public/mojom/cookie_store/cookie_store.mojom-blink.h" #include "third_party/blink/public/platform/web_canonical_cookie.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" @@ -86,8 +86,8 @@ class CookieStore final : public EventTargetWithInlineData, void RemoveAllEventListeners() override; // RestrictedCookieChangeListener - void OnCookieChange(const WebCanonicalCookie&, - network::mojom::blink::CookieChangeCause) override; + void OnCookieChange( + network::mojom::blink::CookieChangeInfoPtr change) override; protected: // EventTarget overrides. diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store_impl.h b/chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store_impl.h index ec85f113d2a..6c0e832e30a 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store_impl.h +++ b/chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store_impl.h @@ -8,6 +8,7 @@ #include <utility> #include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/cookie_store/cookie_store.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/supplementable.h" diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.cc b/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.cc index 586f5394b0f..15ba2afcee1 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.cc +++ b/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.cc @@ -8,6 +8,7 @@ #include "services/network/public/mojom/restricted_cookie_manager.mojom-blink.h" #include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/workers/worker_thread.h" #include "third_party/blink/renderer/modules/cookie_store/cookie_store.h" #include "third_party/blink/renderer/modules/cookie_store/global_cookie_store_impl.h" @@ -24,8 +25,9 @@ CookieStore* GlobalCookieStoreImpl<WorkerGlobalScope>::BuildCookieStore( interface_provider->GetInterface( cookie_manager_remote.BindNewPipeAndPassReceiver( execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI))); + mojo::Remote<blink::mojom::blink::CookieStore> cookie_store_remote; - interface_provider->GetInterface( + execution_context->GetBrowserInterfaceBroker().GetInterface( cookie_store_remote.BindNewPipeAndPassReceiver( execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI))); diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h index 55e7e723644..31c8c8349b0 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_AUTHENTICATOR_ATTESTATION_RESPONSE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_AUTHENTICATOR_ATTESTATION_RESPONSE_H_ -#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink.h" +#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink-forward.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/modules/credentialmanager/authenticator_response.h" #include "third_party/blink/renderer/modules/modules_export.h" diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc index 26a19db1af1..0824e842905 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.cc @@ -4,8 +4,7 @@ #include "third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h" -#include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/public/mojom/frame/document_interface_broker.mojom-blink.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -16,10 +15,10 @@ namespace blink { CredentialManagerProxy::CredentialManagerProxy(Document& document) { LocalFrame* frame = document.GetFrame(); DCHECK(frame); - frame->GetDocumentInterfaceBroker().GetCredentialManager( + frame->GetBrowserInterfaceBroker().GetInterface( credential_manager_.BindNewPipeAndPassReceiver( frame->GetTaskRunner(TaskType::kUserInteraction))); - frame->GetDocumentInterfaceBroker().GetAuthenticator( + frame->GetBrowserInterfaceBroker().GetInterface( authenticator_.BindNewPipeAndPassReceiver( frame->GetTaskRunner(TaskType::kUserInteraction))); } diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h index fd21f867348..25f046d64dc 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_proxy.h @@ -29,7 +29,7 @@ class ScriptState; // whose global object owns the CredentialsContainer instance on which the // method was called. class MODULES_EXPORT CredentialManagerProxy - : public GarbageCollectedFinalized<CredentialManagerProxy>, + : public GarbageCollected<CredentialManagerProxy>, public Supplement<Document> { USING_GARBAGE_COLLECTED_MIXIN(CredentialManagerProxy); diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc index ab7f9ed6e7d..29f4235f74d 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc @@ -8,6 +8,7 @@ #include <utility> #include "build/build_config.h" +#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h" #include "third_party/blink/renderer/modules/credentialmanager/authenticator_selection_criteria.h" #include "third_party/blink/renderer/modules/credentialmanager/cable_authentication_data.h" @@ -575,13 +576,18 @@ TypeConverter<PublicKeyCredentialRequestOptionsPtr, if (extensions->hasCableAuthentication()) { Vector<CableAuthenticationPtr> mojo_data; for (auto& data : extensions->cableAuthentication()) { + if (data->version() != 1) { + continue; + } CableAuthenticationPtr mojo_cable = CableAuthentication::From(data.Get()); if (mojo_cable) { mojo_data.push_back(std::move(mojo_cable)); } } - mojo_options->cable_authentication_data = std::move(mojo_data); + if (mojo_data.size() > 0) { + mojo_options->cable_authentication_data = std::move(mojo_data); + } } #if defined(OS_ANDROID) if (extensions->hasUvm()) { diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h index d58dfd537e8..9766db328d8 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h @@ -8,7 +8,7 @@ #include "base/optional.h" #include "third_party/blink/public/mojom/credentialmanager/credential_manager.mojom-blink.h" -#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink.h" +#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc index 72be464d9bf..2b52ef0e046 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc @@ -13,6 +13,7 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/credentialmanager/credential_manager.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h" @@ -21,7 +22,6 @@ #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/testing/gc_object_liveness_observer.h" -#include "third_party/blink/renderer/core/testing/test_document_interface_broker.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/modules/credentialmanager/credential.h" #include "third_party/blink/renderer/modules/credentialmanager/credential_creation_options.h" @@ -99,30 +99,6 @@ class MockCredentialManager : public mojom::blink::CredentialManager { DISALLOW_COPY_AND_ASSIGN(MockCredentialManager); }; -class MockCredentialManagerDocumentInterfaceBroker - : public TestDocumentInterfaceBroker { - public: - MockCredentialManagerDocumentInterfaceBroker( - mojom::blink::DocumentInterfaceBroker* document_interface_broker, - mojo::PendingReceiver<mojom::blink::DocumentInterfaceBroker> receiver, - MockCredentialManager* mock_credential_manager) - : TestDocumentInterfaceBroker(document_interface_broker, - std::move(receiver)), - mock_credential_manager_(mock_credential_manager) {} - - void GetCredentialManager( - mojo::PendingReceiver<::blink::mojom::blink::CredentialManager> receiver) - override { - mock_credential_manager_->Bind(std::move(receiver)); - } - - void GetAuthenticator( - mojo::PendingReceiver<mojom::blink::Authenticator> receiver) override {} - - private: - MockCredentialManager* mock_credential_manager_; -}; - class CredentialManagerTestingContext { STACK_ALLOCATED(); @@ -132,12 +108,23 @@ class CredentialManagerTestingContext { : dummy_context_(KURL("https://example.test")) { dummy_context_.GetDocument().SetSecureContextStateForTesting( SecureContextState::kSecure); - mojo::PendingRemote<mojom::blink::DocumentInterfaceBroker> doc; - broker_ = std::make_unique<MockCredentialManagerDocumentInterfaceBroker>( - &dummy_context_.GetFrame().GetDocumentInterfaceBroker(), - doc.InitWithNewPipeAndPassReceiver(), mock_credential_manager); - dummy_context_.GetFrame().SetDocumentInterfaceBrokerForTesting( - doc.PassPipe()); + + dummy_context_.GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting( + ::blink::mojom::blink::CredentialManager::Name_, + WTF::BindRepeating( + [](MockCredentialManager* mock_credential_manager, + mojo::ScopedMessagePipeHandle handle) { + mock_credential_manager->Bind( + mojo::PendingReceiver< + ::blink::mojom::blink::CredentialManager>( + std::move(handle))); + }, + WTF::Unretained(mock_credential_manager))); + } + + ~CredentialManagerTestingContext() { + dummy_context_.GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting( + ::blink::mojom::blink::CredentialManager::Name_, {}); } Document* GetDocument() { return &dummy_context_.GetDocument(); } @@ -146,7 +133,6 @@ class CredentialManagerTestingContext { private: V8TestingScope dummy_context_; - std::unique_ptr<MockCredentialManagerDocumentInterfaceBroker> broker_; }; } // namespace diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto_key.cc b/chromium/third_party/blink/renderer/modules/crypto/crypto_key.cc index 39da74d770c..b6ff20c8b9f 100644 --- a/chromium/third_party/blink/renderer/modules/crypto/crypto_key.cc +++ b/chromium/third_party/blink/renderer/modules/crypto/crypto_key.cc @@ -165,7 +165,7 @@ ScriptValue CryptoKey::usages(ScriptState* script_state) { result.push_back(KeyUsageToString(usage)); } - return ScriptValue(script_state, ToV8(result, script_state)); + return ScriptValue(script_state->GetIsolate(), ToV8(result, script_state)); } bool CryptoKey::CanBeUsedForAlgorithm(const WebCryptoAlgorithm& algorithm, diff --git a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h index 70b49fbe219..d885536893d 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h +++ b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.h @@ -30,7 +30,7 @@ class V8PaintCallback; // the author. It will store the properties for invalidation and input argument // types as well. class MODULES_EXPORT CSSPaintDefinition final - : public GarbageCollectedFinalized<CSSPaintDefinition>, + : public GarbageCollected<CSSPaintDefinition>, public NameClient { public: CSSPaintDefinition( diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc index 0988e3db6cd..f29a220fa01 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.cc @@ -31,8 +31,7 @@ PaintRenderingContext2D::PaintRenderingContext2D( void PaintRenderingContext2D::InitializePaintRecorder() { paint_recorder_ = std::make_unique<PaintRecorder>(); cc::PaintCanvas* canvas = paint_recorder_->beginRecording( - container_size_.Width() / effective_zoom_, - container_size_.Height() / effective_zoom_); + container_size_.Width(), container_size_.Height()); // Always save an initial frame, to support resetting the top level matrix // and clip. @@ -150,9 +149,8 @@ void PaintRenderingContext2D::setTransform(double m11, double dx, double dy) { BaseRenderingContext2D::setTransform( - m11 / device_scale_factor_, m12 / device_scale_factor_, - m21 / device_scale_factor_, m22 / device_scale_factor_, - dx / device_scale_factor_, dy / device_scale_factor_); + m11 * effective_zoom_, m12 * effective_zoom_, m21 * effective_zoom_, + m22 * effective_zoom_, dx * effective_zoom_, dy * effective_zoom_); } void PaintRenderingContext2D::setTransform(DOMMatrix2DInit* transform, diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d_test.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d_test.cc index aa4d235ea49..e5d564c0aac 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d_test.cc +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d_test.cc @@ -87,13 +87,12 @@ TEST(PaintRenderingContext2DTest, setTransformWithDeviceScaleFactor) { EXPECT_TRUE(matrix->isIdentity()); ctx->setTransform(2.1, 2.5, 1.4, 2.3, 20, 50); matrix = ctx->getTransform(); - double epsilon = 0.000001; - EXPECT_NEAR(matrix->a(), 2.1 / device_scale_factor, epsilon); - EXPECT_NEAR(matrix->b(), 2.5 / device_scale_factor, epsilon); - EXPECT_NEAR(matrix->c(), 1.4 / device_scale_factor, epsilon); - EXPECT_NEAR(matrix->d(), 2.3 / device_scale_factor, epsilon); - EXPECT_NEAR(matrix->e(), 20 / device_scale_factor, epsilon); - EXPECT_NEAR(matrix->f(), 50 / device_scale_factor, epsilon); + EXPECT_FLOAT_EQ(matrix->a(), 2.1); + EXPECT_FLOAT_EQ(matrix->b(), 2.5); + EXPECT_FLOAT_EQ(matrix->c(), 1.4); + EXPECT_FLOAT_EQ(matrix->d(), 2.3); + EXPECT_FLOAT_EQ(matrix->e(), 20); + EXPECT_FLOAT_EQ(matrix->f(), 50); } TEST(PaintRenderingContext2DTest, setTransformWithDefaultDeviceScaleFactor) { diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h index b7dcf274d10..8182e1f023f 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h @@ -20,7 +20,7 @@ class WorkletModuleResponsesMap; // A proxy for PaintWorklet to talk to PaintWorkletGlobalScope. class MODULES_EXPORT PaintWorkletGlobalScopeProxy - : public GarbageCollectedFinalized<PaintWorkletGlobalScopeProxy>, + : public GarbageCollected<PaintWorkletGlobalScopeProxy>, public WorkletGlobalScopeProxy { USING_GARBAGE_COLLECTED_MIXIN(PaintWorkletGlobalScopeProxy); diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.h index 8312dc5a7ca..8c5f1bc76f1 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.h +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.h @@ -30,7 +30,7 @@ class WorkletGlobalScope; // This class is constructed on the main thread but it is used in the worklet // backing thread. The entire class is used for off-thread CSS Paint. class MODULES_EXPORT PaintWorkletProxyClient - : public GarbageCollectedFinalized<PaintWorkletProxyClient>, + : public GarbageCollected<PaintWorkletProxyClient>, public Supplement<WorkerClients>, public PaintWorkletPainter { USING_GARBAGE_COLLECTED_MIXIN(PaintWorkletProxyClient); diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/DEPS b/chromium/third_party/blink/renderer/modules/device_orientation/DEPS index 7c1b789abcd..5538e5bdbd2 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/DEPS +++ b/chromium/third_party/blink/renderer/modules/device_orientation/DEPS @@ -2,6 +2,7 @@ include_rules = [ "+base/run_loop.h", "+mojo/public/cpp/bindings/binding.h", "+services/device/public/mojom/sensor.mojom-blink.h", + "+services/device/public/mojom/sensor.mojom-blink-forward.h", "+services/device/public/mojom/sensor_provider.mojom-blink.h", "+services/device/public/cpp/test/fake_sensor_and_provider.h", "+services/device/public/cpp/generic_sensor/sensor_reading.h", diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc index 8360b1bbe5f..ba24867cb9c 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/device_orientation/device_motion_controller.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/deprecation.h" diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc index 8bc06547325..9a020ad4632 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.cc @@ -8,7 +8,7 @@ #include "services/device/public/cpp/generic_sensor/sensor_reading.h" #include "services/device/public/mojom/sensor.mojom-blink.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/platform_event_controller.h" @@ -81,9 +81,9 @@ void DeviceMotionEventPump::SendStartMessage(LocalFrame* frame) { if (!sensor_provider_) { DCHECK(frame); - frame->GetInterfaceProvider().GetInterface( - mojo::MakeRequest(&sensor_provider_)); - sensor_provider_.set_connection_error_handler( + frame->GetBrowserInterfaceBroker().GetInterface( + sensor_provider_.BindNewPipeAndPassReceiver()); + sensor_provider_.set_disconnect_handler( WTF::Bind(&DeviceSensorEventPump::HandleSensorProviderError, WrapWeakPersistent(this))); } diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h index 6f36eebb6a1..caec1ea5b21 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump.h @@ -17,7 +17,7 @@ class DeviceSensorEntry; class PlatformEventController; class MODULES_EXPORT DeviceMotionEventPump - : public GarbageCollectedFinalized<DeviceMotionEventPump>, + : public GarbageCollected<DeviceMotionEventPump>, public DeviceSensorEventPump { USING_GARBAGE_COLLECTED_MIXIN(DeviceMotionEventPump); diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc index bf1c8a756e3..1661da2b6a6 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_pump_unittest.cc @@ -7,6 +7,7 @@ #include <memory> #include "base/run_loop.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "services/device/public/cpp/test/fake_sensor_and_provider.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" @@ -24,7 +25,7 @@ namespace blink { using device::FakeSensorProvider; class MockDeviceMotionController final - : public GarbageCollectedFinalized<MockDeviceMotionController>, + : public GarbageCollected<MockDeviceMotionController>, public PlatformEventController { USING_GARBAGE_COLLECTED_MIXIN(MockDeviceMotionController); @@ -75,15 +76,14 @@ class DeviceMotionEventPumpTest : public testing::Test { protected: void SetUp() override { - device::mojom::SensorProviderPtrInfo sensor_provider_ptr_info; - sensor_provider_.Bind(mojo::MakeRequest(&sensor_provider_ptr_info)); + mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider; + sensor_provider_.Bind(sensor_provider.InitWithNewPipeAndPassReceiver()); auto* motion_pump = MakeGarbageCollected<DeviceMotionEventPump>( base::ThreadTaskRunnerHandle::Get()); motion_pump->SetSensorProviderForTesting( - device::mojom::blink::SensorProviderPtr( - device::mojom::blink::SensorProviderPtrInfo( - sensor_provider_ptr_info.PassHandle(), - device::mojom::SensorProvider::Version_))); + mojo::PendingRemote<device::mojom::blink::SensorProvider>( + sensor_provider.PassPipe(), + device::mojom::SensorProvider::Version_)); controller_ = MakeGarbageCollected<MockDeviceMotionController>(motion_pump); diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc index b7781a525fd..8175847221c 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h" diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc index 85f6ed2fc7a..1d253dd5ece 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.cc @@ -8,7 +8,7 @@ #include "services/device/public/cpp/generic_sensor/sensor_reading.h" #include "services/device/public/mojom/sensor.mojom-blink.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/platform_event_controller.h" @@ -97,9 +97,9 @@ void DeviceOrientationEventPump::SendStartMessage(LocalFrame* frame) { if (!sensor_provider_) { DCHECK(frame); - frame->GetInterfaceProvider().GetInterface( - mojo::MakeRequest(&sensor_provider_)); - sensor_provider_.set_connection_error_handler( + frame->GetBrowserInterfaceBroker().GetInterface( + sensor_provider_.BindNewPipeAndPassReceiver()); + sensor_provider_.set_disconnect_handler( WTF::Bind(&DeviceSensorEventPump::HandleSensorProviderError, WrapWeakPersistent(this))); } diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h index 3b2b56499e6..e76252ccc5d 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump.h @@ -17,7 +17,7 @@ class DeviceSensorEntry; class PlatformEventController; class MODULES_EXPORT DeviceOrientationEventPump - : public GarbageCollectedFinalized<DeviceOrientationEventPump>, + : public GarbageCollected<DeviceOrientationEventPump>, public DeviceSensorEventPump { USING_GARBAGE_COLLECTED_MIXIN(DeviceOrientationEventPump); diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc index db858fc2095..84b409f45a3 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event_pump_unittest.cc @@ -7,6 +7,7 @@ #include <memory> #include "base/run_loop.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "services/device/public/cpp/test/fake_sensor_and_provider.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" @@ -27,7 +28,7 @@ namespace blink { using device::FakeSensorProvider; class MockDeviceOrientationController final - : public GarbageCollectedFinalized<MockDeviceOrientationController>, + : public GarbageCollected<MockDeviceOrientationController>, public PlatformEventController { USING_GARBAGE_COLLECTED_MIXIN(MockDeviceOrientationController); @@ -92,15 +93,14 @@ class DeviceOrientationEventPumpTest : public testing::Test { protected: void SetUp() override { - device::mojom::SensorProviderPtrInfo sensor_provider_ptr_info; - sensor_provider_.Bind(mojo::MakeRequest(&sensor_provider_ptr_info)); + mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider; + sensor_provider_.Bind(sensor_provider.InitWithNewPipeAndPassReceiver()); auto* orientation_pump = MakeGarbageCollected<DeviceOrientationEventPump>( base::ThreadTaskRunnerHandle::Get(), false /* absolute */); orientation_pump->SetSensorProviderForTesting( - device::mojom::blink::SensorProviderPtr( - device::mojom::blink::SensorProviderPtrInfo( - sensor_provider_ptr_info.PassHandle(), - device::mojom::SensorProvider::Version_))); + mojo::PendingRemote<device::mojom::blink::SensorProvider>( + sensor_provider.PassPipe(), + device::mojom::SensorProvider::Version_)); controller_ = MakeGarbageCollected<MockDeviceOrientationController>(orientation_pump); @@ -698,16 +698,15 @@ class DeviceAbsoluteOrientationEventPumpTest : public testing::Test { protected: void SetUp() override { - device::mojom::SensorProviderPtrInfo sensor_provider_ptr_info; - sensor_provider_.Bind(mojo::MakeRequest(&sensor_provider_ptr_info)); + mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider; + sensor_provider_.Bind(sensor_provider.InitWithNewPipeAndPassReceiver()); auto* absolute_orientation_pump = MakeGarbageCollected<DeviceOrientationEventPump>( base::ThreadTaskRunnerHandle::Get(), true /* absolute */); absolute_orientation_pump->SetSensorProviderForTesting( - device::mojom::blink::SensorProviderPtr( - device::mojom::blink::SensorProviderPtrInfo( - sensor_provider_ptr_info.PassHandle(), - device::mojom::SensorProvider::Version_))); + mojo::PendingRemote<device::mojom::blink::SensorProvider>( + sensor_provider.PassPipe(), + device::mojom::SensorProvider::Version_)); controller_ = MakeGarbageCollected<MockDeviceOrientationController>( absolute_orientation_pump); diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.cc index 412f8f0b145..0a41f8aaf7b 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.cc @@ -119,7 +119,7 @@ void DeviceSensorEntry::OnSensorCreated( DCHECK_EQ(0u, params->buffer_offset % kReadBufferSize); sensor_remote_.Bind(std::move(params->sensor)); - client_receiver_.Bind(std::move(params->client_request)); + client_receiver_.Bind(std::move(params->client_receiver)); shared_buffer_reader_ = device::SensorReadingSharedBufferReader::Create( std::move(params->memory), params->buffer_offset); diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h index d11d967a163..0f24fc58705 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h @@ -7,7 +7,7 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/device/public/mojom/sensor.mojom-blink.h" +#include "services/device/public/mojom/sensor.mojom-blink-forward.h" #include "services/device/public/mojom/sensor_provider.mojom-blink.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -20,7 +20,7 @@ namespace blink { class DeviceSensorEventPump; -class DeviceSensorEntry : public GarbageCollectedFinalized<DeviceSensorEntry>, +class DeviceSensorEntry : public GarbageCollected<DeviceSensorEntry>, public device::mojom::blink::SensorClient { USING_PRE_FINALIZER(DeviceSensorEntry, Dispose); diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.cc index 1bca4b279cb..c2d7c399ae3 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.cc @@ -41,8 +41,8 @@ void DeviceSensorEventPump::HandleSensorProviderError() { } void DeviceSensorEventPump::SetSensorProviderForTesting( - device::mojom::blink::SensorProviderPtr sensor_provider) { - sensor_provider_ = std::move(sensor_provider); + mojo::PendingRemote<device::mojom::blink::SensorProvider> sensor_provider) { + sensor_provider_.Bind(std::move(sensor_provider)); } DeviceSensorEventPump::PumpState diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h index c5019d5166a..1f41dd4066a 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h @@ -5,6 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_SENSOR_EVENT_PUMP_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_SENSOR_EVENT_PUMP_H_ +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/device/public/mojom/sensor_provider.mojom-blink.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -34,7 +36,8 @@ class MODULES_EXPORT DeviceSensorEventPump : public GarbageCollectedMixin { void HandleSensorProviderError(); void SetSensorProviderForTesting( - device::mojom::blink::SensorProviderPtr sensor_provider); + mojo::PendingRemote<device::mojom::blink::SensorProvider> + sensor_provider); PumpState GetPumpStateForTesting(); protected: @@ -60,7 +63,7 @@ class MODULES_EXPORT DeviceSensorEventPump : public GarbageCollectedMixin { virtual void DidStartIfPossible(); - device::mojom::blink::SensorProviderPtr sensor_provider_; + mojo::Remote<device::mojom::blink::SensorProvider> sensor_provider_; private: virtual bool SensorsReadyOrErrored() const = 0; diff --git a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h b/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h index 2f6ec201e2a..ccdd46729a9 100644 --- a/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h +++ b/chromium/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_COPYLESS_PASTE_EXTRACTOR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_COPYLESS_PASTE_EXTRACTOR_H_ -#include "third_party/blink/public/mojom/document_metadata/copyless_paste.mojom-blink.h" +#include "third_party/blink/public/mojom/document_metadata/copyless_paste.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc index b32235f2752..c08b7b77f61 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.cc @@ -27,8 +27,6 @@ ExceptionCode WebCdmExceptionToExceptionCode( return ToExceptionCode(DOMExceptionCode::kInvalidStateError); case kWebContentDecryptionModuleExceptionQuotaExceededError: return ToExceptionCode(DOMExceptionCode::kQuotaExceededError); - case kWebContentDecryptionModuleExceptionUnknownError: - return ToExceptionCode(DOMExceptionCode::kUnknownError); } NOTREACHED(); diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h index 6d2a65c48ca..fb687dfde63 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.h @@ -27,7 +27,7 @@ class ScriptState; class WebContentDecryptionModule; class MODULES_EXPORT HTMLMediaElementEncryptedMedia final - : public GarbageCollectedFinalized<HTMLMediaElementEncryptedMedia>, + : public GarbageCollected<HTMLMediaElementEncryptedMedia>, public Supplement<HTMLMediaElement>, public WebMediaPlayerEncryptedMediaClient { USING_GARBAGE_COLLECTED_MIXIN(HTMLMediaElementEncryptedMedia); diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc index 664e74c5af1..c72276e1b28 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.cc @@ -133,7 +133,7 @@ static ScriptPromise CreateRejectedPromiseAlreadyInitialized( // A class holding a pending action. class MediaKeySession::PendingAction final - : public GarbageCollectedFinalized<MediaKeySession::PendingAction> { + : public GarbageCollected<MediaKeySession::PendingAction> { public: enum Type { kGenerateRequest, kLoad, kUpdate, kClose, kRemove }; diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc index 11569cdb6bc..a0655337673 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc @@ -18,7 +18,7 @@ namespace blink { // Represents the key ID and associated status. class MediaKeyStatusMap::MapEntry final - : public GarbageCollectedFinalized<MediaKeyStatusMap::MapEntry> { + : public GarbageCollected<MediaKeyStatusMap::MapEntry> { public: MapEntry(WebData key_id, const String& status) : key_id_(DOMArrayBuffer::Create(scoped_refptr<SharedBuffer>(key_id))), @@ -137,8 +137,10 @@ bool MediaKeyStatusMap::has(const ArrayBufferOrArrayBufferView& key_id) { ScriptValue MediaKeyStatusMap::get(ScriptState* script_state, const ArrayBufferOrArrayBufferView& key_id) { uint32_t index = IndexOf(key_id); - if (index >= entries_.size()) - return ScriptValue(script_state, v8::Undefined(script_state->GetIsolate())); + if (index >= entries_.size()) { + return ScriptValue(script_state->GetIsolate(), + v8::Undefined(script_state->GetIsolate())); + } return ScriptValue::From(script_state, at(index).Status()); } diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc index 6fdacf070c0..6197e7c3afd 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc @@ -52,7 +52,7 @@ namespace blink { // A class holding a pending action. class MediaKeys::PendingAction final - : public GarbageCollectedFinalized<MediaKeys::PendingAction> { + : public GarbageCollected<MediaKeys::PendingAction> { public: enum class Type { kSetServerCertificate, kGetStatusForPolicy }; diff --git a/chromium/third_party/blink/renderer/modules/event_target_modules_names.json5 b/chromium/third_party/blink/renderer/modules/event_target_modules_names.json5 index b6ad6e3695d..3445dc8d145 100644 --- a/chromium/third_party/blink/renderer/modules/event_target_modules_names.json5 +++ b/chromium/third_party/blink/renderer/modules/event_target_modules_names.json5 @@ -16,6 +16,7 @@ "CookieStore", "MediaKeySession", "FileWriter", + "GPUDevice", "HID", "HIDDevice", "IdleDetector", @@ -76,5 +77,6 @@ ImplementedAs: "DOMWebSocket", }, "USB", + "WakeLockSentinel", ], } diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h index 7596ab2e7fa..e2b79059674 100644 --- a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h +++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.h @@ -16,7 +16,7 @@ namespace blink { class MODULES_EXPORT EventSourceParser final - : public GarbageCollectedFinalized<EventSourceParser> { + : public GarbageCollected<EventSourceParser> { public: class MODULES_EXPORT Client : public GarbageCollectedMixin { public: diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc index f7ce421bd6f..d36aed3595a 100644 --- a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc +++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser_test.cc @@ -35,7 +35,7 @@ struct EventOrReconnectionTimeSetting { const uint64_t reconnection_time; }; -class Client : public GarbageCollectedFinalized<Client>, +class Client : public GarbageCollected<Client>, public EventSourceParser::Client { USING_GARBAGE_COLLECTED_MIXIN(Client); @@ -57,7 +57,7 @@ class Client : public GarbageCollectedFinalized<Client>, Vector<EventOrReconnectionTimeSetting> events_; }; -class StoppingClient : public GarbageCollectedFinalized<StoppingClient>, +class StoppingClient : public GarbageCollected<StoppingClient>, public EventSourceParser::Client { USING_GARBAGE_COLLECTED_MIXIN(StoppingClient); diff --git a/chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc b/chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc index 4fb9d34273b..1be76479735 100644 --- a/chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc +++ b/chromium/third_party/blink/renderer/modules/exported/web_ax_object.cc @@ -281,11 +281,11 @@ bool WebAXObject::IsAutofillAvailable() const { return private_->IsAutofillAvailable(); } -WebString WebAXObject::AriaAutoComplete() const { +WebString WebAXObject::AutoComplete() const { if (IsDetached()) return WebString(); - return private_->AriaAutoComplete(); + return private_->AutoComplete(); } ax::mojom::AriaCurrentState WebAXObject::AriaCurrentState() const { @@ -1445,6 +1445,7 @@ static ax::mojom::MarkerType ToAXMarkerType( return ax::mojom::MarkerType::kSpelling; case DocumentMarker::kGrammar: return ax::mojom::MarkerType::kGrammar; + case DocumentMarker::kTextFragment: case DocumentMarker::kTextMatch: return ax::mojom::MarkerType::kTextMatch; case DocumentMarker::kActiveSuggestion: @@ -1630,11 +1631,12 @@ void WebAXObject::Swap(WebAXObject& other) { other = temp; } -void WebAXObject::HandleAutofillStateChanged(bool suggestions_available) const { +void WebAXObject::HandleAutofillStateChanged( + const blink::WebAXAutofillState state) const { if (IsDetached() || !private_->IsAXLayoutObject()) return; - private_->HandleAutofillStateChanged(suggestions_available); + private_->HandleAutofillStateChanged(state); } WebString WebAXObject::ToString() const { diff --git a/chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc b/chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc index 380710a7ead..7b274f0f1c9 100644 --- a/chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc +++ b/chromium/third_party/blink/renderer/modules/exported/web_dom_file_system.cc @@ -30,6 +30,7 @@ #include "third_party/blink/public/web/web_dom_file_system.h" +#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_directory_entry.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_dom_file_system.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_file_entry.h" diff --git a/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc b/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc index 8fed6599512..e5297356e3c 100644 --- a/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc +++ b/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc @@ -35,6 +35,9 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/mojom/referrer_policy.mojom-blink.h" +#include "services/service_manager/public/mojom/interface_provider.mojom-blink.h" +#include "third_party/blink/public/mojom/browser_interface_broker.mojom-blink.h" +#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" #include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom-blink.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h" @@ -70,84 +73,28 @@ namespace blink { -// static -std::unique_ptr<WebEmbeddedWorker> WebEmbeddedWorker::Create( - WebServiceWorkerContextClient* client, - std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams> - installed_scripts_manager_params, - mojo::ScopedMessagePipeHandle content_settings_handle, - mojo::ScopedMessagePipeHandle cache_storage, - mojo::ScopedMessagePipeHandle interface_provider, - mojo::ScopedMessagePipeHandle browser_interface_broker) { - return std::make_unique<WebEmbeddedWorkerImpl>( - std::move(client), std::move(installed_scripts_manager_params), - std::make_unique<ServiceWorkerContentSettingsProxy>( - // Chrome doesn't use interface versioning. - // TODO(falken): Is that comment about versioning correct? - mojo::PendingRemote<mojom::blink::WorkerContentSettingsProxy>( - std::move(content_settings_handle), 0u)), - mojo::PendingRemote<mojom::blink::CacheStorage>( - std::move(cache_storage), mojom::blink::CacheStorage::Version_), - service_manager::mojom::blink::InterfaceProviderPtrInfo( - std::move(interface_provider), - service_manager::mojom::blink::InterfaceProvider::Version_), - mojo::PendingRemote<mojom::blink::BrowserInterfaceBroker>( - std::move(browser_interface_broker), - mojom::blink::BrowserInterfaceBroker::Version_)); +WebServiceWorkerInstalledScriptsManagerParams:: + WebServiceWorkerInstalledScriptsManagerParams( + WebVector<WebURL> installed_scripts_urls, + mojo::ScopedMessagePipeHandle manager_receiver, + mojo::ScopedMessagePipeHandle manager_host_remote) + : installed_scripts_urls(std::move(installed_scripts_urls)), + manager_receiver(std::move(manager_receiver)), + manager_host_remote(std::move(manager_host_remote)) { + DCHECK(!this->installed_scripts_urls.empty()); + DCHECK(this->manager_receiver); + DCHECK(this->manager_host_remote); } // static -std::unique_ptr<WebEmbeddedWorkerImpl> WebEmbeddedWorkerImpl::CreateForTesting( - WebServiceWorkerContextClient* client, - std::unique_ptr<ServiceWorkerInstalledScriptsManager> - installed_scripts_manager) { - auto worker_impl = std::make_unique<WebEmbeddedWorkerImpl>( - client, nullptr /* installed_scripts_manager_params */, - std::make_unique<ServiceWorkerContentSettingsProxy>( - mojo::NullRemote() /* host_info */), - mojo::NullRemote() /* cache_storage */, - nullptr /* interface_provider_info */, - mojo::NullRemote() /* browser_interface_broker */); - worker_impl->installed_scripts_manager_ = - std::move(installed_scripts_manager); - return worker_impl; +std::unique_ptr<WebEmbeddedWorker> WebEmbeddedWorker::Create( + WebServiceWorkerContextClient* client) { + return std::make_unique<WebEmbeddedWorkerImpl>(std::move(client)); } WebEmbeddedWorkerImpl::WebEmbeddedWorkerImpl( - WebServiceWorkerContextClient* client, - std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams> - installed_scripts_manager_params, - std::unique_ptr<ServiceWorkerContentSettingsProxy> content_settings_client, - mojo::PendingRemote<mojom::blink::CacheStorage> cache_storage_remote, - service_manager::mojom::blink::InterfaceProviderPtrInfo - interface_provider_info, - mojo::PendingRemote<mojom::blink::BrowserInterfaceBroker> - browser_interface_broker) - : worker_context_client_(client), - content_settings_client_(std::move(content_settings_client)), - cache_storage_remote_(std::move(cache_storage_remote)), - interface_provider_info_(std::move(interface_provider_info)), - browser_interface_broker_(std::move(browser_interface_broker)) { - if (installed_scripts_manager_params) { - DCHECK(installed_scripts_manager_params->manager_receiver.is_valid()); - DCHECK(installed_scripts_manager_params->manager_host_remote.is_valid()); - Vector<KURL> installed_scripts_urls; - installed_scripts_urls.AppendRange( - installed_scripts_manager_params->installed_scripts_urls.begin(), - installed_scripts_manager_params->installed_scripts_urls.end()); - installed_scripts_manager_ = std::make_unique< - ServiceWorkerInstalledScriptsManager>( - installed_scripts_urls, - mojo::PendingReceiver< - mojom::blink::ServiceWorkerInstalledScriptsManager>( - std::move(installed_scripts_manager_params->manager_receiver)), - mojo::PendingRemote< - mojom::blink::ServiceWorkerInstalledScriptsManagerHost>( - std::move(installed_scripts_manager_params->manager_host_remote), - mojom::blink::ServiceWorkerInstalledScriptsManagerHost::Version_), - Platform::Current()->GetIOTaskRunner()); - } -} + WebServiceWorkerContextClient* client) + : worker_context_client_(client) {} WebEmbeddedWorkerImpl::~WebEmbeddedWorkerImpl() { // TerminateWorkerContext() must be called before the destructor. @@ -155,10 +102,24 @@ WebEmbeddedWorkerImpl::~WebEmbeddedWorkerImpl() { } void WebEmbeddedWorkerImpl::StartWorkerContext( - const WebEmbeddedWorkerStartData& data, + std::unique_ptr<WebEmbeddedWorkerStartData> worker_start_data, + std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams> + installed_scripts_manager_params, + mojo::ScopedMessagePipeHandle content_settings_handle, + mojo::ScopedMessagePipeHandle cache_storage, + mojo::ScopedMessagePipeHandle interface_provider, + mojo::ScopedMessagePipeHandle browser_interface_broker, scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner) { DCHECK(!asked_to_terminate_); - worker_start_data_ = data; + + std::unique_ptr<ServiceWorkerInstalledScriptsManager> + installed_scripts_manager; + if (installed_scripts_manager_params) { + installed_scripts_manager = + std::make_unique<ServiceWorkerInstalledScriptsManager>( + std::move(installed_scripts_manager_params), + Platform::Current()->GetIOTaskRunner()); + } // TODO(mkwst): This really needs to be piped through from the requesting // document, like we're doing for SharedWorkers. That turns out to be @@ -168,31 +129,37 @@ void WebEmbeddedWorkerImpl::StartWorkerContext( // we should fix, but we're taking this shortcut for the prototype. // // https://crbug.com/590714 - KURL script_url = worker_start_data_.script_url; - worker_start_data_.address_space = network::mojom::IPAddressSpace::kPublic; + KURL script_url = worker_start_data->script_url; + worker_start_data->address_space = network::mojom::IPAddressSpace::kPublic; if (network_utils::IsReservedIPAddress(script_url.Host())) - worker_start_data_.address_space = network::mojom::IPAddressSpace::kPrivate; + worker_start_data->address_space = network::mojom::IPAddressSpace::kPrivate; if (SecurityOrigin::Create(script_url)->IsLocalhost()) - worker_start_data_.address_space = network::mojom::IPAddressSpace::kLocal; + worker_start_data->address_space = network::mojom::IPAddressSpace::kLocal; - devtools_worker_token_ = data.devtools_worker_token; - wait_for_debugger_mode_ = worker_start_data_.wait_for_debugger_mode; - StartWorkerThread(std::move(initiator_thread_task_runner)); + StartWorkerThread( + std::move(worker_start_data), std::move(installed_scripts_manager), + std::make_unique<ServiceWorkerContentSettingsProxy>( + // Chrome doesn't use interface versioning. + // TODO(falken): Is that comment about versioning correct? + mojo::PendingRemote<mojom::blink::WorkerContentSettingsProxy>( + std::move(content_settings_handle), 0u)), + mojo::PendingRemote<mojom::blink::CacheStorage>( + std::move(cache_storage), mojom::blink::CacheStorage::Version_), + service_manager::mojom::blink::InterfaceProviderPtrInfo( + std::move(interface_provider), + service_manager::mojom::blink::InterfaceProvider::Version_), + mojo::PendingRemote<mojom::blink::BrowserInterfaceBroker>( + std::move(browser_interface_broker), + mojom::blink::BrowserInterfaceBroker::Version_), + std::move(initiator_thread_task_runner)); } void WebEmbeddedWorkerImpl::TerminateWorkerContext() { if (asked_to_terminate_) return; asked_to_terminate_ = true; - if (!worker_thread_) { - // The worker thread has not been created yet if the worker is asked to - // terminate during waiting for debugger. - DCHECK_EQ(WebEmbeddedWorkerStartData::kWaitForDebugger, - worker_start_data_.wait_for_debugger_mode); - // This deletes 'this'. - worker_context_client_->WorkerContextFailedToStartOnInitiatorThread(); - return; - } + // StartWorkerThread() must be called before. + DCHECK(worker_thread_); worker_thread_->Terminate(); } @@ -202,6 +169,15 @@ void WebEmbeddedWorkerImpl::ResumeAfterDownload() { } void WebEmbeddedWorkerImpl::StartWorkerThread( + std::unique_ptr<WebEmbeddedWorkerStartData> worker_start_data, + std::unique_ptr<ServiceWorkerInstalledScriptsManager> + installed_scripts_manager, + std::unique_ptr<ServiceWorkerContentSettingsProxy> content_settings_proxy, + mojo::PendingRemote<mojom::blink::CacheStorage> cache_storage_remote, + service_manager::mojom::blink::InterfaceProviderPtrInfo + interface_provider_info, + mojo::PendingRemote<mojom::blink::BrowserInterfaceBroker> + browser_interface_broker, scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner) { DCHECK(!asked_to_terminate_); @@ -212,7 +188,7 @@ void WebEmbeddedWorkerImpl::StartWorkerThread( // appropriate Document. See comment in CreateFetchClientSettingsObject() for // details. scoped_refptr<const SecurityOrigin> starter_origin = - SecurityOrigin::Create(worker_start_data_.script_url); + SecurityOrigin::Create(worker_start_data->script_url); // This roughly equals to shadow document's IsSecureContext() as a shadow // document have a frame with no parent. // See also Document::InitSecureContextState(). @@ -242,43 +218,38 @@ void WebEmbeddedWorkerImpl::StartWorkerThread( String source_code; std::unique_ptr<Vector<uint8_t>> cached_meta_data; - bool is_script_installed = installed_scripts_manager_ && - installed_scripts_manager_->IsScriptInstalled( - worker_start_data_.script_url); - // We don't have to set ContentSecurityPolicy and ReferrerPolicy. They're // served by the worker script loader or the installed scripts manager on the // worker thread. global_scope_creation_params = std::make_unique<GlobalScopeCreationParams>( - worker_start_data_.script_url, worker_start_data_.script_type, + worker_start_data->script_url, worker_start_data->script_type, OffMainThreadWorkerScriptFetchOption::kEnabled, global_scope_name, - worker_start_data_.user_agent, std::move(web_worker_fetch_context), + worker_start_data->user_agent, std::move(web_worker_fetch_context), Vector<CSPHeaderAndType>(), network::mojom::ReferrerPolicy::kDefault, starter_origin.get(), starter_secure_context, starter_https_state, - nullptr /* worker_clients */, std::move(content_settings_client_), + nullptr /* worker_clients */, std::move(content_settings_proxy), base::nullopt /* response_address_space */, - nullptr /* OriginTrialTokens */, devtools_worker_token_, + nullptr /* OriginTrialTokens */, worker_start_data->devtools_worker_token, std::move(worker_settings), - static_cast<V8CacheOptions>(worker_start_data_.v8_cache_options), + // Generate the full code cache in the first execution of the script. + kV8CacheOptionsFullCodeWithoutHeatCheck, nullptr /* worklet_module_respones_map */, - std::move(interface_provider_info_), std::move(browser_interface_broker_), + std::move(interface_provider_info), std::move(browser_interface_broker), BeginFrameProviderParams(), nullptr /* parent_feature_policy */, base::UnguessableToken() /* agent_cluster_id */); - // Generate the full code cache in the first execution of the script. - global_scope_creation_params->v8_cache_options = - kV8CacheOptionsFullCodeWithoutHeatCheck; - worker_thread_ = std::make_unique<ServiceWorkerThread>( std::make_unique<ServiceWorkerGlobalScopeProxy>( *this, *worker_context_client_, initiator_thread_task_runner), - std::move(installed_scripts_manager_), std::move(cache_storage_remote_), + std::move(installed_scripts_manager), std::move(cache_storage_remote), initiator_thread_task_runner); auto devtools_params = std::make_unique<WorkerDevToolsParams>(); - devtools_params->devtools_worker_token = devtools_worker_token_; + devtools_params->devtools_worker_token = + worker_start_data->devtools_worker_token; devtools_params->wait_for_debugger = - wait_for_debugger_mode_ == WebEmbeddedWorkerStartData::kWaitForDebugger; + worker_start_data->wait_for_debugger_mode == + WebEmbeddedWorkerStartData::kWaitForDebugger; mojo::PendingRemote<mojom::blink::DevToolsAgent> devtools_agent_remote; devtools_params->agent_receiver = devtools_agent_remote.InitWithNewPipeAndPassReceiver(); @@ -290,56 +261,39 @@ void WebEmbeddedWorkerImpl::StartWorkerThread( WorkerBackingThreadStartupData::CreateDefault(), std::move(devtools_params)); - // If this is an installed service worker, the installed script will be read - // from the service worker script storage on the worker thread. - if (is_script_installed) { - switch (worker_start_data_.script_type) { - case mojom::ScriptType::kClassic: - worker_thread_->RunInstalledClassicScript( - worker_start_data_.script_url, v8_inspector::V8StackTraceId()); - break; - case mojom::ScriptType::kModule: - worker_thread_->RunInstalledModuleScript( - worker_start_data_.script_url, - CreateFetchClientSettingsObjectData(starter_origin.get(), - starter_https_state), - network::mojom::CredentialsMode::kOmit); - break; - } - } else { - std::unique_ptr<CrossThreadFetchClientSettingsObjectData> - fetch_client_setting_object_data = CreateFetchClientSettingsObjectData( - starter_origin.get(), starter_https_state); - - // If this is a new (not installed) service worker, we are in the Update - // algorithm here: - // > Switching on job's worker type, run these substeps with the following - // > options: - // https://w3c.github.io/ServiceWorker/#update-algorithm - switch (worker_start_data_.script_type) { - // > "classic": Fetch a classic worker script given job's serialized - // > script url, job's client, "serviceworker", and the to-be-created - // > environment settings object for this service worker. - case mojom::ScriptType::kClassic: - worker_thread_->FetchAndRunClassicScript( - worker_start_data_.script_url, - std::move(fetch_client_setting_object_data), - nullptr /* outside_resource_timing_notifier */, - v8_inspector::V8StackTraceId()); - break; - - // > "module": Fetch a module worker script graph given job’s serialized - // > script url, job’s client, "serviceworker", "omit", and the - // > to-be-created environment settings object for this service worker. - case mojom::ScriptType::kModule: - worker_thread_->FetchAndRunModuleScript( - worker_start_data_.script_url, - std::move(fetch_client_setting_object_data), - nullptr /* outside_resource_timing_notifier */, - network::mojom::CredentialsMode::kOmit); - break; - } + std::unique_ptr<CrossThreadFetchClientSettingsObjectData> + fetch_client_setting_object_data = CreateFetchClientSettingsObjectData( + worker_start_data->script_url, starter_origin.get(), + starter_https_state, worker_start_data->address_space, + worker_start_data->outside_fetch_client_settings_object); + + // > Switching on job's worker type, run these substeps with the following + // > options: + // https://w3c.github.io/ServiceWorker/#update-algorithm + switch (worker_start_data->script_type) { + // > "classic": Fetch a classic worker script given job's serialized script + // > url, job's client, "serviceworker", and the to-be-created environment + // > settings object for this service worker. + case mojom::ScriptType::kClassic: + worker_thread_->FetchAndRunClassicScript( + worker_start_data->script_url, + std::move(fetch_client_setting_object_data), + nullptr /* outside_resource_timing_notifier */, + v8_inspector::V8StackTraceId()); + break; + + // > "module": Fetch a module worker script graph given job’s serialized + // > script url, job’s client, "serviceworker", "omit", and the + // > to-be-created environment settings object for this service worker. + case mojom::ScriptType::kModule: + worker_thread_->FetchAndRunModuleScript( + worker_start_data->script_url, + std::move(fetch_client_setting_object_data), + nullptr /* outside_resource_timing_notifier */, + network::mojom::CredentialsMode::kOmit); + break; } + // We are now ready to inspect worker thread. worker_context_client_->WorkerReadyForInspectionOnInitiatorThread( devtools_agent_remote.PassPipe(), @@ -348,27 +302,33 @@ void WebEmbeddedWorkerImpl::StartWorkerThread( std::unique_ptr<CrossThreadFetchClientSettingsObjectData> WebEmbeddedWorkerImpl::CreateFetchClientSettingsObjectData( + const KURL& script_url, const SecurityOrigin* security_origin, - const HttpsState& https_state) { - // TODO(crbug.com/967265): Currently we create an incomplete outside settings - // object from |worker_start_data_| but we should create a proper outside - // settings objects depending on the situation. For new worker case, this - // should be the Document that called navigator.serviceWorker.register(). For - // ServiceWorkerRegistration#update() case, it should be the Document that - // called update(). For soft update case, it seems to be 'null' document. - // - // To get a correct settings, we need to make a way to pass the settings - // object over mojo IPCs. + const HttpsState& https_state, + network::mojom::IPAddressSpace address_space, + const WebFetchClientSettingsObject& passed_settings_object) { + // TODO(crbug.com/967265): Currently |passed_settings_object| doesn't contain + // enough parameters to create a complete outside settings object. Pass + // all necessary information from the parent execution context. + // For new worker case, the parent is the Document that called + // navigator.serviceWorker.register(). For ServiceWorkerRegistration#update() + // case, it should be the Document that called update(). For soft update case, + // it seems to be 'null' document. + + WebInsecureRequestPolicy insecure_requests_policy = + passed_settings_object.insecure_requests_policy == + mojom::InsecureRequestsPolicy::kUpgrade + ? kUpgradeInsecureRequests + : kBlockAllMixedContent; - const KURL& script_url = worker_start_data_.script_url; return std::make_unique<CrossThreadFetchClientSettingsObjectData>( script_url.Copy() /* global_object_url */, script_url.Copy() /* base_url */, security_origin->IsolatedCopy(), - network::mojom::ReferrerPolicy::kDefault, - script_url.GetString().IsolatedCopy() /* outgoing_referrer */, - https_state, AllowedByNosniff::MimeTypeCheck::kLax, - worker_start_data_.address_space, - kBlockAllMixedContent /* insecure_requests_policy */, + passed_settings_object.referrer_policy, + KURL::CreateIsolated( + passed_settings_object.outgoing_referrer.GetString()), + https_state, AllowedByNosniff::MimeTypeCheck::kLax, address_space, + insecure_requests_policy, FetchClientSettingsObject::InsecureNavigationsSet(), false /* mixed_autoupgrade_opt_out */); } diff --git a/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h b/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h index c4e8c1846d8..bc33444ae2f 100644 --- a/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h +++ b/chromium/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h @@ -36,8 +36,8 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "services/service_manager/public/cpp/interface_provider.h" -#include "services/service_manager/public/mojom/interface_provider.mojom-blink.h" -#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" +#include "services/service_manager/public/mojom/interface_provider.mojom-blink-forward.h" +#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink-forward.h" #include "third_party/blink/public/web/web_embedded_worker.h" #include "third_party/blink/public/web/web_embedded_worker_start_data.h" #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h" @@ -61,65 +61,51 @@ struct CrossThreadFetchClientSettingsObjectData; // worker startup. See https://crbug.com/988335 for details. class MODULES_EXPORT WebEmbeddedWorkerImpl final : public WebEmbeddedWorker { public: - WebEmbeddedWorkerImpl( - WebServiceWorkerContextClient*, - std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>, - std::unique_ptr<ServiceWorkerContentSettingsProxy>, - mojo::PendingRemote<mojom::blink::CacheStorage>, - service_manager::mojom::blink::InterfaceProviderPtrInfo, - mojo::PendingRemote<mojom::blink::BrowserInterfaceBroker>); + explicit WebEmbeddedWorkerImpl(WebServiceWorkerContextClient*); ~WebEmbeddedWorkerImpl() override; // WebEmbeddedWorker overrides. - void StartWorkerContext(const WebEmbeddedWorkerStartData&, - scoped_refptr<base::SingleThreadTaskRunner> - initiator_thread_task_runner) override; + void StartWorkerContext( + std::unique_ptr<WebEmbeddedWorkerStartData>, + std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>, + mojo::ScopedMessagePipeHandle content_settings_handle, + mojo::ScopedMessagePipeHandle cache_storage, + mojo::ScopedMessagePipeHandle interface_provider, + mojo::ScopedMessagePipeHandle browser_interface_broker, + scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner) + override; void TerminateWorkerContext() override; void ResumeAfterDownload() override; - static std::unique_ptr<WebEmbeddedWorkerImpl> CreateForTesting( - WebServiceWorkerContextClient*, - std::unique_ptr<ServiceWorkerInstalledScriptsManager>); - void WaitForShutdownForTesting(); private: - void StartWorkerThread(scoped_refptr<base::SingleThreadTaskRunner>); + void StartWorkerThread( + std::unique_ptr<WebEmbeddedWorkerStartData> worker_start_data, + std::unique_ptr<ServiceWorkerInstalledScriptsManager>, + std::unique_ptr<ServiceWorkerContentSettingsProxy>, + mojo::PendingRemote<mojom::blink::CacheStorage>, + service_manager::mojom::blink::InterfaceProviderPtrInfo, + mojo::PendingRemote<mojom::blink::BrowserInterfaceBroker>, + scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner); // Creates a cross-thread copyable outside settings object for top-level // worker script fetch. std::unique_ptr<CrossThreadFetchClientSettingsObjectData> - CreateFetchClientSettingsObjectData(const SecurityOrigin*, const HttpsState&); - - WebEmbeddedWorkerStartData worker_start_data_; + CreateFetchClientSettingsObjectData( + const KURL& script_url, + const SecurityOrigin*, + const HttpsState&, + network::mojom::IPAddressSpace, + const WebFetchClientSettingsObject& passed_settings_object); // Client must remain valid through the entire life time of the worker. WebServiceWorkerContextClient* const worker_context_client_; - // These are valid until StartWorkerThread() is called. After the worker - // thread is created, these are passed to the worker thread. - std::unique_ptr<ServiceWorkerInstalledScriptsManager> - installed_scripts_manager_; - std::unique_ptr<ServiceWorkerContentSettingsProxy> content_settings_client_; - std::unique_ptr<ServiceWorkerThread> worker_thread_; bool asked_to_terminate_ = false; - // Unique worker token used by DevTools to attribute different instrumentation - // to the same worker. - base::UnguessableToken devtools_worker_token_; - WebEmbeddedWorkerStartData::WaitForDebuggerMode wait_for_debugger_mode_ = - WebEmbeddedWorkerStartData::kDontWaitForDebugger; - - mojo::PendingRemote<mojom::blink::CacheStorage> cache_storage_remote_; - - service_manager::mojom::blink::InterfaceProviderPtrInfo - interface_provider_info_; - - mojo::PendingRemote<mojom::blink::BrowserInterfaceBroker> - browser_interface_broker_; - DISALLOW_COPY_AND_ASSIGN(WebEmbeddedWorkerImpl); }; diff --git a/chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn b/chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn index 23bd32d4d3a..2e2f3d00a4d 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/filesystem/BUILD.gn @@ -45,7 +45,6 @@ blink_modules_sources("filesystem") { "file_entry_sync.h", "file_system_callbacks.cc", "file_system_callbacks.h", - "file_system_client.h", "file_system_dispatcher.cc", "file_system_dispatcher.h", "file_writer.cc", @@ -58,8 +57,6 @@ blink_modules_sources("filesystem") { "html_input_element_file_system.h", "local_file_system.cc", "local_file_system.h", - "local_file_system_client.cc", - "local_file_system_client.h", "metadata.h", "sync_callback_helper.h", "worker_global_scope_file_system.cc", diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc b/chromium/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc index 7259ed52a43..c01ac1ac91a 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.h" +#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/inspector/dev_tools_host.h" diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h index 2035bcfb3c9..f6be95c7e85 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h @@ -31,7 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_DOM_FILE_SYSTEM_BASE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_DOM_FILE_SYSTEM_BASE_H_ -#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h" +#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink-forward.h" #include "third_party/blink/renderer/core/fileapi/file_error.h" #include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h" #include "third_party/blink/renderer/modules/filesystem/file_system_flags.h" diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc index 4b616ae7085..d8cdbb61ae3 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/filesystem/dom_file_system_base.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h" #include "third_party/blink/renderer/core/fileapi/file.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.h b/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.h index e524f907a06..e5f7dbb3a96 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.h @@ -43,7 +43,7 @@ namespace blink { class DOMFileSystem; class DraggedIsolatedFileSystemImpl final - : public GarbageCollectedFinalized<DraggedIsolatedFileSystemImpl>, + : public GarbageCollected<DraggedIsolatedFileSystemImpl>, public DraggedIsolatedFileSystem, public Supplement<DataObject> { USING_GARBAGE_COLLECTED_MIXIN(DraggedIsolatedFileSystemImpl); diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry.cc b/chromium/third_party/blink/renderer/modules/filesystem/entry.cc index b1b371be135..1b3e6eb79f1 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/entry.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/entry.cc @@ -29,6 +29,7 @@ */ #include "third_party/blink/renderer/modules/filesystem/entry.h" +#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/fileapi/file_error.h" #include "third_party/blink/renderer/core/frame/web_feature.h" diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h index 35f91cab514..f671b4b4ea2 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h @@ -33,7 +33,7 @@ #include <memory> -#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h" +#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/v8_void_callback.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_entry_callback.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_error_callback.h" diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_client.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_client.h deleted file mode 100644 index 7288beb24e0..00000000000 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_client.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_CLIENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_CLIENT_H_ - -#include <memory> - -#include "base/callback.h" -#include "base/macros.h" -#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h" -#include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "third_party/blink/renderer/platform/wtf/forward.h" - -namespace blink { - -class ExecutionContext; -class LocalFrame; -class WorkerClients; - -class FileSystemClient { - USING_FAST_MALLOC(FileSystemClient); - - public: - FileSystemClient() = default; - virtual ~FileSystemClient() = default; - - virtual bool RequestFileSystemAccessSync(ExecutionContext*) = 0; - virtual void RequestFileSystemAccessAsync(ExecutionContext*, - base::OnceCallback<void(bool)>) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(FileSystemClient); -}; - -MODULES_EXPORT void ProvideLocalFileSystemTo(LocalFrame&, - std::unique_ptr<FileSystemClient>); - -MODULES_EXPORT void ProvideLocalFileSystemToWorker( - WorkerClients*, - std::unique_ptr<FileSystemClient>); - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_SYSTEM_CLIENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc index 0483ec85bcd..ef829b48015 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc @@ -4,10 +4,10 @@ #include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h" -#include <memory> #include <utility> #include "build/build_config.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/file_path_conversion.h" @@ -284,16 +284,15 @@ void FileSystemDispatcher::ExistsSync( void FileSystemDispatcher::ReadDirectory( const KURL& path, std::unique_ptr<EntriesCallbacks> callbacks) { - mojom::blink::FileSystemOperationListenerPtr ptr; - // See https://bit.ly/2S0zRAS for task types - mojom::blink::FileSystemOperationListenerRequest request = mojo::MakeRequest( - &ptr, - GetSupplementable()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI)); - op_listeners_.AddBinding( + mojo::PendingRemote<mojom::blink::FileSystemOperationListener> listener; + mojo::PendingReceiver<mojom::blink::FileSystemOperationListener> receiver = + listener.InitWithNewPipeAndPassReceiver(); + op_listeners_.Add( std::make_unique<ReadDirectoryListener>(std::move(callbacks)), - std::move(request), + std::move(receiver), + // See https://bit.ly/2S0zRAS for task types GetSupplementable()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI)); - GetFileSystemManager().ReadDirectory(path, std::move(ptr)); + GetFileSystemManager().ReadDirectory(path, std::move(listener)); } void FileSystemDispatcher::ReadDirectorySync( @@ -330,18 +329,19 @@ void FileSystemDispatcher::Truncate(const KURL& path, int64_t offset, int* request_id_out, StatusCallback callback) { - mojom::blink::FileSystemCancellableOperationPtr op_ptr; + mojo::Remote<mojom::blink::FileSystemCancellableOperation> op_remote; // See https://bit.ly/2S0zRAS for task types - mojom::blink::FileSystemCancellableOperationRequest op_request = - mojo::MakeRequest(&op_ptr, GetSupplementable()->GetTaskRunner( - blink::TaskType::kMiscPlatformAPI)); + mojo::PendingReceiver<mojom::blink::FileSystemCancellableOperation> + op_receiver = op_remote.BindNewPipeAndPassReceiver( + GetSupplementable()->GetTaskRunner( + blink::TaskType::kMiscPlatformAPI)); int operation_id = next_operation_id_++; - op_ptr.set_connection_error_handler( - WTF::Bind(&FileSystemDispatcher::RemoveOperationPtr, + op_remote.set_disconnect_handler( + WTF::Bind(&FileSystemDispatcher::RemoveOperationRemote, WrapWeakPersistent(this), operation_id)); - cancellable_operations_.insert(operation_id, std::move(op_ptr)); + cancellable_operations_.insert(operation_id, std::move(op_remote)); GetFileSystemManager().Truncate( - path, offset, std::move(op_request), + path, offset, std::move(op_receiver), WTF::Bind(&FileSystemDispatcher::DidTruncate, WrapWeakPersistent(this), operation_id, std::move(callback))); @@ -363,35 +363,32 @@ void FileSystemDispatcher::Write(const KURL& path, int* request_id_out, const WriteCallback& success_callback, StatusCallback error_callback) { - mojom::blink::FileSystemCancellableOperationPtr op_ptr; + mojo::Remote<mojom::blink::FileSystemCancellableOperation> op_remote; // See https://bit.ly/2S0zRAS for task types - mojom::blink::FileSystemCancellableOperationRequest op_request = - mojo::MakeRequest(&op_ptr, GetSupplementable()->GetTaskRunner( - blink::TaskType::kMiscPlatformAPI)); + scoped_refptr<base::SequencedTaskRunner> task_runner = + GetSupplementable()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI); + mojo::PendingReceiver<mojom::blink::FileSystemCancellableOperation> + op_receiver = op_remote.BindNewPipeAndPassReceiver(task_runner); int operation_id = next_operation_id_++; - op_ptr.set_connection_error_handler( - WTF::Bind(&FileSystemDispatcher::RemoveOperationPtr, + op_remote.set_disconnect_handler( + WTF::Bind(&FileSystemDispatcher::RemoveOperationRemote, WrapWeakPersistent(this), operation_id)); - cancellable_operations_.insert(operation_id, std::move(op_ptr)); - - mojom::blink::FileSystemOperationListenerPtr listener_ptr; - // See https://bit.ly/2S0zRAS for task types - mojom::blink::FileSystemOperationListenerRequest request = mojo::MakeRequest( - &listener_ptr, - GetSupplementable()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI)); - op_listeners_.AddBinding( - std::make_unique<WriteListener>( - WTF::BindRepeating(&FileSystemDispatcher::DidWrite, - WrapWeakPersistent(this), success_callback, - operation_id), - WTF::Bind(&FileSystemDispatcher::WriteErrorCallback, - WrapWeakPersistent(this), std::move(error_callback), - operation_id)), - std::move(request), - GetSupplementable()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI)); - - GetFileSystemManager().Write(path, blob_id, offset, std::move(op_request), - std::move(listener_ptr)); + cancellable_operations_.insert(operation_id, std::move(op_remote)); + + mojo::PendingRemote<mojom::blink::FileSystemOperationListener> listener; + mojo::PendingReceiver<mojom::blink::FileSystemOperationListener> receiver = + listener.InitWithNewPipeAndPassReceiver(); + op_listeners_.Add(std::make_unique<WriteListener>( + WTF::BindRepeating(&FileSystemDispatcher::DidWrite, + WrapWeakPersistent(this), + success_callback, operation_id), + WTF::Bind(&FileSystemDispatcher::WriteErrorCallback, + WrapWeakPersistent(this), + std::move(error_callback), operation_id)), + std::move(receiver), task_runner); + + GetFileSystemManager().Write(path, blob_id, offset, std::move(op_receiver), + std::move(listener)); if (request_id_out) *request_id_out = operation_id; @@ -439,7 +436,7 @@ void FileSystemDispatcher::CreateSnapshotFileSync( base::File::Info file_info; base::FilePath platform_path; base::File::Error error_code = base::File::FILE_ERROR_FAILED; - mojom::blink::ReceivedSnapshotListenerPtr listener; + mojo::PendingRemote<mojom::blink::ReceivedSnapshotListener> listener; GetFileSystemManager().CreateSnapshotFile( file_path, &file_info, &platform_path, &error_code, &listener); DidCreateSnapshotFile(std::move(callbacks), std::move(file_info), @@ -537,7 +534,7 @@ void FileSystemDispatcher::DidTruncate(int operation_id, StatusCallback callback, base::File::Error error_code) { if (error_code != base::File::FILE_ERROR_ABORT) - RemoveOperationPtr(operation_id); + RemoveOperationRemote(operation_id); std::move(callback).Run(error_code); } @@ -547,7 +544,7 @@ void FileSystemDispatcher::DidWrite(const WriteCallback& callback, bool complete) { callback.Run(bytes, complete); if (complete) - RemoveOperationPtr(operation_id); + RemoveOperationRemote(operation_id); } void FileSystemDispatcher::WriteErrorCallback(StatusCallback callback, @@ -555,14 +552,14 @@ void FileSystemDispatcher::WriteErrorCallback(StatusCallback callback, base::File::Error error) { std::move(callback).Run(error); if (error != base::File::FILE_ERROR_ABORT) - RemoveOperationPtr(operation_id); + RemoveOperationRemote(operation_id); } void FileSystemDispatcher::DidCancel(StatusCallback callback, int cancelled_operation_id, base::File::Error error_code) { if (error_code == base::File::FILE_OK) - RemoveOperationPtr(cancelled_operation_id); + RemoveOperationRemote(cancelled_operation_id); std::move(callback).Run(error_code); } @@ -571,7 +568,7 @@ void FileSystemDispatcher::DidCreateSnapshotFile( const base::File::Info& file_info, const base::FilePath& platform_path, base::File::Error error_code, - mojom::blink::ReceivedSnapshotListenerPtr listener) { + mojo::PendingRemote<mojom::blink::ReceivedSnapshotListener> listener) { if (error_code == base::File::FILE_OK) { FileMetadata file_metadata = FileMetadata::From(file_info); file_metadata.platform_path = FilePathToWebString(platform_path); @@ -584,14 +581,16 @@ void FileSystemDispatcher::DidCreateSnapshotFile( callbacks->DidCreateSnapshotFile(file_metadata, snapshot_blob); - if (listener) - listener->DidReceiveSnapshotFile(); + if (listener) { + mojo::Remote<mojom::blink::ReceivedSnapshotListener>(std::move(listener)) + ->DidReceiveSnapshotFile(); + } } else { callbacks->DidFail(error_code); } } -void FileSystemDispatcher::RemoveOperationPtr(int operation_id) { +void FileSystemDispatcher::RemoveOperationRemote(int operation_id) { auto it = cancellable_operations_.find(operation_id); if (it == cancellable_operations_.end()) return; @@ -599,7 +598,7 @@ void FileSystemDispatcher::RemoveOperationPtr(int operation_id) { } void FileSystemDispatcher::Prefinalize() { - op_listeners_.CloseAllBindings(); + op_listeners_.Clear(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h b/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h index 4491c0e2826..5344dcf6015 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h @@ -7,8 +7,9 @@ #include <memory> +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" -#include "mojo/public/cpp/bindings/strong_binding_set.h" +#include "mojo/public/cpp/bindings/unique_receiver_set.h" #include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h" #include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -27,9 +28,8 @@ class SecurityOrigin; // Sends messages via mojo to the blink::mojom::FileSystemManager service // running in the browser process. It is owned by ExecutionContext, and // instances are created lazily by calling FileSystemDispatcher::From(). -class FileSystemDispatcher - : public GarbageCollectedFinalized<FileSystemDispatcher>, - public Supplement<ExecutionContext> { +class FileSystemDispatcher : public GarbageCollected<FileSystemDispatcher>, + public Supplement<ExecutionContext> { USING_GARBAGE_COLLECTED_MIXIN(FileSystemDispatcher); USING_PRE_FINALIZER(FileSystemDispatcher, Prefinalize); @@ -191,18 +191,18 @@ class FileSystemDispatcher const base::File::Info& file_info, const base::FilePath& platform_path, base::File::Error error_code, - mojom::blink::ReceivedSnapshotListenerPtr listener); + mojo::PendingRemote<mojom::blink::ReceivedSnapshotListener> listener); - void RemoveOperationPtr(int operation_id); + void RemoveOperationRemote(int operation_id); void Prefinalize(); mojo::Remote<mojom::blink::FileSystemManager> file_system_manager_; using OperationsMap = - HashMap<int, mojom::blink::FileSystemCancellableOperationPtr>; + HashMap<int, mojo::Remote<mojom::blink::FileSystemCancellableOperation>>; OperationsMap cancellable_operations_; int next_operation_id_; - mojo::StrongBindingSet<mojom::blink::FileSystemOperationListener> + mojo::UniqueReceiverSet<mojom::blink::FileSystemOperationListener> op_listeners_; }; diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc index 1da44bd046f..9e929f7c99a 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_test.cc @@ -30,7 +30,7 @@ KURL mock_path_as_kurl() { } // namespace -class TestableFileWriter : public GarbageCollectedFinalized<TestableFileWriter>, +class TestableFileWriter : public GarbageCollected<TestableFileWriter>, public FileWriterBase { USING_GARBAGE_COLLECTED_MIXIN(TestableFileWriter); diff --git a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc index b0cd5d9bd29..05f3ba3ab2c 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.cc @@ -44,10 +44,8 @@ #include "third_party/blink/renderer/core/fileapi/file_error.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" -#include "third_party/blink/renderer/core/workers/worker_global_scope.h" #include "third_party/blink/renderer/modules/filesystem/dom_file_system.h" #include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h" -#include "third_party/blink/renderer/modules/filesystem/file_system_client.h" #include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" @@ -110,15 +108,26 @@ void LocalFileSystem::RequestFileSystemCallback( void LocalFileSystem::RequestFileSystemAccessInternal( ExecutionContext* context, base::OnceCallback<void(bool)> callback) { - if (!context->IsDocument()) { - if (!Client().RequestFileSystemAccessSync(context)) { - std::move(callback).Run(false); - return; + if (context->IsDocument()) { + auto* client = + To<Document>(context)->GetFrame()->GetContentSettingsClient(); + if (!client) { + std::move(callback).Run(true); + } else { + client->RequestFileSystemAccessAsync(std::move(callback)); } - std::move(callback).Run(true); return; } - Client().RequestFileSystemAccessAsync(context, std::move(callback)); + if (context->IsWorkerGlobalScope()) { + auto* client = To<WorkerGlobalScope>(context)->ContentSettingsClient(); + if (!client) { + std::move(callback).Run(true); + } else { + std::move(callback).Run(client->RequestFileSystemAccessSync()); + } + return; + } + NOTREACHED(); } void LocalFileSystem::FileSystemNotAllowedInternal( @@ -167,21 +176,15 @@ void LocalFileSystem::ResolveURLInternal( } } -LocalFileSystem::LocalFileSystem(LocalFrame& frame, - std::unique_ptr<FileSystemClient> client) - : Supplement<LocalFrame>(frame), client_(std::move(client)) { - DCHECK(client_); -} +LocalFileSystem::LocalFileSystem(LocalFrame& frame) + : Supplement<LocalFrame>(frame) {} -LocalFileSystem::LocalFileSystem(WorkerClients& worker_clients, - std::unique_ptr<FileSystemClient> client) - : Supplement<WorkerClients>(worker_clients), client_(std::move(client)) { - DCHECK(client_); -} +LocalFileSystem::LocalFileSystem(WorkerGlobalScope& worker_global_scope) + : Supplement<WorkerGlobalScope>(worker_global_scope) {} void LocalFileSystem::Trace(blink::Visitor* visitor) { Supplement<LocalFrame>::Trace(visitor); - Supplement<WorkerClients>::Trace(visitor); + Supplement<WorkerGlobalScope>::Trace(visitor); } const char LocalFileSystem::kSupplementName[] = "LocalFileSystem"; @@ -194,25 +197,21 @@ LocalFileSystem* LocalFileSystem::From(ExecutionContext& context) { return file_system; } - WorkerClients* clients = To<WorkerGlobalScope>(context).Clients(); - DCHECK(clients); LocalFileSystem* file_system = - Supplement<WorkerClients>::From<LocalFileSystem>(clients); + Supplement<WorkerGlobalScope>::From<LocalFileSystem>( + To<WorkerGlobalScope>(context)); DCHECK(file_system); return file_system; } -void ProvideLocalFileSystemTo(LocalFrame& frame, - std::unique_ptr<FileSystemClient> client) { - frame.ProvideSupplement( - MakeGarbageCollected<LocalFileSystem>(frame, std::move(client))); +void ProvideLocalFileSystemTo(LocalFrame& frame) { + frame.ProvideSupplement(MakeGarbageCollected<LocalFileSystem>(frame)); } -void ProvideLocalFileSystemToWorker(WorkerClients* worker_clients, - std::unique_ptr<FileSystemClient> client) { - Supplement<WorkerClients>::ProvideTo(*worker_clients, - MakeGarbageCollected<LocalFileSystem>( - *worker_clients, std::move(client))); +void ProvideLocalFileSystemToWorker(WorkerGlobalScope& worker_global_scope) { + Supplement<WorkerGlobalScope>::ProvideTo( + worker_global_scope, + MakeGarbageCollected<LocalFileSystem>(worker_global_scope)); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h index 532745c13d8..48d8734cd72 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system.h @@ -35,9 +35,9 @@ #include "base/callback.h" #include "base/macros.h" -#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h" +#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink-forward.h" #include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/core/workers/worker_clients.h" +#include "third_party/blink/renderer/core/workers/worker_global_scope.h" #include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/supplementable.h" @@ -46,15 +46,14 @@ namespace blink { -class FileSystemClient; class ExecutionContext; class FileSystemCallbacks; class KURL; class ResolveURICallbacks; -class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>, +class LocalFileSystem final : public GarbageCollected<LocalFileSystem>, public Supplement<LocalFrame>, - public Supplement<WorkerClients>, + public Supplement<WorkerGlobalScope>, public NameClient { USING_GARBAGE_COLLECTED_MIXIN(LocalFileSystem); @@ -63,8 +62,8 @@ class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>, static const char kSupplementName[]; - LocalFileSystem(LocalFrame&, std::unique_ptr<FileSystemClient>); - LocalFileSystem(WorkerClients&, std::unique_ptr<FileSystemClient>); + explicit LocalFileSystem(LocalFrame&); + explicit LocalFileSystem(WorkerGlobalScope&); ~LocalFileSystem(); void ResolveURL(ExecutionContext*, @@ -77,8 +76,6 @@ class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>, std::unique_ptr<FileSystemCallbacks>, SynchronousType sync_type); - FileSystemClient& Client() const { return *client_; } - static LocalFileSystem* From(ExecutionContext&); void Trace(blink::Visitor*) override; @@ -110,11 +107,12 @@ class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>, std::unique_ptr<ResolveURICallbacks>, SynchronousType sync_type); - const std::unique_ptr<FileSystemClient> client_; - DISALLOW_COPY_AND_ASSIGN(LocalFileSystem); }; +void ProvideLocalFileSystemTo(LocalFrame&); +void ProvideLocalFileSystemToWorker(WorkerGlobalScope&); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_LOCAL_FILE_SYSTEM_H_ diff --git a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system_client.cc b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system_client.cc deleted file mode 100644 index 0a0c5ea74da..00000000000 --- a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system_client.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/modules/filesystem/local_file_system_client.h" - -#include <memory> -#include <utility> - -#include "base/memory/ptr_util.h" -#include "third_party/blink/public/platform/web_content_settings_client.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/core/workers/worker_global_scope.h" -#include "third_party/blink/renderer/platform/weborigin/security_origin.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -namespace blink { - -LocalFileSystemClient::~LocalFileSystemClient() = default; - -bool LocalFileSystemClient::RequestFileSystemAccessSync( - ExecutionContext* context) { - DCHECK(context); - if (IsA<Document>(context)) { - // TODO(dcheng): Why is this NOTREACHED and handled? - NOTREACHED(); - return false; - } - - WebContentSettingsClient* content_settings_client = - To<WorkerGlobalScope>(context)->ContentSettingsClient(); - if (!content_settings_client) - return true; - return content_settings_client->RequestFileSystemAccessSync(); -} - -void LocalFileSystemClient::RequestFileSystemAccessAsync( - ExecutionContext* context, - base::OnceCallback<void(bool)> callback) { - DCHECK(context); - auto* document = DynamicTo<Document>(context); - if (!document) { - // TODO(dcheng): Why is this NOTREACHED and handled? - NOTREACHED(); - return; - } - - if (auto* client = document->GetFrame()->GetContentSettingsClient()) { - client->RequestFileSystemAccessAsync(std::move(callback)); - } else { - std::move(callback).Run(true); - } -} - -LocalFileSystemClient::LocalFileSystemClient() = default; - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system_client.h b/chromium/third_party/blink/renderer/modules/filesystem/local_file_system_client.h deleted file mode 100644 index a601dc072a8..00000000000 --- a/chromium/third_party/blink/renderer/modules/filesystem/local_file_system_client.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_LOCAL_FILE_SYSTEM_CLIENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_LOCAL_FILE_SYSTEM_CLIENT_H_ - -#include <memory> -#include "base/callback.h" -#include "third_party/blink/renderer/modules/filesystem/file_system_client.h" -#include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/platform/wtf/forward.h" - -namespace blink { - -class LocalFileSystemClient final : public FileSystemClient { - public: - LocalFileSystemClient(); - ~LocalFileSystemClient() override; - - bool RequestFileSystemAccessSync(ExecutionContext*) override; - void RequestFileSystemAccessAsync(ExecutionContext*, - base::OnceCallback<void(bool)>) override; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_LOCAL_FILE_SYSTEM_CLIENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/gamepad/DEPS b/chromium/third_party/blink/renderer/modules/gamepad/DEPS index 1b7f7f46c93..856ad767222 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/DEPS +++ b/chromium/third_party/blink/renderer/modules/gamepad/DEPS @@ -6,6 +6,7 @@ include_rules = [ "+device/gamepad/public/cpp/gamepads.h", "+device/gamepad/public/mojom/gamepad.mojom-blink.h", + "+device/gamepad/public/mojom/gamepad.mojom-blink-forward.h", "+device/gamepad/public/mojom/gamepad_hardware_buffer.h", "+mojo/public/cpp/bindings/binding.h", "+mojo/public/cpp/system/buffer.h", diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc index 56505fbd1d4..b8d4afe8b57 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc @@ -25,6 +25,7 @@ #include "third_party/blink/renderer/modules/gamepad/gamepad.h" +#include "base/trace_event/trace_event.h" #include "third_party/blink/renderer/core/timing/performance.h" #include "third_party/blink/renderer/modules/gamepad/gamepad_comparisons.h" #include "third_party/blink/renderer/platform/wtf/text/string_view.h" diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h index 5dfa9a9c319..afbcdfe984e 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h @@ -22,10 +22,9 @@ namespace blink { class GamepadSharedMemoryReader; -class GamepadDispatcher final - : public GarbageCollectedFinalized<GamepadDispatcher>, - public PlatformEventDispatcher, - public WebGamepadListener { +class GamepadDispatcher final : public GarbageCollected<GamepadDispatcher>, + public PlatformEventDispatcher, + public WebGamepadListener { USING_GARBAGE_COLLECTED_MIXIN(GamepadDispatcher); public: diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc index aaac2409747..0b1c45c2899 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.cc @@ -6,6 +6,7 @@ #include "base/bind_helpers.h" #include "device/gamepad/public/cpp/gamepad.h" +#include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h" diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h index 0a15ef4ecad..a0433c3c44f 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GAMEPAD_GAMEPAD_HAPTIC_ACTUATOR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_GAMEPAD_GAMEPAD_HAPTIC_ACTUATOR_H_ -#include "device/gamepad/public/mojom/gamepad.mojom-blink.h" +#include "device/gamepad/public/mojom/gamepad.mojom-blink-forward.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/heap/member.h" diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc index 34adaffb087..6387d00e327 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.cc @@ -5,10 +5,11 @@ #include "third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.h" #include "base/metrics/histogram_macros.h" +#include "base/trace_event/trace_event.h" #include "device/gamepad/public/cpp/gamepads.h" #include "device/gamepad/public/mojom/gamepad_hardware_buffer.h" #include "mojo/public/cpp/bindings/pending_remote.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/interface_provider.h" #include "third_party/blink/public/platform/web_gamepad_listener.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -16,7 +17,7 @@ namespace blink { GamepadSharedMemoryReader::GamepadSharedMemoryReader(LocalFrame& frame) { - frame.GetInterfaceProvider().GetInterface( + frame.GetBrowserInterfaceBroker().GetInterface( gamepad_monitor_remote_.BindNewPipeAndPassReceiver()); // See https://bit.ly/2S0zRAS for task types scoped_refptr<base::SingleThreadTaskRunner> task_runner = diff --git a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc index ea4946e3957..b59b275dfa0 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc +++ b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc @@ -114,6 +114,17 @@ GamepadList* NavigatorGamepad::Gamepads() { } is_gamepads_exposed_ = true; + ExecutionContext* context = + DomWindow() ? DomWindow()->GetExecutionContext() : nullptr; + + if (GetFrame() && GetFrame()->IsCrossOriginSubframe()) { + UseCounter::Count(context, WebFeature::kGetGamepadsFromCrossOriginSubframe); + } + + if (context && !context->IsSecureContext()) { + UseCounter::Count(context, WebFeature::kGetGamepadsFromInsecureContext); + } + return gamepads_.Get(); } diff --git a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h index 8133c7e7c1b..145d0ee0bdc 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h +++ b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h @@ -50,7 +50,7 @@ class GamepadList; class Navigator; class MODULES_EXPORT NavigatorGamepad final - : public GarbageCollectedFinalized<NavigatorGamepad>, + : public GarbageCollected<NavigatorGamepad>, public Supplement<Navigator>, public DOMWindowClient, public PlatformEventController, diff --git a/chromium/third_party/blink/renderer/modules/geolocation/BUILD.gn b/chromium/third_party/blink/renderer/modules/geolocation/BUILD.gn index 65a4d2126a0..c0a79e2b9f0 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/geolocation/BUILD.gn @@ -6,18 +6,18 @@ import("//third_party/blink/renderer/modules/modules.gni") blink_modules_sources("geolocation") { sources = [ - "coordinates.cc", - "coordinates.h", "geo_notifier.cc", "geo_notifier.h", "geolocation.cc", "geolocation.h", + "geolocation_coordinates.cc", + "geolocation_coordinates.h", "geolocation_error.h", + "geolocation_position_error.h", "geolocation_watchers.cc", "geolocation_watchers.h", "geoposition.h", "navigator_geolocation.cc", "navigator_geolocation.h", - "position_error.h", ] } diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc b/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc index 1f2293b7400..578ab161b9d 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc +++ b/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc @@ -7,7 +7,7 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/modules/geolocation/geolocation.h" -#include "third_party/blink/renderer/modules/geolocation/position_error.h" +#include "third_party/blink/renderer/modules/geolocation/geolocation_position_error.h" #include "third_party/blink/renderer/modules/geolocation/position_options.h" #include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" @@ -45,7 +45,7 @@ void GeoNotifier::Trace(blink::Visitor* visitor) { visitor->Trace(fatal_error_); } -void GeoNotifier::SetFatalError(PositionError* error) { +void GeoNotifier::SetFatalError(GeolocationPositionError* error) { // If a fatal error has already been set, stick with it. This makes sure that // when permission is denied, this is the error reported, as required by the // spec. @@ -67,7 +67,7 @@ void GeoNotifier::RunSuccessCallback(Geoposition* position) { success_callback_->InvokeAndReportException(nullptr, position); } -void GeoNotifier::RunErrorCallback(PositionError* error) { +void GeoNotifier::RunErrorCallback(GeolocationPositionError* error) { if (error_callback_) error_callback_->InvokeAndReportException(nullptr, error); } @@ -132,8 +132,8 @@ void GeoNotifier::TimerFired(TimerBase*) { if (error_callback_) { error_callback_->InvokeAndReportException( - nullptr, MakeGarbageCollected<PositionError>(PositionError::kTimeout, - "Timeout expired")); + nullptr, MakeGarbageCollected<GeolocationPositionError>( + GeolocationPositionError::kTimeout, "Timeout expired")); } DEFINE_STATIC_LOCAL(CustomCountHistogram, timeout_expired_histogram, diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h b/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h index 2da6954d85c..887699311e3 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h +++ b/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h @@ -16,10 +16,10 @@ namespace blink { class Geolocation; +class GeolocationPositionError; class Geoposition; -class PositionError; -class GeoNotifier final : public GarbageCollectedFinalized<GeoNotifier>, +class GeoNotifier final : public GarbageCollected<GeoNotifier>, public NameClient { public: GeoNotifier(Geolocation*, @@ -34,7 +34,7 @@ class GeoNotifier final : public GarbageCollectedFinalized<GeoNotifier>, // Sets the given error as the fatal error if there isn't one yet. // Starts the timer with an interval of 0. - void SetFatalError(PositionError*); + void SetFatalError(GeolocationPositionError*); bool UseCachedPosition() const { return use_cached_position_; } @@ -43,7 +43,7 @@ class GeoNotifier final : public GarbageCollectedFinalized<GeoNotifier>, void SetUseCachedPosition(); void RunSuccessCallback(Geoposition*); - void RunErrorCallback(PositionError*); + void RunErrorCallback(GeolocationPositionError*); void StartTimer(); void StopTimer(); @@ -54,7 +54,7 @@ class GeoNotifier final : public GarbageCollectedFinalized<GeoNotifier>, // notifier and the Geolocation. The timer should run only when the notifier // is owned by the Geolocation. When the Geolocation removes a notifier, the // timer should be stopped beforehand. - class Timer final : public GarbageCollectedFinalized<Timer> { + class Timer final : public GarbageCollected<Timer> { public: explicit Timer(scoped_refptr<base::SingleThreadTaskRunner> web_task_runner, GeoNotifier* notifier, @@ -83,7 +83,7 @@ class GeoNotifier final : public GarbageCollectedFinalized<GeoNotifier>, Member<V8PositionErrorCallback> error_callback_; Member<const PositionOptions> options_; Member<Timer> timer_; - Member<PositionError> fatal_error_; + Member<GeolocationPositionError> fatal_error_; bool use_cached_position_; }; diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc index d8bc322ea96..65952f5ecba 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc @@ -39,7 +39,7 @@ #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/probe/core_probes.h" -#include "third_party/blink/renderer/modules/geolocation/coordinates.h" +#include "third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h" #include "third_party/blink/renderer/modules/geolocation/geolocation_error.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" @@ -55,7 +55,7 @@ const char kFeaturePolicyConsoleWarning[] = Geoposition* CreateGeoposition( const device::mojom::blink::Geoposition& position) { - auto* coordinates = MakeGarbageCollected<Coordinates>( + auto* coordinates = MakeGarbageCollected<GeolocationCoordinates>( position.latitude, position.longitude, // Lowest point on land is at approximately -400 meters. position.altitude > -10000., position.altitude, position.accuracy, @@ -67,23 +67,24 @@ Geoposition* CreateGeoposition( ConvertSecondsToDOMTimeStamp(position.timestamp.ToDoubleT())); } -PositionError* CreatePositionError( +GeolocationPositionError* CreatePositionError( device::mojom::blink::Geoposition::ErrorCode mojom_error_code, const String& error) { - PositionError::ErrorCode error_code = PositionError::kPositionUnavailable; + GeolocationPositionError::ErrorCode error_code = + GeolocationPositionError::kPositionUnavailable; switch (mojom_error_code) { case device::mojom::blink::Geoposition::ErrorCode::PERMISSION_DENIED: - error_code = PositionError::kPermissionDenied; + error_code = GeolocationPositionError::kPermissionDenied; break; case device::mojom::blink::Geoposition::ErrorCode::POSITION_UNAVAILABLE: - error_code = PositionError::kPositionUnavailable; + error_code = GeolocationPositionError::kPositionUnavailable; break; case device::mojom::blink::Geoposition::ErrorCode::NONE: case device::mojom::blink::Geoposition::ErrorCode::TIMEOUT: NOTREACHED(); break; } - return MakeGarbageCollected<PositionError>(error_code, error); + return MakeGarbageCollected<GeolocationPositionError>(error_code, error); } static void ReportGeolocationViolation(Document* doc) { @@ -100,8 +101,7 @@ static void ReportGeolocationViolation(Document* doc) { } // namespace Geolocation* Geolocation::Create(ExecutionContext* context) { - Geolocation* geolocation = MakeGarbageCollected<Geolocation>(context); - return geolocation; + return MakeGarbageCollected<Geolocation>(context); } Geolocation::Geolocation(ExecutionContext* context) @@ -138,6 +138,8 @@ void Geolocation::ContextDestroyed(ExecutionContext*) { StopUpdating(); last_position_ = nullptr; + geolocation_.reset(); + geolocation_service_.reset(); } void Geolocation::RecordOriginTypeAccess() const { @@ -221,8 +223,8 @@ void Geolocation::StartRequest(GeoNotifier* notifier) { String error_message; if (!GetFrame()->GetSettings()->GetAllowGeolocationOnInsecureOrigins() && !GetExecutionContext()->IsSecureContext(error_message)) { - notifier->SetFatalError(MakeGarbageCollected<PositionError>( - PositionError::kPermissionDenied, error_message)); + notifier->SetFatalError(MakeGarbageCollected<GeolocationPositionError>( + GeolocationPositionError::kPermissionDenied, error_message)); return; } @@ -231,8 +233,9 @@ void Geolocation::StartRequest(GeoNotifier* notifier) { ReportOptions::kReportOnFailure, kFeaturePolicyConsoleWarning)) { UseCounter::Count(GetDocument(), WebFeature::kGeolocationDisabledByFeaturePolicy); - notifier->SetFatalError(MakeGarbageCollected<PositionError>( - PositionError::kPermissionDenied, kFeaturePolicyErrorMessage)); + notifier->SetFatalError(MakeGarbageCollected<GeolocationPositionError>( + GeolocationPositionError::kPermissionDenied, + kFeaturePolicyErrorMessage)); return; } @@ -326,7 +329,7 @@ void Geolocation::StopTimers() { } } -void Geolocation::HandleError(PositionError* error) { +void Geolocation::HandleError(GeolocationPositionError* error) { DCHECK(error); DCHECK(one_shots_being_invoked_.IsEmpty()); @@ -448,6 +451,7 @@ void Geolocation::UpdateGeolocationConnection(GeoNotifier* notifier) { if (!GetExecutionContext() || !GetPage() || !GetPage()->IsPageVisible() || !updating_) { geolocation_.reset(); + geolocation_service_.reset(); disconnected_geolocation_ = true; return; } @@ -460,17 +464,15 @@ void Geolocation::UpdateGeolocationConnection(GeoNotifier* notifier) { // See https://bit.ly/2S0zRAS for task types. scoped_refptr<base::SingleThreadTaskRunner> task_runner = GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI); - InterfaceInvalidator* invalidator = - GetExecutionContext()->GetInterfaceInvalidator(); - GetFrame()->GetInterfaceProvider().GetInterface(&geolocation_service_, - invalidator, task_runner); + GetFrame()->GetInterfaceProvider().GetInterface( + geolocation_service_.BindNewPipeAndPassReceiver(task_runner)); geolocation_service_->CreateGeolocation( - MakeRequest(&geolocation_, invalidator, std::move(task_runner)), + geolocation_.BindNewPipeAndPassReceiver(std::move(task_runner)), LocalFrame::HasTransientUserActivation(GetFrame()), WTF::Bind(&Geolocation::OnGeolocationPermissionStatusUpdated, WrapWeakPersistent(this), WrapWeakPersistent(notifier))); - geolocation_.set_connection_error_handler(WTF::Bind( + geolocation_.set_disconnect_handler(WTF::Bind( &Geolocation::OnGeolocationConnectionError, WrapWeakPersistent(this))); if (enable_high_accuracy_) geolocation_->SetHighAccuracy(true); @@ -509,8 +511,9 @@ void Geolocation::OnGeolocationConnectionError() { StopUpdating(); // The only reason that we would fail to get a ConnectionError is if we lack // sufficient permission. - auto* error = MakeGarbageCollected<PositionError>( - PositionError::kPermissionDenied, kPermissionDeniedErrorMessage); + auto* error = MakeGarbageCollected<GeolocationPositionError>( + GeolocationPositionError::kPermissionDenied, + kPermissionDeniedErrorMessage); error->SetIsFatal(true); HandleError(error); } diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h index 6ad28ae59bf..65f8b6709ee 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h @@ -27,6 +27,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_H_ +#include "mojo/public/cpp/bindings/remote.h" #include "services/device/public/mojom/geolocation.mojom-blink.h" #include "third_party/blink/public/mojom/geolocation/geolocation_service.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" @@ -35,14 +36,13 @@ #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/page/page_visibility_observer.h" #include "third_party/blink/renderer/modules/geolocation/geo_notifier.h" +#include "third_party/blink/renderer/modules/geolocation/geolocation_position_error.h" #include "third_party/blink/renderer/modules/geolocation/geolocation_watchers.h" #include "third_party/blink/renderer/modules/geolocation/geoposition.h" -#include "third_party/blink/renderer/modules/geolocation/position_error.h" #include "third_party/blink/renderer/modules/geolocation/position_options.h" #include "third_party/blink/renderer/modules/modules_export.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/mojo/revocable_interface_ptr.h" #include "third_party/blink/renderer/platform/timer.h" namespace blink { @@ -173,7 +173,7 @@ class MODULES_EXPORT Geolocation final // Sends the given error to all notifiers, unless the error is not fatal and // the notifier is due to receive a cached position. Clears the oneshots, // and also clears the watchers if the error is fatal. - void HandleError(PositionError*); + void HandleError(GeolocationPositionError*); // Connects to the Geolocation mojo service and starts polling for updates. void StartUpdating(GeoNotifier*); @@ -184,15 +184,15 @@ class MODULES_EXPORT Geolocation final void QueryNextPosition(); // Attempts to obtain a position for the given notifier, either by using - // the cached position or by requesting one from the Geolocation. + // the cached position or by requesting one from the Geolocation service. // Sets a fatal error if permission is denied or no position can be // obtained. void StartRequest(GeoNotifier*); bool HaveSuitableCachedPosition(const PositionOptions*); - // Record whether the origin trying to access Geolocation would be allowed - // to access a feature that can only be accessed by secure origins. + // Record whether the origin trying to access Geolocation would be + // allowed to access a feature that can only be accessed by secure origins. // See https://goo.gl/Y0ZkNV void RecordOriginTypeAccess() const; @@ -209,10 +209,10 @@ class MODULES_EXPORT Geolocation final // // |HandleError(error)| and |MakeSuccessCallbacks| need to clear |one_shots_| // (and optionally |watchers_|) before invoking the callbacks, in order to - // avoid clearing notifiers added by calls to Geolocation methods from the - // callbacks. Thus, something else needs to make the notifiers being invoked - // alive with wrapper-tracing because V8 GC may run during the callbacks. - // |one_shots_being_invoked_| and |watchers_being_invoked_| perform + // avoid clearing notifiers added by calls to Geolocation methods + // from the callbacks. Thus, something else needs to make the notifiers being + // invoked alive with wrapper-tracing because V8 GC may run during the + // callbacks. |one_shots_being_invoked_| and |watchers_being_invoked_| perform // wrapper-tracing. // TODO(https://crbug.com/796145): Remove this hack once on-stack objects // get supported by either of wrapper-tracing or unified GC. @@ -220,8 +220,8 @@ class MODULES_EXPORT Geolocation final HeapVector<Member<GeoNotifier>> watchers_being_invoked_; Member<Geoposition> last_position_; - RevocableInterfacePtr<device::mojom::blink::Geolocation> geolocation_; - RevocableInterfacePtr<mojom::blink::GeolocationService> geolocation_service_; + mojo::Remote<device::mojom::blink::Geolocation> geolocation_; + mojo::Remote<mojom::blink::GeolocationService> geolocation_service_; bool enable_high_accuracy_ = false; // Whether a GeoNotifier is waiting for a position update. diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.idl b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.idl index 8db3bd87265..93301976d3c 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.idl +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.idl @@ -26,8 +26,7 @@ // https://www.w3.org/TR/geolocation-API/#geolocation_interface [ ActiveScriptWrappable, - Exposed=Window, - NoInterfaceObject + Exposed=Window ] interface Geolocation { [ LogActivity, @@ -51,7 +50,8 @@ }; // https://www.w3.org/TR/geolocation-API/#position-callback -callback PositionCallback = void(Position position); +callback PositionCallback = void(GeolocationPosition position); // https://www.w3.org/TR/geolocation-API/#error-callback -callback PositionErrorCallback = void (PositionError positionError); +callback PositionErrorCallback = + void (GeolocationPositionError positionError); diff --git a/chromium/third_party/blink/renderer/modules/geolocation/coordinates.cc b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc index b30e4e69547..dab1c87a20c 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/coordinates.cc +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.cc @@ -23,11 +23,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "third_party/blink/renderer/modules/geolocation/coordinates.h" +#include "third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h" namespace blink { -double Coordinates::altitude(bool& is_null) const { +double GeolocationCoordinates::altitude(bool& is_null) const { if (can_provide_altitude_) return altitude_; @@ -35,7 +35,7 @@ double Coordinates::altitude(bool& is_null) const { return 0; } -double Coordinates::altitudeAccuracy(bool& is_null) const { +double GeolocationCoordinates::altitudeAccuracy(bool& is_null) const { if (can_provide_altitude_accuracy_) return altitude_accuracy_; @@ -43,7 +43,7 @@ double Coordinates::altitudeAccuracy(bool& is_null) const { return 0; } -double Coordinates::heading(bool& is_null) const { +double GeolocationCoordinates::heading(bool& is_null) const { if (can_provide_heading_) return heading_; @@ -51,7 +51,7 @@ double Coordinates::heading(bool& is_null) const { return 0; } -double Coordinates::speed(bool& is_null) const { +double GeolocationCoordinates::speed(bool& is_null) const { if (can_provide_speed_) return speed_; diff --git a/chromium/third_party/blink/renderer/modules/geolocation/coordinates.h b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h index 6296150c1fd..beefc9278b7 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/coordinates.h +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.h @@ -23,8 +23,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_COORDINATES_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_COORDINATES_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_COORDINATES_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_COORDINATES_H_ #include "third_party/blink/renderer/modules/event_modules.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -32,21 +32,21 @@ namespace blink { -class Coordinates : public ScriptWrappable { +class GeolocationCoordinates : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - Coordinates(double latitude, - double longitude, - bool provides_altitude, - double altitude, - double accuracy, - bool provides_altitude_accuracy, - double altitude_accuracy, - bool provides_heading, - double heading, - bool provides_speed, - double speed) + GeolocationCoordinates(double latitude, + double longitude, + bool provides_altitude, + double altitude, + double accuracy, + bool provides_altitude_accuracy, + double altitude_accuracy, + bool provides_heading, + double heading, + bool provides_speed, + double speed) : latitude_(latitude), longitude_(longitude), altitude_(altitude), @@ -84,4 +84,4 @@ class Coordinates : public ScriptWrappable { } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_COORDINATES_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_COORDINATES_H_ diff --git a/chromium/third_party/blink/renderer/modules/geolocation/coordinates.idl b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.idl index 93bb79c46ea..f2916d2b3a2 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/coordinates.idl +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.idl @@ -24,9 +24,8 @@ */ [ - Exposed=Window, - NoInterfaceObject -] interface Coordinates { + Exposed=Window +] interface GeolocationCoordinates { readonly attribute double latitude; readonly attribute double longitude; readonly attribute double? altitude; diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_error.h b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_error.h index d27b7abf73a..b1a40f07464 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_error.h +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_error.h @@ -30,7 +30,7 @@ namespace blink { -class GeolocationError : public GarbageCollectedFinalized<GeolocationError> { +class GeolocationError final : public GarbageCollected<GeolocationError> { public: enum ErrorCode { kPermissionDenied, kPositionUnavailable }; diff --git a/chromium/third_party/blink/renderer/modules/geolocation/position.idl b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_position.idl index 90d4b17a416..bc3ba9d489a 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/position.idl +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_position.idl @@ -27,9 +27,8 @@ [ Exposed=Window, - NoInterfaceObject, ImplementedAs=Geoposition -] interface Position { - readonly attribute Coordinates coords; +] interface GeolocationPosition { + readonly attribute GeolocationCoordinates coords; readonly attribute DOMTimeStamp timestamp; }; diff --git a/chromium/third_party/blink/renderer/modules/geolocation/position_error.h b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_position_error.h index 5aea482530b..c57b9024085 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/position_error.h +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_position_error.h @@ -23,8 +23,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_POSITION_ERROR_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_POSITION_ERROR_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_POSITION_ERROR_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_POSITION_ERROR_H_ #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -32,7 +32,7 @@ namespace blink { -class PositionError final : public ScriptWrappable { +class GeolocationPositionError final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: @@ -42,7 +42,7 @@ class PositionError final : public ScriptWrappable { kTimeout = 3 }; - PositionError(ErrorCode code, const String& message) + GeolocationPositionError(ErrorCode code, const String& message) : code_(code), message_(message), is_fatal_(false) {} ErrorCode code() const { return code_; } @@ -60,4 +60,4 @@ class PositionError final : public ScriptWrappable { } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_POSITION_ERROR_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_GEOLOCATION_GEOLOCATION_POSITION_ERROR_H_ diff --git a/chromium/third_party/blink/renderer/modules/geolocation/position_error.idl b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_position_error.idl index 16529fa9ff4..a0f3e3be574 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/position_error.idl +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_position_error.idl @@ -24,9 +24,8 @@ */ [ - Exposed=Window, - NoInterfaceObject -] interface PositionError { + Exposed=Window +] interface GeolocationPositionError { readonly attribute unsigned short code; readonly attribute DOMString message; diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h b/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h index 9b39b62ab1e..0559846b928 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h +++ b/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h @@ -28,7 +28,7 @@ #include "third_party/blink/renderer/core/dom/dom_time_stamp.h" #include "third_party/blink/renderer/modules/event_modules.h" -#include "third_party/blink/renderer/modules/geolocation/coordinates.h" +#include "third_party/blink/renderer/modules/geolocation/geolocation_coordinates.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/wtf/assertions.h" @@ -39,7 +39,7 @@ class Geoposition final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - Geoposition(Coordinates* coordinates, DOMTimeStamp timestamp) + Geoposition(GeolocationCoordinates* coordinates, DOMTimeStamp timestamp) : coordinates_(coordinates), timestamp_(timestamp) { DCHECK(coordinates_); } @@ -50,10 +50,10 @@ class Geoposition final : public ScriptWrappable { } DOMTimeStamp timestamp() const { return timestamp_; } - Coordinates* coords() const { return coordinates_; } + GeolocationCoordinates* coords() const { return coordinates_; } private: - Member<Coordinates> coordinates_; + Member<GeolocationCoordinates> coordinates_; DOMTimeStamp timestamp_; }; diff --git a/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc b/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc index 352f21e5946..6804f3a4e39 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc +++ b/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc @@ -51,9 +51,10 @@ Geolocation* NavigatorGeolocation::geolocation(Navigator& navigator) { } Geolocation* NavigatorGeolocation::geolocation() { - if (!geolocation_ && GetSupplementable()->GetFrame()) + if (!geolocation_ && GetSupplementable()->GetFrame()) { geolocation_ = Geolocation::Create(GetSupplementable()->GetFrame()->GetDocument()); + } return geolocation_; } diff --git a/chromium/third_party/blink/renderer/modules/hid/DEPS b/chromium/third_party/blink/renderer/modules/hid/DEPS index 98e4a1cfa94..003ec941158 100644 --- a/chromium/third_party/blink/renderer/modules/hid/DEPS +++ b/chromium/third_party/blink/renderer/modules/hid/DEPS @@ -1,4 +1,5 @@ include_rules = [ "+mojo/public/cpp/bindings", "+services/device/public/mojom/hid.mojom-blink.h", + "+services/device/public/mojom/hid.mojom-blink-forward.h", ] diff --git a/chromium/third_party/blink/renderer/modules/hid/hid.cc b/chromium/third_party/blink/renderer/modules/hid/hid.cc index c4a3e1bc21e..dd6d595b1f2 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid.cc +++ b/chromium/third_party/blink/renderer/modules/hid/hid.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/modules/hid/hid.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -22,6 +22,7 @@ namespace blink { namespace { +const char kContextGone[] = "Script context has shut down."; const char kFeaturePolicyBlocked[] = "Access to the feature \"hid\" is disallowed by feature policy."; const char kNoDeviceSelected[] = "No device selected."; @@ -101,20 +102,19 @@ void HID::AddedEventListener(const AtomicString& event_type, // and disconnect events. } -ScriptPromise HID::getDevices(ScriptState* script_state) { +ScriptPromise HID::getDevices(ScriptState* script_state, + ExceptionState& exception_state) { auto* context = GetExecutionContext(); if (!context) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotSupportedError)); + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + kContextGone); + return ScriptPromise(); } if (!context->GetSecurityContext().IsFeatureEnabled( mojom::FeaturePolicyFeature::kHid, ReportOptions::kReportOnFailure)) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kSecurityError, - kFeaturePolicyBlocked)); + exception_state.ThrowSecurityError(kFeaturePolicyBlocked); + return ScriptPromise(); } auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); @@ -127,28 +127,25 @@ ScriptPromise HID::getDevices(ScriptState* script_state) { } ScriptPromise HID::requestDevice(ScriptState* script_state, - const HIDDeviceRequestOptions* options) { + const HIDDeviceRequestOptions* options, + ExceptionState& exception_state) { auto* frame = GetFrame(); if (!frame || !frame->GetDocument()) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotSupportedError)); + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + kContextGone); + return ScriptPromise(); } if (!frame->GetDocument()->IsFeatureEnabled( mojom::FeaturePolicyFeature::kHid, ReportOptions::kReportOnFailure)) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kSecurityError, - kFeaturePolicyBlocked)); + exception_state.ThrowSecurityError(kFeaturePolicyBlocked); + return ScriptPromise(); } if (!LocalFrame::HasTransientUserActivation(frame)) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>( - DOMExceptionCode::kSecurityError, - "Must be handling a user gesture to show a permission request.")); + exception_state.ThrowSecurityError( + "Must be handling a user gesture to show a permission request."); + return ScriptPromise(); } auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); @@ -230,7 +227,7 @@ void HID::EnsureServiceConnection() { auto task_runner = GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI); - GetExecutionContext()->GetInterfaceProvider()->GetInterface( + GetExecutionContext()->GetBrowserInterfaceBroker().GetInterface( service_.BindNewPipeAndPassReceiver(task_runner)); service_.set_disconnect_handler( WTF::Bind(&HID::OnServiceConnectionError, WrapWeakPersistent(this))); diff --git a/chromium/third_party/blink/renderer/modules/hid/hid.h b/chromium/third_party/blink/renderer/modules/hid/hid.h index dbdc82514ab..8bc43fa1baf 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid.h +++ b/chromium/third_party/blink/renderer/modules/hid/hid.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_H_ #include "mojo/public/cpp/bindings/remote.h" -#include "services/device/public/mojom/hid.mojom-blink.h" +#include "services/device/public/mojom/hid.mojom-blink-forward.h" #include "third_party/blink/public/mojom/hid/hid.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" @@ -37,8 +37,10 @@ class HID : public EventTargetWithInlineData, public ContextLifecycleObserver { // Web-exposed interfaces: DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect) DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect) - ScriptPromise getDevices(ScriptState*); - ScriptPromise requestDevice(ScriptState*, const HIDDeviceRequestOptions*); + ScriptPromise getDevices(ScriptState*, ExceptionState&); + ScriptPromise requestDevice(ScriptState*, + const HIDDeviceRequestOptions*, + ExceptionState&); void Connect(const String& device_guid, mojo::PendingRemote<device::mojom::blink::HidConnectionClient> diff --git a/chromium/third_party/blink/renderer/modules/hid/hid.idl b/chromium/third_party/blink/renderer/modules/hid/hid.idl index b90a32a84f2..ea8de740184 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid.idl +++ b/chromium/third_party/blink/renderer/modules/hid/hid.idl @@ -16,12 +16,14 @@ // Retrieves information about all available HID subsystem devices. [ CallWith=ScriptState, + RaisesException, MeasureAs=HidGetDevices ] Promise<sequence<HIDDevice>> getDevices(); // Requests permission from the user to use a device. [ CallWith=ScriptState, + RaisesException, MeasureAs=HidRequestDevice ] Promise<sequence<HIDDevice>> requestDevice( HIDDeviceRequestOptions options); diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.cc b/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.cc index c95e75307df..e46dd0e4c49 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.cc +++ b/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/hid/hid_collection_info.h" +#include "services/device/public/mojom/hid.mojom-blink.h" #include "third_party/blink/renderer/modules/hid/hid_report_info.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.h b/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.h index 5883758bcd3..aada3a674d0 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.h +++ b/chromium/third_party/blink/renderer/modules/hid/hid_collection_info.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_COLLECTION_INFO_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_COLLECTION_INFO_H_ -#include "services/device/public/mojom/hid.mojom-blink.h" +#include "services/device/public/mojom/hid.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_device.cc b/chromium/third_party/blink/renderer/modules/hid/hid_device.cc index 6dd11d79daa..d06e235a79f 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_device.cc +++ b/chromium/third_party/blink/renderer/modules/hid/hid_device.cc @@ -270,14 +270,15 @@ bool HIDDevice::EnsureNoDeviceChangeInProgress( return true; } -void HIDDevice::FinishOpen(ScriptPromiseResolver* resolver, - device::mojom::blink::HidConnectionPtr connection) { +void HIDDevice::FinishOpen( + ScriptPromiseResolver* resolver, + mojo::PendingRemote<device::mojom::blink::HidConnection> connection) { MarkRequestComplete(resolver); device_state_change_in_progress_ = false; if (connection) { - connection_ = std::move(connection); - connection_.set_connection_error_handler(WTF::Bind( + connection_.Bind(std::move(connection)); + connection_.set_disconnect_handler(WTF::Bind( &HIDDevice::OnServiceConnectionError, WrapWeakPersistent(this))); resolver->Resolve(); } else { diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_device.h b/chromium/third_party/blink/renderer/modules/hid/hid_device.h index b0aa9adc58f..3c6eaf79ca4 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_device.h +++ b/chromium/third_party/blink/renderer/modules/hid/hid_device.h @@ -5,8 +5,10 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_DEVICE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_DEVICE_H_ +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" -#include "services/device/public/mojom/hid.mojom-blink.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "services/device/public/mojom/hid.mojom-blink-forward.h" #include "third_party/blink/public/mojom/hid/hid.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" @@ -79,7 +81,7 @@ class MODULES_EXPORT HIDDevice void OnServiceConnectionError(); void FinishOpen(ScriptPromiseResolver*, - device::mojom::blink::HidConnectionPtr); + mojo::PendingRemote<device::mojom::blink::HidConnection>); void FinishClose(ScriptPromiseResolver*); void FinishSendReport(ScriptPromiseResolver*, bool success); void FinishReceiveReport(ScriptPromiseResolver*, @@ -95,7 +97,7 @@ class MODULES_EXPORT HIDDevice Member<HID> parent_; device::mojom::blink::HidDeviceInfoPtr device_info_; - device::mojom::blink::HidConnectionPtr connection_; + mojo::Remote<device::mojom::blink::HidConnection> connection_; mojo::Receiver<device::mojom::blink::HidConnectionClient> receiver_{this}; HeapHashSet<Member<ScriptPromiseResolver>> device_requests_; HeapVector<Member<HIDCollectionInfo>> collections_; diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_report_info.cc b/chromium/third_party/blink/renderer/modules/hid/hid_report_info.cc index a10eb44c0ff..672a73ca0b7 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_report_info.cc +++ b/chromium/third_party/blink/renderer/modules/hid/hid_report_info.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/hid/hid_report_info.h" +#include "services/device/public/mojom/hid.mojom-blink.h" #include "third_party/blink/renderer/modules/hid/hid_report_item.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_report_info.h b/chromium/third_party/blink/renderer/modules/hid/hid_report_info.h index e7b0d3ca923..05e8847ee02 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_report_info.h +++ b/chromium/third_party/blink/renderer/modules/hid/hid_report_info.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_INFO_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_INFO_H_ -#include "services/device/public/mojom/hid.mojom-blink.h" +#include "services/device/public/mojom/hid.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_report_item.cc b/chromium/third_party/blink/renderer/modules/hid/hid_report_item.cc index a8e98ee354f..514b4c2f0aa 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_report_item.cc +++ b/chromium/third_party/blink/renderer/modules/hid/hid_report_item.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/hid/hid_report_item.h" +#include "services/device/public/mojom/hid.mojom-blink.h" + namespace blink { namespace { diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_report_item.h b/chromium/third_party/blink/renderer/modules/hid/hid_report_item.h index 63085652d8a..223e351a906 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_report_item.h +++ b/chromium/third_party/blink/renderer/modules/hid/hid_report_item.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_ITEM_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_REPORT_ITEM_H_ -#include "services/device/public/mojom/hid.mojom-blink.h" +#include "services/device/public/mojom/hid.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/heap_allocator.h" diff --git a/chromium/third_party/blink/renderer/modules/idle/idle_detector.h b/chromium/third_party/blink/renderer/modules/idle/idle_detector.h index 95786de9e29..5ad49150618 100644 --- a/chromium/third_party/blink/renderer/modules/idle/idle_detector.h +++ b/chromium/third_party/blink/renderer/modules/idle/idle_detector.h @@ -8,7 +8,7 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/mojom/idle/idle_manager.mojom-blink.h" +#include "third_party/blink/public/mojom/idle/idle_manager.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" diff --git a/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.cc b/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.cc index c39a0b20e81..7a29b516de6 100644 --- a/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.cc +++ b/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.cc @@ -187,7 +187,6 @@ void ImageDownloaderImpl::DidDownloadImage( } void ImageDownloaderImpl::Dispose() { - image_fetchers_.clear(); receiver_.reset(); } @@ -234,11 +233,11 @@ void ImageDownloaderImpl::Trace(Visitor* visitor) { } void ImageDownloaderImpl::ContextDestroyed(ExecutionContext*) { - for (const auto& fetchers : image_fetchers_) { + for (const auto& fetcher : image_fetchers_) { // Will run callbacks with an empty image vector. - fetchers->Dispose(); + fetcher->Dispose(); } - Dispose(); + image_fetchers_.clear(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.h b/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.h index 90211f4b693..6051b8745e0 100644 --- a/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.h +++ b/chromium/third_party/blink/renderer/modules/image_downloader/image_downloader_impl.h @@ -16,11 +16,10 @@ class KURL; class LocalFrame; class MultiResolutionImageResourceFetcher; -class ImageDownloaderImpl final - : public GarbageCollectedFinalized<ImageDownloaderImpl>, - public Supplement<LocalFrame>, - public ContextLifecycleObserver, - public mojom::blink::ImageDownloader { +class ImageDownloaderImpl final : public GarbageCollected<ImageDownloaderImpl>, + public Supplement<LocalFrame>, + public ContextLifecycleObserver, + public mojom::blink::ImageDownloader { USING_PRE_FINALIZER(ImageDownloaderImpl, Dispose); USING_GARBAGE_COLLECTED_MIXIN(ImageDownloaderImpl); diff --git a/chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.h b/chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.h index 1bb332172de..eef1acfd94e 100644 --- a/chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.h +++ b/chromium/third_party/blink/renderer/modules/image_downloader/multi_resolution_image_resource_fetcher.h @@ -10,7 +10,7 @@ #include "base/callback.h" #include "base/macros.h" -#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" +#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h" #include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/public/web/web_associated_url_loader_options.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/DEPS b/chromium/third_party/blink/renderer/modules/imagecapture/DEPS index 8328eae6ced..a07306972ea 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/DEPS +++ b/chromium/third_party/blink/renderer/modules/imagecapture/DEPS @@ -1,8 +1,10 @@ include_rules = [ "+media/capture/mojom/image_capture.mojom-blink.h", + "+media/capture/mojom/image_capture.mojom-blink-forward.h", "+media/base", "+skia/ext/platform_canvas.h", "+third_party/libyuv", "+third_party/skia/include/core", + "+ui/gfx/gpu_memory_buffer.h", ] diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc index 7d1c9a12f3f..08eeae358e3 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc +++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc @@ -7,8 +7,7 @@ #include <memory> #include <utility> -#include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/public/platform/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h" @@ -704,9 +703,10 @@ ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track) if (!GetFrame()) return; - GetFrame()->GetInterfaceProvider().GetInterface(mojo::MakeRequest(&service_)); + GetFrame()->GetBrowserInterfaceBroker().GetInterface( + service_.BindNewPipeAndPassReceiver()); - service_.set_connection_error_handler(WTF::Bind( + service_.set_disconnect_handler(WTF::Bind( &ImageCapture::OnServiceConnectionError, WrapWeakPersistent(this))); // Launch a retrieval of the current photo state, which arrive asynchronously diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h index fc3963d8a36..34e4577d81a 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h +++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.h @@ -7,6 +7,7 @@ #include <memory> #include "media/capture/mojom/image_capture.mojom-blink.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" @@ -99,7 +100,7 @@ class MODULES_EXPORT ImageCapture final Member<MediaStreamTrack> stream_track_; std::unique_ptr<ImageCaptureFrameGrabber> frame_grabber_; - media::mojom::blink::ImageCapturePtr service_; + mojo::Remote<media::mojom::blink::ImageCapture> service_; Member<MediaTrackCapabilities> capabilities_; Member<MediaTrackSettings> settings_; diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc index d609544e886..1a250f128bc 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc +++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc @@ -18,6 +18,7 @@ #include "third_party/libyuv/include/libyuv.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkSurface.h" +#include "ui/gfx/gpu_memory_buffer.h" namespace WTF { // Template specialization of [1], needed to be able to pass callbacks @@ -79,7 +80,8 @@ void ImageCaptureFrameGrabber::SingleShotFrameHandler::OnVideoFrameOnIOThread( scoped_refptr<media::VideoFrame> frame, base::TimeTicks /* current_time */) { DCHECK(frame->format() == media::PIXEL_FORMAT_I420 || - frame->format() == media::PIXEL_FORMAT_I420A); + frame->format() == media::PIXEL_FORMAT_I420A || + frame->format() == media::PIXEL_FORMAT_NV12); if (first_frame_received_) return; @@ -107,25 +109,68 @@ void ImageCaptureFrameGrabber::SingleShotFrameHandler::OnVideoFrameOnIOThread( const uint32_t destination_pixel_format = (kN32_SkColorType == kRGBA_8888_SkColorType) ? libyuv::FOURCC_ABGR : libyuv::FOURCC_ARGB; - - libyuv::ConvertFromI420(frame->visible_data(media::VideoFrame::kYPlane), - frame->stride(media::VideoFrame::kYPlane), - frame->visible_data(media::VideoFrame::kUPlane), - frame->stride(media::VideoFrame::kUPlane), - frame->visible_data(media::VideoFrame::kVPlane), - frame->stride(media::VideoFrame::kVPlane), - static_cast<uint8_t*>(pixmap.writable_addr()), - pixmap.width() * 4, pixmap.width(), pixmap.height(), - destination_pixel_format); - - if (frame->format() == media::PIXEL_FORMAT_I420A) { - DCHECK(!info.isOpaque()); - // This function copies any plane into the alpha channel of an ARGB image. - libyuv::ARGBCopyYToAlpha(frame->visible_data(media::VideoFrame::kAPlane), - frame->stride(media::VideoFrame::kAPlane), - static_cast<uint8_t*>(pixmap.writable_addr()), - pixmap.width() * 4, pixmap.width(), - pixmap.height()); + uint8_t* destination_plane = static_cast<uint8_t*>(pixmap.writable_addr()); + int destination_stride = pixmap.width() * 4; + int destination_width = pixmap.width(); + int destination_height = pixmap.height(); + + if (frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) { + auto* gmb = frame->GetGpuMemoryBuffer(); + if (!gmb->Map()) { + DLOG(ERROR) << "Error mapping GpuMemoryBuffer video frame"; + std::move(wrapper_callback).Run(sk_sp<SkImage>()); + return; + } + + // NV12 is the only supported pixel format at the moment. + DCHECK_EQ(frame->format(), media::PIXEL_FORMAT_NV12); + int y_stride = gmb->stride(0); + int uv_stride = gmb->stride(1); + const uint8_t* y_plane = + (static_cast<uint8_t*>(gmb->memory(0)) + frame->visible_rect().x() + + (frame->visible_rect().y() * y_stride)); + // UV plane of NV12 has 2-byte pixel width, with half chroma subsampling + // both horizontally and vertically. + const uint8_t* uv_plane = (static_cast<uint8_t*>(gmb->memory(1)) + + ((frame->visible_rect().x() * 2) / 2) + + ((frame->visible_rect().y() / 2) * uv_stride)); + + switch (destination_pixel_format) { + case libyuv::FOURCC_ABGR: + libyuv::NV12ToABGR(y_plane, y_stride, uv_plane, uv_stride, + destination_plane, destination_stride, + destination_width, destination_height); + break; + case libyuv::FOURCC_ARGB: + libyuv::NV12ToARGB(y_plane, y_stride, uv_plane, uv_stride, + destination_plane, destination_stride, + destination_width, destination_height); + break; + default: + NOTREACHED(); + } + gmb->Unmap(); + } else { + DCHECK(frame->format() == media::PIXEL_FORMAT_I420 || + frame->format() == media::PIXEL_FORMAT_I420A); + libyuv::ConvertFromI420(frame->visible_data(media::VideoFrame::kYPlane), + frame->stride(media::VideoFrame::kYPlane), + frame->visible_data(media::VideoFrame::kUPlane), + frame->stride(media::VideoFrame::kUPlane), + frame->visible_data(media::VideoFrame::kVPlane), + frame->stride(media::VideoFrame::kVPlane), + destination_plane, destination_stride, + destination_width, destination_height, + destination_pixel_format); + + if (frame->format() == media::PIXEL_FORMAT_I420A) { + DCHECK(!info.isOpaque()); + // This function copies any plane into the alpha channel of an ARGB image. + libyuv::ARGBCopyYToAlpha(frame->visible_data(media::VideoFrame::kAPlane), + frame->stride(media::VideoFrame::kAPlane), + destination_plane, destination_stride, + destination_width, destination_height); + } } std::move(wrapper_callback).Run(surface->makeImageSnapshot()); diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h index 85b46e1b854..f050a850607 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h +++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.h @@ -92,10 +92,10 @@ class ScopedWebCallbacks { std::move(destruction_callback_).Run(std::move(callbacks_)); } - ScopedWebCallbacks(ScopedWebCallbacks&& other) noexcept = default; + ScopedWebCallbacks(ScopedWebCallbacks&& other) = default; ScopedWebCallbacks(const ScopedWebCallbacks& other) = delete; - ScopedWebCallbacks& operator=(ScopedWebCallbacks&& other) noexcept = default; + ScopedWebCallbacks& operator=(ScopedWebCallbacks&& other) = default; ScopedWebCallbacks& operator=(const ScopedWebCallbacks& other) = delete; std::unique_ptr<CallbacksType> PassCallbacks() { diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h index f1c0095df8e..314509c5f9b 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h +++ b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_IMAGECAPTURE_PHOTO_CAPABILITIES_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_IMAGECAPTURE_PHOTO_CAPABILITIES_H_ -#include "media/capture/mojom/image_capture.mojom-blink.h" +#include "media/capture/mojom/image_capture.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/imagecapture/media_settings_range.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h index 38dc88f7921..7d037a0fe23 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h @@ -53,7 +53,7 @@ class IDBObjectStore; // This allows for lazy conversion to script values (via IDBBindingUtilities), // and avoids the need for many dedicated union types. -class MODULES_EXPORT IDBAny : public GarbageCollectedFinalized<IDBAny> { +class MODULES_EXPORT IDBAny final : public GarbageCollected<IDBAny> { public: static IDBAny* CreateUndefined(); static IDBAny* CreateNull(); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc index 7f0794ef304..ba4706eb066 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc @@ -37,6 +37,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_idb_observer_callback.h" #include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/modules/indexed_db_names.h" #include "third_party/blink/renderer/modules/indexeddb/idb_any.h" #include "third_party/blink/renderer/modules/indexeddb/idb_event_dispatcher.h" #include "third_party/blink/renderer/modules/indexeddb/idb_index.h" @@ -353,6 +354,14 @@ void IDBDatabase::deleteObjectStore(const String& name, IDBTransaction* IDBDatabase::transaction( ScriptState* script_state, const StringOrStringSequence& store_names, + const String& mode, + ExceptionState& exception_state) { + return transaction(script_state, store_names, mode, nullptr, exception_state); +} + +IDBTransaction* IDBDatabase::transaction( + ScriptState* script_state, + const StringOrStringSequence& store_names, const String& mode_string, const IDBTransactionOptions* options, ExceptionState& exception_state) { @@ -421,17 +430,24 @@ IDBTransaction* IDBDatabase::transaction( ->GetTaskRunner(TaskType::kDatabaseAccess), transaction_id); - bool relaxed_durability = false; - if (RuntimeEnabledFeatures::IDBRelaxedDurabilityEnabled() && options) - relaxed_durability = options->relaxedDurability(); + mojom::IDBTransactionDurability durability = + mojom::IDBTransactionDurability::Default; + if (options) { + DCHECK(RuntimeEnabledFeatures::IDBRelaxedDurabilityEnabled()); + if (options->durability() == indexed_db_names::kRelaxed) { + durability = mojom::IDBTransactionDurability::Relaxed; + } else if (options->durability() == indexed_db_names::kStrict) { + durability = mojom::IDBTransactionDurability::Strict; + } + } backend_->CreateTransaction(transaction_backend->CreateReceiver(), transaction_id, object_store_ids, mode, - relaxed_durability); + durability); return IDBTransaction::CreateNonVersionChange( script_state, std::move(transaction_backend), transaction_id, scope, mode, - this); + durability, this); } void IDBDatabase::ForceClose() { diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h index 38cf13db92c..74452627150 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h @@ -105,6 +105,10 @@ class MODULES_EXPORT IDBDatabase final IDBTransaction* transaction(ScriptState*, const StringOrStringSequence& store_names, const String& mode, + ExceptionState&); + IDBTransaction* transaction(ScriptState*, + const StringOrStringSequence& store_names, + const String& mode, const IDBTransactionOptions* options, ExceptionState&); void deleteObjectStore(const String& name, ExceptionState&); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.idl b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.idl index 5942f0ac58d..938b6b4fae9 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.idl +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.idl @@ -35,8 +35,12 @@ readonly attribute DOMStringList objectStoreNames; [NewObject, CallWith=ScriptState, RaisesException] IDBTransaction transaction((DOMString or sequence<DOMString>) storeNames, + optional IDBTransactionMode mode = "readonly"); + + [NewObject, CallWith=ScriptState, RaisesException, RuntimeEnabled=IDBRelaxedDurability] IDBTransaction transaction((DOMString or sequence<DOMString>) storeNames, + optional IDBTransactionMode mode = "readonly", - optional IDBTransactionOptions options); + IDBTransactionOptions options); void close(); [MeasureAs=IndexedDBWrite, NewObject, RaisesException] diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h index 965cdc72d37..7591e448bf9 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.h @@ -37,7 +37,7 @@ class IDBDatabase; class IDBObservation; class MODULES_EXPORT IDBDatabaseCallbacks - : public GarbageCollectedFinalized<IDBDatabaseCallbacks> { + : public GarbageCollected<IDBDatabaseCallbacks> { public: IDBDatabaseCallbacks(); virtual ~IDBDatabaseCallbacks(); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc index e08787812b4..e95eb90e828 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_factory.cc @@ -213,15 +213,11 @@ static bool IsContextValid(ExecutionContext* context) { WebIDBFactory* IDBFactory::GetFactory(ExecutionContext* execution_context) { if (!web_idb_factory_) { - mojom::blink::IDBFactoryPtrInfo web_idb_factory_host_info; - service_manager::InterfaceProvider* interface_provider = - execution_context->GetInterfaceProvider(); - if (!interface_provider) - return nullptr; - interface_provider->GetInterface( - mojo::MakeRequest(&web_idb_factory_host_info)); + mojo::PendingRemote<mojom::blink::IDBFactory> web_idb_factory_host_remote; + execution_context->GetBrowserInterfaceBroker().GetInterface( + web_idb_factory_host_remote.InitWithNewPipeAndPassReceiver()); web_idb_factory_ = std::make_unique<WebIDBFactoryImpl>( - std::move(web_idb_factory_host_info), + std::move(web_idb_factory_host_remote), execution_context->GetTaskRunner(TaskType::kDatabaseAccess)); } return web_idb_factory_.get(); @@ -229,9 +225,8 @@ WebIDBFactory* IDBFactory::GetFactory(ExecutionContext* execution_context) { ScriptPromise IDBFactory::GetDatabaseInfo(ScriptState* script_state, ExceptionState& exception_state) { - // The BlinkIDL definition for GetDatabaseInfo already has a [MeasureAs] - // attribute, so the kIndexedDBRead use counter for kIndexedDBRead must be - // explicitly updated. + // The BlinkIDL definition for GetDatabaseInfo() already has a [Measure] + // attribute, so the kIndexedDBRead use counter must be explicitly updated. UseCounter::Count(ExecutionContext::From(script_state), WebFeature::kIndexedDBRead); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h index 0c09700a658..0d628fc767c 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h @@ -27,7 +27,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_INDEXEDDB_IDB_INDEX_H_ #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/indexeddb/idb_cursor.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key_path.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h" diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc index 6654cf86889..bcc7fb9828a 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_path.cc @@ -27,7 +27,7 @@ #include "third_party/blink/public/common/indexeddb/web_idb_types.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" -#include "third_party/blink/renderer/platform/wtf/dtoa/dtoa.h" +#include "third_party/blink/renderer/platform/wtf/dtoa.h" #include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h" #include "third_party/blink/renderer/platform/wtf/text/character_names.h" #include "third_party/blink/renderer/platform/wtf/text/unicode.h" diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.idl b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.idl index 49dbff00b80..d922a27821f 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.idl +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.idl @@ -41,5 +41,5 @@ optional boolean lowerOpen = false, optional boolean upperOpen = false); - [CallWith=ScriptState, RaisesException] boolean _includes(any key); + [CallWith=ScriptState, RaisesException] boolean includes(any key); }; diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h index 831fae9df07..bc668d0ea16 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h @@ -8,7 +8,7 @@ #include <memory> #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h index f85b8642cc3..48a337ead33 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h @@ -34,7 +34,7 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink-forward.h" #include "third_party/blink/public/platform/web_blob_info.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" @@ -110,13 +110,13 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData, ~AsyncTraceState(); // Used to transfer the trace end event state to an IDBRequest. - AsyncTraceState(AsyncTraceState&& other) noexcept { + AsyncTraceState(AsyncTraceState&& other) { DCHECK(IsEmpty()); this->trace_event_name_ = other.trace_event_name_; this->id_ = other.id_; other.trace_event_name_ = nullptr; } - AsyncTraceState& operator=(AsyncTraceState&& rhs) noexcept { + AsyncTraceState& operator=(AsyncTraceState&& rhs) { DCHECK(IsEmpty()); this->trace_event_name_ = rhs.trace_event_name_; this->id_ = rhs.id_; diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc index e1a3b49731e..f5cfb941f37 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc @@ -61,7 +61,6 @@ #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" -#include "third_party/blink/renderer/platform/wtf/dtoa/utils.h" #include "third_party/blink/renderer/platform/wtf/shared_buffer.h" #include "third_party/blink/renderer/platform/wtf/vector.h" #include "v8/include/v8.h" @@ -91,7 +90,7 @@ class BackendDatabaseWithMockedClose int64_t transaction_id, const WTF::Vector<int64_t>& object_store_ids, mojom::blink::IDBTransactionMode mode, - bool relaxed_durability) override {} + mojom::blink::IDBTransactionDurability) override {} MOCK_METHOD0(Close, void()); void VersionChangeIgnored() override {} void AddObserver(int64_t transaction_id, @@ -198,7 +197,8 @@ class IDBRequestTest : public testing::Test { HashSet<String> transaction_scope = {"store"}; transaction_ = IDBTransaction::CreateNonVersionChange( scope.GetScriptState(), std::move(transaction_backend), kTransactionId, - transaction_scope, mojom::IDBTransactionMode::ReadOnly, db_.Get()); + transaction_scope, mojom::IDBTransactionMode::ReadOnly, + mojom::IDBTransactionDurability::Relaxed, db_.Get()); IDBKeyPath store_key_path("primaryKey"); scoped_refptr<IDBObjectStoreMetadata> store_metadata = base::AdoptRef( @@ -435,10 +435,9 @@ TEST_F(IDBRequestTest, ConnectionsAfterStopping) { class AsyncTraceStateForTesting : public IDBRequest::AsyncTraceState { public: AsyncTraceStateForTesting() : IDBRequest::AsyncTraceState() {} - AsyncTraceStateForTesting(AsyncTraceStateForTesting&& other) noexcept + AsyncTraceStateForTesting(AsyncTraceStateForTesting&& other) : IDBRequest::AsyncTraceState(std::move(other)) {} - AsyncTraceStateForTesting& operator=( - AsyncTraceStateForTesting&& rhs) noexcept { + AsyncTraceStateForTesting& operator=(AsyncTraceStateForTesting&& rhs) { AsyncTraceState::operator=(std::move(rhs)); return *this; } diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc index 7106e79a344..b1b2ec15656 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc @@ -52,12 +52,14 @@ IDBTransaction* IDBTransaction::CreateNonVersionChange( int64_t id, const HashSet<String>& scope, mojom::IDBTransactionMode mode, + mojom::IDBTransactionDurability durability, IDBDatabase* db) { DCHECK_NE(mode, mojom::IDBTransactionMode::VersionChange); DCHECK(!scope.IsEmpty()) << "Non-version transactions should operate on a " "well-defined set of stores"; - return MakeGarbageCollected<IDBTransaction>( - script_state, std::move(transaction_backend), id, scope, mode, db); + return MakeGarbageCollected<IDBTransaction>(script_state, + std::move(transaction_backend), + id, scope, mode, durability, db); } IDBTransaction* IDBTransaction::CreateVersionChange( @@ -78,12 +80,14 @@ IDBTransaction::IDBTransaction( int64_t id, const HashSet<String>& scope, mojom::IDBTransactionMode mode, + mojom::IDBTransactionDurability durability, IDBDatabase* db) : ContextLifecycleObserver(ExecutionContext::From(script_state)), transaction_backend_(std::move(transaction_backend)), id_(id), database_(db), mode_(mode), + durability_(durability), scope_(scope), event_queue_( MakeGarbageCollected<EventQueue>(ExecutionContext::From(script_state), @@ -122,6 +126,7 @@ IDBTransaction::IDBTransaction( database_(db), open_db_request_(open_db_request), mode_(mojom::IDBTransactionMode::VersionChange), + durability_(mojom::IDBTransactionDurability::Default), state_(kInactive), old_database_metadata_(old_metadata), event_queue_( @@ -495,6 +500,21 @@ const String& IDBTransaction::mode() const { return indexed_db_names::kReadonly; } +const String& IDBTransaction::durability() const { + switch (durability_) { + case mojom::IDBTransactionDurability::Default: + return indexed_db_names::kDefault; + + case mojom::IDBTransactionDurability::Strict: + return indexed_db_names::kStrict; + + case mojom::IDBTransactionDurability::Relaxed: + return indexed_db_names::kRelaxed; + } + + NOTREACHED(); +} + DOMStringList* IDBTransaction::objectStoreNames() const { if (IsVersionChange()) return database_->objectStoreNames(); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h index 913cb291937..f73fb13f8b8 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h @@ -29,7 +29,7 @@ #include <memory> #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/core/dom/dom_string_list.h" #include "third_party/blink/renderer/core/dom/events/event_listener.h" @@ -75,6 +75,7 @@ class MODULES_EXPORT IDBTransaction final int64_t transaction_id, const HashSet<String>& scope, mojom::IDBTransactionMode, + mojom::IDBTransactionDurability, IDBDatabase* database); static IDBTransaction* CreateVersionChange( ExecutionContext*, @@ -90,6 +91,7 @@ class MODULES_EXPORT IDBTransaction final int64_t, const HashSet<String>& scope, mojom::IDBTransactionMode, + mojom::IDBTransactionDurability, IDBDatabase*); // For upgrade transactions. IDBTransaction(ExecutionContext*, @@ -122,6 +124,7 @@ class MODULES_EXPORT IDBTransaction final // Implement the IDBTransaction IDL const String& mode() const; + const String& durability() const; DOMStringList* objectStoreNames() const; IDBDatabase* db() const { return database_.Get(); } DOMException* error() const { return error_; } @@ -213,6 +216,7 @@ class MODULES_EXPORT IDBTransaction final Member<IDBDatabase> database_; Member<IDBOpenDBRequest> open_db_request_; const mojom::IDBTransactionMode mode_; + const mojom::IDBTransactionDurability durability_; // The names of the object stores that make up this transaction's scope. // diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.idl b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.idl index 4a09acb0f46..2956e888fb8 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.idl +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.idl @@ -42,15 +42,13 @@ enum IDBTransactionMode { // Properties readonly attribute DOMStringList objectStoreNames; readonly attribute IDBTransactionMode mode; + [RuntimeEnabled=IDBRelaxedDurability] readonly attribute IDBTransactionDurability durability; [SameObject] readonly attribute IDBDatabase db; readonly attribute DOMException error; // Methods [RaisesException] IDBObjectStore objectStore(DOMString name); - [ - RaisesException, - RuntimeEnabled=IDBTransactionCommit - ] void commit(); + [RaisesException] void commit(); [RaisesException] void abort(); // Events diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_options.idl b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_options.idl index 2a20f7217a1..64109b9655e 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_options.idl +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_options.idl @@ -2,8 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -[inline_doc] dictionary IDBTransactionOptions { - // If relaxedDurability is true, then the transaction will not be flushed - // to disk. This is more performant at the cost of durability. - boolean relaxedDurability = false; +enum IDBTransactionDurability { "default", "strict", "relaxed" }; + +dictionary IDBTransactionOptions { + // If durability is "relaxed", then the transaction will not be flushed + // to disk. This is more performant at the cost of durability. If it is + // "strict", then it will always be flushed to disk. "default" leaves the + // decision up to the implementation. + IDBTransactionDurability durability = "default"; }; diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc index a599928b6db..f71d72e1c45 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction_test.cc @@ -98,7 +98,8 @@ class IDBTransactionTest : public testing::Test { HashSet<String> transaction_scope = {"store"}; transaction_ = IDBTransaction::CreateNonVersionChange( scope.GetScriptState(), std::move(transaction_backend), kTransactionId, - transaction_scope, mojom::IDBTransactionMode::ReadOnly, db_.Get()); + transaction_scope, mojom::IDBTransactionMode::ReadOnly, + mojom::IDBTransactionDurability::Relaxed, db_.Get()); IDBKeyPath store_key_path("primaryKey"); scoped_refptr<IDBObjectStoreMetadata> store_metadata = base::AdoptRef( diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.h index 850b3fcef01..3f803a71646 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.h @@ -28,7 +28,7 @@ #include "base/optional.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" #include "third_party/blink/renderer/modules/event_modules.h" #include "third_party/blink/renderer/modules/indexeddb/idb_any.h" diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc b/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc index 81967544713..59866c6b2ff 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.cc @@ -6,6 +6,7 @@ #include "base/stl_util.h" #include "mojo/public/cpp/bindings/array_traits_wtf_vector.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/platform/file_path_conversion.h" #include "third_party/blink/public/platform/web_blob_info.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h" @@ -207,7 +208,7 @@ StructTraits<blink::mojom::IDBValueDataView, std::unique_ptr<blink::IDBValue>>:: if (mime_type.IsNull()) mime_type = g_empty_string; blob_info->mime_type = mime_type; - blob_info->blob = blink::mojom::blink::BlobPtrInfo( + blob_info->blob = mojo::PendingRemote<blink::mojom::blink::Blob>( info.CloneBlobHandle(), blink::mojom::blink::Blob::Version_); blob_or_file_info.push_back(std::move(blob_info)); } @@ -244,10 +245,10 @@ bool StructTraits<blink::mojom::IDBValueDataView, blink::FilePathToWebString(info->file->path), info->file->name, info->mime_type, info->file->last_modified.ToDoubleT(), - info->size, info->blob.PassHandle()); + info->size, info->blob.PassPipe()); } else { value_blob_info.emplace_back(info->uuid, info->mime_type, info->size, - info->blob.PassHandle()); + info->blob.PassPipe()); } } diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_names.json5 b/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_names.json5 index edab532e48d..3aa16b76096 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_names.json5 +++ b/chromium/third_party/blink/renderer/modules/indexeddb/indexed_db_names.json5 @@ -32,5 +32,11 @@ "put", "delete", "clear", + + // The IDBTransactionDurability enum is still being standardized. + // https://chromestatus.com/feature/5730701489995776 + "default", + "relaxed", + "strict", ], } diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc b/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc index 337cbc7f03c..e278a24906d 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc @@ -326,7 +326,7 @@ IDBTransaction* TransactionForDatabase( StringOrStringSequence scope; scope.SetString(object_store_name); IDBTransactionOptions options; - options.setRelaxedDurability(true); + options.setDurability("relaxed"); IDBTransaction* idb_transaction = idb_database->transaction( script_state, scope, mode, &options, exception_state); if (exception_state.HadException()) @@ -896,7 +896,8 @@ class GetMetadata final : public ExecutableWithDatabase<GetMetadataCallback> { ScriptState::Scope scope(script_state); DummyExceptionStateForTesting exception_state; IDBRequest* idb_request_get_entries_count = idb_object_store->count( - script_state, ScriptValue::CreateNull(script_state), exception_state); + script_state, ScriptValue::CreateNull(script_state->GetIsolate()), + exception_state); DCHECK(!exception_state.HadException()); if (exception_state.HadException()) { ExceptionCode ec = exception_state.Code(); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h b/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h index 118199a7dbd..c89042ae206 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h @@ -9,7 +9,7 @@ #include "base/optional.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink-forward.h" #include "third_party/blink/public/platform/web_blob_info.h" #include "third_party/blink/public/web/web_heap.h" #include "third_party/blink/renderer/modules/indexeddb/idb_database_error.h" diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h b/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h index 6f91bdee460..9dce5f21f24 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_database.h @@ -29,7 +29,7 @@ class MockWebIDBDatabase : public testing::StrictMock<WebIDBDatabase> { int64_t id, const Vector<int64_t>& scope, mojom::IDBTransactionMode, - bool relaxed_durability)); + mojom::IDBTransactionDurability)); MOCK_METHOD0(Close, void()); MOCK_METHOD0(VersionChangeIgnored, void()); MOCK_METHOD1(Abort, void(int64_t transaction_id)); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_transaction.h b/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_transaction.h index aca1e9a8d9d..a1e3449924c 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_transaction.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/mock_web_idb_transaction.h @@ -9,7 +9,7 @@ #include <memory> #include "mojo/public/cpp/bindings/pending_associated_receiver.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key_path.h" #include "third_party/blink/renderer/modules/indexeddb/web_idb_transaction.h" diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database.h b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database.h index 04ec3a37c08..34ed7bc4886 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database.h @@ -53,7 +53,7 @@ class MODULES_EXPORT WebIDBDatabase { int64_t id, const Vector<int64_t>& scope, mojom::IDBTransactionMode, - bool relaxed_durability) = 0; + mojom::IDBTransactionDurability) = 0; virtual void Close() = 0; virtual void VersionChangeIgnored() = 0; diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc index 482b56dec72..ce509c8ed7c 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.cc @@ -37,9 +37,9 @@ void WebIDBDatabaseImpl::CreateTransaction( int64_t transaction_id, const Vector<int64_t>& object_store_ids, mojom::IDBTransactionMode mode, - bool relaxed_durability) { + mojom::IDBTransactionDurability durability) { database_->CreateTransaction(std::move(transaction_receiver), transaction_id, - object_store_ids, mode, relaxed_durability); + object_store_ids, mode, durability); } void WebIDBDatabaseImpl::Close() { diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h index 63309de97c0..84f75aa5b9b 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_database_impl.h @@ -36,7 +36,7 @@ class MODULES_EXPORT WebIDBDatabaseImpl : public WebIDBDatabase { int64_t transaction_id, const Vector<int64_t>& scope, mojom::IDBTransactionMode mode, - bool relaxed_durability) override; + mojom::IDBTransactionDurability durability) override; void Close() override; void VersionChangeIgnored() override; diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.cc b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.cc index acb0d9948b4..875fb3037f2 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.h" #include "base/memory/ptr_util.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/self_owned_associated_receiver.h" #include "third_party/blink/renderer/modules/indexeddb/indexed_db_database_callbacks_impl.h" #include "third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h" @@ -13,10 +14,10 @@ namespace blink { WebIDBFactoryImpl::WebIDBFactoryImpl( - mojom::blink::IDBFactoryPtrInfo factory_info, + mojo::PendingRemote<mojom::blink::IDBFactory> pending_factory, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : task_runner_(std::move(task_runner)) { - factory_.Bind(std::move(factory_info), task_runner_); + factory_.Bind(std::move(pending_factory), task_runner_); } WebIDBFactoryImpl::~WebIDBFactoryImpl() = default; diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.h b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.h index 49db75aa900..aaec596aa00 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_factory_impl.h @@ -7,7 +7,9 @@ #include "mojo/public/cpp/bindings/pending_associated_receiver.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h" #include "third_party/blink/renderer/modules/indexeddb/indexed_db_database_callbacks_impl.h" #include "third_party/blink/renderer/modules/indexeddb/web_idb_callbacks.h" @@ -23,7 +25,7 @@ namespace blink { class WebIDBFactoryImpl : public WebIDBFactory { public: explicit WebIDBFactoryImpl( - mojom::blink::IDBFactoryPtrInfo factory_info, + mojo::PendingRemote<mojom::blink::IDBFactory> pending_factory, scoped_refptr<base::SingleThreadTaskRunner> task_runner); ~WebIDBFactoryImpl() override; @@ -49,7 +51,7 @@ class WebIDBFactoryImpl : public WebIDBFactory { GetDatabaseCallbacksProxy( std::unique_ptr<IndexedDBDatabaseCallbacksImpl> callbacks); - mojom::blink::IDBFactoryPtr factory_; + mojo::Remote<mojom::blink::IDBFactory> factory_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; }; diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_transaction.h b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_transaction.h index a1a0fb65247..9638494a249 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_transaction.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/web_idb_transaction.h @@ -30,7 +30,7 @@ #include <memory> #include "mojo/public/cpp/bindings/pending_associated_receiver.h" -#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" +#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/indexeddb/web_idb_callbacks.h" #include "third_party/blink/renderer/modules/modules_export.h" diff --git a/chromium/third_party/blink/renderer/modules/installedapp/BUILD.gn b/chromium/third_party/blink/renderer/modules/installedapp/BUILD.gn index a72dfcef974..5dd66caec92 100644 --- a/chromium/third_party/blink/renderer/modules/installedapp/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/installedapp/BUILD.gn @@ -10,6 +10,5 @@ blink_modules_sources("installedapp") { "installed_app_controller.h", "navigator_installed_app.cc", "navigator_installed_app.h", - "related_application.h", ] } diff --git a/chromium/third_party/blink/renderer/modules/installedapp/OWNERS b/chromium/third_party/blink/renderer/modules/installedapp/OWNERS index 065b1322ca1..e3383b0300a 100644 --- a/chromium/third_party/blink/renderer/modules/installedapp/OWNERS +++ b/chromium/third_party/blink/renderer/modules/installedapp/OWNERS @@ -1,3 +1,4 @@ -mgiuca@chromium.org +peter@chromium.org +rayankans@chromium.org # COMPONENT: Platform>Apps>AppLauncher>Install diff --git a/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc b/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc index 83a32dd1b91..64d7dba3b61 100644 --- a/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc +++ b/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc @@ -6,8 +6,10 @@ #include <utility> -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/common/manifest/manifest.h" +#include "third_party/blink/public/mojom/installedapp/related_application.mojom-blink.h" +#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -74,7 +76,7 @@ void InstalledAppController::OnGetManifestForRelatedApps( if (!provider_) { // See https://bit.ly/2S0zRAS for task types. - GetSupplementable()->GetInterfaceProvider().GetInterface( + GetSupplementable()->GetBrowserInterfaceBroker().GetInterface( provider_.BindNewPipeAndPassReceiver( GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI))); // TODO(mgiuca): Set a connection error handler. This requires a refactor to @@ -94,8 +96,11 @@ void InstalledAppController::OnFilterInstalledApps( Vector<mojom::blink::RelatedApplicationPtr> result) { HeapVector<Member<RelatedApplication>> applications; for (const auto& res : result) { - auto* app = MakeGarbageCollected<RelatedApplication>(res->platform, - res->url, res->id); + auto* app = MakeGarbageCollected<RelatedApplication>(); + app->setPlatform(res->platform); + app->setURL(res->url); + app->setId(res->id); + app->setVersion(res->version); applications.push_back(app); } callbacks->OnSuccess(applications); diff --git a/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.h b/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.h index 13f912a6554..5d1ff418360 100644 --- a/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.h +++ b/chromium/third_party/blink/renderer/modules/installedapp/installed_app_controller.h @@ -11,8 +11,8 @@ #include "base/memory/scoped_refptr.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/installedapp/installed_app_provider.mojom-blink.h" -#include "third_party/blink/public/mojom/installedapp/related_application.mojom-blink.h" -#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h" +#include "third_party/blink/public/mojom/installedapp/related_application.mojom-blink-forward.h" +#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -29,7 +29,7 @@ using AppInstalledCallbacks = CallbackPromiseAdapter<HeapVector<Member<RelatedApplication>>, void>; class MODULES_EXPORT InstalledAppController final - : public GarbageCollectedFinalized<InstalledAppController>, + : public GarbageCollected<InstalledAppController>, public Supplement<LocalFrame>, public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(InstalledAppController); diff --git a/chromium/third_party/blink/renderer/modules/installedapp/related_application.h b/chromium/third_party/blink/renderer/modules/installedapp/related_application.h deleted file mode 100644 index 16fb773eccb..00000000000 --- a/chromium/third_party/blink/renderer/modules/installedapp/related_application.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2016 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 THIRD_PARTY_BLINK_RENDERER_MODULES_INSTALLEDAPP_RELATED_APPLICATION_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_INSTALLEDAPP_RELATED_APPLICATION_H_ - -#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -namespace blink { - -class RelatedApplication final : public ScriptWrappable { - DEFINE_WRAPPERTYPEINFO(); - - public: - RelatedApplication(const String& platform, - const String& url, - const String& id) - : platform_(platform), url_(url), id_(id) {} - ~RelatedApplication() override = default; - - String platform() const { return platform_; } - String url() const { return url_; } - String id() const { return id_; } - - private: - const String platform_; - const String url_; - const String id_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_INSTALLEDAPP_RELATED_APPLICATION_H_ diff --git a/chromium/third_party/blink/renderer/modules/installedapp/related_application.idl b/chromium/third_party/blink/renderer/modules/installedapp/related_application.idl index c55b7f6f1c7..2e2085bb49a 100644 --- a/chromium/third_party/blink/renderer/modules/installedapp/related_application.idl +++ b/chromium/third_party/blink/renderer/modules/installedapp/related_application.idl @@ -5,14 +5,9 @@ // TODO(mgiuca): Link to full spec, rather than explainer, upon completion. // https://github.com/WICG/get-installed-related-apps/blob/master/EXPLAINER.md -// TODO(mgiuca): This should be a dictionary, not an interface. -// (NoInterfaceObject is basically a makeshift dictionary.) -// https://crbug.com/687444. -[ - NoInterfaceObject, - RuntimeEnabled=InstalledApp -] interface RelatedApplication { - readonly attribute DOMString platform; - readonly attribute DOMString url; - readonly attribute DOMString id; +dictionary RelatedApplication { + required USVString platform; + USVString url; + DOMString id; + DOMString version; }; diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc index 0b2456e3f31..f787a3140df 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc +++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/modules/keyboard/keyboard_layout.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -80,7 +80,8 @@ bool KeyboardLayout::EnsureServiceConnected() { if (!frame) { return false; } - frame->GetInterfaceProvider().GetInterface(mojo::MakeRequest(&service_)); + frame->GetBrowserInterfaceBroker().GetInterface( + service_.BindNewPipeAndPassReceiver()); DCHECK(service_); } return true; diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h index aa70f5d5302..c607f439b1f 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h +++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_KEYBOARD_KEYBOARD_LAYOUT_H_ #include "base/macros.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/keyboard_lock/keyboard_lock.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/core_export.h" @@ -16,7 +17,7 @@ namespace blink { class ScriptPromiseResolver; -class KeyboardLayout final : public GarbageCollectedFinalized<KeyboardLayout>, +class KeyboardLayout final : public GarbageCollected<KeyboardLayout>, public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(KeyboardLayout); @@ -44,7 +45,7 @@ class KeyboardLayout final : public GarbageCollectedFinalized<KeyboardLayout>, Member<ScriptPromiseResolver> script_promise_resolver_; - mojom::blink::KeyboardLockServicePtr service_; + mojo::Remote<mojom::blink::KeyboardLockService> service_; DISALLOW_COPY_AND_ASSIGN(KeyboardLayout); }; diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc index 2a3e41b76b9..575c8b87ecf 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc +++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/modules/keyboard/keyboard_lock.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -100,8 +100,9 @@ bool KeyboardLock::EnsureServiceConnected() { return false; } // See https://bit.ly/2S0zRAS for task types. - frame->GetInterfaceProvider().GetInterface(mojo::MakeRequest( - &service_, frame->GetTaskRunner(TaskType::kMiscPlatformAPI))); + frame->GetBrowserInterfaceBroker().GetInterface( + service_.BindNewPipeAndPassReceiver( + frame->GetTaskRunner(TaskType::kMiscPlatformAPI))); DCHECK(service_); } diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h index 3a8fe37a58d..ffee4473d70 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h +++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_KEYBOARD_KEYBOARD_LOCK_H_ #include "base/macros.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/keyboard_lock/keyboard_lock.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/core_export.h" @@ -16,7 +17,7 @@ namespace blink { class ScriptPromiseResolver; -class KeyboardLock final : public GarbageCollectedFinalized<KeyboardLock>, +class KeyboardLock final : public GarbageCollected<KeyboardLock>, public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(KeyboardLock); @@ -43,7 +44,7 @@ class KeyboardLock final : public GarbageCollectedFinalized<KeyboardLock>, void LockRequestFinished(ScriptPromiseResolver*, mojom::KeyboardLockRequestResult); - mojom::blink::KeyboardLockServicePtr service_; + mojo::Remote<mojom::blink::KeyboardLockService> service_; Member<ScriptPromiseResolver> request_keylock_resolver_; DISALLOW_COPY_AND_ASSIGN(KeyboardLock); diff --git a/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_params.h b/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_params.h index 881fcb36b9a..d20cfa4e51a 100644 --- a/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_params.h +++ b/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_params.h @@ -20,7 +20,7 @@ class LocalDOMWindow; class Visitor; class DOMWindowLaunchParams final - : public GarbageCollectedFinalized<DOMWindowLaunchParams>, + : public GarbageCollected<DOMWindowLaunchParams>, public Supplement<LocalDOMWindow> { USING_GARBAGE_COLLECTED_MIXIN(DOMWindowLaunchParams); diff --git a/chromium/third_party/blink/renderer/modules/launch/launch_params.h b/chromium/third_party/blink/renderer/modules/launch/launch_params.h index ddb62be9808..026f1423611 100644 --- a/chromium/third_party/blink/renderer/modules/launch/launch_params.h +++ b/chromium/third_party/blink/renderer/modules/launch/launch_params.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_LAUNCH_LAUNCH_PARAMS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_LAUNCH_LAUNCH_PARAMS_H_ -#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h" +#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/heap.h" diff --git a/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc b/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc index 2f6acc89dad..af48942235c 100644 --- a/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc +++ b/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc @@ -7,7 +7,7 @@ #include <algorithm> #include "mojo/public/cpp/bindings/associated_receiver.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_lock_granted_callback.h" @@ -23,6 +23,8 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" +#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -54,7 +56,7 @@ HeapVector<Member<LockInfo>> ToLockInfos( } // namespace class LockManager::LockRequestImpl final - : public GarbageCollectedFinalized<LockRequestImpl>, + : public GarbageCollected<LockRequestImpl>, public NameClient, public mojom::blink::LockRequest { USING_PRE_FINALIZER(LockManager::LockRequestImpl, Dispose); @@ -215,6 +217,10 @@ ScriptPromise LockManager::request(ScriptState* script_state, ExecutionContext* context = ExecutionContext::From(script_state); DCHECK(context->IsContextThread()); + context->GetScheduler()->RegisterStickyFeature( + blink::SchedulingPolicy::Feature::kWebLocks, + {blink::SchedulingPolicy::RecordMetricsForBackForwardCache()}); + // 5. If origin is an opaque origin, then reject promise with a // "SecurityError" DOMException. if (!context->GetSecurityOrigin()->CanAccessLocks()) { @@ -227,10 +233,10 @@ ScriptPromise LockManager::request(ScriptState* script_state, } if (!service_.is_bound()) { - if (auto* provider = context->GetInterfaceProvider()) { - provider->GetInterface(service_.BindNewPipeAndPassReceiver( - context->GetTaskRunner(TaskType::kMiscPlatformAPI))); - } + context->GetBrowserInterfaceBroker().GetInterface( + service_.BindNewPipeAndPassReceiver( + context->GetTaskRunner(TaskType::kMiscPlatformAPI))); + if (!service_.is_bound()) { exception_state.ThrowTypeError("Service not available."); return ScriptPromise(); @@ -347,10 +353,10 @@ ScriptPromise LockManager::query(ScriptState* script_state, } if (!service_.is_bound()) { - if (auto* provider = context->GetInterfaceProvider()) { - provider->GetInterface(service_.BindNewPipeAndPassReceiver( - context->GetTaskRunner(TaskType::kMiscPlatformAPI))); - } + context->GetBrowserInterfaceBroker().GetInterface( + service_.BindNewPipeAndPassReceiver( + context->GetTaskRunner(TaskType::kMiscPlatformAPI))); + if (!service_.is_bound()) { exception_state.ThrowTypeError("Service not available."); return ScriptPromise(); diff --git a/chromium/third_party/blink/renderer/modules/locks/lock_manager.h b/chromium/third_party/blink/renderer/modules/locks/lock_manager.h index cbb606f1e5e..b3bfa941e15 100644 --- a/chromium/third_party/blink/renderer/modules/locks/lock_manager.h +++ b/chromium/third_party/blink/renderer/modules/locks/lock_manager.h @@ -7,7 +7,7 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/mojom/locks/lock_manager.mojom-blink.h" +#include "third_party/blink/public/mojom/locks/lock_manager.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/string_or_string_sequence.h" #include "third_party/blink/renderer/modules/locks/lock.h" #include "third_party/blink/renderer/modules/locks/lock_options.h" diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest.json new file mode 100644 index 00000000000..b0ffff41c0c --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest.json @@ -0,0 +1 @@ +{ "name": "Manifest test app", "start_url": "manifest_test_page.html", "icons": [ { "src": "launcher-icon-1x.png", "sizes": "48x48", "type": "image/png" }, { "src": "image-512px.png", "sizes": "512x512", "type": "image/png" } ], "display": "standalone", "orientation": "landscape" } diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_1.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_1.json new file mode 100644 index 00000000000..965aa1a8da5 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_1.json @@ -0,0 +1,15 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + } + ], + "start_url": "manifest_test_page.html", + "file_handler": { + "action": "/files" + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_2.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_2.json new file mode 100644 index 00000000000..bc761fbbb48 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_2.json @@ -0,0 +1,16 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + } + ], + "start_url": "manifest_test_page.html", + "file_handler": { + "action": "/files", + "files": [] + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_3.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_3.json new file mode 100644 index 00000000000..5aa338a5c5e --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_3.json @@ -0,0 +1,19 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + } + ], + "start_url": "manifest_test_page.html", + "file_handler": { + "action": "/files", + "files": [{ + "name": "name", + "accept": "image/png" + }] + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_4.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_4.json new file mode 100644 index 00000000000..fa58608b26f --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_4.json @@ -0,0 +1,18 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + } + ], + "start_url": "manifest_test_page.html", + "file_handler": { + "files": [{ + "name": "name", + "accept": "image/png" + }] + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_5.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_5.json new file mode 100644 index 00000000000..b92df185212 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_5.json @@ -0,0 +1,18 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + } + ], + "start_url": "manifest_test_page.html", + "file_handler": { + "files": [{ + "name": "name", + "accept": ["image/png", "image/jpg"] + }] + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_6.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_6.json new file mode 100644 index 00000000000..b76df252f4b --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_file_handler_6.json @@ -0,0 +1,24 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + } + ], + "start_url": "manifest_test_page.html", + "file_handler": { + "files": [ + { + "name": "name", + "accept": ["image/png", "image/jpg"] + }, + { + "name": "svgish", + "accept": [".svg", "xml/svg"] + } + ] + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_listing_related_android_app.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_listing_related_android_app.json new file mode 100644 index 00000000000..3ce01c658c2 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_listing_related_android_app.json @@ -0,0 +1,18 @@ +{ + "name": "Manifest listing related android app", + "icons": [ + { + "src": "/banners/image-512px.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "scope": ".", + "start_url": ".", + "display": "standalone", + "prefer_related_applications": false, + "related_applications": [{ + "platform": "play", + "id": "com.example.app" + }] +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_maskable.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_maskable.json new file mode 100644 index 00000000000..8c46cfbe63d --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_maskable.json @@ -0,0 +1,20 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + }, + { + "src": "launcher-icon-3x.png", + "sizes": "144x144", + "type": "image/png", + "purpose": "maskable" + } + ], + "scope": "/", + "start_url": "manifest_test_page.html", + "display": "standalone" +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_minimal-ui.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_minimal-ui.json new file mode 100644 index 00000000000..28b8015c84a --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_minimal-ui.json @@ -0,0 +1,14 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "badge" + } + ], + "start_url": "/", + "display": "standalone", + "display": "minimal-ui" +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_1.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_1.json new file mode 100644 index 00000000000..14dcd01faed --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_1.json @@ -0,0 +1,12 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": "manifest_test_page.html", + "share_target": {} +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_2.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_2.json new file mode 100644 index 00000000000..8c23831a49a --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_2.json @@ -0,0 +1,14 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": "manifest_test_page.html", + "share_target": { + "action": "" + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_3.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_3.json new file mode 100644 index 00000000000..a51afa0f690 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_3.json @@ -0,0 +1,14 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": "manifest_test_page.html", + "share_target": { + "params": {} + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_4.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_4.json new file mode 100644 index 00000000000..879eae779f0 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_4.json @@ -0,0 +1,15 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": "manifest_test_page.html", + "share_target": { + "action": "https://example.com/", + "params": {} + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_5.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_5.json new file mode 100644 index 00000000000..de638f366c1 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_5.json @@ -0,0 +1,15 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": "manifest_test_page.html", + "share_target": { + "action": "share/", + "params": {} + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_6.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_6.json new file mode 100644 index 00000000000..d70f4f9e0bc --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_6.json @@ -0,0 +1,19 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": "manifest_test_page.html", + "share_target": { + "action": "share/blah/", + "params": { + "text": "foo", + "title": "bar", + "url": "baz" + } + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_7.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_7.json new file mode 100644 index 00000000000..339c157f0d5 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_7.json @@ -0,0 +1,20 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": "manifest_test_page.html", + "share_target": { + "url_template": "https://whatever.test/share?title={title}", + "action": "share/blah/", + "params": { + "text": "foo", + "title": "bar", + "url": "baz" + } + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_8.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_8.json new file mode 100644 index 00000000000..e8f0a83c101 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_share_target_8.json @@ -0,0 +1,22 @@ +{ + "name": "Manifest test app", + "icons": [ + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png" + } + ], + "start_url": "manifest_test_page.html", + "share_target": { + "url_template": "https://whatever.test/share?title={title}", + "action": "share/blah/", + "enctype": "application/x-www-form-urlencoded", + "method": "POST", + "params": { + "text": "foo", + "title": "bar", + "url": "baz" + } + } +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_short_name.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_short_name.json new file mode 100644 index 00000000000..d9c5dfc3d2b --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_short_name.json @@ -0,0 +1 @@ +{ "short_name": "Manifest", "start_url": "https://whatever.test/pwa/manifest_test_page.html", "icons": [ { "src": "launcher-icon-1x.png", "sizes": "48x48", "type": "image/png" }, { "src": "image-512px.png", "sizes": "512x512", "type": "image/png" } ], "display": "browser", "orientation": "portrait", "theme_color": "#000", "scope": "https://whatever.test/pwa/" } diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_wrong_origin.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_wrong_origin.json new file mode 100644 index 00000000000..43138d91ca7 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/manifest_wrong_origin.json @@ -0,0 +1 @@ +{ "short_name": "Manifest", "start_url": "https://example.com/pwa/manifest_test_page.html", "icons": [ { "src": "launcher-icon-1x.png", "sizes": "48x48", "type": "image/png" }, { "src": "image-512px.png", "sizes": "512x512", "type": "image/png" } ], "display": "browser", "orientation": "portrait", "theme_color": "#000", "scope": "https://example.com/pwa/" } diff --git a/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/play_app_url_manifest.json b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/play_app_url_manifest.json new file mode 100644 index 00000000000..aa9931264c3 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/fuzzer_seed_corpus/play_app_url_manifest.json @@ -0,0 +1,8 @@ +{ + "prefer_related_applications": true, + "related_applications": [{ + "platform": "play", + "id": "com.google.android.apps.chrome", + "url": "https://play.google.com/store/apps/details?id=123456&referrer=chrome_inline" + }] +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.cc b/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.cc index ab10edbfb97..9dcb4d6fb6c 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.cc +++ b/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/manifest/image_resource_type_converters.h" #include "third_party/blink/public/common/mime_util/mime_util.h" +#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h" #include "third_party/blink/public/platform/web_icon_sizes_parser.h" #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/public/platform/web_string.h" diff --git a/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.h b/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.h index 100eee1bc80..20c7b45cf2f 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.h +++ b/chromium/third_party/blink/renderer/modules/manifest/image_resource_type_converters.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_IMAGE_RESOURCE_TYPE_CONVERTERS_H_ #include "third_party/blink/public/common/manifest/manifest.h" -#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h" +#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.h b/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.h index b49e7f8b6e5..770cb163f05 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.h +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.h @@ -17,7 +17,7 @@ namespace blink { class LocalFrame; class MODULES_EXPORT ManifestChangeNotifier - : public GarbageCollectedFinalized<ManifestChangeNotifier> { + : public GarbageCollected<ManifestChangeNotifier> { public: explicit ManifestChangeNotifier(LocalFrame& frame); virtual ~ManifestChangeNotifier(); diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc index 44b1e8aae79..f38899dd5c0 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/manifest/manifest_fetcher.h" +#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" #include "third_party/blink/renderer/core/loader/threadable_loader.h" diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.h b/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.h index 5e8af0313d0..bda2edd79e3 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.h +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.h @@ -24,7 +24,7 @@ class TextResourceDecoder; // Helper class to download a Web Manifest. When an instance is created, the // caller need to call Start() and wait for the passed callback to be executed. // If the fetch fails, the callback will be called with two empty objects. -class ManifestFetcher final : public GarbageCollectedFinalized<ManifestFetcher>, +class ManifestFetcher final : public GarbageCollected<ManifestFetcher>, public ThreadableLoaderClient { USING_GARBAGE_COLLECTED_MIXIN(ManifestFetcher); // This will be called asynchronously after the URL has been fetched, diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_fuzzer.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_fuzzer.cc new file mode 100644 index 00000000000..274f6620f7c --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_fuzzer.cc @@ -0,0 +1,27 @@ +// 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. + +#include "third_party/blink/renderer/modules/manifest/manifest_parser.h" +#include "third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +// Fuzzer for blink::ManifestParser +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + static BlinkFuzzerTestSupport test_support = BlinkFuzzerTestSupport(); + String string = String::FromUTF8(reinterpret_cast<const char*>(data), size); + KURL manifest_url("https://whatever.test/manifest.json"); + KURL document_url("https://whatever.test/"); + ManifestParser parser(string, manifest_url, document_url); + parser.Parse(); + return 0; +} + +} // namespace blink + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + return blink::LLVMFuzzerTestOneInput(data, size); +} diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_fuzzer.dict b/chromium/third_party/blink/renderer/modules/manifest/manifest_fuzzer.dict new file mode 100644 index 00000000000..01e3f0f95e7 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_fuzzer.dict @@ -0,0 +1,88 @@ +# 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. + +"*" +"{" +"}" +"[" +"]" +"." +"\".\"" +"/" +"\"/\"" +"/*" +"true" +"\"true\"" +"false" +"\"false\"" +"name" +"\"name\"" +"short_name" +"\"short_name\"" +"icons" +"\"icons\"" +"src" +"\"src\"" +"type" +"\"type\"" +"sizes" +"\"sizes\"" +"start_url" +"\"start_url\"" +"display" +"\"display\"" +"orientation" +"\"orientation\"" +"standalone" +"\"standalone\"" +"minimal-ui" +"\"minimal-ui\"" +"browser" +"\"browser\"" +"purpose" +"\"purpose\"" +"any" +"\"any\"" +"image/png" +"\"image/png\"" +"url" +"\"url\"" +"platform" +"\"platform\"" +"id" +"\"id\"" +"related_applications" +"\"related_applications\"" +"prefer_related_applications" +"\"prefer_related_applications\"" +"theme_color" +"\"theme_color\"" +"play" +"\"play\"" +"https://example.com/" +"\"https://example.com/\"" +"https://example.com/some/path" +"\"https://example.com/some/path\"" +"GET" +"\"GET\"" +"POST" +"\"POST\"" +"action" +"\"action\"" +"enctype" +"\"enctype\"" +"share_target" +"\"share_target\"" +"url_template" +"\"url_template\"" +"file_handler" +"\"file_handler\"" +"params" +"\"params\"" +"application/x-www-form-urlencoded" +"\"application/x-www-form-urlencoded\"" +"png" +".png" +"image/png" +"\"image/png\"" diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc index 8faab6a7179..2eb33b333d0 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc @@ -255,10 +255,6 @@ void ManifestManager::BindReceiver( } void ManifestManager::ContextDestroyed(ExecutionContext*) { - Dispose(); -} - -void ManifestManager::Dispose() { if (fetcher_) fetcher_->Cancel(); @@ -270,6 +266,10 @@ void ManifestManager::Dispose() { receivers_.Clear(); } +void ManifestManager::Prefinalize() { + receivers_.Clear(); +} + void ManifestManager::Trace(blink::Visitor* visitor) { visitor->Trace(fetcher_); visitor->Trace(manifest_change_notifier_); diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h b/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h index 678c08a8ed9..9f40633d078 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h @@ -9,7 +9,7 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "third_party/blink/public/common/manifest/manifest.h" -#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h" +#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink-forward.h" #include "third_party/blink/public/mojom/manifest/manifest_manager.mojom-blink.h" #include "third_party/blink/public/web/web_manifest_manager.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" @@ -30,12 +30,12 @@ class ResourceResponse; // the ManifestParser in order to do so. // // Consumers should use the mojo ManifestManager interface to use this class. -class MODULES_EXPORT ManifestManager - : public GarbageCollectedFinalized<ManifestManager>, - public Supplement<LocalFrame>, - public mojom::blink::ManifestManager, - public ContextLifecycleObserver { +class MODULES_EXPORT ManifestManager : public GarbageCollected<ManifestManager>, + public Supplement<LocalFrame>, + public mojom::blink::ManifestManager, + public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(ManifestManager); + USING_PRE_FINALIZER(ManifestManager, Prefinalize); public: static const char kSupplementName[]; @@ -85,7 +85,7 @@ class MODULES_EXPORT ManifestManager void BindReceiver( mojo::PendingReceiver<mojom::blink::ManifestManager> receiver); - void Dispose(); + void Prefinalize(); friend class ManifestManagerTest; diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc index 45020797187..917b0b63531 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc @@ -239,13 +239,15 @@ KURL ManifestParser::ParseScope(const JSONObject* object, return scope; } -WebDisplayMode ManifestParser::ParseDisplay(const JSONObject* object) { +blink::mojom::DisplayMode ManifestParser::ParseDisplay( + const JSONObject* object) { base::Optional<String> display = ParseString(object, "display", Trim); if (!display.has_value()) - return kWebDisplayModeUndefined; + return blink::mojom::DisplayMode::kUndefined; - WebDisplayMode display_enum = WebDisplayModeFromString(display->Utf8()); - if (display_enum == kWebDisplayModeUndefined) + blink::mojom::DisplayMode display_enum = + DisplayModeFromString(display->Utf8()); + if (display_enum == blink::mojom::DisplayMode::kUndefined) AddErrorInfo("unknown 'display' value ignored."); return display_enum; } diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h index db468b331ec..cdf3bcd7352 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h @@ -106,9 +106,9 @@ class MODULES_EXPORT ManifestParser { // Parses the 'display' field of the manifest, as defined in: // https://w3c.github.io/manifest/#dfn-steps-for-processing-the-display-member - // Returns the parsed DisplayMode if any, WebDisplayModeUndefined if the + // Returns the parsed DisplayMode if any, DisplayMode::kUndefined if the // parsing failed. - WebDisplayMode ParseDisplay(const JSONObject* object); + blink::mojom::DisplayMode ParseDisplay(const JSONObject* object); // Parses the 'orientation' field of the manifest, as defined in: // https://w3c.github.io/manifest/#dfn-steps-for-processing-the-orientation-member diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc index 1ee1ec177e9..346cfe2a97e 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser_unittest.cc @@ -99,7 +99,7 @@ TEST_F(ManifestParserTest, ValidNoContentParses) { ASSERT_TRUE(manifest->name.IsNull()); ASSERT_TRUE(manifest->short_name.IsNull()); ASSERT_TRUE(manifest->start_url.IsEmpty()); - ASSERT_EQ(manifest->display, kWebDisplayModeUndefined); + ASSERT_EQ(manifest->display, blink::mojom::DisplayMode::kUndefined); ASSERT_EQ(manifest->orientation, kWebScreenOrientationLockDefault); ASSERT_FALSE(manifest->has_theme_color); ASSERT_FALSE(manifest->has_background_color); @@ -452,7 +452,7 @@ TEST_F(ManifestParserTest, DisplayParseRules) { // Smoke test. { auto& manifest = ParseManifest("{ \"display\": \"browser\" }"); - EXPECT_EQ(manifest->display, kWebDisplayModeBrowser); + EXPECT_EQ(manifest->display, blink::mojom::DisplayMode::kBrowser); EXPECT_FALSE(IsManifestEmpty(manifest)); EXPECT_EQ(0u, GetErrorCount()); } @@ -460,14 +460,14 @@ TEST_F(ManifestParserTest, DisplayParseRules) { // Trim whitespaces. { auto& manifest = ParseManifest("{ \"display\": \" browser \" }"); - EXPECT_EQ(manifest->display, kWebDisplayModeBrowser); + EXPECT_EQ(manifest->display, blink::mojom::DisplayMode::kBrowser); EXPECT_EQ(0u, GetErrorCount()); } // Don't parse if name isn't a string. { auto& manifest = ParseManifest("{ \"display\": {} }"); - EXPECT_EQ(manifest->display, kWebDisplayModeUndefined); + EXPECT_EQ(manifest->display, blink::mojom::DisplayMode::kUndefined); EXPECT_EQ(1u, GetErrorCount()); EXPECT_EQ( "property 'display' ignored," @@ -478,7 +478,7 @@ TEST_F(ManifestParserTest, DisplayParseRules) { // Don't parse if name isn't a string. { auto& manifest = ParseManifest("{ \"display\": 42 }"); - EXPECT_EQ(manifest->display, kWebDisplayModeUndefined); + EXPECT_EQ(manifest->display, blink::mojom::DisplayMode::kUndefined); EXPECT_EQ(1u, GetErrorCount()); EXPECT_EQ( "property 'display' ignored," @@ -489,7 +489,7 @@ TEST_F(ManifestParserTest, DisplayParseRules) { // Parse fails if string isn't known. { auto& manifest = ParseManifest("{ \"display\": \"browser_something\" }"); - EXPECT_EQ(manifest->display, kWebDisplayModeUndefined); + EXPECT_EQ(manifest->display, blink::mojom::DisplayMode::kUndefined); EXPECT_EQ(1u, GetErrorCount()); EXPECT_EQ("unknown 'display' value ignored.", errors()[0]); } @@ -497,35 +497,35 @@ TEST_F(ManifestParserTest, DisplayParseRules) { // Accept 'fullscreen'. { auto& manifest = ParseManifest("{ \"display\": \"fullscreen\" }"); - EXPECT_EQ(manifest->display, kWebDisplayModeFullscreen); + EXPECT_EQ(manifest->display, blink::mojom::DisplayMode::kFullscreen); EXPECT_EQ(0u, GetErrorCount()); } // Accept 'fullscreen'. { auto& manifest = ParseManifest("{ \"display\": \"standalone\" }"); - EXPECT_EQ(manifest->display, kWebDisplayModeStandalone); + EXPECT_EQ(manifest->display, blink::mojom::DisplayMode::kStandalone); EXPECT_EQ(0u, GetErrorCount()); } // Accept 'minimal-ui'. { auto& manifest = ParseManifest("{ \"display\": \"minimal-ui\" }"); - EXPECT_EQ(manifest->display, kWebDisplayModeMinimalUi); + EXPECT_EQ(manifest->display, blink::mojom::DisplayMode::kMinimalUi); EXPECT_EQ(0u, GetErrorCount()); } // Accept 'browser'. { auto& manifest = ParseManifest("{ \"display\": \"browser\" }"); - EXPECT_EQ(manifest->display, kWebDisplayModeBrowser); + EXPECT_EQ(manifest->display, blink::mojom::DisplayMode::kBrowser); EXPECT_EQ(0u, GetErrorCount()); } // Case insensitive. { auto& manifest = ParseManifest("{ \"display\": \"BROWSER\" }"); - EXPECT_EQ(manifest->display, kWebDisplayModeBrowser); + EXPECT_EQ(manifest->display, blink::mojom::DisplayMode::kBrowser); EXPECT_EQ(0u, GetErrorCount()); } } diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc index a07f4771265..38cc1352fb0 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.cc @@ -8,7 +8,7 @@ #include "third_party/blink/public/common/manifest/manifest.h" #include "third_party/blink/public/common/manifest/manifest_mojom_traits.h" -#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink-forward.h" +#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.h b/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.h index 5acd0f64cb8..3642dc58172 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.h +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_type_converters.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_MANIFEST_MANIFEST_TYPE_CONVERTERS_H_ #include "third_party/blink/public/common/manifest/manifest.h" -#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h" +#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_uma_util.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_uma_util.cc index 330ba3c282f..ed75fc1aa1a 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_uma_util.cc +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_uma_util.cc @@ -42,8 +42,9 @@ void ManifestUmaUtil::ParseSucceeded( !manifest->short_name.IsEmpty()); UMA_HISTOGRAM_BOOLEAN("Manifest.HasProperty.start_url", !manifest->start_url.IsEmpty()); - UMA_HISTOGRAM_BOOLEAN("Manifest.HasProperty.display", - manifest->display != kWebDisplayModeUndefined); + UMA_HISTOGRAM_BOOLEAN( + "Manifest.HasProperty.display", + manifest->display != blink::mojom::DisplayMode::kUndefined); UMA_HISTOGRAM_BOOLEAN( "Manifest.HasProperty.orientation", manifest->orientation != kWebScreenOrientationLockDefault); diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc index 22d4041512b..ec10ba83c5c 100644 --- a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc +++ b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.cc @@ -12,16 +12,12 @@ #include "media/base/supported_types.h" #include "media/filters/stream_parser_factory.h" #include "media/mojo/mojom/media_types.mojom-blink.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h" -#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_info.h" -#include "third_party/blink/public/platform/modules/media_capabilities/web_media_configuration.h" -#include "third_party/blink/public/platform/modules/media_capabilities/web_media_decoding_configuration.h" -#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/web_encrypted_media_client.h" #include "third_party/blink/public/platform/web_encrypted_media_request.h" -#include "third_party/blink/public/platform/web_transmission_encoding_info_handler.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -48,7 +44,11 @@ #include "third_party/blink/renderer/platform/heap/heap_allocator.h" #include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" +#include "third_party/blink/renderer/platform/media_capabilities/web_media_capabilities_info.h" +#include "third_party/blink/renderer/platform/media_capabilities/web_media_configuration.h" +#include "third_party/blink/renderer/platform/media_capabilities/web_media_decoding_configuration.h" #include "third_party/blink/renderer/platform/network/parsed_content_type.h" +#include "third_party/blink/renderer/platform/peerconnection/transmission_encoding_info_handler.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -737,8 +737,7 @@ ScriptPromise MediaCapabilities::encodingInfo( } if (configuration->type() == "transmission") { - if (auto* handler = - Platform::Current()->TransmissionEncodingInfoHandler()) { + if (auto* handler = TransmissionEncodingInfoHandler::Instance()) { handler->EncodingInfo(ToWebMediaConfiguration(configuration), WTF::Bind(&OnMediaCapabilitiesEncodingInfo, WrapPersistent(resolver))); @@ -776,14 +775,14 @@ bool MediaCapabilities::EnsureService(ExecutionContext* execution_context) { if (decode_history_service_) return true; - if (!execution_context || !execution_context->GetInterfaceProvider()) + if (!execution_context) return false; scoped_refptr<base::SingleThreadTaskRunner> task_runner = execution_context->GetTaskRunner(TaskType::kMediaElementEvent); - execution_context->GetInterfaceProvider()->GetInterface( - mojo::MakeRequest(&decode_history_service_, task_runner)); + execution_context->GetBrowserInterfaceBroker().GetInterface( + decode_history_service_.BindNewPipeAndPassReceiver(task_runner)); return true; } diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h index a052fd0eecc..100e5b0367c 100644 --- a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h +++ b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities.h @@ -7,6 +7,7 @@ #include "media/base/video_codecs.h" // for media::VideoCodecProfile #include "media/mojo/mojom/video_decode_perf_history.mojom-blink.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/visitor.h" @@ -52,7 +53,8 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable { bool is_smooth, bool is_power_efficient); - media::mojom::blink::VideoDecodePerfHistoryPtr decode_history_service_; + mojo::Remote<media::mojom::blink::VideoDecodePerfHistory> + decode_history_service_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn b/chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn index 0eb064ec84e..cb8247d66c0 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/media_controls/BUILD.gn @@ -101,38 +101,6 @@ blink_modules_sources("media_controls") { ":media_controls_resources", "//services/service_manager/public/cpp", ] - - if (is_android && notouch_build) { - sources += [ - "touchless/elements/media_controls_touchless_bottom_container_element.cc", - "touchless/elements/media_controls_touchless_bottom_container_element.h", - "touchless/elements/media_controls_touchless_element.cc", - "touchless/elements/media_controls_touchless_element.h", - "touchless/elements/media_controls_touchless_overlay_element.cc", - "touchless/elements/media_controls_touchless_overlay_element.h", - "touchless/elements/media_controls_touchless_play_button_element.cc", - "touchless/elements/media_controls_touchless_play_button_element.h", - "touchless/elements/media_controls_touchless_seek_button_element.cc", - "touchless/elements/media_controls_touchless_seek_button_element.h", - "touchless/elements/media_controls_touchless_time_display_element.cc", - "touchless/elements/media_controls_touchless_time_display_element.h", - "touchless/elements/media_controls_touchless_timeline_element.cc", - "touchless/elements/media_controls_touchless_timeline_element.h", - "touchless/elements/media_controls_touchless_volume_button_element.cc", - "touchless/elements/media_controls_touchless_volume_button_element.h", - "touchless/elements/media_controls_touchless_volume_container_element.cc", - "touchless/elements/media_controls_touchless_volume_container_element.h", - "touchless/media_controls_touchless_impl.cc", - "touchless/media_controls_touchless_impl.h", - "touchless/media_controls_touchless_media_event_listener.cc", - "touchless/media_controls_touchless_media_event_listener.h", - "touchless/media_controls_touchless_media_event_listener_observer.h", - "touchless/media_controls_touchless_resource_loader.cc", - "touchless/media_controls_touchless_resource_loader.h", - ] - - deps += [ ":media_controls_touchless_resources" ] - } } grit("media_controls_resources") { @@ -144,14 +112,3 @@ grit("media_controls_resources") { "media_controls_resources_200_percent.pak", ] } - -if (is_android && notouch_build) { - grit("media_controls_touchless_resources") { - output_dir = "$blink_modules_output_dir/media_controls/touchless/resources/" - source = "touchless/resources/media_controls_touchless_resources.grd" - outputs = [ - "grit/media_controls_touchless_resources.h", - "media_controls_touchless_resources.pak", - ] - } -} diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.cc index 23e7404c150..03536cd57df 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/geometry/dom_rect.h" @@ -56,12 +57,12 @@ void MediaControlCastButtonElement::TryShowOverlay() { void MediaControlCastButtonElement::UpdateDisplayType() { if (IsPlayingRemotely()) { setAttribute(html_names::kAriaLabelAttr, - WTF::AtomicString(GetLocale().QueryString( - WebLocalizedString::kAXMediaCastOnButton))); + WTF::AtomicString( + GetLocale().QueryString(IDS_AX_MEDIA_CAST_ON_BUTTON))); } else { setAttribute(html_names::kAriaLabelAttr, - WTF::AtomicString(GetLocale().QueryString( - WebLocalizedString::kAXMediaCastOffButton))); + WTF::AtomicString( + GetLocale().QueryString(IDS_AX_MEDIA_CAST_OFF_BUTTON))); } UpdateOverflowString(); SetClass("on", IsPlayingRemotely()); @@ -73,9 +74,8 @@ bool MediaControlCastButtonElement::WillRespondToMouseClickEvents() { return true; } -WebLocalizedString::Name MediaControlCastButtonElement::GetOverflowStringName() - const { - return WebLocalizedString::kOverflowMenuCast; +int MediaControlCastButtonElement::GetOverflowStringId() const { + return IDS_MEDIA_OVERFLOW_MENU_CAST; } bool MediaControlCastButtonElement::HasOverflowButton() const { diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h index 0b0a774a010..9bc21a99da0 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_cast_button_element.h @@ -26,7 +26,7 @@ class MediaControlCastButtonElement final : public MediaControlInputElement { // MediaControlInputElement overrides. bool WillRespondToMouseClickEvents() final; - WebLocalizedString::Name GetOverflowStringName() const final; + int GetOverflowStringId() const final; bool HasOverflowButton() const final; protected: diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_current_time_display_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_current_time_display_element.cc index 92d077b7c00..42baaa490c9 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_current_time_display_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_current_time_display_element.cc @@ -4,15 +4,15 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_current_time_display_element.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h" namespace blink { MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement( MediaControlsImpl& media_controls) - : MediaControlTimeDisplayElement( - media_controls, - WebLocalizedString::kAXMediaCurrentTimeDisplay) { + : MediaControlTimeDisplayElement(media_controls, + IDS_AX_MEDIA_CURRENT_TIME_DISPLAY) { SetShadowPseudoId( AtomicString("-webkit-media-controls-current-time-display")); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.cc index 80c544b9d42..5ed74878bce 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/frame/viewport_data.h" @@ -21,7 +22,7 @@ MediaControlDisplayCutoutFullscreenButtonElement:: setType(input_type_names::kButton); setAttribute(html_names::kAriaLabelAttr, WTF::AtomicString(GetLocale().QueryString( - WebLocalizedString::kAXMediaDisplayCutoutFullscreenButton))); + IDS_AX_MEDIA_DISPLAY_CUT_OUT_FULL_SCREEN_BUTTON))); SetShadowPseudoId(AtomicString( "-internal-media-controls-display-cutout-fullscreen-button")); SetIsWanted(false); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc index e7cf7466465..eb065bd0697 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element_test.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_display_cutout_fullscreen_button_element.h" #include "third_party/blink/public/mojom/page/display_cutout.mojom-blink.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/events/touch_event.h" #include "third_party/blink/renderer/core/frame/viewport_data.h" #include "third_party/blink/renderer/core/frame/web_feature.h" @@ -98,7 +99,7 @@ class MediaControlDisplayCutoutFullscreenButtonElementTest TEST_F(MediaControlDisplayCutoutFullscreenButtonElementTest, Fullscreen_ButtonAccessibility) { EXPECT_EQ(display_cutout_fullscreen_button_->GetLocale().QueryString( - WebLocalizedString::kAXMediaDisplayCutoutFullscreenButton), + IDS_AX_MEDIA_DISPLAY_CUT_OUT_FULL_SCREEN_BUTTON), display_cutout_fullscreen_button_->getAttribute( html_names::kAriaLabelAttr)); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc index 5f8267cbda9..26e648a0df6 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/core/frame/settings.h" @@ -22,9 +23,9 @@ MediaControlDownloadButtonElement::MediaControlDownloadButtonElement( MediaControlsImpl& media_controls) : MediaControlInputElement(media_controls) { setType(input_type_names::kButton); - setAttribute(html_names::kAriaLabelAttr, - WTF::AtomicString(GetLocale().QueryString( - WebLocalizedString::kAXMediaDownloadButton))); + setAttribute( + html_names::kAriaLabelAttr, + WTF::AtomicString(GetLocale().QueryString(IDS_AX_MEDIA_DOWNLOAD_BUTTON))); SetShadowPseudoId(AtomicString("-internal-media-controls-download-button")); SetIsWanted(false); @@ -46,9 +47,8 @@ bool MediaControlDownloadButtonElement::ShouldDisplayDownloadButton() const { return true; } -WebLocalizedString::Name -MediaControlDownloadButtonElement::GetOverflowStringName() const { - return WebLocalizedString::kOverflowMenuDownload; +int MediaControlDownloadButtonElement::GetOverflowStringId() const { + return IDS_MEDIA_OVERFLOW_MENU_DOWNLOAD; } bool MediaControlDownloadButtonElement::HasOverflowButton() const { @@ -68,7 +68,7 @@ const char* MediaControlDownloadButtonElement::GetNameForHistograms() const { } void MediaControlDownloadButtonElement::DefaultEventHandler(Event& event) { - const KURL& url = MediaElement().currentSrc(); + const KURL& url = MediaElement().downloadURL(); if ((event.type() == event_type_names::kClick || event.type() == event_type_names::kGesturetap) && !(url.IsNull() || url.IsEmpty())) { @@ -79,7 +79,7 @@ void MediaControlDownloadButtonElement::DefaultEventHandler(Event& event) { request.SetRequestContext(mojom::RequestContextType::DOWNLOAD); request.SetRequestorOrigin(SecurityOrigin::Create(GetDocument().Url())); GetDocument().GetFrame()->Client()->DownloadURL( - request, DownloadCrossOriginRedirects::kFollow); + request, network::mojom::RedirectMode::kError); } MediaControlInputElement::DefaultEventHandler(event); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h index a499019b32c..93334801f6e 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h @@ -23,7 +23,7 @@ class MediaControlDownloadButtonElement final // MediaControlInputElement overrides. // TODO(mlamouri): add WillRespondToMouseClickEvents - WebLocalizedString::Name GetOverflowStringName() const final; + int GetOverflowStringId() const final; bool HasOverflowButton() const final; bool IsControlPanelButton() const final; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.h index 32569074eca..334248fb8df 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.h @@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_ELEMENT_BASE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_ELEMENT_BASE_H_ -#include "third_party/blink/public/platform/web_localized_string.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.cc index 0ba85ffc249..efcd5928385 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/frame/settings.h" @@ -28,11 +29,11 @@ void MediaControlFullscreenButtonElement::SetIsFullscreen(bool is_fullscreen) { if (is_fullscreen) { setAttribute(html_names::kAriaLabelAttr, WTF::AtomicString(GetLocale().QueryString( - WebLocalizedString::kAXMediaExitFullscreenButton))); + IDS_AX_MEDIA_EXIT_FULL_SCREEN_BUTTON))); } else { setAttribute(html_names::kAriaLabelAttr, WTF::AtomicString(GetLocale().QueryString( - WebLocalizedString::kAXMediaEnterFullscreenButton))); + IDS_AX_MEDIA_ENTER_FULL_SCREEN_BUTTON))); } SetClass("fullscreen", is_fullscreen); } @@ -41,11 +42,10 @@ bool MediaControlFullscreenButtonElement::WillRespondToMouseClickEvents() { return true; } -WebLocalizedString::Name -MediaControlFullscreenButtonElement::GetOverflowStringName() const { +int MediaControlFullscreenButtonElement::GetOverflowStringId() const { if (MediaElement().IsFullscreen()) - return WebLocalizedString::kOverflowMenuExitFullscreen; - return WebLocalizedString::kOverflowMenuEnterFullscreen; + return IDS_MEDIA_OVERFLOW_MENU_EXIT_FULLSCREEN; + return IDS_MEDIA_OVERFLOW_MENU_ENTER_FULLSCREEN; } bool MediaControlFullscreenButtonElement::HasOverflowButton() const { diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.h index 12b50993fe1..d8aa1ae18c0 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_fullscreen_button_element.h @@ -22,7 +22,7 @@ class MediaControlFullscreenButtonElement final // MediaControlInputElement overrides. bool WillRespondToMouseClickEvents() override; - WebLocalizedString::Name GetOverflowStringName() const override; + int GetOverflowStringId() const override; bool HasOverflowButton() const override; bool IsControlPanelButton() const override; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc index 705b56e59c7..9ed59699962 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h" #include "third_party/blink/public/platform/web_size.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/core/dom/dom_token_list.h" @@ -186,10 +187,9 @@ MediaControlInputElement::MediaControlInputElement( : HTMLInputElement(media_controls.GetDocument(), CreateElementFlags()), MediaControlElementBase(media_controls, this) {} -WebLocalizedString::Name MediaControlInputElement::GetOverflowStringName() - const { +int MediaControlInputElement::GetOverflowStringId() const { NOTREACHED(); - return WebLocalizedString::kAXAMPMFieldText; + return IDS_AX_AM_PM_FIELD_TEXT; } void MediaControlInputElement::UpdateShownState() { @@ -256,7 +256,7 @@ bool MediaControlInputElement::IsMediaControlElement() const { } String MediaControlInputElement::GetOverflowMenuString() const { - return MediaElement().GetLocale().QueryString(GetOverflowStringName()); + return MediaElement().GetLocale().QueryString(GetOverflowStringId()); } String MediaControlInputElement::GetOverflowMenuSubtitleString() const { diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h index 54970c0f729..8f39a187026 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h @@ -49,10 +49,10 @@ class MODULES_EXPORT MediaControlInputElement : public HTMLInputElement, // will be used as a suffix for histograms. virtual const char* GetNameForHistograms() const = 0; - // Returns a string representation of the media control element. - // Subclasses should override this method to return the string representation + // Returns a string resource id of the media control element. + // Subclasses should override this method to return the string resource id // of the overflow button. - virtual WebLocalizedString::Name GetOverflowStringName() const; + virtual int GetOverflowStringId() const; // Implements a default event handler to record interaction on click. void DefaultEventHandler(Event&) override; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element_test.cc index 20ae4a42321..f6fa3ce832f 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element_test.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_input_element_test.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_input_element.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/html/media/html_video_element.h" @@ -44,8 +45,8 @@ class MediaControlInputElementImpl final : public MediaControlInputElement { : "MediaControlInputElementImpl"; } - WebLocalizedString::Name GetOverflowStringName() const final { - return WebLocalizedString::kOverflowMenuDownload; + int GetOverflowStringId() const final { + return IDS_MEDIA_OVERFLOW_MENU_DOWNLOAD; } }; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.cc index a753f9a2a91..8950bbed67e 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/css/css_style_declaration.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/events/event_listener.h" @@ -38,9 +39,9 @@ MediaControlLoadingPanelElement::MediaControlLoadingPanelElement( MediaControlsImpl& media_controls) : MediaControlDivElement(media_controls) { SetShadowPseudoId(AtomicString("-internal-media-controls-loading-panel")); - setAttribute(html_names::kAriaLabelAttr, - WTF::AtomicString(GetLocale().QueryString( - WebLocalizedString::kAXMediaLoadingPanel))); + setAttribute( + html_names::kAriaLabelAttr, + WTF::AtomicString(GetLocale().QueryString(IDS_AX_MEDIA_LOADING_PANEL))); setAttribute(html_names::kAriaLiveAttr, "polite"); CreateUserAgentShadowRoot(); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc index 39afbe98d6e..2ed62bcb85b 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/input_type_names.h" @@ -29,21 +30,20 @@ void MediaControlMuteButtonElement::UpdateDisplayType() { // 'muted' when the volume is 0 even if the element is not muted. This allows // the painting and the display type to actually match. bool muted = MediaElement().muted() || MediaElement().volume() == 0; - setAttribute(html_names::kAriaLabelAttr, - WTF::AtomicString(GetLocale().QueryString( - muted ? WebLocalizedString::kAXMediaUnMuteButton - : WebLocalizedString::kAXMediaMuteButton))); + setAttribute( + html_names::kAriaLabelAttr, + WTF::AtomicString(GetLocale().QueryString( + muted ? IDS_AX_MEDIA_UNMUTE_BUTTON : IDS_AX_MEDIA_MUTE_BUTTON))); SetClass("muted", muted); UpdateOverflowString(); MediaControlInputElement::UpdateDisplayType(); } -WebLocalizedString::Name MediaControlMuteButtonElement::GetOverflowStringName() - const { +int MediaControlMuteButtonElement::GetOverflowStringId() const { if (MediaElement().muted()) - return WebLocalizedString::kOverflowMenuUnmute; - return WebLocalizedString::kOverflowMenuMute; + return IDS_MEDIA_OVERFLOW_MENU_UNMUTE; + return IDS_MEDIA_OVERFLOW_MENU_MUTE; } bool MediaControlMuteButtonElement::HasOverflowButton() const { diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.h index f9fbeb82f84..70feb7e2e27 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.h @@ -19,7 +19,7 @@ class MediaControlMuteButtonElement final : public MediaControlInputElement { // MediaControlInputElement overrides. bool WillRespondToMouseClickEvents() override; void UpdateDisplayType() override; - WebLocalizedString::Name GetOverflowStringName() const override; + int GetOverflowStringId() const override; bool HasOverflowButton() const override; bool IsControlPanelButton() const override; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.cc index 284eaf03141..3fce3d9e6c4 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/input_type_names.h" #include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h" @@ -16,12 +17,12 @@ MediaControlOverflowMenuButtonElement::MediaControlOverflowMenuButtonElement( MediaControlsImpl& media_controls) : MediaControlInputElement(media_controls) { setType(input_type_names::kButton); - setAttribute(html_names::kAriaLabelAttr, - WTF::AtomicString(GetLocale().QueryString( - WebLocalizedString::kAXMediaOverflowButton))); + setAttribute( + html_names::kAriaLabelAttr, + WTF::AtomicString(GetLocale().QueryString(IDS_AX_MEDIA_OVERFLOW_BUTTON))); setAttribute(html_names::kTitleAttr, - WTF::AtomicString(GetLocale().QueryString( - WebLocalizedString::kAXMediaOverflowButtonHelp))); + WTF::AtomicString( + GetLocale().QueryString(IDS_AX_MEDIA_OVERFLOW_BUTTON_HELP))); SetShadowPseudoId(AtomicString("-internal-media-controls-overflow-button")); SetIsWanted(false); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc index e41057b89e1..a06074cf44c 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.cc @@ -6,6 +6,7 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_size.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" @@ -47,9 +48,8 @@ MediaControlOverlayPlayButtonElement::MediaControlOverlayPlayButtonElement( void MediaControlOverlayPlayButtonElement::UpdateDisplayType() { SetIsWanted(MediaElement().ShouldShowControls()); - WebLocalizedString::Name state = - MediaElement().paused() ? WebLocalizedString::kAXMediaPlayButton - : WebLocalizedString::kAXMediaPauseButton; + int state = MediaElement().paused() ? IDS_AX_MEDIA_PLAY_BUTTON + : IDS_AX_MEDIA_PAUSE_BUTTON; setAttribute(html_names::kAriaLabelAttr, WTF::AtomicString(GetLocale().QueryString(state))); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.cc index 77bb081a854..333982bfe05 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/html/media/html_media_source.h" @@ -51,16 +52,15 @@ void MediaControlPictureInPictureButtonElement::UpdateDisplayType() { MediaControlInputElement::UpdateDisplayType(); } -WebLocalizedString::Name -MediaControlPictureInPictureButtonElement::GetOverflowStringName() const { +int MediaControlPictureInPictureButtonElement::GetOverflowStringId() const { DCHECK(MediaElement().IsHTMLVideoElement()); bool isInPictureInPicture = PictureInPictureController::IsElementInPictureInPicture( &ToHTMLVideoElement(MediaElement())); return isInPictureInPicture - ? WebLocalizedString::kOverflowMenuExitPictureInPicture - : WebLocalizedString::kOverflowMenuEnterPictureInPicture; + ? IDS_MEDIA_OVERFLOW_MENU_EXIT_PICTURE_IN_PICTURE + : IDS_MEDIA_OVERFLOW_MENU_ENTER_PICTURE_IN_PICTURE; } bool MediaControlPictureInPictureButtonElement::HasOverflowButton() const { @@ -102,10 +102,9 @@ void MediaControlPictureInPictureButtonElement::UpdateAriaString( bool isInPictureInPicture) { String aria_string = isInPictureInPicture - ? GetLocale().QueryString( - WebLocalizedString::kAXMediaExitPictureInPictureButton) + ? GetLocale().QueryString(IDS_AX_MEDIA_EXIT_PICTURE_IN_PICTURE_BUTTON) : GetLocale().QueryString( - WebLocalizedString::kAXMediaEnterPictureInPictureButton); + IDS_AX_MEDIA_ENTER_PICTURE_IN_PICTURE_BUTTON); setAttribute(html_names::kAriaLabelAttr, WTF::AtomicString(aria_string)); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.h index 54a30d5adf4..c23a2aac832 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_picture_in_picture_button_element.h @@ -20,7 +20,7 @@ class MediaControlPictureInPictureButtonElement final // MediaControlInputElement: bool WillRespondToMouseClickEvents() override; void UpdateDisplayType() override; - WebLocalizedString::Name GetOverflowStringName() const override; + int GetOverflowStringId() const override; bool HasOverflowButton() const override; bool IsControlPanelButton() const override; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.cc index c91f1de30b5..526d64f7a03 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/input_type_names.h" @@ -25,9 +26,8 @@ bool MediaControlPlayButtonElement::WillRespondToMouseClickEvents() { } void MediaControlPlayButtonElement::UpdateDisplayType() { - WebLocalizedString::Name state = - MediaElement().paused() ? WebLocalizedString::kAXMediaPlayButton - : WebLocalizedString::kAXMediaPauseButton; + int state = MediaElement().paused() ? IDS_AX_MEDIA_PLAY_BUTTON + : IDS_AX_MEDIA_PAUSE_BUTTON; setAttribute(html_names::kAriaLabelAttr, WTF::AtomicString(GetLocale().QueryString(state))); SetClass("pause", MediaElement().paused()); @@ -36,11 +36,10 @@ void MediaControlPlayButtonElement::UpdateDisplayType() { MediaControlInputElement::UpdateDisplayType(); } -WebLocalizedString::Name MediaControlPlayButtonElement::GetOverflowStringName() - const { +int MediaControlPlayButtonElement::GetOverflowStringId() const { if (MediaElement().paused()) - return WebLocalizedString::kOverflowMenuPlay; - return WebLocalizedString::kOverflowMenuPause; + return IDS_MEDIA_OVERFLOW_MENU_PLAY; + return IDS_MEDIA_OVERFLOW_MENU_PAUSE; } bool MediaControlPlayButtonElement::HasOverflowButton() const { diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.h index 1248bf8cb68..4fea9d5c53c 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.h @@ -19,7 +19,7 @@ class MediaControlPlayButtonElement final : public MediaControlInputElement { // MediaControlInputElement overrides. bool WillRespondToMouseClickEvents() override; void UpdateDisplayType() override; - WebLocalizedString::Name GetOverflowStringName() const override; + int GetOverflowStringId() const override; bool HasOverflowButton() const override; bool IsControlPanelButton() const override; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_remaining_time_display_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_remaining_time_display_element.cc index 1622c84e74f..d5fa0869c8a 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_remaining_time_display_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_remaining_time_display_element.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_remaining_time_display_element.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h" namespace { @@ -18,9 +19,8 @@ namespace blink { MediaControlRemainingTimeDisplayElement:: MediaControlRemainingTimeDisplayElement(MediaControlsImpl& media_controls) - : MediaControlTimeDisplayElement( - media_controls, - WebLocalizedString::kAXMediaTimeRemainingDisplay) { + : MediaControlTimeDisplayElement(media_controls, + IDS_AX_MEDIA_TIME_REMAINING_DISPLAY) { SetShadowPseudoId( AtomicString("-webkit-media-controls-time-remaining-display")); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_scrubbing_message_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_scrubbing_message_element.cc index 27a1ed54eb7..d9e9c8f2ce5 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_scrubbing_message_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_scrubbing_message_element.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_scrubbing_message_element.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/html/html_style_element.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" @@ -50,9 +51,9 @@ void MediaControlScrubbingMessageElement::PopulateChildren() { MediaControlsResourceLoader::GetArrowLeftSVGImage()); arrow_left_div2->SetInnerHTMLFromString( MediaControlsResourceLoader::GetArrowLeftSVGImage()); - message_div->setInnerText(MediaElement().GetLocale().QueryString( - WebLocalizedString::kMediaScrubbingMessageText), - ASSERT_NO_EXCEPTION); + message_div->setInnerText( + MediaElement().GetLocale().QueryString(IDS_MEDIA_SCRUBBING_MESSAGE_TEXT), + ASSERT_NO_EXCEPTION); arrow_right_div1->SetInnerHTMLFromString( MediaControlsResourceLoader::GetArrowRightSVGImage()); arrow_right_div2->SetInnerHTMLFromString( diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc index 55959a5d40f..0dde7c68f04 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h" #include "third_party/blink/renderer/core/dom/text.h" @@ -57,7 +58,7 @@ MediaControlTextTrackListElement::MediaControlTextTrackListElement( setAttribute(html_names::kRoleAttr, "menu"); setAttribute(html_names::kAriaLabelAttr, WTF::AtomicString(GetLocale().QueryString( - WebLocalizedString::kOverflowMenuCaptionsSubmenuTitle))); + IDS_MEDIA_OVERFLOW_MENU_CLOSED_CAPTIONS_SUBMENU_TITLE))); SetShadowPseudoId(AtomicString("-internal-media-controls-text-track-list")); } @@ -177,12 +178,12 @@ Element* MediaControlTextTrackListElement::CreateTextTrackHeaderItem() { header_item->ParserAppendChild( Text::Create(GetDocument(), GetLocale().QueryString( - WebLocalizedString::kOverflowMenuCaptionsSubmenuTitle))); + IDS_MEDIA_OVERFLOW_MENU_CLOSED_CAPTIONS_SUBMENU_TITLE))); header_item->setAttribute(html_names::kRoleAttr, "button"); header_item->setAttribute( html_names::kAriaLabelAttr, AtomicString(GetLocale().QueryString( - WebLocalizedString::kAXMediaHideClosedCaptionsMenuButton))); + IDS_AX_MEDIA_HIDE_CLOSED_CAPTIONS_MENU_BUTTON))); header_item->setTabIndex(0); return header_item; } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_time_display_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_time_display_element.cc index e8e525be988..c1e60fcbf40 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_time_display_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_time_display_element.cc @@ -25,9 +25,9 @@ namespace blink { MediaControlTimeDisplayElement::MediaControlTimeDisplayElement( MediaControlsImpl& media_controls, - blink::WebLocalizedString::Name localized_label) + int localized_resource_id) : MediaControlDivElement(media_controls), - localized_label_(localized_label) { + localized_resource_id_(localized_resource_id) { SetAriaLabel(); } @@ -58,7 +58,8 @@ String MediaControlTimeDisplayElement::FormatTime() const { } void MediaControlTimeDisplayElement::SetAriaLabel() { - String aria_label = GetLocale().QueryString(localized_label_, FormatTime()); + String aria_label = + GetLocale().QueryString(localized_resource_id_, FormatTime()); setAttribute(html_names::kAriaLabelAttr, AtomicString(aria_label)); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_time_display_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_time_display_element.h index 2176a8601fe..661fef47960 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_time_display_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_time_display_element.h @@ -21,8 +21,7 @@ class MediaControlTimeDisplayElement : public MediaControlDivElement { WebSize GetSizeOrDefault() const override; protected: - MediaControlTimeDisplayElement(MediaControlsImpl&, - blink::WebLocalizedString::Name); + MediaControlTimeDisplayElement(MediaControlsImpl&, int resource_id); virtual int EstimateElementWidth() const; @@ -32,7 +31,7 @@ class MediaControlTimeDisplayElement : public MediaControlDivElement { void SetAriaLabel(); double current_value_ = 0; - blink::WebLocalizedString::Name localized_label_; + int localized_resource_id_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc index 946a9fd2ba3..ffb6a069fc8 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.cc @@ -6,6 +6,7 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_screen_info.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/events/keyboard_event.h" @@ -66,17 +67,16 @@ bool MediaControlTimelineElement::WillRespondToMouseClickEvents() { void MediaControlTimelineElement::SetPosition(double current_time) { setValue(String::Number(current_time)); String aria_label = - GetLocale().QueryString( - MediaElement().IsHTMLVideoElement() - ? WebLocalizedString::kAXMediaVideoSliderHelp - : WebLocalizedString::kAXMediaAudioSliderHelp) + + GetLocale().QueryString(MediaElement().IsHTMLVideoElement() + ? IDS_AX_MEDIA_VIDEO_SLIDER_HELP + : IDS_AX_MEDIA_AUDIO_SLIDER_HELP) + " " + GetMediaControls().CurrentTimeDisplay().textContent(true) + " " + GetMediaControls().RemainingTimeDisplay().textContent(true); setAttribute(html_names::kAriaLabelAttr, AtomicString(aria_label)); setAttribute(html_names::kAriaValuetextAttr, AtomicString(GetLocale().QueryString( - WebLocalizedString::kAXMediaCurrentTimeDisplay, + IDS_AX_MEDIA_CURRENT_TIME_DISPLAY, GetMediaControls().CurrentTimeDisplay().textContent(true)))); RenderBarSegments(); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.cc index 8fcd4313b31..53cb32fb7a2 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/html/track/text_track.h" @@ -50,7 +51,7 @@ MediaControlToggleClosedCaptionsButtonElement:: : MediaControlInputElement(media_controls) { setAttribute(html_names::kAriaLabelAttr, WTF::AtomicString(GetLocale().QueryString( - WebLocalizedString::kAXMediaShowClosedCaptionsMenuButton))); + IDS_AX_MEDIA_SHOW_CLOSED_CAPTIONS_MENU_BUTTON))); setType(input_type_names::kButton); SetShadowPseudoId( AtomicString("-webkit-media-controls-toggle-closed-captions-button")); @@ -70,9 +71,8 @@ void MediaControlToggleClosedCaptionsButtonElement::UpdateDisplayType() { MediaControlInputElement::UpdateDisplayType(); } -WebLocalizedString::Name -MediaControlToggleClosedCaptionsButtonElement::GetOverflowStringName() const { - return WebLocalizedString::kOverflowMenuCaptions; +int MediaControlToggleClosedCaptionsButtonElement::GetOverflowStringId() const { + return IDS_MEDIA_OVERFLOW_MENU_CLOSED_CAPTIONS; } bool MediaControlToggleClosedCaptionsButtonElement::HasOverflowButton() const { diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.h index 470b3c2724d..e9dcf0dca96 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.h @@ -21,7 +21,7 @@ class MODULES_EXPORT MediaControlToggleClosedCaptionsButtonElement final // MediaControlInputElement overrides. bool WillRespondToMouseClickEvents() override; void UpdateDisplayType() override; - WebLocalizedString::Name GetOverflowStringName() const override; + int GetOverflowStringId() const override; bool HasOverflowButton() const override; String GetOverflowMenuSubtitleString() const override; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element_test.cc index f5c1e836784..9c3eaf1275d 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element_test.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element_test.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_toggle_closed_captions_button_element.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h" @@ -21,7 +22,7 @@ const char kEnglishLabel[] = "English"; class LocalePlatformSupport : public TestingPlatformSupport { public: WebString QueryLocalizedString(int resource_id) override { - if (resource_id == WebLocalizedString::kTextTracksOff) + if (resource_id == IDS_MEDIA_TRACKS_OFF) return kTextTracksOffString; return TestingPlatformSupport::QueryLocalizedString(resource_id); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc index 66787e645e3..cefff9b5772 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc @@ -1464,7 +1464,7 @@ void MediaControlsImpl::DefaultEventHandler(Event& event) { ResetHideMediaControlsTimer(); } - if (event.IsKeyboardEvent() && + if (event.IsKeyboardEvent() && !event.defaultPrevented() && !IsSpatialNavigationEnabled(GetDocument().GetFrame())) { const String& key = ToKeyboardEvent(event).key(); if (key == "Enter" || ToKeyboardEvent(event).keyCode() == ' ') { @@ -1905,6 +1905,9 @@ void MediaControlsImpl::NotifyElementSizeChanged(DOMRectReadOnly* new_size) { } void MediaControlsImpl::ElementSizeChangedTimerFired(TimerBase*) { + if (!MediaElement().isConnected()) + return; + ComputeWhichControlsFit(); // Rerender timeline bar segments when size changed. diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h index 5134c7cfac1..eb976bb28cf 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.h @@ -116,7 +116,6 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement, // There is no update because only the overlay is expected to change. RefreshCastButtonVisibilityWithoutUpdate(); } - void ShowContextMenu() override {} // Called by the fullscreen buttons to toggle fulllscreen on/off. void EnterFullscreen(); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc index e691c1b3b62..45a2ca0ce22 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc @@ -62,10 +62,10 @@ namespace blink { namespace { -class MockChromeClientForImpl : public EmptyChromeClient { +class FakeChromeClient : public EmptyChromeClient { public: - // EmptyChromeClient overrides: - WebScreenInfo GetScreenInfo() const override { + // ChromeClient overrides. + WebScreenInfo GetScreenInfo(LocalFrame&) const override { WebScreenInfo screen_info; screen_info.orientation_type = kWebScreenOrientationLandscapePrimary; return screen_info; @@ -171,7 +171,7 @@ class MediaControlsImplTest : public PageTestBase, void InitializePage() { Page::PageClients clients; FillWithEmptyClients(clients); - clients.chrome_client = MakeGarbageCollected<MockChromeClientForImpl>(); + clients.chrome_client = MakeGarbageCollected<FakeChromeClient>(); SetupPageWithClients(&clients, MakeGarbageCollected<StubLocalFrameClientForImpl>()); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc index a3ad5315f4a..f2b7505d7b2 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.cc @@ -293,11 +293,12 @@ MediaControlsOrientationLockDelegate::ComputeOrientationLock() const { // consistency. Use WebScreenOrientationLockLandscape as a fallback value. // TODO(mlamouri): we could improve this by having direct access to // `window.screen.orientation.type`. - Frame* frame = GetDocument().GetFrame(); + LocalFrame* frame = GetDocument().GetFrame(); if (!frame) return kWebScreenOrientationLockLandscape; - switch (frame->GetChromeClient().GetScreenInfo().orientation_type) { + ChromeClient& chrome_client = frame->GetChromeClient(); + switch (chrome_client.GetScreenInfo(*frame).orientation_type) { case kWebScreenOrientationPortraitPrimary: case kWebScreenOrientationPortraitSecondary: return kWebScreenOrientationLockPortrait; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc index 4e5c0360f2b..42327ab4dcc 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate_test.cc @@ -131,7 +131,7 @@ class MockChromeClientForOrientationLockDelegate final WTF::Bind(DidExitFullscreen, WrapPersistent(frame.GetDocument()))); } - MOCK_CONST_METHOD0(GetScreenInfo, WebScreenInfo()); + MOCK_CONST_METHOD1(GetScreenInfo, WebScreenInfo(LocalFrame&)); MockScreenOrientation& ScreenOrientationClient() { return mock_screen_orientation_; @@ -373,7 +373,7 @@ class MediaControlsOrientationLockAndRotateToFullscreenDelegateTest screen_info.rect, screen_info.orientation_angle)); testing::Mock::VerifyAndClearExpectations(&ChromeClient()); - EXPECT_CALL(ChromeClient(), GetScreenInfo()) + EXPECT_CALL(ChromeClient(), GetScreenInfo(_)) .Times(AtLeast(1)) .WillRepeatedly(Return(screen_info)); @@ -589,31 +589,31 @@ TEST_F(MediaControlsOrientationLockDelegateTest, ComputeOrientationLock) { // 100x100 has more subtilities, it depends on the current screen orientation. WebScreenInfo screen_info; screen_info.orientation_type = kWebScreenOrientationUndefined; - EXPECT_CALL(ChromeClient(), GetScreenInfo()) + EXPECT_CALL(ChromeClient(), GetScreenInfo(_)) .Times(1) .WillOnce(Return(screen_info)); EXPECT_EQ(kWebScreenOrientationLockLandscape, ComputeOrientationLock()); screen_info.orientation_type = kWebScreenOrientationPortraitPrimary; - EXPECT_CALL(ChromeClient(), GetScreenInfo()) + EXPECT_CALL(ChromeClient(), GetScreenInfo(_)) .Times(1) .WillOnce(Return(screen_info)); EXPECT_EQ(kWebScreenOrientationLockPortrait, ComputeOrientationLock()); screen_info.orientation_type = kWebScreenOrientationPortraitPrimary; - EXPECT_CALL(ChromeClient(), GetScreenInfo()) + EXPECT_CALL(ChromeClient(), GetScreenInfo(_)) .Times(1) .WillOnce(Return(screen_info)); EXPECT_EQ(kWebScreenOrientationLockPortrait, ComputeOrientationLock()); screen_info.orientation_type = kWebScreenOrientationLandscapePrimary; - EXPECT_CALL(ChromeClient(), GetScreenInfo()) + EXPECT_CALL(ChromeClient(), GetScreenInfo(_)) .Times(1) .WillOnce(Return(screen_info)); EXPECT_EQ(kWebScreenOrientationLockLandscape, ComputeOrientationLock()); screen_info.orientation_type = kWebScreenOrientationLandscapeSecondary; - EXPECT_CALL(ChromeClient(), GetScreenInfo()) + EXPECT_CALL(ChromeClient(), GetScreenInfo(_)) .Times(1) .WillOnce(Return(screen_info)); EXPECT_EQ(kWebScreenOrientationLockLandscape, ComputeOrientationLock()); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc index bb12a4a6de6..6188026fdb4 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.cc @@ -270,11 +270,11 @@ MediaControlsRotateToFullscreenDelegate::ComputeVideoOrientation() const { MediaControlsRotateToFullscreenDelegate::SimpleOrientation MediaControlsRotateToFullscreenDelegate::ComputeScreenOrientation() const { - Frame* frame = video_element_->GetDocument().GetFrame(); + LocalFrame* frame = video_element_->GetDocument().GetFrame(); if (!frame) return SimpleOrientation::kUnknown; - switch (frame->GetChromeClient().GetScreenInfo().orientation_type) { + switch (frame->GetChromeClient().GetScreenInfo(*frame).orientation_type) { case kWebScreenOrientationPortraitPrimary: case kWebScreenOrientationPortraitSecondary: return SimpleOrientation::kPortrait; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc index cfe9298a224..260cd09f21c 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate_test.cc @@ -34,13 +34,12 @@ #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" +using testing::_; using testing::AtLeast; using testing::Return; namespace blink { -using namespace html_names; - namespace { class MockVideoWebMediaPlayer : public EmptyWebMediaPlayer { @@ -72,7 +71,7 @@ class MockChromeClient : public EmptyChromeClient { Fullscreen::DidExitFullscreen(*frame.GetDocument()); } - MOCK_CONST_METHOD0(GetScreenInfo, WebScreenInfo()); + MOCK_CONST_METHOD1(GetScreenInfo, WebScreenInfo(LocalFrame&)); }; class StubLocalFrameClient : public EmptyLocalFrameClient { @@ -110,7 +109,7 @@ class MediaControlsRotateToFullscreenDelegateTest SetupPageWithClients(&clients, MakeGarbageCollected<StubLocalFrameClient>()); video_ = MakeGarbageCollected<HTMLVideoElement>(GetDocument()); - GetVideo().setAttribute(kControlsAttr, g_empty_atom); + GetVideo().setAttribute(html_names::kControlsAttr, g_empty_atom); // Most tests should call GetDocument().body()->AppendChild(&GetVideo()); // This is not done automatically, so that tests control timing of `Attach`. } @@ -147,7 +146,7 @@ class MediaControlsRotateToFullscreenDelegateTest // If scripts are not enabled, controls will always be shown. GetFrame().GetSettings()->SetScriptEnabled(true); - GetVideo().removeAttribute(kControlsAttr); + GetVideo().removeAttribute(html_names::kControlsAttr); } void DispatchEvent(EventTarget& target, const AtomicString& type) { @@ -191,7 +190,7 @@ void MediaControlsRotateToFullscreenDelegateTest::InitScreenAndVideo( // Set initial screen orientation (called by `Attach` during `AppendChild`). WebScreenInfo screen_info; screen_info.orientation_type = initial_screen_orientation; - EXPECT_CALL(GetChromeClient(), GetScreenInfo()) + EXPECT_CALL(GetChromeClient(), GetScreenInfo(_)) .Times(AtLeast(1)) .WillRepeatedly(Return(screen_info)); @@ -232,7 +231,7 @@ void MediaControlsRotateToFullscreenDelegateTest::RotateTo( WebScreenInfo screen_info; screen_info.orientation_type = new_screen_orientation; testing::Mock::VerifyAndClearExpectations(&GetChromeClient()); - EXPECT_CALL(GetChromeClient(), GetScreenInfo()) + EXPECT_CALL(GetChromeClient(), GetScreenInfo(_)) .Times(AtLeast(1)) .WillRepeatedly(Return(screen_info)); DispatchEvent(GetWindow(), event_type_names::kOrientationchange); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.cc index 4f986eb3a1c..40978603e6c 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/html/track/text_track.h" #include "third_party/blink/renderer/core/html/track/text_track_list.h" @@ -18,8 +19,7 @@ MediaControlsTextTrackManager::MediaControlsTextTrackManager( String MediaControlsTextTrackManager::GetTextTrackLabel( TextTrack* track) const { if (!track) { - return media_element_->GetLocale().QueryString( - WebLocalizedString::kTextTracksOff); + return media_element_->GetLocale().QueryString(IDS_MEDIA_TRACKS_OFF); } String track_label = track->label(); @@ -29,8 +29,7 @@ String MediaControlsTextTrackManager::GetTextTrackLabel( if (track_label.IsEmpty()) { track_label = String(media_element_->GetLocale().QueryString( - WebLocalizedString::kTextTracksNoLabel, - String::Number(track->TrackIndex() + 1))); + IDS_MEDIA_TRACKS_NO_LABEL, String::Number(track->TrackIndex() + 1))); } return track_label; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css b/chromium/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css index 6cb8ca304cc..fdf46239953 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css +++ b/chromium/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css @@ -1312,6 +1312,32 @@ video::-internal-media-controls-scrubbing-message { display: none; } +video::-internal-media-controls-text-track-list-kind-captions { + -webkit-appearance: none; + background-image: -webkit-image-set( + url(ic_closed_caption.svg) 1x); + background-size: 32px; + background-repeat: no-repeat; + background-position: center center; + height: 20px; + width: 20px; + margin-left: 10px; + vertical-align: middle; +} + +video::-internal-media-controls-text-track-list-kind-subtitles { + -webkit-appearance: none; + background-image: -webkit-image-set( + url(ic_subtitles.svg) 1x); + background-size: 32px; + background-repeat: no-repeat; + background-position: center center; + height: 20px; + width: 20px; + margin-left: 10px; + vertical-align: middle; +} + /** * VR styling. */ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc deleted file mode 100644 index 4359bbc3167..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc +++ /dev/null @@ -1,79 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h" - -#include "third_party/blink/renderer/core/css/properties/css_property.h" -#include "third_party/blink/renderer/core/css_value_keywords.h" -#include "third_party/blink/renderer/core/html/media/html_media_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h" -#include "third_party/blink/renderer/platform/wtf/functional.h" - -namespace blink { - -MediaControlsTouchlessBottomContainerElement:: - MediaControlsTouchlessBottomContainerElement( - MediaControlsTouchlessImpl& media_controls) - : MediaControlsTouchlessElement(media_controls) { - SetShadowPseudoId( - AtomicString("-internal-media-controls-touchless-bottom-container")); - - time_display_element_ = - MakeGarbageCollected<MediaControlsTouchlessTimeDisplayElement>( - media_controls); - timeline_element_ = - MakeGarbageCollected<MediaControlsTouchlessTimelineElement>( - media_controls); - - ParserAppendChild(time_display_element_); - ParserAppendChild(timeline_element_); - - event_listener_ = - MakeGarbageCollected<MediaControlsSharedHelpers::TransitionEventListener>( - this, - WTF::BindRepeating(&MediaControlsTouchlessBottomContainerElement:: - HandleTransitionEndEvent, - WrapWeakPersistent(this))); - event_listener_->Attach(); -} - -LayoutObject* -MediaControlsTouchlessBottomContainerElement::TimelineLayoutObject() { - return timeline_element_->GetLayoutObject(); -} - -LayoutObject* -MediaControlsTouchlessBottomContainerElement::TimeDisplayLayoutObject() { - return time_display_element_->GetLayoutObject(); -} - -void MediaControlsTouchlessBottomContainerElement::MakeOpaque( - bool should_hide) { - SetDisplayed(true); - MediaElement().MediaControlsDidBecomeVisible(); - MediaControlsTouchlessElement::MakeOpaque(should_hide); -} - -void MediaControlsTouchlessBottomContainerElement::HandleTransitionEndEvent() { - SetDisplayed(false); -} - -void MediaControlsTouchlessBottomContainerElement::SetDisplayed( - bool displayed) { - if (displayed) - RemoveInlineStyleProperty(CSSPropertyID::kDisplay); - else - SetInlineStyleProperty(CSSPropertyID::kDisplay, CSSValueID::kNone); -} - -void MediaControlsTouchlessBottomContainerElement::Trace( - blink::Visitor* visitor) { - visitor->Trace(timeline_element_); - visitor->Trace(time_display_element_); - visitor->Trace(event_listener_); - MediaControlsTouchlessElement::Trace(visitor); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h deleted file mode 100644 index e23acc51a24..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h +++ /dev/null @@ -1,39 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_BOTTOM_CONTAINER_ELEMENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_BOTTOM_CONTAINER_ELEMENT_H_ - -#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h" - -namespace blink { - -class MediaControlsTouchlessImpl; -class MediaControlsTouchlessTimelineElement; -class MediaControlsTouchlessTimeDisplayElement; -class LayoutObject; - -class MediaControlsTouchlessBottomContainerElement - : public MediaControlsTouchlessElement { - public: - MediaControlsTouchlessBottomContainerElement(MediaControlsTouchlessImpl&); - LayoutObject* TimelineLayoutObject(); - LayoutObject* TimeDisplayLayoutObject(); - - void MakeOpaque(bool); - void Trace(blink::Visitor*) override; - - private: - void HandleTransitionEndEvent(); - void SetDisplayed(bool); - - Member<MediaControlsTouchlessTimelineElement> timeline_element_; - Member<MediaControlsTouchlessTimeDisplayElement> time_display_element_; - Member<MediaControlsSharedHelpers::TransitionEventListener> event_listener_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_BOTTOM_CONTAINER_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc deleted file mode 100644 index 063c3038669..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc +++ /dev/null @@ -1,81 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h" - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/dom_token_list.h" -#include "third_party/blink/renderer/core/html/media/html_media_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.h" - -namespace blink { - -namespace { - -// Amount of time that media controls are visible. -constexpr base::TimeDelta kTimeToHideControl = - base::TimeDelta::FromMilliseconds(3000); - -const char kTransparentCSSClass[] = "transparent"; -const char kTransparentImmediateCSSClass[] = "transparent-immediate"; - -} // namespace - -MediaControlsTouchlessElement::MediaControlsTouchlessElement( - MediaControlsTouchlessImpl& media_controls) - : HTMLDivElement(media_controls.GetDocument()), - media_controls_(media_controls) { - media_controls_->MediaEventListener().AddObserver(this); -} - -HTMLMediaElement& MediaControlsTouchlessElement::MediaElement() const { - return media_controls_->MediaElement(); -} - -void MediaControlsTouchlessElement::MakeOpaque(bool should_hide) { - EnsureHideControlTimer(); - - removeAttribute("class"); - - if (hide_control_timer_->IsActive()) - StopHideControlTimer(); - - if (should_hide) - StartHideControlTimer(); -} - -void MediaControlsTouchlessElement::MakeTransparent(bool hide_immediate) { - classList().Add(hide_immediate ? kTransparentImmediateCSSClass - : kTransparentCSSClass); -} - -void MediaControlsTouchlessElement::EnsureHideControlTimer() { - if (!hide_control_timer_) { - hide_control_timer_ = - std::make_unique<TaskRunnerTimer<MediaControlsTouchlessElement>>( - MediaElement().GetDocument().GetTaskRunner( - TaskType::kInternalMedia), - this, &MediaControlsTouchlessElement::HideControlTimerFired); - } -} - -void MediaControlsTouchlessElement::HideControlTimerFired(TimerBase*) { - MakeTransparent(); -} - -void MediaControlsTouchlessElement::StartHideControlTimer() { - hide_control_timer_->StartOneShot(kTimeToHideControl, FROM_HERE); -} - -void MediaControlsTouchlessElement::StopHideControlTimer() { - hide_control_timer_->Stop(); -} - -void MediaControlsTouchlessElement::Trace(blink::Visitor* visitor) { - HTMLDivElement::Trace(visitor); - visitor->Trace(media_controls_); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h deleted file mode 100644 index f5463bbf466..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h +++ /dev/null @@ -1,67 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_ELEMENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_ELEMENT_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/core/html/html_div_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h" -#include "third_party/blink/renderer/platform/heap/member.h" -#include "third_party/blink/renderer/platform/timer.h" - -namespace blink { - -class HTMLMediaElement; -class MediaControlsTouchlessImpl; - -class MediaControlsTouchlessElement - : public HTMLDivElement, - public MediaControlsTouchlessMediaEventListenerObserver { - USING_GARBAGE_COLLECTED_MIXIN(MediaControlsTouchlessElement); - - public: - HTMLMediaElement& MediaElement() const; - - void Trace(blink::Visitor* visitor) override; - - void MakeOpaque(bool /** True if control should hide after timer fired */); - void MakeTransparent(bool = false /** True if hide immediately */); - - // Non-touch media event listener observer implementation. - void OnFocusIn() override {} - void OnTimeUpdate() override {} - void OnDurationChange() override {} - void OnSeeking() override {} - void OnLoadingProgress() override {} - void OnPlay() override {} - void OnPause() override {} - void OnEnterFullscreen() override {} - void OnExitFullscreen() override {} - void OnError() override {} - void OnLoadedMetadata() override {} - void OnKeyPress(KeyboardEvent* event) override {} - void OnKeyDown(KeyboardEvent* event) override {} - void OnKeyUp(KeyboardEvent* event) override {} - - protected: - MediaControlsTouchlessElement(MediaControlsTouchlessImpl& media_controls); - - private: - void EnsureHideControlTimer(); - void HideControlTimerFired(TimerBase*); - void StartHideControlTimer(); - void StopHideControlTimer(); - - Member<MediaControlsTouchlessImpl> media_controls_; - - std::unique_ptr<TaskRunnerTimer<MediaControlsTouchlessElement>> - hide_control_timer_; - - DISALLOW_COPY_AND_ASSIGN(MediaControlsTouchlessElement); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc deleted file mode 100644 index 7ae6f420ca5..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc +++ /dev/null @@ -1,61 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.h" - -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" -#include "third_party/blink/renderer/platform/text/platform_locale.h" -#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" - -namespace blink { - -MediaControlsTouchlessOverlayElement::MediaControlsTouchlessOverlayElement( - MediaControlsTouchlessImpl& media_controls) - : MediaControlsTouchlessElement(media_controls) { - SetShadowPseudoId(AtomicString("-internal-media-controls-touchless-overlay")); - - MediaControlsTouchlessPlayButtonElement* play_button = - MakeGarbageCollected<MediaControlsTouchlessPlayButtonElement>( - media_controls); - - MediaControlsTouchlessVolumeButtonElement* volume_up_button = - MakeGarbageCollected<MediaControlsTouchlessVolumeButtonElement>( - media_controls, true); - MediaControlsTouchlessVolumeButtonElement* volume_down_button = - MakeGarbageCollected<MediaControlsTouchlessVolumeButtonElement>( - media_controls, false); - - MediaControlsTouchlessSeekButtonElement* seek_forward_button = - MakeGarbageCollected<MediaControlsTouchlessSeekButtonElement>( - media_controls, true); - MediaControlsTouchlessSeekButtonElement* seek_backward_button = - MakeGarbageCollected<MediaControlsTouchlessSeekButtonElement>( - media_controls, false); - - ParserAppendChild(volume_up_button); - ParserAppendChild(seek_backward_button); - ParserAppendChild(play_button); - ParserAppendChild(seek_forward_button); - ParserAppendChild(volume_down_button); - - StringBuilder aria_label; - aria_label.Append(GetLocale().QueryString( - WebLocalizedString::kAXMediaTouchLessPlayPauseAction)); - aria_label.Append(" "); - aria_label.Append( - GetLocale().QueryString(WebLocalizedString::kAXMediaTouchLessSeekAction)); - aria_label.Append(" "); - aria_label.Append(GetLocale().QueryString( - WebLocalizedString::kAXMediaTouchLessVolumeAction)); - setAttribute(html_names::kAriaLabelAttr, aria_label.ToAtomicString()); -} - -void MediaControlsTouchlessOverlayElement::Trace(blink::Visitor* visitor) { - MediaControlsTouchlessElement::Trace(visitor); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.h deleted file mode 100644 index 6c384537362..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.h +++ /dev/null @@ -1,24 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_OVERLAY_ELEMENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_OVERLAY_ELEMENT_H_ - -#include "third_party/blink/renderer/core/html/html_div_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h" - -namespace blink { - -class MediaControlsTouchlessImpl; - -class MediaControlsTouchlessOverlayElement - : public MediaControlsTouchlessElement { - public: - MediaControlsTouchlessOverlayElement(MediaControlsTouchlessImpl&); - void Trace(blink::Visitor*) override; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_OVERLAY_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.cc deleted file mode 100644 index ed9724358c7..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.cc +++ /dev/null @@ -1,42 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.h" - -#include "third_party/blink/renderer/core/dom/dom_token_list.h" -#include "third_party/blink/renderer/core/html/media/html_media_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" - -namespace blink { - -namespace { - -const char kPlayingCSSClass[] = "playing"; -const char kPausedCSSClass[] = "paused"; - -} // namespace - -MediaControlsTouchlessPlayButtonElement:: - MediaControlsTouchlessPlayButtonElement( - MediaControlsTouchlessImpl& controls) - : MediaControlsTouchlessElement(controls) { - SetShadowPseudoId( - AtomicString("-internal-media-controls-touchless-play-button")); - - controls.MediaElement().paused() ? OnPause() : OnPlay(); -} - -void MediaControlsTouchlessPlayButtonElement::OnPlay() { - classList().setValue(kPlayingCSSClass); -} - -void MediaControlsTouchlessPlayButtonElement::OnPause() { - classList().setValue(kPausedCSSClass); -} - -void MediaControlsTouchlessPlayButtonElement::Trace(blink::Visitor* visitor) { - MediaControlsTouchlessElement::Trace(visitor); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.h deleted file mode 100644 index 46eb44fdadc..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.h +++ /dev/null @@ -1,27 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_PLAY_BUTTON_ELEMENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_PLAY_BUTTON_ELEMENT_H_ - -#include "third_party/blink/renderer/core/html/html_div_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h" - -namespace blink { - -class MediaControlsTouchlessPlayButtonElement - : public MediaControlsTouchlessElement { - public: - MediaControlsTouchlessPlayButtonElement(MediaControlsTouchlessImpl&); - - // MediaControlsTouchlessMediaEventListenerObserver implementation. - void OnPlay() override; - void OnPause() override; - - void Trace(blink::Visitor*) override; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_PLAY_BUTTON_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.cc deleted file mode 100644 index 4d778ebbee5..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.cc +++ /dev/null @@ -1,25 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.h" - -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" - -namespace blink { - -MediaControlsTouchlessSeekButtonElement:: - MediaControlsTouchlessSeekButtonElement( - MediaControlsTouchlessImpl& controls, - bool forward) - : MediaControlsTouchlessElement(controls) { - SetShadowPseudoId(AtomicString( - forward ? "-internal-media-controls-touchless-seek-forward-button" - : "-internal-media-controls-touchless-seek-backward-button")); -} - -void MediaControlsTouchlessSeekButtonElement::Trace(blink::Visitor* visitor) { - MediaControlsTouchlessElement::Trace(visitor); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.h deleted file mode 100644 index fa0acbf3853..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.h +++ /dev/null @@ -1,24 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_SEEK_BUTTON_ELEMENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_SEEK_BUTTON_ELEMENT_H_ - -#include "third_party/blink/renderer/core/html/html_div_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h" - -namespace blink { - -class MediaControlsTouchlessSeekButtonElement - : public MediaControlsTouchlessElement { - public: - MediaControlsTouchlessSeekButtonElement( - MediaControlsTouchlessImpl&, - bool /** True if it is a seek forward button, false otherwise. */); - void Trace(blink::Visitor*) override; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_SEEK_BUTTON_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc deleted file mode 100644 index 5c6db6bfa01..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc +++ /dev/null @@ -1,63 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h" - -#include "third_party/blink/renderer/core/html/media/html_media_element.h" -#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" -#include "third_party/blink/renderer/platform/text/platform_locale.h" -#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" - -namespace blink { - -MediaControlsTouchlessTimeDisplayElement:: - MediaControlsTouchlessTimeDisplayElement( - MediaControlsTouchlessImpl& media_controls) - : MediaControlsTouchlessElement(media_controls), - current_time_(0.0), - duration_(0.0) { - SetShadowPseudoId( - AtomicString("-internal-media-controls-touchless-time-display")); - UpdateTimeDisplay(); -} - -void MediaControlsTouchlessTimeDisplayElement::OnTimeUpdate() { - current_time_ = MediaElement().currentTime(); - UpdateTimeDisplay(); -} - -void MediaControlsTouchlessTimeDisplayElement::OnSeeking() { - current_time_ = MediaElement().currentTime(); - UpdateTimeDisplay(); -} - -void MediaControlsTouchlessTimeDisplayElement::OnDurationChange() { - duration_ = MediaElement().duration(); - UpdateTimeDisplay(); -} - -void MediaControlsTouchlessTimeDisplayElement::Trace(blink::Visitor* visitor) { - MediaControlsTouchlessElement::Trace(visitor); -} - -void MediaControlsTouchlessTimeDisplayElement::UpdateTimeDisplay() { - StringBuilder builder; - builder.Append(MediaControlsSharedHelpers::FormatTime(current_time_)); - builder.Append(" / "); - builder.Append(MediaControlsSharedHelpers::FormatTime(duration_)); - setInnerText(builder.ToAtomicString(), ASSERT_NO_EXCEPTION); - - StringBuilder aria_label; - aria_label.Append(GetLocale().QueryString( - WebLocalizedString::kAXMediaCurrentTimeDisplay, - MediaControlsSharedHelpers::FormatTime(current_time_))); - aria_label.Append(" "); - aria_label.Append(GetLocale().QueryString( - WebLocalizedString::kAXMediaTimeRemainingDisplay, - MediaControlsSharedHelpers::FormatTime(duration_))); - setAttribute(html_names::kAriaLabelAttr, aria_label.ToAtomicString()); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h deleted file mode 100644 index 0134b091c4c..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h +++ /dev/null @@ -1,35 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_TIME_DISPLAY_ELEMENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_TIME_DISPLAY_ELEMENT_H_ - -#include "third_party/blink/renderer/core/html/html_div_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h" - -namespace blink { - -class MediaControlsTouchlessTimeDisplayElement - : public MediaControlsTouchlessElement { - public: - explicit MediaControlsTouchlessTimeDisplayElement( - MediaControlsTouchlessImpl&); - - // MediaControlsTouchlessMediaEventListenerObserver overrides - void OnTimeUpdate() override; - void OnSeeking() override; - void OnDurationChange() override; - - void Trace(blink::Visitor* visitor) override; - - private: - void UpdateTimeDisplay(); - - double current_time_; - double duration_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_TIME_DISPLAY_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc deleted file mode 100644 index 413ae227057..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc +++ /dev/null @@ -1,98 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h" - -#include "third_party/blink/renderer/core/html/media/html_media_element.h" -#include "third_party/blink/renderer/core/html/time_ranges.h" -#include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h" -#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" -#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" - -namespace blink { - -MediaControlsTouchlessTimelineElement::MediaControlsTouchlessTimelineElement( - MediaControlsTouchlessImpl& media_controls) - : MediaControlsTouchlessElement(media_controls) { - SetShadowPseudoId( - AtomicString("-internal-media-controls-touchless-timeline")); - - loaded_bar_ = MediaControlElementsHelper::CreateDiv( - "-internal-media-controls-touchless-timeline-loaded", this); - progress_bar_ = MediaControlElementsHelper::CreateDiv( - "-internal-media-controls-touchless-timeline-progress", loaded_bar_); -} - -void MediaControlsTouchlessTimelineElement::OnLoadingProgress() { - UpdateBarsCSS(); -} - -void MediaControlsTouchlessTimelineElement::OnTimeUpdate() { - current_time_ = MediaElement().currentTime(); - UpdateBars(); -} - -void MediaControlsTouchlessTimelineElement::OnSeeking() { - current_time_ = MediaElement().currentTime(); - UpdateBars(); -} - -void MediaControlsTouchlessTimelineElement::OnDurationChange() { - duration_ = MediaElement().duration(); - UpdateBars(); -} - -void MediaControlsTouchlessTimelineElement::UpdateBars() { - if (std::isnan(duration_) || std::isinf(duration_) || !duration_ || - std::isnan(current_time_)) { - progress_percent_ = 0; - loaded_percent_ = 0; - UpdateBarsCSS(); - return; - } - - progress_percent_ = current_time_ / duration_; - loaded_percent_ = progress_percent_; - - base::Optional<unsigned> current_buffered_time_range = - MediaControlsSharedHelpers::GetCurrentBufferedTimeRange(MediaElement()); - if (current_buffered_time_range) { - TimeRanges* buffered_time_ranges = MediaElement().buffered(); - float end = buffered_time_ranges->end(current_buffered_time_range.value(), - ASSERT_NO_EXCEPTION); - loaded_percent_ = end / duration_; - } - - UpdateBarsCSS(); -} - -void MediaControlsTouchlessTimelineElement::UpdateBarsCSS() { - SetBarWidth(loaded_bar_, loaded_percent_); - - // Since progress bar is a child of loaded bar, we need to calculate - // the percentage accordingly. - double adjusted_width_percent = 0; - if (loaded_percent_ != 0) - adjusted_width_percent = progress_percent_ / loaded_percent_; - - SetBarWidth(progress_bar_, adjusted_width_percent); -} - -void MediaControlsTouchlessTimelineElement::SetBarWidth(HTMLDivElement* bar, - double percent) { - StringBuilder builder; - builder.Append("width:"); - builder.AppendNumber(percent * 100); - builder.Append("%"); - bar->setAttribute("style", builder.ToAtomicString()); -} - -void MediaControlsTouchlessTimelineElement::Trace(blink::Visitor* visitor) { - visitor->Trace(loaded_bar_); - visitor->Trace(progress_bar_); - MediaControlsTouchlessElement::Trace(visitor); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h deleted file mode 100644 index c8a17e7ac55..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h +++ /dev/null @@ -1,45 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_TIMELINE_ELEMENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_TIMELINE_ELEMENT_H_ - -#include "third_party/blink/renderer/core/html/html_div_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h" - -namespace blink { - -class MediaControlsTouchlessTimelineElement - : public MediaControlsTouchlessElement { - public: - explicit MediaControlsTouchlessTimelineElement(MediaControlsTouchlessImpl&); - - // MediaControlsTouchlessMediaEventListenerObserver overrides - void OnTimeUpdate() override; - void OnSeeking() override; - void OnDurationChange() override; - void OnLoadingProgress() override; - - void Trace(blink::Visitor*) override; - - private: - void SetBarWidth(HTMLDivElement* bar, double percent); - - void UpdateBars(); - void UpdateBarsCSS(); - - Member<HTMLDivElement> loaded_bar_; - Member<HTMLDivElement> progress_bar_; - double current_time_; - double duration_; - - // Used for setting the width of the progress and loaded bars. This is - // a percentage of the duration of the media. - double progress_percent_; - double loaded_percent_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_TIMELINE_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.cc deleted file mode 100644 index b8c660b8b57..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.cc +++ /dev/null @@ -1,25 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.h" - -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" - -namespace blink { - -MediaControlsTouchlessVolumeButtonElement:: - MediaControlsTouchlessVolumeButtonElement( - MediaControlsTouchlessImpl& controls, - bool up) - : MediaControlsTouchlessElement(controls) { - SetShadowPseudoId(AtomicString( - up ? "-internal-media-controls-touchless-volume-up-button" - : "-internal-media-controls-touchless-volume-down-button")); -} - -void MediaControlsTouchlessVolumeButtonElement::Trace(blink::Visitor* visitor) { - MediaControlsTouchlessElement::Trace(visitor); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.h deleted file mode 100644 index ad7ae783e4a..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.h +++ /dev/null @@ -1,24 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_VOLUME_BUTTON_ELEMENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_VOLUME_BUTTON_ELEMENT_H_ - -#include "third_party/blink/renderer/core/html/html_div_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h" - -namespace blink { - -class MediaControlsTouchlessVolumeButtonElement - : public MediaControlsTouchlessElement { - public: - MediaControlsTouchlessVolumeButtonElement( - MediaControlsTouchlessImpl&, - bool /** True if it is a volume up button, false otherwise. */); - void Trace(blink::Visitor*) override; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_VOLUME_BUTTON_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_container_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_container_element.cc deleted file mode 100644 index 9e38e007d85..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_container_element.cc +++ /dev/null @@ -1,63 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_container_element.h" - -#include "third_party/blink/renderer/core/dom/dom_token_list.h" -#include "third_party/blink/renderer/core/html/media/html_media_element.h" -#include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h" -#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" - -namespace blink { - -namespace { - -const char kMutedCSSClass[] = "muted"; - -} // namespace - -MediaControlsTouchlessVolumeContainerElement:: - MediaControlsTouchlessVolumeContainerElement( - MediaControlsTouchlessImpl& media_controls) - : MediaControlsTouchlessElement(media_controls) { - SetShadowPseudoId( - AtomicString("-internal-media-controls-touchless-volume-container")); - - Element* volume_bar_background = MediaControlElementsHelper::CreateDiv( - "-internal-media-controls-touchless-volume-bar-background", this); - volume_bar_ = MediaControlElementsHelper::CreateDiv( - "-internal-media-controls-touchless-volume-bar", volume_bar_background); - volume_icon_ = MediaControlElementsHelper::CreateDiv( - "-internal-media-controls-touchless-volume-icon", this); -} - -void MediaControlsTouchlessVolumeContainerElement::UpdateVolume() { - volume_ = MediaElement().volume(); - UpdateCSSClass(); - UpdateVolumeBarCSS(); -} - -void MediaControlsTouchlessVolumeContainerElement::UpdateCSSClass() { - if (volume_ > 0) - volume_icon_->classList().Remove(kMutedCSSClass); - else - volume_icon_->classList().Add(kMutedCSSClass); -} - -void MediaControlsTouchlessVolumeContainerElement::UpdateVolumeBarCSS() { - StringBuilder builder; - builder.Append("height:"); - builder.AppendNumber(volume_ * 100); - builder.Append("%"); - volume_bar_->setAttribute("style", builder.ToAtomicString()); -} - -void MediaControlsTouchlessVolumeContainerElement::Trace( - blink::Visitor* visitor) { - visitor->Trace(volume_bar_); - visitor->Trace(volume_icon_); - MediaControlsTouchlessElement::Trace(visitor); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_container_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_container_element.h deleted file mode 100644 index 2b704c0ea76..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_container_element.h +++ /dev/null @@ -1,32 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_VOLUME_CONTAINER_ELEMENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_VOLUME_CONTAINER_ELEMENT_H_ - -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h" - -namespace blink { - -class MediaControlsTouchlessVolumeContainerElement - : public MediaControlsTouchlessElement { - public: - explicit MediaControlsTouchlessVolumeContainerElement( - MediaControlsTouchlessImpl&); - void UpdateVolume(); - - void Trace(blink::Visitor*) override; - - private: - void UpdateCSSClass(); - void UpdateVolumeBarCSS(); - - Member<HTMLDivElement> volume_bar_; - Member<HTMLDivElement> volume_icon_; - double volume_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_VOLUME_CONTAINER_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc deleted file mode 100644 index 7adcbc6709e..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc +++ /dev/null @@ -1,541 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" - -#include <algorithm> - -#include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/public/platform/task_type.h" -#include "third_party/blink/public/platform/web_screen_info.h" -#include "third_party/blink/renderer/core/css/properties/css_property.h" -#include "third_party/blink/renderer/core/css_value_keywords.h" -#include "third_party/blink/renderer/core/dom/dom_token_list.h" -#include "third_party/blink/renderer/core/dom/events/event.h" -#include "third_party/blink/renderer/core/dom/shadow_root.h" -#include "third_party/blink/renderer/core/events/keyboard_event.h" -#include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/core/frame/local_frame_client.h" -#include "third_party/blink/renderer/core/fullscreen/fullscreen.h" -#include "third_party/blink/renderer/core/html/media/html_media_element.h" -#include "third_party/blink/renderer/core/html/media/html_video_element.h" -#include "third_party/blink/renderer/core/html/track/text_track.h" -#include "third_party/blink/renderer/core/html/track/text_track_list.h" -#include "third_party/blink/renderer/core/page/chrome_client.h" -#include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h" -#include "third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h" -#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h" -#include "third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_container_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_resource_loader.h" -#include "third_party/blink/renderer/platform/keyboard_codes.h" -#include "third_party/blink/renderer/platform/wtf/functional.h" - -namespace blink { - -namespace { - -// When specified as trackIndex, disable text tracks. -constexpr int kTrackIndexOffValue = -1; - -// Number of seconds to jump when press left/right arrow. -constexpr int kNumberOfSecondsToJumpForTouchless = 10; - -// Amount of volume to change when press up/down arrow. -constexpr double kVolumeToChangeForTouchless = 0.05; - -const char kInlineCSSClass[] = "inline"; - -const char kNoSourceCSSClass[] = "state-no-source"; - -const char kUseDefaultPosterCSSClass[] = "use-default-poster"; - -} // namespace - -enum class MediaControlsTouchlessImpl::ArrowDirection { - kUp, - kDown, - kLeft, - kRight, -}; - -enum class MediaControlsTouchlessImpl::ControlsState { - kNoSource, - kPreReady, - kReady, -}; - -MediaControlsTouchlessImpl::MediaControlsTouchlessImpl( - HTMLMediaElement& media_element) - : HTMLDivElement(media_element.GetDocument()), - MediaControls(media_element), - overlay_(nullptr), - bottom_container_(nullptr), - media_event_listener_( - MakeGarbageCollected<MediaControlsTouchlessMediaEventListener>( - media_element)), - text_track_manager_( - MakeGarbageCollected<MediaControlsTextTrackManager>(media_element)), - orientation_lock_delegate_(nullptr) { - SetShadowPseudoId(AtomicString("-webkit-media-controls-touchless")); - media_event_listener_->AddObserver(this); -} - -MediaControlsTouchlessImpl* MediaControlsTouchlessImpl::Create( - HTMLMediaElement& media_element, - ShadowRoot& shadow_root) { - MediaControlsTouchlessImpl* controls = - MakeGarbageCollected<MediaControlsTouchlessImpl>(media_element); - controls->bottom_container_ = - MakeGarbageCollected<MediaControlsTouchlessBottomContainerElement>( - *controls); - controls->overlay_ = - MakeGarbageCollected<MediaControlsTouchlessOverlayElement>(*controls); - controls->volume_container_ = - MakeGarbageCollected<MediaControlsTouchlessVolumeContainerElement>( - *controls); - - MediaControlElementsHelper::CreateDiv( - "-internal-media-controls-touchless-info", controls); - - controls->ParserAppendChild(controls->bottom_container_); - controls->ParserAppendChild(controls->overlay_); - controls->ParserAppendChild(controls->volume_container_); - - // Controls start hidden. - if (!media_element.paused()) - controls->bottom_container_->MakeTransparent(); - controls->overlay_->MakeTransparent(); - controls->volume_container_->MakeTransparent(); - - if (RuntimeEnabledFeatures::VideoFullscreenOrientationLockEnabled() && - media_element.IsHTMLVideoElement()) { - // Initialize the orientation lock when going fullscreen feature. - controls->orientation_lock_delegate_ = - MakeGarbageCollected<MediaControlsOrientationLockDelegate>( - ToHTMLVideoElement(media_element)); - } - - MediaControlsTouchlessResourceLoader:: - InjectMediaControlsTouchlessUAStyleSheet(); - - if (!media_element.IsFullscreen()) - controls->classList().Add(kInlineCSSClass); - - controls->UpdateCSSFromState(); - - shadow_root.ParserAppendChild(controls); - return controls; -} - -Node::InsertionNotificationRequest MediaControlsTouchlessImpl::InsertedInto( - ContainerNode& root) { - media_event_listener_->Attach(); - - if (orientation_lock_delegate_) - orientation_lock_delegate_->Attach(); - - return HTMLDivElement::InsertedInto(root); -} - -void MediaControlsTouchlessImpl::RemovedFrom(ContainerNode& insertion_point) { - HTMLDivElement::RemovedFrom(insertion_point); - - Hide(); - - media_event_listener_->Detach(); - - if (orientation_lock_delegate_) - orientation_lock_delegate_->Detach(); -} - -void MediaControlsTouchlessImpl::MaybeShow() { - RemoveInlineStyleProperty(CSSPropertyID::kDisplay); -} - -void MediaControlsTouchlessImpl::Hide() { - SetInlineStyleProperty(CSSPropertyID::kDisplay, CSSValueID::kNone); -} - -void MediaControlsTouchlessImpl::NetworkStateChanged() { - UpdateCSSFromState(); -} - -LayoutObject* MediaControlsTouchlessImpl::PanelLayoutObject() { - return nullptr; -} - -LayoutObject* MediaControlsTouchlessImpl::TimelineLayoutObject() { - return bottom_container_->TimelineLayoutObject(); -} - -LayoutObject* MediaControlsTouchlessImpl::ButtonPanelLayoutObject() { - return bottom_container_->TimeDisplayLayoutObject(); -} - -LayoutObject* MediaControlsTouchlessImpl::ContainerLayoutObject() { - return GetLayoutObject(); -} - -MediaControlsTouchlessMediaEventListener& -MediaControlsTouchlessImpl::MediaEventListener() const { - return *media_event_listener_; -} - -void MediaControlsTouchlessImpl::OnFocusIn() { - if (MediaElement().ShouldShowControls()) { - bottom_container_->MakeOpaque(!MediaElement().paused()); - overlay_->MakeOpaque(true); - } -} - -void MediaControlsTouchlessImpl::OnPlay() { - bottom_container_->MakeOpaque(true); -} - -void MediaControlsTouchlessImpl::OnPause() { - bottom_container_->MakeOpaque(false); -} - -void MediaControlsTouchlessImpl::OnEnterFullscreen() { - classList().Remove(kInlineCSSClass); -} - -void MediaControlsTouchlessImpl::OnExitFullscreen() { - classList().Add(kInlineCSSClass); -} - -void MediaControlsTouchlessImpl::OnKeyDown(KeyboardEvent* event) { - if (!MediaElement().ShouldShowControls()) - return; - - bool handled = true; - switch (event->keyCode()) { - case VKEY_RETURN: - volume_container_->MakeTransparent(true); - overlay_->MakeOpaque(true); - MediaElement().TogglePlayState(); - break; - case VKEY_LEFT: - HandleOrientedArrowPress(OrientArrowPress(ArrowDirection::kLeft)); - break; - case VKEY_RIGHT: - HandleOrientedArrowPress(OrientArrowPress(ArrowDirection::kRight)); - break; - case VKEY_UP: - HandleOrientedArrowPress(OrientArrowPress(ArrowDirection::kUp)); - break; - case VKEY_DOWN: - HandleOrientedArrowPress(OrientArrowPress(ArrowDirection::kDown)); - break; - default: - handled = false; - break; - } - - if (handled) - event->SetDefaultHandled(); -} - -void MediaControlsTouchlessImpl::EnsureMediaControlsMenuHost() { - if (!media_controls_host_) { - GetDocument().GetFrame()->GetInterfaceProvider().GetInterface( - media_controls_host_.BindNewPipeAndPassReceiver( - GetExecutionContext()->GetTaskRunner( - blink::TaskType::kMediaElementEvent))); - media_controls_host_.set_disconnect_handler(WTF::Bind( - &MediaControlsTouchlessImpl::OnMediaControlsMenuHostConnectionError, - WrapWeakPersistent(this))); - } -} - -mojom::blink::VideoStatePtr MediaControlsTouchlessImpl::GetVideoState() { - mojom::blink::VideoStatePtr video_state = mojom::blink::VideoState::New(); - video_state->is_muted = MediaElement().muted(); - video_state->is_fullscreen = MediaElement().IsFullscreen(); - return video_state; -} - -WTF::Vector<mojom::blink::TextTrackMetadataPtr> -MediaControlsTouchlessImpl::GetTextTracks() { - WTF::Vector<mojom::blink::TextTrackMetadataPtr> text_tracks; - TextTrackList* track_list = MediaElement().textTracks(); - for (unsigned i = 0; i < track_list->length(); i++) { - TextTrack* track = track_list->AnonymousIndexedGetter(i); - if (!track->CanBeRendered()) - continue; - - mojom::blink::TextTrackMetadataPtr text_track( - mojom::blink::TextTrackMetadata::New()); - text_track->track_index = track->TrackIndex(); - text_track->label = text_track_manager_->GetTextTrackLabel(track); - text_tracks.push_back(std::move(text_track)); - } - - if (!text_tracks.IsEmpty()) { - mojom::blink::TextTrackMetadataPtr text_track( - mojom::blink::TextTrackMetadata::New()); - text_track->track_index = kTrackIndexOffValue; - text_track->label = text_track_manager_->GetTextTrackLabel(nullptr); - text_tracks.push_front(std::move(text_track)); - } - - return text_tracks; -} - -void MediaControlsTouchlessImpl::ShowContextMenu() { - EnsureMediaControlsMenuHost(); - - mojom::blink::VideoStatePtr video_state = GetVideoState(); - WTF::Vector<mojom::blink::TextTrackMetadataPtr> text_tracks = GetTextTracks(); - - WTF::Vector<mojom::blink::MenuItem> menu_items; - - if (MediaControlsSharedHelpers::ShouldShowFullscreenButton(MediaElement())) - menu_items.push_back(mojom::blink::MenuItem::FULLSCREEN); - - if (MediaElement().HasAudio()) - menu_items.push_back(mojom::blink::MenuItem::MUTE); - - if (MediaElement().SupportsSave()) - menu_items.push_back(mojom::blink::MenuItem::DOWNLOAD); - - if (!text_tracks.IsEmpty()) - menu_items.push_back(mojom::blink::MenuItem::CAPTIONS); - - media_controls_host_->ShowMediaMenu( - std::move(menu_items), std::move(video_state), std::move(text_tracks), - WTF::Bind(&MediaControlsTouchlessImpl::OnMediaMenuResult, - WrapWeakPersistent(this))); -} - -void MediaControlsTouchlessImpl::OnMediaMenuResult( - mojom::blink::MenuResponsePtr response) { - if (response.is_null()) - return; - - switch (response->clicked) { - case mojom::blink::MenuItem::FULLSCREEN: - if (MediaElement().IsFullscreen()) - Fullscreen::ExitFullscreen(GetDocument()); - else - Fullscreen::RequestFullscreen(MediaElement()); - break; - case mojom::blink::MenuItem::MUTE: - MediaElement().setMuted(!MediaElement().muted()); - break; - case mojom::blink::MenuItem::DOWNLOAD: - Download(); - break; - case mojom::blink::MenuItem::CAPTIONS: - text_track_manager_->DisableShowingTextTracks(); - if (response->track_index >= 0) - text_track_manager_->ShowTextTrackAtIndex(response->track_index); - break; - } -} - -void MediaControlsTouchlessImpl::Download() { - const KURL& url = MediaElement().currentSrc(); - if (url.IsNull() || url.IsEmpty()) - return; - ResourceRequest request(url); - request.SetSuggestedFilename(MediaElement().title()); - request.SetRequestContext(mojom::RequestContextType::DOWNLOAD); - request.SetRequestorOrigin(SecurityOrigin::Create(GetDocument().Url())); - GetDocument().GetFrame()->Client()->DownloadURL( - request, DownloadCrossOriginRedirects::kFollow); -} - -void MediaControlsTouchlessImpl::OnMediaControlsMenuHostConnectionError() { - media_controls_host_.reset(); -} - -MediaControlsTouchlessImpl::ArrowDirection -MediaControlsTouchlessImpl::OrientArrowPress(ArrowDirection direction) { - switch (GetOrientation()) { - case kWebScreenOrientationUndefined: - case kWebScreenOrientationPortraitPrimary: - return direction; - case kWebScreenOrientationPortraitSecondary: - switch (direction) { - case ArrowDirection::kUp: - return ArrowDirection::kDown; - case ArrowDirection::kDown: - return ArrowDirection::kUp; - case ArrowDirection::kLeft: - return ArrowDirection::kRight; - case ArrowDirection::kRight: - return ArrowDirection::kLeft; - } - case kWebScreenOrientationLandscapePrimary: - switch (direction) { - case ArrowDirection::kUp: - return ArrowDirection::kLeft; - case ArrowDirection::kDown: - return ArrowDirection::kRight; - case ArrowDirection::kLeft: - return ArrowDirection::kDown; - case ArrowDirection::kRight: - return ArrowDirection::kUp; - } - case kWebScreenOrientationLandscapeSecondary: - switch (direction) { - case ArrowDirection::kUp: - return ArrowDirection::kRight; - case ArrowDirection::kDown: - return ArrowDirection::kLeft; - case ArrowDirection::kLeft: - return ArrowDirection::kUp; - case ArrowDirection::kRight: - return ArrowDirection::kDown; - } - } -} - -void MediaControlsTouchlessImpl::HandleOrientedArrowPress( - ArrowDirection direction) { - switch (direction) { - case ArrowDirection::kUp: - HandleTopButtonPress(); - break; - case ArrowDirection::kDown: - HandleBottomButtonPress(); - break; - case ArrowDirection::kLeft: - HandleLeftButtonPress(); - break; - case ArrowDirection::kRight: - HandleRightButtonPress(); - break; - } -} - -WebScreenOrientationType MediaControlsTouchlessImpl::GetOrientation() { - LocalFrame* frame = GetDocument().GetFrame(); - if (!frame) - return kWebScreenOrientationUndefined; - - return frame->GetChromeClient().GetScreenInfo().orientation_type; -} - -void MediaControlsTouchlessImpl::HandleTopButtonPress() { - MaybeChangeVolume(kVolumeToChangeForTouchless); - volume_container_->UpdateVolume(); - overlay_->MakeTransparent(true); - volume_container_->MakeOpaque(true); -} - -void MediaControlsTouchlessImpl::HandleBottomButtonPress() { - MaybeChangeVolume(kVolumeToChangeForTouchless * -1); - volume_container_->UpdateVolume(); - overlay_->MakeTransparent(true); - volume_container_->MakeOpaque(true); -} - -void MediaControlsTouchlessImpl::HandleLeftButtonPress() { - if (!MediaElement().paused()) - bottom_container_->MakeOpaque(true); - MaybeJump(kNumberOfSecondsToJumpForTouchless * -1); -} - -void MediaControlsTouchlessImpl::HandleRightButtonPress() { - if (!MediaElement().paused()) - bottom_container_->MakeOpaque(true); - MaybeJump(kNumberOfSecondsToJumpForTouchless); -} - -void MediaControlsTouchlessImpl::MaybeChangeVolume(double volume_to_change) { - double new_volume = std::max(0.0, MediaElement().volume() + volume_to_change); - new_volume = std::min(new_volume, 1.0); - MediaElement().setVolume(new_volume); -} - -void MediaControlsTouchlessImpl::MaybeJump(int seconds) { - double new_time = std::max(0.0, MediaElement().currentTime() + seconds); - new_time = std::min(new_time, MediaElement().duration()); - MediaElement().setCurrentTime(new_time); -} - -MediaControlsTouchlessImpl::ControlsState MediaControlsTouchlessImpl::State() { - HTMLMediaElement::NetworkState network_state = - MediaElement().getNetworkState(); - HTMLMediaElement::ReadyState ready_state = MediaElement().getReadyState(); - - switch (network_state) { - case HTMLMediaElement::kNetworkEmpty: - case HTMLMediaElement::kNetworkNoSource: - return ControlsState::kNoSource; - case HTMLMediaElement::kNetworkLoading: - if (ready_state == HTMLMediaElement::kHaveNothing) - return ControlsState::kPreReady; - else - return ControlsState::kReady; - case HTMLMediaElement::kNetworkIdle: - if (ready_state == HTMLMediaElement::kHaveNothing) - return ControlsState::kPreReady; - break; - } - - return ControlsState::kReady; -} - -void MediaControlsTouchlessImpl::UpdateCSSFromState() { - ControlsState state = State(); - - if (state == ControlsState::kNoSource) - classList().Add(kNoSourceCSSClass); - else - classList().Remove(kNoSourceCSSClass); - - if (!MediaElement().IsHTMLVideoElement()) - return; - - if (MediaElement().ShouldShowControls() && - !VideoElement().HasAvailableVideoFrame() && - VideoElement().PosterImageURL().IsEmpty() && - state <= ControlsState::kPreReady) { - classList().Add(kUseDefaultPosterCSSClass); - } else { - classList().Remove(kUseDefaultPosterCSSClass); - } -} - -HTMLVideoElement& MediaControlsTouchlessImpl::VideoElement() { - DCHECK(MediaElement().IsHTMLVideoElement()); - return *ToHTMLVideoElement(&MediaElement()); -} - -void MediaControlsTouchlessImpl::OnError() { - UpdateCSSFromState(); -} - -void MediaControlsTouchlessImpl::OnLoadedMetadata() { - UpdateCSSFromState(); -} - -void MediaControlsTouchlessImpl::Trace(blink::Visitor* visitor) { - visitor->Trace(bottom_container_); - visitor->Trace(overlay_); - visitor->Trace(media_event_listener_); - visitor->Trace(text_track_manager_); - visitor->Trace(orientation_lock_delegate_); - visitor->Trace(volume_container_); - MediaControls::Trace(visitor); - HTMLDivElement::Trace(visitor); -} - -void MediaControlsTouchlessImpl::SetMediaControlsMenuHostForTesting( - mojo::PendingRemote<mojom::blink::MediaControlsMenuHost> menu_host) { - media_controls_host_.Bind(std::move(menu_host)); -} - -void MediaControlsTouchlessImpl::MenuHostFlushForTesting() { - media_controls_host_.FlushForTesting(); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h deleted file mode 100644 index 21d32a91007..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h +++ /dev/null @@ -1,130 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_MEDIA_CONTROLS_TOUCHLESS_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_MEDIA_CONTROLS_TOUCHLESS_IMPL_H_ - -#include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h" -#include "third_party/blink/public/mojom/media_controls/touchless/media_controls.mojom-blink.h" -#include "third_party/blink/renderer/core/html/html_div_element.h" -#include "third_party/blink/renderer/core/html/media/media_controls.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h" -#include "third_party/blink/renderer/modules/modules_export.h" - -namespace blink { - -class MediaControlsOrientationLockDelegate; -class MediaControlsTouchlessBottomContainerElement; -class MediaControlsTouchlessOverlayElement; -class MediaControlsTouchlessMediaEventListener; -class MediaControlsTouchlessVolumeContainerElement; -class MediaControlsTextTrackManager; - -class MODULES_EXPORT MediaControlsTouchlessImpl final - : public HTMLDivElement, - public MediaControls, - public MediaControlsTouchlessMediaEventListenerObserver { - USING_GARBAGE_COLLECTED_MIXIN(MediaControlsTouchlessImpl); - - public: - static MediaControlsTouchlessImpl* Create(HTMLMediaElement&, ShadowRoot&); - - explicit MediaControlsTouchlessImpl(HTMLMediaElement&); - - // Node override. - Node::InsertionNotificationRequest InsertedInto(ContainerNode&) override; - void RemovedFrom(ContainerNode&) override; - - // MediaControls implementation. - void MaybeShow() override; - void Hide() override; - void Reset() override {} - void OnControlsListUpdated() override {} - void OnTrackElementFailedToLoad() override {} - void NetworkStateChanged() override; - LayoutObject* PanelLayoutObject() override; - LayoutObject* TimelineLayoutObject() override; - LayoutObject* ButtonPanelLayoutObject() override; - LayoutObject* ContainerLayoutObject() override; - void ShowContextMenu() override; - void SetTestMode(bool) override {} - HTMLDivElement* PanelElement() override { return nullptr; } - void OnMediaControlsEnabledChange() override {} - - // MediaControlsTouchlessMediaEventListenerObserver implementation. - void OnFocusIn() override; - void OnTimeUpdate() override {} - void OnDurationChange() override {} - void OnSeeking() override {} - void OnLoadingProgress() override {} - void OnPlay() override; - void OnPause() override; - void OnEnterFullscreen() override; - void OnExitFullscreen() override; - void OnError() override; - void OnLoadedMetadata() override; - void OnKeyPress(KeyboardEvent* event) override {} - void OnKeyDown(KeyboardEvent* event) override; - void OnKeyUp(KeyboardEvent* event) override {} - - MediaControlsTouchlessMediaEventListener& MediaEventListener() const; - - // Test functions - void SetMediaControlsMenuHostForTesting( - mojo::PendingRemote<mojom::blink::MediaControlsMenuHost>); - void MenuHostFlushForTesting(); - - void Trace(blink::Visitor*) override; - - private: - friend class MediaControlsTouchlessImplTest; - - enum class ArrowDirection; - enum class ControlsState; - ArrowDirection OrientArrowPress(ArrowDirection direction); - void HandleOrientedArrowPress(ArrowDirection direction); - - WebScreenOrientationType GetOrientation(); - - ControlsState State(); - void UpdateCSSFromState(); - - void HandleTopButtonPress(); - void HandleBottomButtonPress(); - void HandleLeftButtonPress(); - void HandleRightButtonPress(); - - void MaybeJump(int); - void MaybeChangeVolume(double); - - void Download(); - - HTMLVideoElement& VideoElement(); - - // Node - bool IsMediaControls() const override { return true; } - - void EnsureMediaControlsMenuHost(); - mojom::blink::VideoStatePtr GetVideoState(); - WTF::Vector<mojom::blink::TextTrackMetadataPtr> GetTextTracks(); - void OnMediaMenuResult(mojom::blink::MenuResponsePtr); - void OnMediaControlsMenuHostConnectionError(); - - Member<MediaControlsTouchlessOverlayElement> overlay_; - Member<MediaControlsTouchlessBottomContainerElement> bottom_container_; - Member<MediaControlsTouchlessVolumeContainerElement> volume_container_; - - Member<MediaControlsTouchlessMediaEventListener> media_event_listener_; - Member<MediaControlsTextTrackManager> text_track_manager_; - Member<MediaControlsOrientationLockDelegate> orientation_lock_delegate_; - - mojo::Remote<mojom::blink::MediaControlsMenuHost> media_controls_host_; - - DISALLOW_COPY_AND_ASSIGN(MediaControlsTouchlessImpl); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_MEDIA_CONTROLS_TOUCHLESS_IMPL_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc deleted file mode 100644 index b18531c663f..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc +++ /dev/null @@ -1,637 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" - -#include <memory> - -#include "build/build_config.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/mojom/media_controls/touchless/media_controls.mojom-blink.h" -#include "third_party/blink/renderer/core/css/css_property_value_set.h" -#include "third_party/blink/renderer/core/dom/dom_token_list.h" -#include "third_party/blink/renderer/core/dom/element.h" -#include "third_party/blink/renderer/core/dom/element_traversal.h" -#include "third_party/blink/renderer/core/events/keyboard_event.h" -#include "third_party/blink/renderer/core/frame/settings.h" -#include "third_party/blink/renderer/core/fullscreen/fullscreen.h" -#include "third_party/blink/renderer/core/geometry/dom_rect.h" -#include "third_party/blink/renderer/core/html/media/html_media_element.h" -#include "third_party/blink/renderer/core/html/media/html_media_element_controls_list.h" -#include "third_party/blink/renderer/core/html/media/html_media_test_helper.h" -#include "third_party/blink/renderer/core/html/media/html_video_element.h" -#include "third_party/blink/renderer/core/html/time_ranges.h" -#include "third_party/blink/renderer/core/html/track/text_track.h" -#include "third_party/blink/renderer/core/html/track/text_track_list.h" -#include "third_party/blink/renderer/core/layout/layout_object.h" -#include "third_party/blink/renderer/core/loader/empty_clients.h" -#include "third_party/blink/renderer/core/testing/page_test_base.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h" -#include "third_party/blink/renderer/platform/keyboard_codes.h" -#include "third_party/blink/renderer/platform/testing/empty_web_media_player.h" -#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" - -namespace blink { - -namespace { - -const char kTextTracksOffString[] = "Off"; - -class LocalePlatformSupport : public TestingPlatformSupport { - public: - WebString QueryLocalizedString(int resource_id) override { - if (resource_id == WebLocalizedString::kTextTracksOff) - return kTextTracksOffString; - return TestingPlatformSupport::QueryLocalizedString(resource_id); - } -}; - -class MockWebMediaPlayerForTouchlessImpl : public EmptyWebMediaPlayer { - public: - WebTimeRanges Seekable() const override { return seekable_; } - bool HasVideo() const override { return true; } - bool HasAudio() const override { return has_audio_; } - WebTimeRanges Buffered() const override { return buffered_; } - - WebTimeRanges buffered_; - WebTimeRanges seekable_; - bool has_audio_ = false; -}; - -} // namespace - -class MockChromeClientForTouchlessImpl : public EmptyChromeClient { - public: - explicit MockChromeClientForTouchlessImpl() - : orientation_(kWebScreenOrientationPortraitPrimary) {} - - WebScreenInfo GetScreenInfo() const override { - WebScreenInfo screen_info; - screen_info.orientation_type = orientation_; - return screen_info; - } - - void EnterFullscreen(LocalFrame& frame, const FullscreenOptions*) final { - Fullscreen::DidEnterFullscreen(*frame.GetDocument()); - } - - void ExitFullscreen(LocalFrame& frame) final { - Fullscreen::DidExitFullscreen(*frame.GetDocument()); - } - - void SetOrientation(WebScreenOrientationType orientation_type) { - orientation_ = orientation_type; - } - - private: - WebScreenOrientationType orientation_; -}; - -class MediaControlsTouchlessImplTest : public PageTestBase { - protected: - void SetUp() override { InitializePage(); } - - void InitializePage() { - Page::PageClients clients; - - FillWithEmptyClients(clients); - chrome_client_ = MakeGarbageCollected<MockChromeClientForTouchlessImpl>(); - clients.chrome_client = chrome_client_; - SetupPageWithClients( - &clients, MakeGarbageCollected<test::MediaStubLocalFrameClient>( - std::make_unique<MockWebMediaPlayerForTouchlessImpl>())); - - GetDocument().write("<video controls>"); - HTMLMediaElement& video = - ToHTMLVideoElement(*GetDocument().QuerySelector("video")); - media_controls_ = - static_cast<MediaControlsTouchlessImpl*>(video.GetMediaControls()); - - test_media_controls_host_ = std::make_unique<TestMediaControlsMenuHost>(); - - media_controls_->SetMediaControlsMenuHostForTesting( - test_media_controls_host_->CreateMediaControlsMenuHostRemote()); - - // Scripts are disabled by default which forces controls to be on. - GetFrame().GetSettings()->SetScriptEnabled(true); - } - - MediaControlsTouchlessImpl& MediaControls() { return *media_controls_; } - HTMLMediaElement& MediaElement() { return MediaControls().MediaElement(); } - - MockWebMediaPlayerForTouchlessImpl* WebMediaPlayer() { - return static_cast<MockWebMediaPlayerForTouchlessImpl*>( - MediaElement().GetWebMediaPlayer()); - } - - TestMenuHostArgList& GetMenuHostArgList() { - return test_media_controls_host_->GetMenuHostArgList(); - } - - void SetNetworkState(HTMLMediaElement::NetworkState state) { - MediaElement().SetNetworkState(state); - } - - void SetReadyState(HTMLMediaElement::ReadyState state) { - MediaElement().SetReadyState(state); - } - - void SimulateKeydownEvent(Element& element, int key_code) { - KeyboardEventInit* keyboard_event_init = KeyboardEventInit::Create(); - keyboard_event_init->setKeyCode(key_code); - - Event* keyboard_event = - MakeGarbageCollected<KeyboardEvent>("keydown", keyboard_event_init); - element.DispatchEvent(*keyboard_event); - } - - void LoadMediaWithDuration(double duration) { - MediaElement().SetSrc("https://example.com/foo.mp4"); - test::RunPendingTasks(); - WebTimeRange time_range(0.0, duration); - WebMediaPlayer()->seekable_.Assign(&time_range, 1); - MediaElement().DurationChanged(duration, false /* requestSeek */); - } - - void SetBufferedRange(double end) { - WebTimeRange time_range(0.0, end); - WebMediaPlayer()->buffered_.Assign(&time_range, 1); - } - - bool IsControlsVisible(Element* element) { - return !element->classList().contains("transparent") && - !element->classList().contains("transparent-immediate"); - } - - bool IsElementDisplayed(Element* element) { - if (!element->InlineStyle()) - return true; - - return element->InlineStyle()->GetPropertyValue(CSSPropertyID::kDisplay) != - "none"; - } - - void SetHasAudio(bool has_audio) { WebMediaPlayer()->has_audio_ = has_audio; } - - Element* GetControlByShadowPseudoId(const char* shadow_pseudo_id) { - for (Element& element : ElementTraversal::DescendantsOf(MediaControls())) { - if (element.ShadowPseudoId() == shadow_pseudo_id) - return &element; - } - return nullptr; - } - - void SetScreenOrientation(WebScreenOrientationType orientation_type) { - chrome_client_->SetOrientation(orientation_type); - } - - void SetMenuResponse(mojom::blink::MenuItem menu_item, int track_index = -1) { - test_media_controls_host_->SetMenuResponse(menu_item, track_index); - } - - void SetMenuResponseAndShowMenu(mojom::blink::MenuItem menu_item, - int track_index = -1) { - SetMenuResponse(menu_item, track_index); - MediaControls().ShowContextMenu(); - MediaControls().MenuHostFlushForTesting(); - } - - void CheckControlKeys(int seek_forward_key, - int seek_backward_key, - int volume_up_key, - int volume_down_key) { - const int kNumberOfSecondsToJump = 10; - const double kVolumeToChange = 0.05; - const int initTime = 10; - const double initVolume = 0.5; - MediaElement().setCurrentTime(initTime); - MediaElement().setVolume(initVolume); - - SimulateKeydownEvent(MediaElement(), seek_forward_key); - ASSERT_EQ(MediaElement().currentTime(), initTime + kNumberOfSecondsToJump); - - SimulateKeydownEvent(MediaElement(), seek_backward_key); - ASSERT_EQ(MediaElement().currentTime(), initTime); - - SimulateKeydownEvent(MediaElement(), volume_up_key); - ASSERT_EQ(MediaElement().volume(), initVolume + kVolumeToChange); - - SimulateKeydownEvent(MediaElement(), volume_down_key); - ASSERT_EQ(MediaElement().volume(), initVolume); - } - - private: - Persistent<MediaControlsTouchlessImpl> media_controls_; - Persistent<MockChromeClientForTouchlessImpl> chrome_client_; - std::unique_ptr<TestMediaControlsMenuHost> test_media_controls_host_; -}; - -class MediaControlsTouchlessImplTestWithMockScheduler - : public MediaControlsTouchlessImplTest { - public: - MediaControlsTouchlessImplTestWithMockScheduler() { EnablePlatform(); } - - protected: - void SetUp() override { - platform()->AdvanceClockSeconds(1); - MediaControlsTouchlessImplTest::SetUp(); - } -}; - -TEST_F(MediaControlsTouchlessImplTest, PlayPause) { - MediaElement().SetFocused(true, WebFocusType::kWebFocusTypeNone); - MediaElement().Play(); - ASSERT_FALSE(MediaElement().paused()); - - // Press center key and video should be paused. - SimulateKeydownEvent(MediaElement(), VKEY_RETURN); - ASSERT_TRUE(MediaElement().paused()); - - // Press center key and video should be played. - SimulateKeydownEvent(MediaElement(), VKEY_RETURN); - ASSERT_FALSE(MediaElement().paused()); -} - -TEST_F(MediaControlsTouchlessImplTest, HandlesOrientationForArrowInput) { - MediaElement().SetFocused(true, WebFocusType::kWebFocusTypeNone); - - SetScreenOrientation(kWebScreenOrientationPortraitPrimary); - CheckControlKeys(VKEY_RIGHT, VKEY_LEFT, VKEY_UP, VKEY_DOWN); - - SetScreenOrientation(kWebScreenOrientationLandscapePrimary); - CheckControlKeys(VKEY_DOWN, VKEY_UP, VKEY_RIGHT, VKEY_LEFT); - - SetScreenOrientation(kWebScreenOrientationPortraitSecondary); - CheckControlKeys(VKEY_LEFT, VKEY_RIGHT, VKEY_DOWN, VKEY_UP); - - SetScreenOrientation(kWebScreenOrientationLandscapeSecondary); - CheckControlKeys(VKEY_UP, VKEY_DOWN, VKEY_LEFT, VKEY_RIGHT); -} - -TEST_F(MediaControlsTouchlessImplTest, ArrowInputEdgeCaseHandling) { - const double duration = 100; - - LoadMediaWithDuration(duration); - MediaElement().SetFocused(true, WebFocusType::kWebFocusTypeNone); - - // Seek backward at low current time - MediaElement().setCurrentTime(1); - SimulateKeydownEvent(MediaElement(), VKEY_LEFT); - ASSERT_EQ(MediaElement().currentTime(), 0); - - // Seek forward at high current time - MediaElement().setCurrentTime(duration - 1); - SimulateKeydownEvent(MediaElement(), VKEY_RIGHT); - ASSERT_EQ(MediaElement().currentTime(), duration); - - // Volume down at low volume - MediaElement().setVolume(0.01); - SimulateKeydownEvent(MediaElement(), VKEY_DOWN); - ASSERT_EQ(MediaElement().volume(), 0); - - // Volume up at high volume - MediaElement().setVolume(0.99); - SimulateKeydownEvent(MediaElement(), VKEY_UP); - ASSERT_EQ(MediaElement().volume(), 1); -} - -TEST_F(MediaControlsTouchlessImplTest, PlayPauseIcon) { - MediaElement().SetFocused(true, WebFocusType::kWebFocusTypeNone); - - Element* play_button = GetControlByShadowPseudoId( - "-internal-media-controls-touchless-play-button"); - ASSERT_NE(nullptr, play_button); - - MediaElement().pause(); - - MediaElement().Play(); - test::RunPendingTasks(); - ASSERT_TRUE(play_button->classList().contains("playing")); - ASSERT_FALSE(play_button->classList().contains("paused")); - - MediaElement().pause(); - test::RunPendingTasks(); - ASSERT_TRUE(play_button->classList().contains("paused")); - ASSERT_FALSE(play_button->classList().contains("playing")); -} - -TEST_F(MediaControlsTouchlessImplTest, ProgressBar) { - const double duration = 100.0; - const double buffered = 60.0; - const double current_time = 15.0; - - LoadMediaWithDuration(duration); - SetBufferedRange(buffered); - MediaElement().setCurrentTime(current_time); - test::RunPendingTasks(); - - MediaElement().DispatchEvent(*Event::Create(event_type_names::kTimeupdate)); - - Element* timeline = - GetControlByShadowPseudoId("-internal-media-controls-touchless-timeline"); - Element* progress_bar = GetControlByShadowPseudoId( - "-internal-media-controls-touchless-timeline-progress"); - Element* loaded_bar = GetControlByShadowPseudoId( - "-internal-media-controls-touchless-timeline-loaded"); - - ASSERT_NE(nullptr, timeline); - ASSERT_NE(nullptr, progress_bar); - ASSERT_NE(nullptr, loaded_bar); - - double timeline_width = timeline->getBoundingClientRect()->width(); - double progress_bar_width = progress_bar->getBoundingClientRect()->width(); - double loaded_bar_width = loaded_bar->getBoundingClientRect()->width(); - ASSERT_GT(timeline_width, 0); - - EXPECT_DOUBLE_EQ(buffered / duration, loaded_bar_width / timeline_width); - EXPECT_DOUBLE_EQ(current_time / buffered, - progress_bar_width / loaded_bar_width); - - // Seek event should trigger a UI update as well. - SetBufferedRange(0); - MediaElement().setCurrentTime(0); - MediaElement().DispatchEvent(*Event::Create(event_type_names::kSeeking)); - - EXPECT_DOUBLE_EQ(progress_bar->getBoundingClientRect()->width(), 0); - EXPECT_DOUBLE_EQ(loaded_bar->getBoundingClientRect()->width(), 0); -} - -TEST_F(MediaControlsTouchlessImplTest, TimeDisplay) { - const double duration = 4000; - const double current_time = 3599; - const char expect_display[] = "59:59 / 1:06:40"; - - Element* time_display = GetControlByShadowPseudoId( - "-internal-media-controls-touchless-time-display"); - - EXPECT_EQ(time_display->InnerHTMLAsString(), "0:00 / 0:00"); - - LoadMediaWithDuration(duration); - MediaElement().setCurrentTime(current_time); - test::RunPendingTasks(); - MediaElement().DispatchEvent(*Event::Create(event_type_names::kTimeupdate)); - - EXPECT_EQ(time_display->InnerHTMLAsString(), expect_display); -} - -TEST_F(MediaControlsTouchlessImplTest, VolumeDisplayTest) { - Element* volume_bar_background = GetControlByShadowPseudoId( - "-internal-media-controls-touchless-volume-bar-background"); - Element* volume_bar = GetControlByShadowPseudoId( - "-internal-media-controls-touchless-volume-bar"); - ASSERT_NE(nullptr, volume_bar_background); - ASSERT_NE(nullptr, volume_bar); - - const double volume = 0.65; // Initial volume. - const double volume_delta = 0.05; // Volume change for each press. - const double error = 0.01; // Allow precision error. - MediaElement().setVolume(volume); - SimulateKeydownEvent(MediaElement(), VK_UP); - - double volume_bar_background_height = - volume_bar_background->getBoundingClientRect()->height(); - double volume_bar_height = volume_bar->getBoundingClientRect()->height(); - - EXPECT_NEAR(volume + volume_delta, - volume_bar_height / volume_bar_background_height, error); -} - -TEST_F(MediaControlsTouchlessImplTest, ContextMenuMojomTest) { - ScopedTestingPlatformSupport<LocalePlatformSupport> support; - - MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4"); - std::unique_ptr<UserGestureIndicator> user_gesture_scope = - LocalFrame::NotifyUserActivation(GetDocument().GetFrame(), - UserGestureToken::kNewGesture); - test::RunPendingTasks(); - - WebKeyboardEvent web_keyboard_event( - WebInputEvent::kKeyUp, WebInputEvent::Modifiers::kNoModifiers, - WebInputEvent::GetStaticTimeStampForTests()); - // TODO: Cleanup magic numbers once https://crbug.com/949766 lands. - web_keyboard_event.dom_key = 0x00200310; - Event* keyboard_event = KeyboardEvent::Create(web_keyboard_event, nullptr); - - // Test fullscreen function. - SetMenuResponse(mojom::blink::MenuItem::FULLSCREEN); - MediaElement().DispatchEvent(*keyboard_event); - MediaControls().MenuHostFlushForTesting(); - test::RunPendingTasks(); - - TestMenuHostArgList& arg_list = GetMenuHostArgList(); - EXPECT_EQ((int)arg_list.menu_items.size(), 2); - EXPECT_EQ(arg_list.menu_items[0], mojom::blink::MenuItem::FULLSCREEN); - EXPECT_EQ(arg_list.menu_items[1], mojom::blink::MenuItem::DOWNLOAD); - EXPECT_FALSE(arg_list.video_state->is_fullscreen); - EXPECT_TRUE(MediaElement().IsFullscreen()); - - SetMenuResponseAndShowMenu(mojom::blink::MenuItem::FULLSCREEN); - test::RunPendingTasks(); - - EXPECT_TRUE(arg_list.video_state->is_fullscreen); - EXPECT_FALSE(MediaElement().IsFullscreen()); - - // Disable download and fullscreen, and show mute option. - MediaElement().ControlsListInternal()->Add("nofullscreen"); - MediaElement().GetDocument().GetSettings()->SetHideDownloadUI(true); - SetHasAudio(true); - - SetMenuResponseAndShowMenu(mojom::blink::MenuItem::MUTE); - - EXPECT_EQ((int)arg_list.menu_items.size(), 1); - EXPECT_EQ(arg_list.menu_items[0], mojom::blink::MenuItem::MUTE); - EXPECT_FALSE(arg_list.video_state->is_muted); - EXPECT_TRUE(MediaElement().muted()); - - SetMenuResponseAndShowMenu(mojom::blink::MenuItem::MUTE); - - EXPECT_TRUE(arg_list.video_state->is_muted); - EXPECT_FALSE(MediaElement().muted()); - - // Disable mute option and show text track option. - SetHasAudio(false); - TextTrack* track = MediaElement().addTextTrack("subtitles", "english", "en", - ASSERT_NO_EXCEPTION); - SetMenuResponseAndShowMenu(mojom::blink::MenuItem::CAPTIONS, 0); - - EXPECT_EQ((int)arg_list.menu_items.size(), 1); - EXPECT_EQ(arg_list.menu_items[0], mojom::blink::MenuItem::CAPTIONS); - EXPECT_EQ(arg_list.text_tracks[1]->label, "english"); - EXPECT_EQ(track->mode(), TextTrack::ShowingKeyword()); - - SetMenuResponseAndShowMenu(mojom::blink::MenuItem::CAPTIONS, -1); - EXPECT_NE(track->mode(), TextTrack::ShowingKeyword()); -} - -TEST_F(MediaControlsTouchlessImplTest, NoSourceTest) { - EXPECT_TRUE(MediaControls().classList().contains("state-no-source")); - - LoadMediaWithDuration(10); - EXPECT_FALSE(MediaControls().classList().contains("state-no-source")); -} - -TEST_F(MediaControlsTouchlessImplTest, DefaultPosterTest) { - LoadMediaWithDuration(10); - - SetNetworkState(HTMLMediaElement::NetworkState::kNetworkLoading); - test::RunPendingTasks(); - EXPECT_TRUE(MediaControls().classList().contains("use-default-poster")); - - SetNetworkState(HTMLMediaElement::NetworkState::kNetworkIdle); - SetReadyState(HTMLMediaElement::ReadyState::kHaveMetadata); - test::RunPendingTasks(); - EXPECT_FALSE(MediaControls().classList().contains("use-default-poster")); -} - -TEST_F(MediaControlsTouchlessImplTest, DoesNotHandleKeysWhenDisabled) { - // Disable the controls. - MediaElement().SetBooleanAttribute(html_names::kControlsAttr, false); - - // Focus the video. - MediaElement().SetFocused(true, WebFocusType::kWebFocusTypeNone); - ASSERT_TRUE(MediaElement().paused()); - - // Enter should not play the video. - SimulateKeydownEvent(MediaElement(), VKEY_RETURN); - ASSERT_TRUE(MediaElement().paused()); - - // The arrow keys should also not be handled. - const int initTime = 10; - const double initVolume = 0.5; - MediaElement().setCurrentTime(initTime); - MediaElement().setVolume(initVolume); - - SimulateKeydownEvent(MediaElement(), VKEY_RIGHT); - ASSERT_EQ(MediaElement().currentTime(), initTime); - - SimulateKeydownEvent(MediaElement(), VKEY_LEFT); - ASSERT_EQ(MediaElement().currentTime(), initTime); - - SimulateKeydownEvent(MediaElement(), VKEY_UP); - ASSERT_EQ(MediaElement().volume(), initVolume); - - SimulateKeydownEvent(MediaElement(), VKEY_DOWN); - ASSERT_EQ(MediaElement().volume(), initVolume); -} - -TEST_F(MediaControlsTouchlessImplTestWithMockScheduler, - MidOverlayHideTimerTest) { - Element* overlay = - GetControlByShadowPseudoId("-internal-media-controls-touchless-overlay"); - ASSERT_NE(nullptr, overlay); - - // Overlay should starts hidden. - EXPECT_FALSE(IsControlsVisible(overlay)); - - // Overlay should show when focus in. - MediaElement().SetFocused(true, WebFocusType::kWebFocusTypeNone); - MediaElement().DispatchEvent(*Event::Create(event_type_names::kFocusin)); - EXPECT_TRUE(IsControlsVisible(overlay)); - - // Overlay should hide after 3 seconds. - platform()->RunForPeriodSeconds(2.99); - EXPECT_TRUE(IsControlsVisible(overlay)); - platform()->RunForPeriodSeconds(0.01); - EXPECT_FALSE(IsControlsVisible(overlay)); - - // Overlay should show upon pressing return key. - SimulateKeydownEvent(MediaElement(), VKEY_RETURN); - EXPECT_TRUE(IsControlsVisible(overlay)); - - // Overlay should not disappear after 2 seconds. - platform()->RunForPeriodSeconds(2); - EXPECT_TRUE(IsControlsVisible(overlay)); - - // Overlay should hide 3 seconds after last key press. - platform()->RunForPeriodSeconds(1); - EXPECT_FALSE(IsControlsVisible(overlay)); -} - -TEST_F(MediaControlsTouchlessImplTestWithMockScheduler, - BottomContainerHideTimerTest) { - Element* bottom_container = GetControlByShadowPseudoId( - "-internal-media-controls-touchless-bottom-container"); - ASSERT_NE(nullptr, bottom_container); - - // Bottom container starts opaque since video is paused. - EXPECT_TRUE(IsControlsVisible(bottom_container)); - EXPECT_TRUE(IsElementDisplayed(bottom_container)); - - MediaElement().Play(); - platform()->RunForPeriodSeconds(3); - EXPECT_FALSE(IsControlsVisible(bottom_container)); - - MediaElement().pause(); - - // Pause after play should stop hide timer. - MediaElement().Play(); - MediaElement().pause(); - platform()->RunForPeriodSeconds(5); - EXPECT_TRUE(IsControlsVisible(bottom_container)); - - MediaElement().Play(); - platform()->RunForPeriodSeconds(5); - EXPECT_FALSE(IsControlsVisible(bottom_container)); - - // Bottom container should show after focus in. - MediaElement().SetFocused(true, WebFocusType::kWebFocusTypeNone); - MediaElement().DispatchEvent(*Event::Create(event_type_names::kFocusin)); - EXPECT_TRUE(IsControlsVisible(bottom_container)); - - // Hide after 3 seconds - platform()->RunForPeriodSeconds(3); - EXPECT_FALSE(IsControlsVisible(bottom_container)); - - // Display should be none after hide transition ends. - bottom_container->DispatchEvent( - *Event::Create(event_type_names::kTransitionend)); - EXPECT_FALSE(IsElementDisplayed(bottom_container)); - - // Bottom container should show after pressing right/left arrow. - SimulateKeydownEvent(MediaElement(), VK_RIGHT); - EXPECT_TRUE(IsControlsVisible(bottom_container)); - - platform()->RunForPeriodSeconds(3); - EXPECT_FALSE(IsControlsVisible(bottom_container)); - - SimulateKeydownEvent(MediaElement(), VK_LEFT); - EXPECT_TRUE(IsControlsVisible(bottom_container)); - - platform()->RunForPeriodSeconds(3); - EXPECT_FALSE(IsControlsVisible(bottom_container)); -} - -TEST_F(MediaControlsTouchlessImplTestWithMockScheduler, - VolumeDisplayTimerTest) { - Element* volume_container = GetControlByShadowPseudoId( - "-internal-media-controls-touchless-volume-container"); - Element* overlay = - GetControlByShadowPseudoId("-internal-media-controls-touchless-overlay"); - ASSERT_NE(nullptr, volume_container); - ASSERT_NE(nullptr, overlay); - - MediaElement().SetFocused(true, WebFocusType::kWebFocusTypeNone); - MediaElement().DispatchEvent(*Event::Create(event_type_names::kFocusin)); - EXPECT_TRUE(IsControlsVisible(overlay)); - - // Press up button should bring up volume display and hide overlay - // immediately. - SimulateKeydownEvent(MediaElement(), VK_UP); - EXPECT_TRUE(IsControlsVisible(volume_container)); - EXPECT_FALSE(IsControlsVisible(overlay)); - - platform()->RunForPeriodSeconds(3); - EXPECT_FALSE(IsControlsVisible(volume_container)); - - SimulateKeydownEvent(MediaElement(), VK_UP); - EXPECT_TRUE(IsControlsVisible(volume_container)); - - // Press mid key should bring up mid overlay and hide volume display - // immediately. - SimulateKeydownEvent(MediaElement(), VK_RETURN); - EXPECT_FALSE(IsControlsVisible(volume_container)); - EXPECT_TRUE(IsControlsVisible(overlay)); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.cc deleted file mode 100644 index 9077df3b625..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.cc +++ /dev/null @@ -1,144 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.h" - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/events/event.h" -#include "third_party/blink/renderer/core/events/keyboard_event.h" -#include "third_party/blink/renderer/core/html/media/html_media_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h" - -namespace blink { - -MediaControlsTouchlessMediaEventListener:: - MediaControlsTouchlessMediaEventListener(HTMLMediaElement& media_element) - : media_element_(media_element) { - if (media_element.isConnected()) - Attach(); -} - -void MediaControlsTouchlessMediaEventListener::AddObserver( - MediaControlsTouchlessMediaEventListenerObserver* observer) { - observers_.insert(observer); -} - -void MediaControlsTouchlessMediaEventListener::RemoveObserver( - MediaControlsTouchlessMediaEventListenerObserver* observer) { - observers_.erase(observer); -} - -void MediaControlsTouchlessMediaEventListener::Attach() { - DCHECK(media_element_->isConnected()); - - media_element_->addEventListener(event_type_names::kFocusin, this, false); - media_element_->addEventListener(event_type_names::kTimeupdate, this, false); - media_element_->addEventListener(event_type_names::kDurationchange, this, - false); - media_element_->addEventListener(event_type_names::kSeeking, this, false); - media_element_->addEventListener(event_type_names::kProgress, this, false); - - media_element_->addEventListener(event_type_names::kPlay, this, false); - media_element_->addEventListener(event_type_names::kPause, this, false); - - media_element_->addEventListener(event_type_names::kError, this, false); - media_element_->addEventListener(event_type_names::kLoadedmetadata, this, - false); - - media_element_->addEventListener(event_type_names::kKeypress, this, false); - media_element_->addEventListener(event_type_names::kKeydown, this, false); - media_element_->addEventListener(event_type_names::kKeyup, this, false); - - media_element_->addEventListener(event_type_names::kWebkitfullscreenchange, - this, false); - media_element_->GetDocument().addEventListener( - event_type_names::kFullscreenchange, this, false); -} - -void MediaControlsTouchlessMediaEventListener::Detach() { - DCHECK(!media_element_->isConnected()); -} - -void MediaControlsTouchlessMediaEventListener::Invoke( - ExecutionContext* execution_context, - Event* event) { - if (event->type() == event_type_names::kFocusin) { - for (auto& observer : observers_) - observer->OnFocusIn(); - return; - } - if (event->type() == event_type_names::kTimeupdate) { - for (auto& observer : observers_) - observer->OnTimeUpdate(); - return; - } - if (event->type() == event_type_names::kDurationchange) { - for (auto& observer : observers_) - observer->OnDurationChange(); - return; - } - if (event->type() == event_type_names::kSeeking) { - for (auto& observer : observers_) - observer->OnSeeking(); - return; - } - if (event->type() == event_type_names::kProgress) { - for (auto& observer : observers_) - observer->OnLoadingProgress(); - return; - } - if (event->type() == event_type_names::kPlay) { - for (auto& observer : observers_) - observer->OnPlay(); - return; - } - if (event->type() == event_type_names::kPause) { - for (auto& observer : observers_) - observer->OnPause(); - return; - } - if (event->type() == event_type_names::kError) { - for (auto& observer : observers_) - observer->OnError(); - return; - } - if (event->type() == event_type_names::kLoadedmetadata) { - for (auto& observer : observers_) - observer->OnLoadedMetadata(); - return; - } - if (event->type() == event_type_names::kKeypress) { - for (auto& observer : observers_) - observer->OnKeyPress(ToKeyboardEvent(event)); - return; - } - if (event->type() == event_type_names::kKeydown) { - for (auto& observer : observers_) - observer->OnKeyDown(ToKeyboardEvent(event)); - return; - } - if (event->type() == event_type_names::kKeyup) { - for (auto& observer : observers_) - observer->OnKeyUp(ToKeyboardEvent(event)); - return; - } - if (event->type() == event_type_names::kFullscreenchange || - event->type() == event_type_names::kWebkitfullscreenchange) { - if (media_element_->IsFullscreen()) { - for (auto& observer : observers_) - observer->OnEnterFullscreen(); - } else { - for (auto& observer : observers_) - observer->OnExitFullscreen(); - } - } -} - -void MediaControlsTouchlessMediaEventListener::Trace(blink::Visitor* visitor) { - NativeEventListener::Trace(visitor); - visitor->Trace(media_element_); - visitor->Trace(observers_); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.h deleted file mode 100644 index a290bd91510..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.h +++ /dev/null @@ -1,41 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_MEDIA_CONTROLS_TOUCHLESS_MEDIA_EVENT_LISTENER_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_MEDIA_CONTROLS_TOUCHLESS_MEDIA_EVENT_LISTENER_H_ - -#include "third_party/blink/renderer/core/dom/events/native_event_listener.h" - -namespace blink { - -class HTMLMediaElement; -class MediaControlsTouchlessMediaEventListenerObserver; - -class MediaControlsTouchlessMediaEventListener final - : public NativeEventListener { - public: - explicit MediaControlsTouchlessMediaEventListener(HTMLMediaElement&); - - void AddObserver(MediaControlsTouchlessMediaEventListenerObserver*); - void RemoveObserver(MediaControlsTouchlessMediaEventListenerObserver*); - - void Attach(); - void Detach(); - - void Trace(blink::Visitor*) override; - void Invoke(ExecutionContext*, Event*) override; - - private: - HTMLMediaElement& GetMediaElement(); - - HeapLinkedHashSet<Member<MediaControlsTouchlessMediaEventListenerObserver>> - observers_; - Member<HTMLMediaElement> media_element_; - - DISALLOW_COPY_AND_ASSIGN(MediaControlsTouchlessMediaEventListener); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_MEDIA_CONTROLS_TOUCHLESS_MEDIA_EVENT_LISTENER_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h deleted file mode 100644 index cf07510f775..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h +++ /dev/null @@ -1,35 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_MEDIA_CONTROLS_TOUCHLESS_MEDIA_EVENT_LISTENER_OBSERVER_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_MEDIA_CONTROLS_TOUCHLESS_MEDIA_EVENT_LISTENER_OBSERVER_H_ - -#include "third_party/blink/renderer/platform/heap/garbage_collected.h" - -namespace blink { - -class KeyboardEvent; - -class MediaControlsTouchlessMediaEventListenerObserver - : public GarbageCollectedMixin { - public: - virtual void OnFocusIn() = 0; - virtual void OnTimeUpdate() = 0; - virtual void OnDurationChange() = 0; - virtual void OnSeeking() = 0; - virtual void OnLoadingProgress() = 0; - virtual void OnPlay() = 0; - virtual void OnPause() = 0; - virtual void OnEnterFullscreen() = 0; - virtual void OnExitFullscreen() = 0; - virtual void OnError() = 0; - virtual void OnLoadedMetadata() = 0; - virtual void OnKeyPress(KeyboardEvent* event) = 0; - virtual void OnKeyDown(KeyboardEvent* event) = 0; - virtual void OnKeyUp(KeyboardEvent* event) = 0; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_MEDIA_CONTROLS_TOUCHLESS_MEDIA_EVENT_LISTENER_OBSERVER_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_resource_loader.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_resource_loader.cc deleted file mode 100644 index 1af1f09c2f8..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_resource_loader.cc +++ /dev/null @@ -1,38 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_resource_loader.h" - -#include "third_party/blink/renderer/modules/media_controls/touchless/resources/grit/media_controls_touchless_resources.h" -#include "third_party/blink/renderer/platform/data_resource_helper.h" - -namespace blink { - -MediaControlsTouchlessResourceLoader::MediaControlsTouchlessResourceLoader() - : UAStyleSheetLoader() {} - -MediaControlsTouchlessResourceLoader::~MediaControlsTouchlessResourceLoader() = - default; - -String MediaControlsTouchlessResourceLoader::GetMediaControlsTouchlessCSS() - const { - return UncompressResourceAsString(IDR_UASTYLE_MEDIA_CONTROLS_TOUCHLESS_CSS); -} - -String MediaControlsTouchlessResourceLoader::GetUAStyleSheet() { - return GetMediaControlsTouchlessCSS(); -} - -void MediaControlsTouchlessResourceLoader:: - InjectMediaControlsTouchlessUAStyleSheet() { - CSSDefaultStyleSheets& default_style_sheets = - CSSDefaultStyleSheets::Instance(); - std::unique_ptr<MediaControlsTouchlessResourceLoader> loader = - std::make_unique<MediaControlsTouchlessResourceLoader>(); - - if (!default_style_sheets.HasMediaControlsStyleSheetLoader()) - default_style_sheets.SetMediaControlsStyleSheetLoader(std::move(loader)); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_resource_loader.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_resource_loader.h deleted file mode 100644 index 74ed1ac5f1a..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_resource_loader.h +++ /dev/null @@ -1,28 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_MEDIA_CONTROLS_TOUCHLESS_RESOURCE_LOADER_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_MEDIA_CONTROLS_TOUCHLESS_RESOURCE_LOADER_H_ - -#include "third_party/blink/renderer/core/css/css_default_style_sheets.h" - -namespace blink { - -// Builds the UA stylesheet for the touchless Media Controls. -class MediaControlsTouchlessResourceLoader - : public CSSDefaultStyleSheets::UAStyleSheetLoader { - public: - static void InjectMediaControlsTouchlessUAStyleSheet(); - - String GetUAStyleSheet() override; - MediaControlsTouchlessResourceLoader(); - ~MediaControlsTouchlessResourceLoader() override; - - private: - String GetMediaControlsTouchlessCSS() const; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_MEDIA_CONTROLS_TOUCHLESS_RESOURCE_LOADER_H_ diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/gradient_bg.png b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/gradient_bg.png Binary files differdeleted file mode 100644 index 25f2a028ae3..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/gradient_bg.png +++ /dev/null diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_fast_forward.svg b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_fast_forward.svg deleted file mode 100644 index 09a980598bc..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_fast_forward.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#FFFFFF"><path d="M15 9.86L18.03 12 15 14.14V9.86m-9 0L9.03 12 6 14.14V9.86M13 6v12l8.5-6L13 6zM4 6v12l8.5-6L4 6z"/><path fill="none" d="M0 0h24v24H0zm0 0h24v24H0zm0 0h24v24H0z"/></svg> diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_fast_rewind.svg b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_fast_rewind.svg deleted file mode 100644 index 384fdc49eab..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_fast_rewind.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#FFFFFF"><path d="M18 9.86v4.28L14.97 12 18 9.86m-9 0v4.28L5.97 12 9 9.86M20 6l-8.5 6 8.5 6V6zm-9 0l-8.5 6 8.5 6V6z"/><path fill="none" d="M0 0h24v24H0V0z"/></svg> diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_mid_background.svg b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_mid_background.svg deleted file mode 100644 index 77cf41fc354..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_mid_background.svg +++ /dev/null @@ -1,4 +0,0 @@ -<svg width="104" height="104" viewBox="0 0 104 104" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path opacity="0.85" fill-rule="evenodd" clip-rule="evenodd" d="M32 0C14.3269 0 0 14.3269 0 32V72C0 89.6731 14.3269 104 32 104H72C89.6731 104 104 89.6731 104 72V32C104 14.3269 89.6731 0 72 0H32ZM46 30C37.1634 30 30 37.1634 30 46V58C30 66.8366 37.1634 74 46 74H58C66.8366 74 74 66.8366 74 58V46C74 37.1634 66.8366 30 58 30H46Z" fill="#202124"/> -<rect opacity="0.85" x="32" y="32" width="40" height="40" rx="14" fill="#202124"/> -</svg> diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_music_note.svg b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_music_note.svg deleted file mode 100644 index bcabd88d2ee..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_music_note.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 3l.01 10.55c-.59-.34-1.27-.55-2-.55C7.79 13 6 14.79 6 17s1.79 4 4.01 4S14 19.21 14 17V7h4V3h-6z"/><path fill="none" d="M0 0h24v24H0V0z"/></svg>
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_no_source.svg b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_no_source.svg deleted file mode 100644 index 49b7eaf5769..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_no_source.svg +++ /dev/null @@ -1,5 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="#000000"> - <path fill="none" d="M0 0h24v24H0zm0 0h24v24H0zm21 19c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2V5c0-1.1.9-2 2-2h14c1.1 0 2 .9 2 2"/> - <path fill="none" d="M0 0h24v24H0z"/> - <path d="M21 5v6.59l-3-3.01-4 4.01-4-4-4 4-3-3.01V5c0-1.1.9-2 2-2h14c1.1 0 2 .9 2 2zm-3 6.42l3 3.01V19c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2v-6.58l3 2.99 4-4 4 4 4-3.99z"/> -</svg> diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_pause.svg b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_pause.svg deleted file mode 100644 index bd17d16c452..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_pause.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#FFFFFF"><path d="M19 19h-6V5h6v14zm-4-2h2V7h-2v10zm-4 2H5V5h6v14zm-4-2h2V7H7v10z"/><path fill="none" d="M0 0h24v24H0V0z"/></svg> diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_play_arrow.svg b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_play_arrow.svg deleted file mode 100644 index 10c1d08fa74..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_play_arrow.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#FFFFFF"><path d="M10 8.64L15.27 12 10 15.36V8.64M8 5v14l11-7L8 5z"/><path fill="none" d="M0 0h24v24H0V0z"/></svg> diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_volume_down.svg b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_volume_down.svg deleted file mode 100644 index 67af7988c68..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_volume_down.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#FFFFFF"><path d="M16 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02 0-1.77-1.02-3.29-2.5-4.03zM5 9v6h4l5 5V4L9 9H5zm7-.17v6.34L9.83 13H7v-2h2.83L12 8.83z"/><path fill="none" d="M0 0h24v24H0V0z"/></svg> diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_volume_off.svg b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_volume_off.svg deleted file mode 100644 index a8636be347d..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_volume_off.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#FFFFFF"><path d="M21.19 21.19L14 14l-2-2-9.2-9.2-1.41 1.42 8.79 8.79c-.06 0-.12-.01-.18-.01-2.21 0-4 1.79-4 4s1.79 4 4.01 4S14 19.21 14 17v-.17l5.78 5.78 1.41-1.42zM14 11.17V7h4V3h-6v6.17z"/><path fill="none" d="M0 0h24v24H0V0z"/></svg> diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_volume_on.svg b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_volume_on.svg deleted file mode 100644 index ba098e8640f..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_volume_on.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#FFFFFF"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/><path fill="none" d="M0 0h24v24H0V0z"/></svg> diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_volume_up.svg b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_volume_up.svg deleted file mode 100644 index 9c82fbcef37..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/ic_volume_up.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#FFFFFF"><path d="M3 9v6h4l5 5V4L7 9H3zm7-.17v6.34L7.83 13H5v-2h2.83L10 8.83zM16.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77 0-4.28-2.99-7.86-7-8.77z"/><path fill="none" d="M0 0h24v24H0V0z"/></svg> diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css deleted file mode 100644 index 67a19135220..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css +++ /dev/null @@ -1,370 +0,0 @@ -/* 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. */ - -audio { - width: 300px; - height: 180px; -} - -audio::-webkit-media-controls-touchless, -video::-webkit-media-controls-touchless { - width: inherit; - height: inherit; - - position: relative; - direction: ltr; - display: flex; - flex-direction: column; - opacity: 1; - - margin-top: env(safe-area-inset-top); - margin-left: env(safe-area-inset-left); - margin-right: env(safe-area-inset-right); - margin-bottom: env(safe-area-inset-bottom); -} - -audio::-webkit-media-controls-touchless, -video::-webkit-media-controls-touchless.use-default-poster { - background: #333; -} - -audio::-internal-media-controls-touchless-info, -video::-internal-media-controls-touchless-info { - display: none; - height: 72px; - width: 72px; - border-radius: 50%; - opacity: 0.3; - background-color: rgba(255, 255, 255, 0.9); - background-size: 50%; - background-position: center; - background-repeat: no-repeat; - position: absolute; - margin: auto; - top: 0; - left: 0; - bottom: 0; - right: 0; -} - -audio::-internal-media-controls-touchless-info { - background-image: -webkit-image-set(url(ic_music_note.svg) 1x); - display: block; -} - -audio::-webkit-media-controls-touchless.state-no-source [pseudo="-internal-media-controls-touchless-info"], -video::-webkit-media-controls-touchless.state-no-source [pseudo="-internal-media-controls-touchless-info"] { - background-image: -webkit-image-set(url(ic_no_source.svg) 1x); - display: block; -} - -audio::-internal-media-controls-touchless-overlay, -video::-internal-media-controls-touchless-overlay { - width: 104px; - height: 104px; - background-image: -webkit-image-set(url(ic_mid_background.svg) 1x); - background-size: 104px; - background-position: center; - background-repeat: no-repeat; - position: absolute; - opacity: 1; - z-index: 1; - margin: auto; - top: 0; - left: 0; - bottom: 0; - right: 0; -} - -audio::-webkit-media-controls-touchless.state-no-source [pseudo="-internal-media-controls-touchless-overlay"], -video::-webkit-media-controls-touchless.state-no-source [pseudo="-internal-media-controls-touchless-overlay"] { - display: none; -} - -audio::-internal-media-controls-touchless-overlay.transparent, -video::-internal-media-controls-touchless-overlay.transparent { - opacity: 0; - transition: opacity .5s; -} - -audio::-internal-media-controls-touchless-overlay.transparent-immediate, -video::-internal-media-controls-touchless-overlay.transparent-immediate { - opacity: 0; -} - -audio::-internal-media-controls-touchless-volume-up-button, -video::-internal-media-controls-touchless-volume-up-button { - width: 30px; - height: 30px; - margin-left: 37px /* (overlay width -width) / 2 */; - background-image: -webkit-image-set(url(ic_volume_up.svg) 1x); - background-size: 20px; - background-position: center; - background-repeat: no-repeat; -} - -audio::-internal-media-controls-touchless-seek-backward-button, -video::-internal-media-controls-touchless-seek-backward-button { - width: 30px; - height: 30px; - margin-top: 7px /* (play button height - height) / 2 */; - float: left; - background-image: -webkit-image-set(url(ic_fast_rewind.svg) 1x); - background-size: 20px; - background-position: center; - background-repeat: no-repeat; -} - -audio::-internal-media-controls-touchless-play-button, -video::-internal-media-controls-touchless-play-button { - width: 44px; - height: 44px; - background-position: center; - background-size: 24px; - background-repeat: no-repeat; - float: left; -} - -audio::-internal-media-controls-touchless-play-button.playing, -video::-internal-media-controls-touchless-play-button.playing { - background-image: -webkit-image-set(url(ic_pause.svg) 1x); -} - -audio::-internal-media-controls-touchless-play-button.paused, -video::-internal-media-controls-touchless-play-button.paused { - background-image: -webkit-image-set(url(ic_play_arrow.svg) 1x); -} - -audio::-internal-media-controls-touchless-seek-forward-button, -video::-internal-media-controls-touchless-seek-forward-button { - width: 30px; - height: 30px; - margin-top: 7px /* (play button height - height) / 2 */; - float: left; - background-image: -webkit-image-set(url(ic_fast_forward.svg) 1x); - background-size: 20px; - background-position: center; - background-repeat: no-repeat; -} - -audio::-internal-media-controls-touchless-volume-down-button, -video::-internal-media-controls-touchless-volume-down-button { - width: 30px; - height: 30px; - margin-left: 37px /* (overlay width -width) / 2 */; - position: absolute; - bottom: 0; - background-image: -webkit-image-set(url(ic_volume_down.svg) 1x); - background-size: 20px; - background-position: center; - background-repeat: no-repeat; -} - -audio::-internal-media-controls-touchless-bottom-container, -video::-internal-media-controls-touchless-bottom-container { - position: absolute; - display: flex; - flex-direction: column; - justify-content: flex-end; - height: 100%; - width: 100%; - z-index: 0; - - background: - -webkit-image-set(url('gradient_bg.png') 1x) - repeat-x bottom left; - background-size: auto 48px; -} - -audio::-internal-media-controls-touchless-bottom-container.transparent, -video::-internal-media-controls-touchless-bottom-container.transparent { - opacity: 0; - transition: opacity .5s; -} - -audio::-internal-media-controls-touchless-time-display, -video::-internal-media-controls-touchless-time-display { - color: #ffffff; - font-family: Roboto-Regular, Roboto, sans-serif; - font-size: 14px; - width: 100%; - bottom: auto; - padding-left: 8px; - padding-bottom: 8px; -} - -audio::-internal-media-controls-touchless-timeline, -video::-internal-media-controls-touchless-timeline { - width: 100%; - bottom: auto; - height: 4px; - background-color: rgba(0, 0, 0, 0.2); -} - -audio::-internal-media-controls-touchless-timeline-loaded, -video::-internal-media-controls-touchless-timeline-loaded { - height: 100%; - width: 0; /* We are using style attribute to override this. */ - border-radius: 0 2px 2px 0; - background-color: rgba(255, 255, 255, 0.54); -} - -audio::-internal-media-controls-touchless-timeline-progress, -video::-internal-media-controls-touchless-timeline-progress { - height: 100%; - width: 0; /* We are using style attribute to override this. */ - border-radius: 0 2px 2px 0; - background-color: rgba(255, 255, 255, 1.0); -} - -audio::-internal-media-controls-touchless-volume-container, -video::-internal-media-controls-touchless-volume-container { - width: 44px; - max-height: 152px; - height: 90%; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - margin: auto; - background-color: rgba(60,64,67,0.9); - border-radius: 22px; - - display: flex; - flex-direction: column; - justify-content: flex-end; -} - -audio::-internal-media-controls-touchless-volume-container.transparent, -video::-internal-media-controls-touchless-volume-container.transparent { - opacity: 0; - transition: opacity .5s; -} - -audio::-internal-media-controls-touchless-volume-container.transparent-immediate, -video::-internal-media-controls-touchless-volume-container.transparent-immediate { - opacity: 0; -} - -audio::-internal-media-controls-touchless-volume-bar-background, -video::-internal-media-controls-touchless-volume-bar-background { - width: 4px; - margin-left: 20px; - margin-top: 12px; - margin-bottom: 8px; - background-color: rgba(255,255,255,0.54); - flex: 1 1 auto; - border-radius: 2px; - display: flex; - flex-direction: column; - justify-content: flex-end; -} - -audio::-webkit-media-controls-touchless.inline [pseudo="-internal-media-controls-touchless-volume-bar-background"], -video::-webkit-media-controls-touchless.inline [pseudo="-internal-media-controls-touchless-volume-bar-background"] { - margin-bottom: 12px; -} - -audio::-internal-media-controls-touchless-volume-bar, -video::-internal-media-controls-touchless-volume-bar { - background-color: #FFFFFF; - border-radius: 2px; -} - -audio::-internal-media-controls-touchless-volume-icon, -video::-internal-media-controls-touchless-volume-icon { - width: 24px; - height: 24px; - margin-left: 10px; - margin-bottom: 10px; - flex: 0 1 auto; - background-image: -webkit-image-set(url(ic_volume_on.svg) 1x); -} - -audio::-internal-media-controls-touchless-volume-icon.muted, -video::-internal-media-controls-touchless-volume-icon.muted { - background-image: -webkit-image-set(url(ic_volume_off.svg) 1x); -} - -audio::-webkit-media-controls-touchless.inline div[pseudo="-internal-media-controls-touchless-volume-icon" i], -video::-webkit-media-controls-touchless.inline div[pseudo="-internal-media-controls-touchless-volume-icon" i] { - display: none; -} - -/** - * Text Tracks - */ -video::-webkit-media-text-track-container { - position: relative; - width: inherit; - height: inherit; - overflow: hidden; - - font: 22px sans-serif; - text-align: center; - color: rgba(255, 255, 255, 1); - - letter-spacing: normal; - word-spacing: normal; - text-transform: none; - text-indent: 0; - text-decoration: none; - pointer-events: none; - -webkit-user-select: none; - word-break: break-word; -} - -video::cue { - display: inline; - - background-color: rgba(0, 0, 0, 0.8); -} - -video::-webkit-media-text-track-region { - position: absolute; - line-height: 5.33vh; - writing-mode: horizontal-tb; - background: rgba(0, 0, 0, 0.8); - color: rgba(255, 255, 255, 1); - word-wrap: break-word; - overflow-wrap: break-word; - overflow: hidden; -} - -video::-webkit-media-text-track-region-container { - position: relative; - - display: flex; - flex-flow: column; - flex-direction: column; -} - -video::-webkit-media-text-track-region-container.scrolling { - transition: top 433ms linear; -} - -video::-webkit-media-text-track-display { - position: absolute; - overflow: hidden; - white-space: pre-wrap; - -webkit-box-sizing: border-box; - flex: 0 0 auto; -} - -video::cue(:future) { - color: gray; -} - -video::cue(b) { - font-weight: bold; -} - -video::cue(u) { - text-decoration: underline; -} - -video::cue(i) { - font-style: italic; -} diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/media_controls_touchless_resources.grd b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/media_controls_touchless_resources.grd deleted file mode 100644 index 5f74e838e60..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/media_controls_touchless_resources.grd +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> - <outputs> - <output filename="grit/media_controls_touchless_resources.h" type="rc_header"> - <emit emit_type='prepend'></emit> - </output> - <output filename="media_controls_touchless_resources.pak" type="data_package" /> - </outputs> - <release seq="1"> - <structures fallback_to_low_resolution="true"> - <structure type="chrome_html" name="IDR_UASTYLE_MEDIA_CONTROLS_TOUCHLESS_CSS" file="mediaControlsTouchless.css" flattenhtml="true" compress="gzip"/> - </structures> - </release> -</grit> diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc deleted file mode 100644 index 25b68b98cb6..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc +++ /dev/null @@ -1,45 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h" - -namespace blink { - -mojo::PendingRemote<mojom::blink::MediaControlsMenuHost> -TestMediaControlsMenuHost::CreateMediaControlsMenuHostRemote() { - return receiver_.BindNewPipeAndPassRemote(); -} - -void TestMediaControlsMenuHost::ShowMediaMenu( - const WTF::Vector<mojom::MenuItem>& menu_items, - mojo::PendingRemote<mojom::blink::VideoState> video_state, - base::Optional<WTF::Vector<mojom::blink::TextTrackMetadataPtr>> text_tracks, - ShowMediaMenuCallback callback) { - arg_list_.menu_items = WTF::Vector<mojom::MenuItem>(menu_items); - - arg_list_.video_state = mojom::blink::VideoState::New(); - arg_list_.video_state->is_fullscreen = video_state->is_fullscreen; - arg_list_.video_state->is_muted = video_state->is_muted; - - arg_list_.text_tracks = WTF::Vector<mojom::blink::TextTrackMetadataPtr>( - std::move(text_tracks.value())); - - std::move(callback).Run(std::move(response_)); -} - -TestMenuHostArgList& TestMediaControlsMenuHost::GetMenuHostArgList() { - return arg_list_; -} - -void TestMediaControlsMenuHost::SetMenuResponse( - mojom::blink::MenuItem menu_item, - int track_index) { - if (response_.is_null()) - response_ = mojom::blink::MenuResponse::New(); - - response_->clicked = menu_item; - response_->track_index = track_index; -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h deleted file mode 100644 index 018022feaf0..00000000000 --- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h +++ /dev/null @@ -1,42 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_TEST_MEDIA_CONTROLS_MENU_HOST_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_TEST_MEDIA_CONTROLS_MENU_HOST_H_ - -#include "mojo/public/cpp/bindings/receiver.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/mojom/media_controls/touchless/media_controls.mojom-blink.h" - -namespace blink { - -struct TestMenuHostArgList { - WTF::Vector<mojom::MenuItem> menu_items; - mojom::blink::VideoStatePtr video_state; - WTF::Vector<mojom::blink::TextTrackMetadataPtr> text_tracks; -}; - -class TestMediaControlsMenuHost : public mojom::blink::MediaControlsMenuHost { - public: - mojo::PendingRemote<mojom::blink::MediaControlsMenuHost> - CreateMediaControlsMenuHostRemote(); - void ShowMediaMenu( - const WTF::Vector<mojom::MenuItem>& menu_items, - mojo::PendingRemote<mojom::blink::VideoState> video_state, - base::Optional<WTF::Vector<mojom::blink::TextTrackMetadataPtr>> - text_tracks, - ShowMediaMenuCallback callback) override; - - TestMenuHostArgList& GetMenuHostArgList(); - void SetMenuResponse(mojom::blink::MenuItem menu_item, int track_index); - - private: - mojo::Receiver<mojom::blink::MediaControlsMenuHost> receiver_{this}; - TestMenuHostArgList arg_list_; - mojo::Remote<mojom::blink::MenuResponse> response_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_TEST_MEDIA_CONTROLS_MENU_HOST_H_ diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/DEPS b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/DEPS index 1384f5ed1cd..725f02f25ef 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/DEPS +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/DEPS @@ -8,6 +8,7 @@ include_rules = [ "+cc/paint/paint_canvas.h", "+cc/paint/skia_paint_canvas.h", "+components/viz/common", + "+gpu/GLES2", "+media/base", "+media/capture", "+skia/ext/platform_canvas.h", diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.cc index 7bb34cb386e..cc92feb0861 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.cc +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.cc @@ -18,8 +18,7 @@ AutoCanvasDrawListener::AutoCanvasDrawListener( void AutoCanvasDrawListener::SendNewFrame( sk_sp<SkImage> image, base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider) { - handler_->SendNewFrame( - image, context_provider ? context_provider->ContextProvider() : nullptr); + handler_->SendNewFrame(image, context_provider); } bool AutoCanvasDrawListener::NeedsNewFrame() const { diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.h b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.h index 3523062c394..c3a22e22085 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.h +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/auto_canvas_draw_listener.h @@ -12,9 +12,8 @@ namespace blink { -class AutoCanvasDrawListener - : public GarbageCollectedFinalized<AutoCanvasDrawListener>, - public CanvasDrawListener { +class AutoCanvasDrawListener : public GarbageCollected<AutoCanvasDrawListener>, + public CanvasDrawListener { USING_GARBAGE_COLLECTED_MIXIN(AutoCanvasDrawListener); public: diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.cc index fcab7d34fdf..25f4949f127 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.cc +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.cc @@ -21,6 +21,7 @@ #include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h" +#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/text/base64.h" #include "third_party/libyuv/include/libyuv.h" @@ -171,7 +172,8 @@ CanvasCaptureHandler::CreateCanvasCaptureHandler( void CanvasCaptureHandler::SendNewFrame( sk_sp<SkImage> image, - blink::WebGraphicsContext3DProvider* context_provider) { + base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper> + context_provider) { DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_); TRACE_EVENT0("webrtc", "CanvasCaptureHandler::SendNewFrame"); if (!image) @@ -209,7 +211,7 @@ void CanvasCaptureHandler::SendNewFrame( if (image->isOpaque()) { ReadYUVPixelsAsync(image, context_provider); } else { - ReadARGBPixelsAsync(image, context_provider); + ReadARGBPixelsAsync(image, context_provider->ContextProvider()); } } @@ -289,6 +291,7 @@ void CanvasCaptureHandler::ReadARGBPixelsAsync( sk_sp<SkImage> image, blink::WebGraphicsContext3DProvider* context_provider) { DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_); + DCHECK(context_provider); const base::TimeTicks timestamp = base::TimeTicks::Now(); const gfx::Size image_size(image->width(), image->height()); @@ -308,7 +311,7 @@ void CanvasCaptureHandler::ReadARGBPixelsAsync( DCHECK(result); DCHECK(context_provider->GetGLHelper()); context_provider->GetGLHelper()->ReadbackTextureAsync( - texture_info.fID, image_size, + texture_info.fID, texture_info.fTarget, image_size, temp_argb_frame->visible_data(VideoFrame::kARGBPlane), kN32_SkColorType, WTF::Bind(&CanvasCaptureHandler::OnARGBPixelsReadAsync, weak_ptr_factory_.GetWeakPtr(), image, temp_argb_frame, @@ -317,8 +320,10 @@ void CanvasCaptureHandler::ReadARGBPixelsAsync( void CanvasCaptureHandler::ReadYUVPixelsAsync( sk_sp<SkImage> image, - blink::WebGraphicsContext3DProvider* context_provider) { + base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper> + context_provider) { DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_); + DCHECK(context_provider); const base::TimeTicks timestamp = base::TimeTicks::Now(); const gfx::Size image_size(image->width(), image->height()); @@ -337,12 +342,36 @@ void CanvasCaptureHandler::ReadYUVPixelsAsync( GrGLTextureInfo texture_info; const bool result = backend_texture.getGLTextureInfo(&texture_info); DCHECK(result); - DCHECK(context_provider->GetGLHelper()); + + // The YUV readback path only works for 2D textures. + GLuint texture_for_readback = texture_info.fID; + GLuint copy_texture = 0; + if (texture_info.fTarget != GL_TEXTURE_2D) { + auto* gl = context_provider->ContextProvider()->ContextGL(); + int width = image->imageInfo().width(); + int height = image->imageInfo().height(); + + gl->GenTextures(1, ©_texture); + gl->BindTexture(GL_TEXTURE_2D, copy_texture); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, nullptr); + gl->CopyTextureCHROMIUM(texture_info.fID, 0, GL_TEXTURE_2D, copy_texture, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0, 0, 0); + image = nullptr; + texture_for_readback = copy_texture; + } + + DCHECK(context_provider->ContextProvider()->GetGLHelper()); viz::ReadbackYUVInterface* const yuv_reader = - context_provider->GetGLHelper()->GetReadbackPipelineYUV( - surface_origin != kTopLeft_GrSurfaceOrigin); + context_provider->ContextProvider() + ->GetGLHelper() + ->GetReadbackPipelineYUV(surface_origin != kTopLeft_GrSurfaceOrigin); yuv_reader->ReadbackYUV( - texture_info.fID, image_size, gfx::Rect(image_size), + texture_for_readback, image_size, gfx::Rect(image_size), output_frame->stride(media::VideoFrame::kYPlane), output_frame->visible_data(media::VideoFrame::kYPlane), output_frame->stride(media::VideoFrame::kUPlane), @@ -350,8 +379,8 @@ void CanvasCaptureHandler::ReadYUVPixelsAsync( output_frame->stride(media::VideoFrame::kVPlane), output_frame->visible_data(media::VideoFrame::kVPlane), gfx::Point(0, 0), WTF::Bind(&CanvasCaptureHandler::OnYUVPixelsReadAsync, - weak_ptr_factory_.GetWeakPtr(), image, output_frame, - timestamp)); + weak_ptr_factory_.GetWeakPtr(), image, copy_texture, + context_provider, output_frame, timestamp)); } void CanvasCaptureHandler::OnARGBPixelsReadAsync( @@ -384,10 +413,17 @@ void CanvasCaptureHandler::OnARGBPixelsReadAsync( void CanvasCaptureHandler::OnYUVPixelsReadAsync( sk_sp<SkImage> image, + GLuint copy_texture, + base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper> context_provider, scoped_refptr<media::VideoFrame> yuv_frame, base::TimeTicks this_frame_ticks, bool success) { DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_); + if (copy_texture && context_provider) { + context_provider->ContextProvider()->ContextGL()->DeleteTextures( + 1, ©_texture); + } + if (!success) { DLOG(ERROR) << "Couldn't read SkImage using async callback"; return; diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.h b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.h index 907dd5dcdf6..e685d093040 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.h +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.h @@ -15,6 +15,7 @@ #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_checker.h" +#include "gpu/GLES2/gl2extchromium.h" #include "media/base/video_frame_pool.h" #include "media/capture/video_capturer_source.h" #include "third_party/blink/public/platform/web_media_stream_track.h" @@ -28,6 +29,7 @@ namespace blink { class LocalFrame; class WebGraphicsContext3DProvider; +class WebGraphicsContext3DProviderWrapper; // CanvasCaptureHandler acts as the link between Blink side HTMLCanvasElement // and Chrome side VideoCapturerSource. It is responsible for handling @@ -51,7 +53,8 @@ class MODULES_EXPORT CanvasCaptureHandler { blink::WebMediaStreamTrack* track); void SendNewFrame(sk_sp<SkImage> image, - blink::WebGraphicsContext3DProvider* context_provider); + base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper> + context_provider); bool NeedsNewFrame() const; // Functions called by media::VideoCapturerSource implementation. @@ -82,16 +85,21 @@ class MODULES_EXPORT CanvasCaptureHandler { blink::WebGraphicsContext3DProvider* context_provider); void ReadYUVPixelsAsync( sk_sp<SkImage> image, - blink::WebGraphicsContext3DProvider* context_provider); + base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper> + context_provider); void OnARGBPixelsReadAsync(sk_sp<SkImage> image, scoped_refptr<media::VideoFrame> temp_argb_frame, base::TimeTicks this_frame_ticks, bool flip, bool success); - void OnYUVPixelsReadAsync(sk_sp<SkImage> image, - scoped_refptr<media::VideoFrame> yuv_frame, - base::TimeTicks this_frame_ticks, - bool success); + void OnYUVPixelsReadAsync( + sk_sp<SkImage> image, + GLuint copy_texture, + base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper> + context_provider, + scoped_refptr<media::VideoFrame> yuv_frame, + base::TimeTicks this_frame_ticks, + bool success); scoped_refptr<media::VideoFrame> ConvertToYUVFrame( bool is_opaque, diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc index a2129ed72a8..e4b9b8d8741 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc @@ -122,12 +122,15 @@ void HtmlVideoElementCapturerSource::sendNewFrame() { const base::TimeTicks current_time = base::TimeTicks::Now(); if (start_capture_time_.is_null()) start_capture_time_ = current_time; - const blink::WebSize resolution = web_media_player_->NaturalSize(); if (!canvas_ || is_opaque_ != web_media_player_->IsOpaque()) { + // TODO(crbug.com/964494): Avoid the explicit conversion to gfx::Size here. + // TODO(sandersd): Implement support for size changes rather than scaling. + if (!canvas_) + natural_size_ = gfx::Size(web_media_player_->NaturalSize()); is_opaque_ = web_media_player_->IsOpaque(); if (!bitmap_.tryAllocPixels(SkImageInfo::MakeN32( - resolution.width, resolution.height, + natural_size_.width(), natural_size_.height(), is_opaque_ ? kOpaque_SkAlphaType : kPremul_SkAlphaType))) { running_callback_.Run(false); return; @@ -138,12 +141,11 @@ void HtmlVideoElementCapturerSource::sendNewFrame() { cc::PaintFlags flags; flags.setBlendMode(SkBlendMode::kSrc); flags.setFilterQuality(kLow_SkFilterQuality); - web_media_player_->Paint( - canvas_.get(), blink::WebRect(0, 0, resolution.width, resolution.height), - flags); + // TODO(crbug.com/964494): Avoid the explicit conversion to blink::WebRect + // here. + web_media_player_->Paint(canvas_.get(), + blink::WebRect(gfx::Rect(natural_size_)), flags); DCHECK_NE(kUnknown_SkColorType, canvas_->imageInfo().colorType()); - DCHECK_EQ(canvas_->imageInfo().width(), resolution.width); - DCHECK_EQ(canvas_->imageInfo().height(), resolution.height); DCHECK_NE(kUnknown_SkColorType, bitmap_.colorType()); DCHECK(!bitmap_.drawsNothing()); @@ -153,11 +155,9 @@ void HtmlVideoElementCapturerSource::sendNewFrame() { return; } - // TODO(crbug.com/964494): Avoid the explicit convertion to gfx::Size here. - gfx::Size gfx_resolution = gfx::Size(resolution); scoped_refptr<media::VideoFrame> frame = frame_pool_.CreateFrame( is_opaque_ ? media::PIXEL_FORMAT_I420 : media::PIXEL_FORMAT_I420A, - gfx_resolution, gfx::Rect(gfx_resolution), gfx_resolution, + natural_size_, gfx::Rect(natural_size_), natural_size_, current_time - start_capture_time_); const uint32_t source_pixel_format = diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.h b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.h index 2ba15320bfa..081ea9dfb25 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.h +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.h @@ -64,6 +64,7 @@ class MODULES_EXPORT HtmlVideoElementCapturerSource final media::VideoFramePool frame_pool_; SkBitmap bitmap_; std::unique_ptr<cc::PaintCanvas> canvas_; + gfx::Size natural_size_; const base::WeakPtr<blink::WebMediaPlayer> web_media_player_; const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc index c2c1bb0611f..c0c0ffe3013 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc @@ -58,8 +58,8 @@ class MockWebMediaPlayer : public WebMediaPlayer { WebSetSinkIdCompleteCallback) override {} bool HasVideo() const override { return true; } bool HasAudio() const override { return false; } - WebSize NaturalSize() const override { return WebSize(16, 10); } - WebSize VisibleRect() const override { return WebSize(16, 10); } + WebSize NaturalSize() const override { return size_; } + WebSize VisibleRect() const override { return size_; } bool Paused() const override { return false; } bool Seeking() const override { return false; } double Duration() const override { return 0.0; } @@ -98,6 +98,7 @@ class MockWebMediaPlayer : public WebMediaPlayer { } bool is_video_opaque_ = true; + WebSize size_ = WebSize(16, 10); base::WeakPtrFactory<MockWebMediaPlayer> weak_factory_{this}; }; @@ -128,6 +129,8 @@ class HTMLVideoElementCapturerSourceTest : public testing::TestWithParam<bool> { web_media_player_->is_video_opaque_ = opacity; } + void SetVideoPlayerSize(WebSize size) { web_media_player_->size_ = size; } + protected: std::unique_ptr<MockWebMediaPlayer> web_media_player_; std::unique_ptr<HtmlVideoElementCapturerSource> html_video_capturer_; @@ -284,4 +287,48 @@ TEST_F(HTMLVideoElementCapturerSourceTest, AlphaAndNot) { Mock::VerifyAndClearExpectations(this); } +// Verify that changes in the natural size of the source WebMediaPlayer do not +// crash. +// TODO(crbug.com/1817203): Verify that size changes are fully supported. +TEST_F(HTMLVideoElementCapturerSourceTest, SizeChange) { + InSequence s; + media::VideoCaptureFormats formats = + html_video_capturer_->GetPreferredFormats(); + media::VideoCaptureParams params; + params.requested_format = formats[0]; + + { + SetVideoPlayerSize(WebSize(16, 10)); + + base::RunLoop run_loop; + base::RepeatingClosure quit_closure = run_loop.QuitClosure(); + scoped_refptr<media::VideoFrame> frame; + EXPECT_CALL(*this, DoOnRunning(true)).Times(1); + EXPECT_CALL(*this, DoOnDeliverFrame(_, _)) + .WillOnce( + DoAll(SaveArg<0>(&frame), RunClosure2(std::move(quit_closure)))); + html_video_capturer_->StartCapture( + params, + WTF::BindRepeating(&HTMLVideoElementCapturerSourceTest::OnDeliverFrame, + base::Unretained(this)), + WTF::BindRepeating(&HTMLVideoElementCapturerSourceTest::OnRunning, + base::Unretained(this))); + run_loop.Run(); + } + { + SetVideoPlayerSize(WebSize(32, 20)); + + base::RunLoop run_loop; + base::RepeatingClosure quit_closure = run_loop.QuitClosure(); + scoped_refptr<media::VideoFrame> frame; + EXPECT_CALL(*this, DoOnDeliverFrame(_, _)) + .WillOnce( + DoAll(SaveArg<0>(&frame), RunClosure2(std::move(quit_closure)))); + run_loop.Run(); + } + + html_video_capturer_->StopCapture(); + Mock::VerifyAndClearExpectations(this); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/DEPS b/chromium/third_party/blink/renderer/modules/mediarecorder/DEPS index 2e96f7b831f..d7451d8d225 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/DEPS +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/DEPS @@ -22,5 +22,6 @@ include_rules = [ specific_include_rules = { ".*_unittest.cc": [ "+base/run_loop.h", + "+ui/gfx/gpu_memory_buffer.h", ], } diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h b/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h index d8a87a0d3cc..48ff1e9cbd9 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.h @@ -32,7 +32,7 @@ class Thread; // which lives an AudioTrackEncoder with its own threading subtleties, see the // implementation file. class MODULES_EXPORT AudioTrackRecorder - : public GarbageCollectedFinalized<AudioTrackRecorder>, + : public GarbageCollected<AudioTrackRecorder>, public WebMediaStreamAudioSink { USING_PRE_FINALIZER(AudioTrackRecorder, Prefinalize); diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc index 44aafb7115b..106f651eeb9 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc @@ -4,8 +4,9 @@ #include "third_party/blink/renderer/modules/mediarecorder/blob_event.h" +#include <cmath> + #include "third_party/blink/renderer/modules/mediarecorder/blob_event_init.h" -#include "third_party/blink/renderer/platform/wtf/dtoa/double.h" namespace blink { @@ -34,9 +35,7 @@ void BlobEvent::Trace(blink::Visitor* visitor) { BlobEvent::BlobEvent(const AtomicString& type, const BlobEventInit* initializer) : Event(type, initializer), blob_(initializer->data()), - timecode_(initializer->hasTimecode() - ? initializer->timecode() - : WTF::double_conversion::Double::NaN()) {} + timecode_(initializer->hasTimecode() ? initializer->timecode() : NAN) {} BlobEvent::BlobEvent(const AtomicString& type, Blob* blob, double timecode) : Event(type, Bubbles::kNo, Cancelable::kNo), diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc index 3764fbcf01f..add1b5c9aad 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc @@ -57,6 +57,9 @@ void H264Encoder::EncodeOnEncodingTaskRunner( TRACE_EVENT0("media", "H264Encoder::EncodeOnEncodingTaskRunner"); DCHECK(encoding_task_runner_->BelongsToCurrentThread()); + if (frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) + frame = ConvertToI420ForSoftwareEncoder(frame); + const gfx::Size frame_size = frame->visible_rect().size(); if (!openh264_encoder_ || configured_size_ != frame_size) { ConfigureEncoderOnEncodingTaskRunner(frame_size); diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc index 297295cbab7..9767c19a276 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc @@ -16,13 +16,13 @@ #include "media/base/video_codecs.h" #include "media/base/video_frame.h" #include "media/muxers/webm_muxer.h" -#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_info.h" -#include "third_party/blink/public/platform/modules/media_capabilities/web_media_configuration.h" #include "third_party/blink/public/platform/modules/mediastream/webrtc_uma_histograms.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" #include "third_party/blink/renderer/modules/mediarecorder/buildflags.h" #include "third_party/blink/renderer/modules/mediarecorder/media_recorder.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/media_capabilities/web_media_capabilities_info.h" +#include "third_party/blink/renderer/platform/media_capabilities/web_media_configuration.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h" #include "third_party/blink/renderer/platform/wtf/functional.h" diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h index 7c3da873a9c..1ebb7dbd574 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.h @@ -42,9 +42,8 @@ struct WebMediaConfiguration; // All methods are called on the same thread as construction and destruction, // i.e. the Main Render thread. (Note that a BindToCurrentLoop is used to // guarantee this, since VideoTrackRecorder sends back frames on IO thread.) -class MODULES_EXPORT MediaRecorderHandler - : public GarbageCollectedFinalized<MediaRecorderHandler> { - +class MODULES_EXPORT MediaRecorderHandler final + : public GarbageCollected<MediaRecorderHandler> { public: static MediaRecorderHandler* Create( scoped_refptr<base::SingleThreadTaskRunner> task_runner); diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc index 8da2d01bc5e..38d5b4248a7 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc @@ -41,6 +41,7 @@ scoped_refptr<VEAEncoder> VEAEncoder::Create( int32_t bits_per_second, media::VideoCodecProfile codec, const gfx::Size& size, + bool use_native_input, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { auto encoder = base::AdoptRef( new VEAEncoder(on_encoded_video_callback, on_error_callback, @@ -48,7 +49,7 @@ scoped_refptr<VEAEncoder> VEAEncoder::Create( PostCrossThreadTask( *encoder->encoding_task_runner_.get(), FROM_HERE, CrossThreadBindOnce(&VEAEncoder::ConfigureEncoderOnEncodingTaskRunner, - encoder, size)); + encoder, size, use_native_input)); return encoder; } @@ -186,8 +187,12 @@ void VEAEncoder::EncodeOnEncodingTaskRunner(scoped_refptr<VideoFrame> frame, if (input_visible_size_ != frame->visible_rect().size() && video_encoder_) video_encoder_.reset(); - if (!video_encoder_) - ConfigureEncoderOnEncodingTaskRunner(frame->visible_rect().size()); + if (!video_encoder_) { + bool use_native_input = + frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER; + ConfigureEncoderOnEncodingTaskRunner(frame->visible_rect().size(), + use_native_input); + } if (error_notified_) { DVLOG(3) << "An error occurred in VEA encoder"; @@ -214,13 +219,16 @@ void VEAEncoder::EncodeOnEncodingTaskRunner(scoped_refptr<VideoFrame> frame, // Therefore, a copy is necessary to release the current frame. // Only STORAGE_SHMEM backed frames can be shared with GPU process, therefore // a copy is required for other storage types. + // With STORAGE_GPU_MEMORY_BUFFER we delay the scaling of the frame to the end + // of the encoding pipeline. scoped_refptr<media::VideoFrame> video_frame = frame; bool can_share_frame = (video_frame->storage_type() == media::VideoFrame::STORAGE_SHMEM); - if (!can_share_frame || - vea_requested_input_coded_size_ != frame->coded_size() || - input_visible_size_.width() < kVEAEncoderMinResolutionWidth || - input_visible_size_.height() < kVEAEncoderMinResolutionHeight) { + if (frame->storage_type() != media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER && + (!can_share_frame || + vea_requested_input_coded_size_ != frame->coded_size() || + input_visible_size_.width() < kVEAEncoderMinResolutionWidth || + input_visible_size_.height() < kVEAEncoderMinResolutionHeight)) { // Create SharedMemory backed input buffers as necessary. These SharedMemory // instances will be shared with GPU process. const size_t desired_mapped_size = media::VideoFrame::AllocationSize( @@ -274,7 +282,8 @@ void VEAEncoder::EncodeOnEncodingTaskRunner(scoped_refptr<VideoFrame> frame, force_next_frame_to_be_keyframe_ = false; } -void VEAEncoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) { +void VEAEncoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size, + bool use_native_input) { DVLOG(3) << __func__; DCHECK(encoding_task_runner_->BelongsToCurrentThread()); DCHECK(gpu_factories_->GetTaskRunner()->BelongsToCurrentThread()); @@ -283,8 +292,20 @@ void VEAEncoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) { input_visible_size_ = size; vea_requested_input_coded_size_ = gfx::Size(); video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator(); + + auto pixel_format = media::VideoPixelFormat::PIXEL_FORMAT_I420; + auto storage_type = + media::VideoEncodeAccelerator::Config::StorageType::kShmem; + if (use_native_input) { + // Currently the VAAPI and V4L2 VEA support only native input mode with NV12 + // DMA-buf buffers. + pixel_format = media::PIXEL_FORMAT_NV12; + storage_type = media::VideoEncodeAccelerator::Config::StorageType::kDmabuf; + } const media::VideoEncodeAccelerator::Config config( - media::PIXEL_FORMAT_I420, input_visible_size_, codec_, bits_per_second_); + pixel_format, input_visible_size_, codec_, bits_per_second_, + base::nullopt, base::nullopt, base::nullopt, storage_type, + media::VideoEncodeAccelerator::Config::ContentType::kCamera); if (!video_encoder_ || !video_encoder_->Initialize(config, this)) NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); } diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h b/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h index 743ebe05623..e7f63b76f1e 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h @@ -35,6 +35,7 @@ class VEAEncoder final : public VideoTrackRecorder::Encoder, int32_t bits_per_second, media::VideoCodecProfile codec, const gfx::Size& size, + bool use_native_input, scoped_refptr<base::SingleThreadTaskRunner> task_runner); // media::VideoEncodeAccelerator::Client implementation. @@ -73,7 +74,8 @@ class VEAEncoder final : public VideoTrackRecorder::Encoder, void EncodeOnEncodingTaskRunner(scoped_refptr<media::VideoFrame> frame, base::TimeTicks capture_timestamp) override; - void ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size); + void ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size, + bool use_native_input); void DestroyOnEncodingTaskRunner(base::WaitableEvent* async_waiter = nullptr); diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc index c84797f978b..e0b291a0080 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc @@ -125,6 +125,8 @@ VideoTrackRecorder::CodecEnumerator::CodecEnumerator( if (codec >= codec_id_and_profile.min_profile && codec <= codec_id_and_profile.max_profile) { DVLOG(2) << "Accelerated codec found: " << media::GetProfileName(codec) + << ", min_resolution: " + << supported_profile.min_resolution.ToString() << ", max_resolution: " << supported_profile.max_resolution.ToString() << ", max_framerate: " @@ -243,7 +245,9 @@ void VideoTrackRecorder::Encoder::StartFrameEncode( return; } - if (video_frame->HasTextures()) { + if (video_frame->HasTextures() && + video_frame->storage_type() != + media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) { PostCrossThreadTask( *main_task_runner_.get(), FROM_HERE, CrossThreadBindOnce(&Encoder::RetrieveFrameOnMainThread, @@ -253,28 +257,27 @@ void VideoTrackRecorder::Encoder::StartFrameEncode( return; } - scoped_refptr<media::VideoFrame> wrapped_frame; - // Drop alpha channel if the encoder does not support it yet. - if (!CanEncodeAlphaChannel() && - video_frame->format() == media::PIXEL_FORMAT_I420A) { - wrapped_frame = media::WrapAsI420VideoFrame(video_frame); - } else { - wrapped_frame = media::VideoFrame::WrapVideoFrame( - *video_frame, video_frame->format(), video_frame->visible_rect(), - video_frame->natural_size()); + scoped_refptr<media::VideoFrame> frame = video_frame; + if (frame->storage_type() != media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) { + // Drop alpha channel if the encoder does not support it yet. + if (!CanEncodeAlphaChannel() && + video_frame->format() == media::PIXEL_FORMAT_I420A) { + frame = media::WrapAsI420VideoFrame(video_frame); + } else { + frame = media::VideoFrame::WrapVideoFrame( + video_frame, video_frame->format(), video_frame->visible_rect(), + video_frame->natural_size()); + } } - wrapped_frame->AddDestructionObserver(media::BindToCurrentLoop( + frame->AddDestructionObserver(media::BindToCurrentLoop( WTF::Bind(&VideoTrackRecorder::Counter::DecreaseCount, num_frames_in_encode_->GetWeakPtr()))); - wrapped_frame->AddDestructionObserver(ConvertToBaseOnceCallback( - CrossThreadBindOnce([](scoped_refptr<VideoFrame> video_frame) {}, - std::move(video_frame)))); num_frames_in_encode_->IncreaseCount(); - PostCrossThreadTask(*encoding_task_runner_.get(), FROM_HERE, - CrossThreadBindOnce(&Encoder::EncodeOnEncodingTaskRunner, - WrapRefCounted(this), wrapped_frame, - capture_timestamp)); + PostCrossThreadTask( + *encoding_task_runner_.get(), FROM_HERE, + CrossThreadBindOnce(&Encoder::EncodeOnEncodingTaskRunner, + WrapRefCounted(this), frame, capture_timestamp)); } void VideoTrackRecorder::Encoder::RetrieveFrameOnMainThread( @@ -393,6 +396,37 @@ bool VideoTrackRecorder::Encoder::CanEncodeAlphaChannel() { } // static +scoped_refptr<media::VideoFrame> +VideoTrackRecorder::Encoder::ConvertToI420ForSoftwareEncoder( + scoped_refptr<media::VideoFrame> frame) { + DCHECK_EQ(frame->storage_type(), + media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER); + // NV12 is currently the only supported pixel format for GpuMemoryBuffer. + DCHECK_EQ(frame->format(), media::VideoPixelFormat::PIXEL_FORMAT_NV12); + + auto* gmb = frame->GetGpuMemoryBuffer(); + if (!gmb->Map()) + return frame; + scoped_refptr<media::VideoFrame> i420_frame = media::VideoFrame::CreateFrame( + media::VideoPixelFormat::PIXEL_FORMAT_I420, frame->coded_size(), + frame->visible_rect(), frame->natural_size(), frame->timestamp()); + auto ret = libyuv::NV12ToI420( + static_cast<const uint8_t*>(gmb->memory(0)), gmb->stride(0), + static_cast<const uint8_t*>(gmb->memory(1)), gmb->stride(1), + i420_frame->data(media::VideoFrame::kYPlane), + i420_frame->stride(media::VideoFrame::kYPlane), + i420_frame->data(media::VideoFrame::kUPlane), + i420_frame->stride(media::VideoFrame::kUPlane), + i420_frame->data(media::VideoFrame::kVPlane), + i420_frame->stride(media::VideoFrame::kVPlane), + frame->coded_size().width(), frame->coded_size().height()); + gmb->Unmap(); + if (ret) + return frame; + return i420_frame; +} + +// static VideoTrackRecorder::CodecId VideoTrackRecorder::GetPreferredCodecId() { return GetCodecEnumerator()->GetPreferredCodecId(); } @@ -413,16 +447,20 @@ bool VideoTrackRecorder::CanUseAcceleratedEncoder(CodecId codec, if (profile.profile == media::VIDEO_CODEC_PROFILE_UNKNOWN) return false; + const gfx::Size& min_resolution = profile.min_resolution; + const size_t min_width = static_cast<size_t>( + std::max(kVEAEncoderMinResolutionWidth, min_resolution.width())); + const size_t min_height = static_cast<size_t>( + std::max(kVEAEncoderMinResolutionHeight, min_resolution.height())); + const gfx::Size& max_resolution = profile.max_resolution; DCHECK_GE(max_resolution.width(), 0); const size_t max_width = static_cast<size_t>(max_resolution.width()); DCHECK_GE(max_resolution.height(), 0); const size_t max_height = static_cast<size_t>(max_resolution.height()); - const bool width_within_range = - max_width >= width && width >= kVEAEncoderMinResolutionWidth; - const bool height_within_range = - max_height >= height && height >= kVEAEncoderMinResolutionHeight; + const bool width_within_range = max_width >= width && width >= min_width; + const bool height_within_range = max_height >= height && height >= min_height; const bool valid_framerate = framerate * profile.max_framerate_denominator <= profile.max_framerate_numerator; return width_within_range && height_within_range && valid_framerate; @@ -505,11 +543,14 @@ void VideoTrackRecorder::InitializeEncoder( UMA_HISTOGRAM_BOOLEAN("Media.MediaRecorder.VEAUsed", true); const auto vea_profile = GetCodecEnumerator()->GetFirstSupportedVideoCodecProfile(codec); + bool use_import_mode = + frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER; encoder_ = VEAEncoder::Create( on_encoded_video_callback, media::BindToCurrentLoop(WTF::BindRepeating( &VideoTrackRecorder::OnError, WrapWeakPersistent(this))), - bits_per_second, vea_profile, input_size, main_task_runner_); + bits_per_second, vea_profile, input_size, use_import_mode, + main_task_runner_); } else { UMA_HISTOGRAM_BOOLEAN("Media.MediaRecorder.VEAUsed", false); switch (codec) { diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h b/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h index c12dbbf4f01..a55085d7622 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h @@ -73,7 +73,7 @@ class Thread; // thread but that pass frames on Render IO thread. It has an internal Encoder // with its own threading subtleties, see the implementation file. class MODULES_EXPORT VideoTrackRecorder - : public GarbageCollectedFinalized<VideoTrackRecorder>, + : public GarbageCollected<VideoTrackRecorder>, public WebMediaStreamSink { USING_PRE_FINALIZER(VideoTrackRecorder, Prefinalize); @@ -184,6 +184,13 @@ class MODULES_EXPORT VideoTrackRecorder // Called when the frame reference is released after encode. void FrameReleased(scoped_refptr<media::VideoFrame> frame); + // A helper function to convert the given |frame| to an I420 video frame. + // Used mainly by the software encoders since I420 is the only supported + // pixel format. The function is best-effort. If for any reason the + // conversion fails, the original |frame| will be returned. + static scoped_refptr<media::VideoFrame> ConvertToI420ForSoftwareEncoder( + scoped_refptr<media::VideoFrame> frame); + // Used to shutdown properly on the same thread we were created. const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc index 68a2f2f42b8..797704c1e44 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc @@ -19,8 +19,10 @@ #include "third_party/blink/public/web/web_heap.h" #include "third_party/blink/renderer/modules/mediarecorder/buildflags.h" #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" +#include "third_party/blink/renderer/platform/testing/video_frame_utils.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/blink/renderer/platform/wtf/functional.h" +#include "ui/gfx/gpu_memory_buffer.h" using media::VideoFrame; using video_track_recorder::kVEAEncoderMinResolutionHeight; @@ -54,11 +56,16 @@ const gfx::Size kTrackRecorderTestSize[] = { gfx::Size(kVEAEncoderMinResolutionWidth / 2, kVEAEncoderMinResolutionHeight / 2), gfx::Size(kVEAEncoderMinResolutionWidth, kVEAEncoderMinResolutionHeight)}; +const media::VideoFrame::StorageType kStorageTypeToTest[] = { + media::VideoFrame::STORAGE_OWNED_MEMORY, + media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER}; static const int kTrackRecorderTestSizeDiff = 20; class VideoTrackRecorderTest - : public TestWithParam< - testing::tuple<VideoTrackRecorder::CodecId, gfx::Size, bool>> { + : public TestWithParam<testing::tuple<VideoTrackRecorder::CodecId, + gfx::Size, + bool, + media::VideoFrame::StorageType>> { public: VideoTrackRecorderTest() : mock_source_(new MockMediaStreamVideoSource()) { const WebString webkit_track_id(WebString::FromASCII("dummy")); @@ -162,9 +169,52 @@ TEST_P(VideoTrackRecorderTest, VideoEncoding) { const bool encode_alpha_channel = testing::get<2>(GetParam()); // |frame_size| cannot be arbitrarily small, should be reasonable. const gfx::Size& frame_size = testing::get<1>(GetParam()); + const media::VideoFrame::StorageType storage_type = + testing::get<3>(GetParam()); + + // We don't support alpha channel with GpuMemoryBuffer frames. + if (storage_type == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER && + encode_alpha_channel) { + return; + } + + auto create_test_frame = + [](media::VideoFrame::StorageType storage_type, + const gfx::Size& frame_size, + bool encode_alpha_channel) -> scoped_refptr<VideoFrame> { + scoped_refptr<VideoFrame> video_frame; + switch (storage_type) { + case media::VideoFrame::STORAGE_OWNED_MEMORY: + video_frame = encode_alpha_channel + ? VideoFrame::CreateTransparentFrame(frame_size) + : VideoFrame::CreateBlackFrame(frame_size); + break; + case media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER: { + video_frame = CreateTestFrame(frame_size, gfx::Rect(frame_size), + frame_size, storage_type); + // Create a black NV12 frame. + auto* gmb = video_frame->GetGpuMemoryBuffer(); + gmb->Map(); + const uint8_t kBlackY = 0x00; + const uint8_t kBlackUV = 0x80; + memset(static_cast<uint8_t*>(gmb->memory(0)), kBlackY, + gmb->stride(0) * frame_size.height()); + memset(static_cast<uint8_t*>(gmb->memory(1)), kBlackUV, + gmb->stride(1) * (frame_size.height() / 2)); + gmb->Unmap(); + break; + } + default: + DLOG(ERROR) << "Unexpected storage type"; + } + return video_frame; + }; + const scoped_refptr<VideoFrame> video_frame = - encode_alpha_channel ? VideoFrame::CreateTransparentFrame(frame_size) - : VideoFrame::CreateBlackFrame(frame_size); + create_test_frame(storage_type, frame_size, encode_alpha_channel); + if (!video_frame) + ASSERT_TRUE(!!video_frame); + const double kFrameRate = 60.0f; video_frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, kFrameRate); @@ -193,8 +243,7 @@ TEST_P(VideoTrackRecorderTest, VideoEncoding) { const gfx::Size frame_size2(frame_size.width() + kTrackRecorderTestSizeDiff, frame_size.height()); const scoped_refptr<VideoFrame> video_frame2 = - encode_alpha_channel ? VideoFrame::CreateTransparentFrame(frame_size2) - : VideoFrame::CreateBlackFrame(frame_size2); + create_test_frame(storage_type, frame_size2, encode_alpha_channel); base::RunLoop run_loop; base::Closure quit_closure = run_loop.QuitClosure(); @@ -215,7 +264,9 @@ TEST_P(VideoTrackRecorderTest, VideoEncoding) { EXPECT_GE(second_frame_encoded_data.size(), kEncodedSizeThreshold); EXPECT_GE(third_frame_encoded_data.size(), kEncodedSizeThreshold); - if (encode_alpha_channel && CanEncodeAlphaChannel()) { + // We only support NV12 with GpuMemoryBuffer video frame. + if (storage_type != media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER && + encode_alpha_channel && CanEncodeAlphaChannel()) { EXPECT_GE(first_frame_encoded_alpha.size(), kEncodedSizeThreshold); EXPECT_GE(second_frame_encoded_alpha.size(), kEncodedSizeThreshold); EXPECT_GE(third_frame_encoded_alpha.size(), kEncodedSizeThreshold); @@ -236,12 +287,24 @@ TEST_P(VideoTrackRecorderTest, EncodeFrameWithPaddedCodedSize) { const gfx::Size& frame_size = testing::get<1>(GetParam()); const size_t kCodedSizePadding = 16; - const scoped_refptr<VideoFrame> video_frame = - VideoFrame::CreateZeroInitializedFrame( - media::PIXEL_FORMAT_I420, - gfx::Size(frame_size.width() + kCodedSizePadding, - frame_size.height()), - gfx::Rect(frame_size), frame_size, base::TimeDelta()); + const media::VideoFrame::StorageType storage_type = + testing::get<3>(GetParam()); + const gfx::Size padded_size(frame_size.width() + kCodedSizePadding, + frame_size.height()); + scoped_refptr<VideoFrame> video_frame; + switch (storage_type) { + case media::VideoFrame::STORAGE_OWNED_MEMORY: + video_frame = VideoFrame::CreateZeroInitializedFrame( + media::PIXEL_FORMAT_I420, padded_size, gfx::Rect(frame_size), + frame_size, base::TimeDelta()); + break; + case media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER: + video_frame = CreateTestFrame(padded_size, gfx::Rect(frame_size), + frame_size, storage_type); + break; + default: + NOTREACHED() << "Unexpected storage type"; + } base::RunLoop run_loop; base::Closure quit_closure = run_loop.QuitClosure(); @@ -354,7 +417,8 @@ INSTANTIATE_TEST_SUITE_P(, VideoTrackRecorderTest, ::testing::Combine(ValuesIn(kTrackRecorderTestCodec), ValuesIn(kTrackRecorderTestSize), - ::testing::Bool())); + ::testing::Bool(), + ValuesIn(kStorageTypeToTest))); class CodecEnumeratorTest : public ::testing::Test { public: diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc index 5d1afe33d5a..57fca1b3a68 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc @@ -72,6 +72,9 @@ void VpxEncoder::EncodeOnEncodingTaskRunner(scoped_refptr<VideoFrame> frame, TRACE_EVENT0("media", "VpxEncoder::EncodeOnEncodingTaskRunner"); DCHECK(encoding_task_runner_->BelongsToCurrentThread()); + if (frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) + frame = ConvertToI420ForSoftwareEncoder(frame); + const gfx::Size frame_size = frame->visible_rect().size(); base::TimeDelta duration = EstimateFrameDuration(*frame); const media::WebmMuxer::VideoParameters video_params(frame); diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc index 44637c4fafa..999d75d511c 100644 --- a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc +++ b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.h" +#include "third_party/blink/public/mojom/mediasession/media_session.mojom-blink.h" #include "third_party/blink/public/platform/web_icon_sizes_parser.h" #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/public/platform/web_string.h" diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.h b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.h index 28c0d454a6c..ac3300b91bf 100644 --- a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.h +++ b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata_sanitizer.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASESSION_MEDIA_METADATA_SANITIZER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASESSION_MEDIA_METADATA_SANITIZER_H_ -#include "third_party/blink/public/mojom/mediasession/media_session.mojom-blink.h" +#include "third_party/blink/public/mojom/mediasession/media_session.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc b/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc index f194a6404cd..bd6d83f5184 100644 --- a/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc +++ b/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc @@ -6,7 +6,7 @@ #include <memory> #include "base/optional.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_session_action_handler.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -320,7 +320,7 @@ mojom::blink::MediaSessionService* MediaSession::GetService() { // See https://bit.ly/2S0zRAS for task types. auto task_runner = GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI); - frame->GetInterfaceProvider().GetInterface( + frame->GetBrowserInterfaceBroker().GetInterface( service_.BindNewPipeAndPassReceiver()); if (service_.get()) { // Record the eTLD+1 of the frame using the API. diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc b/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc index 045b6a0ae29..9e24dab598b 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc +++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source.cc @@ -533,10 +533,6 @@ WebTimeRanges MediaSource::SeekableInternal() const { return ranges; } -TimeRanges* MediaSource::Seekable() const { - return MakeGarbageCollected<TimeRanges>(SeekableInternal()); -} - void MediaSource::OnTrackChanged(TrackBase* track) { DCHECK(HTMLMediaElement::MediaTracksEnabledInternally()); SourceBuffer* source_buffer = diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source.h b/chromium/third_party/blink/renderer/modules/mediasource/media_source.h index 09e586748cd..de8973e436c 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/media_source.h +++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source.h @@ -102,7 +102,6 @@ class MediaSource final : public EventTargetWithInlineData, WebTimeRanges BufferedInternal() const override; WebTimeRanges SeekableInternal() const override; TimeRanges* Buffered() const override; - TimeRanges* Seekable() const override; void OnTrackChanged(TrackBase*) override; // EventTarget interface diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc index c74de365208..e6e82edff11 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc +++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc @@ -1149,6 +1149,16 @@ void SourceBuffer::NotifyParseWarning(const ParseWarning warning) { UseCounter::Count(source_->MediaElement()->GetDocument(), WebFeature::kMediaSourceMuxedSequenceMode); break; + case WebSourceBufferClient::kGroupEndTimestampDecreaseWithinMediaSegment: + // Report this problematic Media Segment structure usage to help inform + // follow-up work. + // TODO(wolenetz): Use the data to scope additional work. See + // https://crbug.com/920853 and + // https://github.com/w3c/media-source/issues/203. + UseCounter::Count( + source_->MediaElement()->GetDocument(), + WebFeature::kMediaSourceGroupEndTimestampDecreaseWithinMediaSegment); + break; } } diff --git a/chromium/third_party/blink/renderer/modules/mediasource/track_default.cc b/chromium/third_party/blink/renderer/modules/mediasource/track_default.cc index 46283ee2c13..c9373a99ad3 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/track_default.cc +++ b/chromium/third_party/blink/renderer/modules/mediasource/track_default.cc @@ -29,7 +29,7 @@ const AtomicString& TrackDefault::TextKeyword() { } ScriptValue TrackDefault::kinds(ScriptState* script_state) const { - return ScriptValue(script_state, ToV8(kinds_, script_state)); + return ScriptValue(script_state->GetIsolate(), ToV8(kinds_, script_state)); } TrackDefault* TrackDefault::Create(const AtomicString& type, diff --git a/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn b/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn index f33987b6828..dbc9febb592 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn @@ -3,6 +3,7 @@ # found in the LICENSE file. import("//build/config/jumbo.gni") +import("//media/webrtc/audio_processing.gni") import("//third_party/blink/renderer/modules/modules.gni") blink_modules_sources("mediastream") { @@ -89,6 +90,7 @@ blink_modules_sources("mediastream") { ] deps = [ "//media/capture/mojom:image_capture_blink", + "//media/webrtc", ] } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/DEPS b/chromium/third_party/blink/renderer/modules/mediastream/DEPS index 5ec9ce3d062..59774da88d5 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/DEPS +++ b/chromium/third_party/blink/renderer/modules/mediastream/DEPS @@ -61,5 +61,8 @@ specific_include_rules = { "+base/files/scoped_temp_dir.h", "+base/memory/aligned_memory.h", "+base/path_service.h", + "+base/test/bind_test_util.h", + "+base/threading/thread.h", + "+third_party/blink/renderer/platform/testing/video_frame_utils.h", ], } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc index 1af65160117..e4b9a61ab06 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc @@ -8,6 +8,7 @@ #include "base/location.h" #include "base/single_thread_task_runner.h" +#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" #include "third_party/blink/public/platform/web_media_stream_source.h" #include "third_party/blink/public/platform/web_media_stream_track.h" @@ -349,7 +350,7 @@ void ApplyConstraintsProcessor::CleanupRequest( video_source_ = nullptr; } -const blink::mojom::blink::MediaDevicesDispatcherHostPtr& +blink::mojom::blink::MediaDevicesDispatcherHost* ApplyConstraintsProcessor::GetMediaDevicesDispatcher() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return media_devices_dispatcher_cb_.Run(); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h index 96933f41210..49c9dd49232 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.h @@ -10,7 +10,8 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread_checker.h" #include "media/capture/video_capture_types.h" -#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink-forward.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h" #include "third_party/blink/renderer/modules/mediastream/apply_constraints_request.h" @@ -26,11 +27,11 @@ class MediaStreamVideoTrack; // requests. Only one applyConstraints() request can be processed at a time. // ApplyConstraintsProcessor must be created, called and destroyed on the main // render thread. There should be only one ApplyConstraintsProcessor per frame. -class MODULES_EXPORT ApplyConstraintsProcessor - : public GarbageCollectedFinalized<ApplyConstraintsProcessor> { +class MODULES_EXPORT ApplyConstraintsProcessor final + : public GarbageCollected<ApplyConstraintsProcessor> { public: using MediaDevicesDispatcherCallback = base::RepeatingCallback< - const blink::mojom::blink::MediaDevicesDispatcherHostPtr&()>; + blink::mojom::blink::MediaDevicesDispatcherHost*()>; ApplyConstraintsProcessor( MediaDevicesDispatcherCallback media_devices_dispatcher_cb, scoped_refptr<base::SingleThreadTaskRunner> task_runner); @@ -75,8 +76,7 @@ class MODULES_EXPORT ApplyConstraintsProcessor void ApplyConstraintsFailed(const char* failed_constraint_name); void CannotApplyConstraints(const String& message); void CleanupRequest(base::OnceClosure web_request_callback); - const blink::mojom::blink::MediaDevicesDispatcherHostPtr& - GetMediaDevicesDispatcher(); + blink::mojom::blink::MediaDevicesDispatcherHost* GetMediaDevicesDispatcher(); // ApplyConstraints requests are processed sequentially. |current_request_| // contains the request currently being processed, if any. diff --git a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h index ab728233c37..798e4032f04 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h @@ -16,7 +16,7 @@ namespace blink { class ScriptPromiseResolver; class MODULES_EXPORT ApplyConstraintsRequest final - : public GarbageCollectedFinalized<ApplyConstraintsRequest> { + : public GarbageCollected<ApplyConstraintsRequest> { public: static ApplyConstraintsRequest* CreateForTesting(const WebMediaStreamTrack&, const WebMediaConstraints&); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/input_device_info.cc b/chromium/third_party/blink/renderer/modules/mediastream/input_device_info.cc index cf2b6e5dab4..77403396b62 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/input_device_info.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/input_device_info.cc @@ -8,6 +8,7 @@ #include "build/build_config.h" #include "media/base/sample_format.h" +#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" #include "third_party/blink/public/platform/web_media_stream_track.h" diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.cc index bddcf8cca3f..fa1f3dd489f 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.cc @@ -25,6 +25,7 @@ #include "third_party/blink/renderer/modules/mediastream/media_device_info.h" +#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.h b/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.h index a2f807ee08c..4b47acf6150 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_device_info.h @@ -26,7 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_DEVICE_INFO_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_MEDIA_DEVICE_INFO_H_ -#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h" +#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/heap_allocator.h" diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc index 4ea5988ca47..faaaf763bb5 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc @@ -7,8 +7,8 @@ #include <utility> #include "mojo/public/cpp/bindings/remote.h" -#include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/platform/modules/mediastream/webrtc_uma_histograms.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -64,7 +64,7 @@ MediaDevices::MediaDevices(ExecutionContext* context) MediaDevices::~MediaDevices() = default; ScriptPromise MediaDevices::enumerateDevices(ScriptState* script_state) { - Platform::Current()->UpdateWebRTCAPICount(WebRTCAPIName::kEnumerateDevices); + UpdateWebRTCMethodCount(WebRTCAPIName::kEnumerateDevices); LocalFrame* frame = To<Document>(ExecutionContext::From(script_state))->GetFrame(); if (!frame) { @@ -346,7 +346,7 @@ void MediaDevices::OnDispatcherHostConnectionError() { const mojo::Remote<mojom::blink::MediaDevicesDispatcherHost>& MediaDevices::GetDispatcherHost(LocalFrame* frame) { if (!dispatcher_host_) { - frame->GetInterfaceProvider().GetInterface( + frame->GetBrowserInterfaceBroker().GetInterface( dispatcher_host_.BindNewPipeAndPassReceiver()); dispatcher_host_.set_disconnect_handler( WTF::Bind(&MediaDevices::OnDispatcherHostConnectionError, diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc index 0147fb818e3..287276312cb 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices_test.cc @@ -179,6 +179,7 @@ class PromiseObserver { bool isFulfilled() { return is_fulfilled_; } bool isRejected() { return is_rejected_; } ScriptValue argument() { return saved_arg_; } + void Trace(blink::Visitor* visitor) { visitor->Trace(saved_arg_); } private: class MyScriptFunction : public ScriptFunction { diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc index 24499bd1a0c..3bf00e9d36a 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.cc @@ -134,13 +134,13 @@ VideoCaptureSettings::VideoCaptureSettings( VideoCaptureSettings::VideoCaptureSettings(const VideoCaptureSettings& other) = default; -VideoCaptureSettings::VideoCaptureSettings( - VideoCaptureSettings&& other) noexcept = default; +VideoCaptureSettings::VideoCaptureSettings(VideoCaptureSettings&& other) = + default; VideoCaptureSettings::~VideoCaptureSettings() = default; VideoCaptureSettings& VideoCaptureSettings::operator=( const VideoCaptureSettings& other) = default; VideoCaptureSettings& VideoCaptureSettings::operator=( - VideoCaptureSettings&& other) noexcept = default; + VideoCaptureSettings&& other) = default; AudioCaptureSettings::AudioCaptureSettings() : AudioCaptureSettings("") {} @@ -166,10 +166,10 @@ AudioCaptureSettings::AudioCaptureSettings(const AudioCaptureSettings& other) = default; AudioCaptureSettings& AudioCaptureSettings::operator=( const AudioCaptureSettings& other) = default; -AudioCaptureSettings::AudioCaptureSettings( - AudioCaptureSettings&& other) noexcept = default; +AudioCaptureSettings::AudioCaptureSettings(AudioCaptureSettings&& other) = + default; AudioCaptureSettings& AudioCaptureSettings::operator=( - AudioCaptureSettings&& other) noexcept = default; + AudioCaptureSettings&& other) = default; bool GetConstraintValueAsBoolean( const WebMediaConstraints& constraints, diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.cc index f2884c59e50..1a2a3bdf292 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.cc @@ -16,6 +16,7 @@ #include "media/audio/audio_features.h" #include "media/base/audio_parameters.h" #include "media/base/limits.h" +#include "media/webrtc/webrtc_switches.h" #include "third_party/blink/public/common/mediastream/media_stream_controls.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_processor_options.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" @@ -1011,7 +1012,7 @@ class DeviceContainer { } if (is_reconfiguration_allowed || source_info.type() == SourceType::kNone || source_info.type() == SourceType::kApmProcessed) { - if (IsApmInAudioServiceEnabled()) { + if (media::IsWebRtcApmInAudioServiceEnabled()) { processing_based_containers_.push_back( ProcessingBasedContainer::CreateRemoteApmProcessedContainer( source_info, is_device_capture, device_parameters_, diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc index e5605bb8797..e062b237394 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio_test.cc @@ -34,22 +34,6 @@ using blink::AudioCaptureSettings; using blink::AudioProcessingProperties; using EchoCancellationType = AudioProcessingProperties::EchoCancellationType; -// Test blink::Platform imlementation that overrides the known methods needed -// by the tests, including creation of WebRtcAudioDevice instances. -class WebRtcAudioDeviceTestingPlatformSupport - : public IOTaskRunnerTestingPlatformSupport { - public: - WebRtcAudioDeviceTestingPlatformSupport() - : webrtc_audio_device_( - new rtc::RefCountedObject<WebRtcAudioDeviceImpl>()) {} - blink::WebRtcAudioDeviceImpl* GetWebRtcAudioDevice() override { - return webrtc_audio_device_.get(); - } - - private: - scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device_; -}; - namespace { using BoolSetFunction = void (blink::BooleanConstraint::*)(bool); @@ -450,8 +434,7 @@ class MediaStreamConstraintsUtilAudioTestBase { blink::WebString::FromASCII("system")}; private: - ScopedTestingPlatformSupport<WebRtcAudioDeviceTestingPlatformSupport> - platform_; + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; }; class MediaStreamConstraintsUtilAudioTest @@ -1916,7 +1899,7 @@ TEST_P(MediaStreamConstraintsRemoteAPMTest, Channels) { constraint_factory_.basic().echo_cancellation.SetExact(true); result = SelectSettings(); - if (IsApmInAudioServiceEnabled() && GetParam()) + if (media::IsWebRtcApmInAudioServiceEnabled() && GetParam()) EXPECT_FALSE(result.HasValue()); else EXPECT_TRUE(result.HasValue()); @@ -1933,7 +1916,7 @@ TEST_P(MediaStreamConstraintsRemoteAPMTest, SampleRate) { constraint_factory_.basic().echo_cancellation.SetExact(true); result = SelectSettings(); - if (IsApmInAudioServiceEnabled() && GetParam()) + if (media::IsWebRtcApmInAudioServiceEnabled() && GetParam()) EXPECT_TRUE(result.HasValue()); else EXPECT_FALSE(result.HasValue()); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc index 96992217b9c..67c8babd6f2 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.cc @@ -529,9 +529,9 @@ VideoInputDeviceCapabilities::VideoInputDeviceCapabilities( facing_mode(facing_mode) {} VideoInputDeviceCapabilities::VideoInputDeviceCapabilities( - VideoInputDeviceCapabilities&& other) noexcept = default; + VideoInputDeviceCapabilities&& other) = default; VideoInputDeviceCapabilities& VideoInputDeviceCapabilities::operator=( - VideoInputDeviceCapabilities&& other) noexcept = default; + VideoInputDeviceCapabilities&& other) = default; VideoInputDeviceCapabilities::~VideoInputDeviceCapabilities() = default; @@ -557,10 +557,10 @@ WebMediaStreamTrack::FacingMode ToWebFacingMode( VideoDeviceCaptureCapabilities::VideoDeviceCaptureCapabilities() = default; VideoDeviceCaptureCapabilities::VideoDeviceCaptureCapabilities( - VideoDeviceCaptureCapabilities&& other) noexcept = default; + VideoDeviceCaptureCapabilities&& other) = default; VideoDeviceCaptureCapabilities::~VideoDeviceCaptureCapabilities() = default; VideoDeviceCaptureCapabilities& VideoDeviceCaptureCapabilities::operator=( - VideoDeviceCaptureCapabilities&& other) noexcept = default; + VideoDeviceCaptureCapabilities&& other) = default; VideoCaptureSettings SelectSettingsVideoDeviceCapture( const VideoDeviceCaptureCapabilities& capabilities, diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h index 66ae103f079..94d8ed9616a 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h @@ -34,9 +34,8 @@ struct MODULES_EXPORT VideoInputDeviceCapabilities { Vector<media::VideoCaptureFormat> formats, media::VideoFacingMode facing_mode); VideoInputDeviceCapabilities(); - VideoInputDeviceCapabilities(VideoInputDeviceCapabilities&& other) noexcept; - VideoInputDeviceCapabilities& operator=( - VideoInputDeviceCapabilities&& other) noexcept; + VideoInputDeviceCapabilities(VideoInputDeviceCapabilities&& other); + VideoInputDeviceCapabilities& operator=(VideoInputDeviceCapabilities&& other); ~VideoInputDeviceCapabilities(); String device_id; @@ -47,11 +46,10 @@ struct MODULES_EXPORT VideoInputDeviceCapabilities { struct MODULES_EXPORT VideoDeviceCaptureCapabilities { VideoDeviceCaptureCapabilities(); - VideoDeviceCaptureCapabilities( - VideoDeviceCaptureCapabilities&& other) noexcept; + VideoDeviceCaptureCapabilities(VideoDeviceCaptureCapabilities&& other); ~VideoDeviceCaptureCapabilities(); VideoDeviceCaptureCapabilities& operator=( - VideoDeviceCaptureCapabilities&& other) noexcept; + VideoDeviceCaptureCapabilities&& other); // Each capabilities field is independent of each other. // TODO(crbug.com/704136): Replace VideoInputDeviceCapabilities in the diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc index 9c372261685..0ff66af2433 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.cc @@ -49,7 +49,7 @@ MediaStreamDeviceObserver::MediaStreamDeviceObserver(WebLocalFrame* frame) { static_cast<LocalFrame*>(WebFrame::ToCoreFrame(*frame)) ->GetInterfaceRegistry() ->AddInterface(WTF::BindRepeating( - &MediaStreamDeviceObserver::BindMediaStreamDeviceObserverRequest, + &MediaStreamDeviceObserver::BindMediaStreamDeviceObserverReceiver, WTF::Unretained(this))); } @@ -133,7 +133,7 @@ void MediaStreamDeviceObserver::OnDeviceChanged( } } -void MediaStreamDeviceObserver::BindMediaStreamDeviceObserverRequest( +void MediaStreamDeviceObserver::BindMediaStreamDeviceObserverReceiver( mojo::PendingReceiver<mojom::blink::MediaStreamDeviceObserver> receiver) { receiver_.Bind(std::move(receiver)); } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h index b79f3e4b306..cf4477650a1 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer.h @@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "third_party/blink/public/common/mediastream/media_stream_request.h" #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h" @@ -75,7 +76,7 @@ class MODULES_EXPORT MediaStreamDeviceObserver const MediaStreamDevice& old_device, const MediaStreamDevice& new_device) override; - void BindMediaStreamDeviceObserverRequest( + void BindMediaStreamDeviceObserverReceiver( mojo::PendingReceiver<mojom::blink::MediaStreamDeviceObserver> receiver); mojo::Receiver<mojom::blink::MediaStreamDeviceObserver> receiver_{this}; diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_renderer_factory_impl.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_renderer_factory_impl.cc index fdab8d44177..5b43153396e 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_renderer_factory_impl.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_renderer_factory_impl.cc @@ -11,6 +11,7 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_media_stream.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" +#include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h" #include "third_party/blink/public/web/modules/webrtc/webrtc_audio_device_impl.h" #include "third_party/blink/public/web/modules/webrtc/webrtc_audio_renderer.h" #include "third_party/blink/public/web/web_local_frame.h" @@ -32,7 +33,7 @@ namespace { // will not be able to pick an appropriate device and return 0. base::UnguessableToken GetSessionIdForWebRtcAudioRenderer() { WebRtcAudioDeviceImpl* audio_device = - Platform::Current()->GetWebRtcAudioDevice(); + PeerConnectionDependencyFactory::GetInstance()->GetWebRtcAudioDevice(); return audio_device ? audio_device->GetAuthorizedDeviceSessionIdForAudioRenderer() : base::UnguessableToken(); @@ -117,7 +118,7 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer( // This is a remote WebRTC media stream. WebRtcAudioDeviceImpl* audio_device = - Platform::Current()->GetWebRtcAudioDevice(); + PeerConnectionDependencyFactory::GetInstance()->GetWebRtcAudioDevice(); DCHECK(audio_device); // Share the existing renderer if any, otherwise create a new one. @@ -128,8 +129,10 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer( DVLOG(1) << "Creating WebRtcAudioRenderer for remote WebRTC track."; renderer = new WebRtcAudioRenderer( - Platform::Current()->GetWebRtcSignalingTaskRunner(), web_stream, - web_frame, GetSessionIdForWebRtcAudioRenderer(), device_id.Utf8()); + PeerConnectionDependencyFactory::GetInstance() + ->GetWebRtcSignalingTaskRunner(), + web_stream, web_frame, GetSessionIdForWebRtcAudioRenderer(), + device_id.Utf8()); if (!audio_device->SetAudioRenderer(renderer.get())) { WebRtcLogMessage("Error: SetAudioRenderer failed for remote track."); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc index ebc845f2ca6..3305239635b 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.cc @@ -7,7 +7,7 @@ #include <utility> #include "media/capture/video_capturer_source.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -210,7 +210,7 @@ mojom::blink::MediaStreamDispatcherHost* MediaStreamVideoCapturerSource::GetMediaStreamDispatcherHost() { DCHECK(frame_); if (!host_) { - frame_->GetInterfaceProvider().GetInterface( + frame_->GetBrowserInterfaceBroker().GetInterface( host_.BindNewPipeAndPassReceiver()); } return host_.get(); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc index eeef014b9ad..d0e7e2d3908 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc @@ -83,6 +83,9 @@ class MediaStreamVideoRendererSink::FrameDeliverer { media::VideoFrame::CreateBlackFrame( state_ == STOPPED ? gfx::Size(kMinFrameSize, kMinFrameSize) : frame_size_); + if (!video_frame) + return; + video_frame->metadata()->SetBoolean( media::VideoFrameMetadata::END_OF_STREAM, true); video_frame->metadata()->SetTimeTicks( diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc index 7651e4761a6..99759c1041b 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_source.cc @@ -461,10 +461,10 @@ MediaStreamVideoSource::PendingTrackInfo::PendingTrackInfo( callback(callback) {} MediaStreamVideoSource::PendingTrackInfo::PendingTrackInfo( - PendingTrackInfo&& other) noexcept = default; + PendingTrackInfo&& other) = default; MediaStreamVideoSource::PendingTrackInfo& MediaStreamVideoSource::PendingTrackInfo::operator=( - MediaStreamVideoSource::PendingTrackInfo&& other) noexcept = default; + MediaStreamVideoSource::PendingTrackInfo&& other) = default; MediaStreamVideoSource::PendingTrackInfo::~PendingTrackInfo() {} diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc index 8508564ede1..676dacd7faf 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc @@ -35,10 +35,6 @@ void ResetCallback( // |callback| will be deleted when this exits. } -// Empty method used for keeping a reference to the original media::VideoFrame. -// The reference to |frame| is kept in the closure that calls this method. -void ReleaseOriginalFrame(scoped_refptr<media::VideoFrame> frame) {} - } // namespace // MediaStreamVideoTrack::FrameDeliverer is a helper class used for registering @@ -230,13 +226,11 @@ MediaStreamVideoTrack::FrameDeliverer::GetBlackFrame( // Wrap |black_frame_| so we get a fresh timestamp we can modify. Frames // returned from this function may still be in use. scoped_refptr<media::VideoFrame> wrapped_black_frame = - media::VideoFrame::WrapVideoFrame(*black_frame_, black_frame_->format(), + media::VideoFrame::WrapVideoFrame(black_frame_, black_frame_->format(), black_frame_->visible_rect(), black_frame_->natural_size()); if (!wrapped_black_frame) return nullptr; - wrapped_black_frame->AddDestructionObserver(ConvertToBaseOnceCallback( - CrossThreadBindOnce(&ReleaseOriginalFrame, black_frame_))); wrapped_black_frame->set_timestamp(reference_frame.timestamp()); base::TimeTicks reference_time; diff --git a/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc b/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc index 7dee5233acb..2dfc83085ac 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc @@ -21,6 +21,7 @@ #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h" +#include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h" #include "third_party/blink/public/web/modules/webrtc/webrtc_audio_device_impl.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_audio_processor.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_local_frame_wrapper.h" @@ -83,14 +84,6 @@ void LogAudioProcesingProperties( } } // namespace -bool IsApmInAudioServiceEnabled() { -#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) - return base::FeatureList::IsEnabled(features::kWebRtcApmInAudioService); -#else - return false; -#endif -} - ProcessedLocalAudioSource::ProcessedLocalAudioSource( WebLocalFrame* web_frame, const blink::MediaStreamDevice& device, @@ -202,7 +195,7 @@ bool ProcessedLocalAudioSource::EnsureSourceIsStarted() { // Create the MediaStreamAudioProcessor, bound to the WebRTC audio device // module. WebRtcAudioDeviceImpl* const rtc_audio_device = - Platform::Current()->GetWebRtcAudioDevice(); + PeerConnectionDependencyFactory::GetInstance()->GetWebRtcAudioDevice(); if (!rtc_audio_device) { blink::WebRtcLogMessage( "ProcessedLocalAudioSource::EnsureSourceIsStarted() fails" @@ -267,7 +260,7 @@ bool ProcessedLocalAudioSource::EnsureSourceIsStarted() { DCHECK(params.IsValid()); media::AudioSourceParameters source_params(device().session_id()); const bool use_remote_apm = - IsApmInAudioServiceEnabled() && + media::IsWebRtcApmInAudioServiceEnabled() && MediaStreamAudioProcessor::WouldModifyAudio(audio_processing_properties_); if (use_remote_apm) { audio_processor_proxy_ = @@ -326,7 +319,8 @@ void ProcessedLocalAudioSource::EnsureSourceIsStopped() { scoped_refptr<media::AudioCapturerSource> source_to_stop(std::move(source_)); if (WebRtcAudioDeviceImpl* rtc_audio_device = - Platform::Current()->GetWebRtcAudioDevice()) { + PeerConnectionDependencyFactory::GetInstance() + ->GetWebRtcAudioDevice()) { rtc_audio_device->RemoveAudioCapturer(this); } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source_test.cc index 3a6d0a9e3d6..9ea18522cc6 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source_test.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/processed_local_audio_source_test.cc @@ -69,14 +69,11 @@ MockAudioCapturerSource::MockAudioCapturerSource() {} MockAudioCapturerSource::~MockAudioCapturerSource() {} // Test Platform implementation that overrides the known methods needed -// by the tests, including creation of WebRtcAudioDevice and -// AudioCapturerSource instances. -class WebRtcAudioDeviceTestingPlatformSupport : public TestingPlatformSupport { +// by the tests, including creation of AudioCapturerSource instances. +class AudioCapturerSourceTestingPlatformSupport + : public TestingPlatformSupport { public: - WebRtcAudioDeviceTestingPlatformSupport() = default; - WebRtcAudioDeviceImpl* GetWebRtcAudioDevice() override { - return audio_device_.get(); - } + AudioCapturerSourceTestingPlatformSupport() = default; scoped_refptr<media::AudioCapturerSource> NewAudioCapturerSource( WebLocalFrame* web_frame, @@ -91,8 +88,6 @@ class WebRtcAudioDeviceTestingPlatformSupport : public TestingPlatformSupport { } private: - scoped_refptr<blink::WebRtcAudioDeviceImpl> audio_device_ = - new rtc::RefCountedObject<blink::WebRtcAudioDeviceImpl>(); scoped_refptr<MockAudioCapturerSource> mock_audio_capturer_source_ = base::MakeRefCounted<MockAudioCapturerSource>(); }; @@ -188,7 +183,7 @@ class ProcessedLocalAudioSourceTest : public testing::Test { } private: - ScopedTestingPlatformSupport<WebRtcAudioDeviceTestingPlatformSupport> + ScopedTestingPlatformSupport<AudioCapturerSourceTestingPlatformSupport> webrtc_audio_device_platform_support_; WebMediaStreamSource blink_audio_source_; WebMediaStreamTrack blink_audio_track_; diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc index 316c44b9bfe..377ab1191cf 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.cc @@ -11,7 +11,7 @@ #include "base/location.h" #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/modules/mediastream/webrtc_uma_histograms.h" #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h" #include "third_party/blink/public/platform/platform.h" @@ -88,7 +88,7 @@ UserMediaClient::UserMediaClient( MakeGarbageCollected<ApplyConstraintsProcessor>( WTF::BindRepeating( [](UserMediaClient* client) - -> const mojom::blink::MediaDevicesDispatcherHostPtr& { + -> mojom::blink::MediaDevicesDispatcherHost* { // |client| is guaranteed to be not null because |client| // owns this ApplyConstraintsProcessor. DCHECK(client); @@ -113,7 +113,7 @@ UserMediaClient::UserMediaClient( frame, WTF::BindRepeating( [](UserMediaClient* client) - -> const mojom::blink::MediaDevicesDispatcherHostPtr& { + -> mojom::blink::MediaDevicesDispatcherHost* { // |client| is guaranteed to be not null because |client| // owns this UserMediaProcessor. DCHECK(client); @@ -295,19 +295,19 @@ void UserMediaClient::Trace(Visitor* visitor) { } void UserMediaClient::SetMediaDevicesDispatcherForTesting( - blink::mojom::blink::MediaDevicesDispatcherHostPtr + mojo::PendingRemote<blink::mojom::blink::MediaDevicesDispatcherHost> media_devices_dispatcher) { - media_devices_dispatcher_ = std::move(media_devices_dispatcher); + media_devices_dispatcher_.Bind(std::move(media_devices_dispatcher)); } -const blink::mojom::blink::MediaDevicesDispatcherHostPtr& +blink::mojom::blink::MediaDevicesDispatcherHost* UserMediaClient::GetMediaDevicesDispatcher() { if (!media_devices_dispatcher_) { - frame_->GetInterfaceProvider().GetInterface( - mojo::MakeRequest(&media_devices_dispatcher_)); + frame_->GetBrowserInterfaceBroker().GetInterface( + media_devices_dispatcher_.BindNewPipeAndPassReceiver()); } - return media_devices_dispatcher_; + return media_devices_dispatcher_.get(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h index a955fd2665b..f6c403a8750 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client.h @@ -10,8 +10,10 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/threading/thread_checker.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/common/mediastream/media_devices.h" -#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h" +#include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink-forward.h" #include "third_party/blink/public/web/web_user_media_request.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/modules/mediastream/apply_constraints_request.h" @@ -32,7 +34,7 @@ class LocalFrame; // object. This includes getUserMedia and enumerateDevices. It must be created, // called and destroyed on the render thread. class MODULES_EXPORT UserMediaClient - : public GarbageCollectedFinalized<UserMediaClient> { + : public GarbageCollected<UserMediaClient> { public: // TODO(guidou): Make all constructors private and replace with Create methods // that return a std::unique_ptr. This class is intended for instantiation on @@ -56,11 +58,11 @@ class MODULES_EXPORT UserMediaClient void Trace(Visitor*); void SetMediaDevicesDispatcherForTesting( - blink::mojom::blink::MediaDevicesDispatcherHostPtr + mojo::PendingRemote<blink::mojom::blink::MediaDevicesDispatcherHost> media_devices_dispatcher); private: - class Request : public GarbageCollectedFinalized<Request> { + class Request final : public GarbageCollected<Request> { public: explicit Request(std::unique_ptr<UserMediaRequestInfo> request); explicit Request(blink::ApplyConstraintsRequest* request); @@ -98,8 +100,7 @@ class MODULES_EXPORT UserMediaClient void DeleteAllUserMediaRequests(); - const blink::mojom::blink::MediaDevicesDispatcherHostPtr& - GetMediaDevicesDispatcher(); + blink::mojom::blink::MediaDevicesDispatcherHost* GetMediaDevicesDispatcher(); // LocalFrame instance associated with the UserMediaController that // own this UserMediaClient. @@ -112,7 +113,8 @@ class MODULES_EXPORT UserMediaClient // problems in builds that do not include WebRTC. Member<ApplyConstraintsProcessor> apply_constraints_processor_; - blink::mojom::blink::MediaDevicesDispatcherHostPtr media_devices_dispatcher_; + mojo::Remote<blink::mojom::blink::MediaDevicesDispatcherHost> + media_devices_dispatcher_; // UserMedia requests are processed sequentially. |is_processing_request_| // is a flag that indicates if a request is being processed at a given time, diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc index 62b0c3d6700..617e292cd21 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc @@ -15,7 +15,7 @@ #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "media/audio/audio_device_description.h" -#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/receiver.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/mediastream/media_devices.h" #include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h" @@ -311,7 +311,7 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor { UserMediaProcessorUnderTest( std::unique_ptr<blink::WebMediaStreamDeviceObserver> media_stream_device_observer, - blink::mojom::blink::MediaDevicesDispatcherHostPtr + mojo::PendingRemote<blink::mojom::blink::MediaDevicesDispatcherHost> media_devices_dispatcher, RequestState* state) : UserMediaProcessor( @@ -326,9 +326,9 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor { SetMediaStreamDeviceObserverForTesting(media_stream_device_observer_.get()); } - const blink::mojom::blink::MediaDevicesDispatcherHostPtr& - media_devices_dispatcher() const { - return media_devices_dispatcher_; + blink::mojom::blink::MediaDevicesDispatcherHost* media_devices_dispatcher() + const { + return media_devices_dispatcher_.get(); } MockMediaStreamVideoCapturerSource* last_created_video_source() const { @@ -433,7 +433,8 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor { } std::unique_ptr<WebMediaStreamDeviceObserver> media_stream_device_observer_; - blink::mojom::blink::MediaDevicesDispatcherHostPtr media_devices_dispatcher_; + mojo::Remote<blink::mojom::blink::MediaDevicesDispatcherHost> + media_devices_dispatcher_; MockMediaStreamVideoCapturerSource* video_source_ = nullptr; MockLocalMediaStreamAudioSource* local_audio_source_ = nullptr; bool create_source_that_fails_ = false; @@ -477,31 +478,24 @@ class UserMediaClientUnderTest : public UserMediaClient { class UserMediaClientTest : public ::testing::Test { public: UserMediaClientTest() - : binding_user_media_processor_(&media_devices_dispatcher_), - binding_user_media_client_(&media_devices_dispatcher_) {} + : user_media_processor_receiver_(&media_devices_dispatcher_), + user_media_client_receiver_(&media_devices_dispatcher_) {} void SetUp() override { // Create our test object. auto* msd_observer = new blink::WebMediaStreamDeviceObserver(nullptr); - blink::mojom::blink::MediaDevicesDispatcherHostPtr - user_media_processor_host_proxy; - binding_user_media_processor_.Bind( - mojo::MakeRequest(&user_media_processor_host_proxy)); user_media_processor_ = MakeGarbageCollected<UserMediaProcessorUnderTest>( base::WrapUnique(msd_observer), - std::move(user_media_processor_host_proxy), &state_); + user_media_processor_receiver_.BindNewPipeAndPassRemote(), &state_); user_media_processor_->set_media_stream_dispatcher_host_for_testing( mock_dispatcher_host_.CreatePendingRemoteAndBind()); user_media_client_impl_ = MakeGarbageCollected<UserMediaClientUnderTest>( user_media_processor_, &state_); - blink::mojom::blink::MediaDevicesDispatcherHostPtr - user_media_client_host_proxy; - binding_user_media_client_.Bind( - mojo::MakeRequest(&user_media_client_host_proxy)); + user_media_client_impl_->SetMediaDevicesDispatcherForTesting( - std::move(user_media_client_host_proxy)); + user_media_client_receiver_.BindNewPipeAndPassRemote()); } void TearDown() override { @@ -646,10 +640,10 @@ class UserMediaClientTest : public ::testing::Test { testing_platform_; MockMojoMediaStreamDispatcherHost mock_dispatcher_host_; MockMediaDevicesDispatcherHost media_devices_dispatcher_; - mojo::Binding<blink::mojom::blink::MediaDevicesDispatcherHost> - binding_user_media_processor_; - mojo::Binding<blink::mojom::blink::MediaDevicesDispatcherHost> - binding_user_media_client_; + mojo::Receiver<blink::mojom::blink::MediaDevicesDispatcherHost> + user_media_processor_receiver_; + mojo::Receiver<blink::mojom::blink::MediaDevicesDispatcherHost> + user_media_client_receiver_; WeakPersistent<UserMediaProcessorUnderTest> user_media_processor_; Persistent<UserMediaClientUnderTest> user_media_client_impl_; diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.h b/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.h index a214acfef74..d674cb7271c 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.h @@ -37,10 +37,9 @@ class ApplyConstraintsRequest; class MediaStreamComponent; class UserMediaRequest; -class UserMediaController final - : public GarbageCollectedFinalized<UserMediaController>, - public Supplement<LocalFrame>, - public ContextLifecycleObserver { +class UserMediaController final : public GarbageCollected<UserMediaController>, + public Supplement<LocalFrame>, + public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(UserMediaController); public: diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.cc b/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.cc index a99fd495096..8dda7e5c342 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.cc @@ -17,7 +17,7 @@ #include "base/strings/stringprintf.h" #include "media/base/audio_parameters.h" #include "media/capture/video_capture_types.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/common/mediastream/media_stream_controls.h" #include "third_party/blink/public/common/mediastream/media_stream_request.h" #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" @@ -263,8 +263,8 @@ UserMediaRequestInfo::UserMediaRequestInfo( is_processing_user_gesture(is_processing_user_gesture) {} // Class for storing state of the the processing of getUserMedia requests. -class UserMediaProcessor::RequestInfo - : public GarbageCollectedFinalized<UserMediaProcessor::RequestInfo> { +class UserMediaProcessor::RequestInfo final + : public GarbageCollected<UserMediaProcessor::RequestInfo> { public: using ResourcesReady = base::OnceCallback<void(RequestInfo* request_info, @@ -516,6 +516,11 @@ void UserMediaProcessor::ProcessRequest( DCHECK(!current_request_info_); request_completed_cb_ = std::move(callback); current_request_info_ = MakeGarbageCollected<RequestInfo>(std::move(request)); + blink::WebRtcLogMessage(base::StringPrintf( + "UMP::ProcessRequest. request_id = %d. Has audio = %d. Has video = %d.", + current_request_info_->request_id(), + current_request_info_->request()->web_request.Audio(), + current_request_info_->request()->web_request.Video())); // TODO(guidou): Set up audio and video in parallel. if (current_request_info_->web_request().Audio()) { SetupAudioInput(); @@ -528,6 +533,14 @@ void UserMediaProcessor::SetupAudioInput() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(current_request_info_); DCHECK(current_request_info_->web_request().Audio()); + blink::WebRtcLogMessage(base::StringPrintf( + "UMP::SetupAudioInput. request_id = %d, audio constraints = %s", + current_request_info_->request_id(), + current_request_info_->request() + ->web_request.AudioConstraints() + .ToString() + .Utf8() + .c_str())); auto& audio_controls = current_request_info_->stream_controls()->audio; InitializeAudioTrackControls(current_request_info_->web_request(), @@ -540,6 +553,10 @@ void UserMediaProcessor::SetupAudioInput() { } if (blink::IsDeviceMediaType(audio_controls.stream_type)) { + blink::WebRtcLogMessage( + base::StringPrintf("UMP::SetupAudioInput. request_id = %d, " + "Requesting device capabilities", + current_request_info_->request_id())); GetMediaDevicesDispatcher()->GetAudioInputCapabilities(WTF::Bind( &UserMediaProcessor::SelectAudioDeviceSettings, WrapWeakPersistent(this), current_request_info_->web_request())); @@ -605,6 +622,9 @@ void UserMediaProcessor::SelectAudioSettings( return; DCHECK(current_request_info_->stream_controls()->audio.requested); + blink::WebRtcLogMessage( + base::StringPrintf("UMP::SelectAudioSettings. request_id = %d.", + current_request_info_->request_id())); auto settings = SelectSettingsAudioCapture( capabilities, web_request.AudioConstraints(), web_request.ShouldDisableHardwareNoiseSuppression(), @@ -681,6 +701,14 @@ void UserMediaProcessor::SetupVideoInput() { : StreamSelectionStrategy::FORCE_NEW_STREAM); return; } + blink::WebRtcLogMessage(base::StringPrintf( + "UMP::SetupVideoInput. request_id = %d, video constraints = %s", + current_request_info_->request_id(), + current_request_info_->request() + ->web_request.VideoConstraints() + .ToString() + .Utf8() + .c_str())); auto& video_controls = current_request_info_->stream_controls()->video; InitializeVideoTrackControls(current_request_info_->web_request(), @@ -719,6 +747,9 @@ void UserMediaProcessor::SelectVideoDeviceSettings( DCHECK(current_request_info_->stream_controls()->video.requested); DCHECK(blink::IsDeviceMediaType( current_request_info_->stream_controls()->video.stream_type)); + blink::WebRtcLogMessage( + base::StringPrintf("UMP::SelectVideoDeviceSettings. request_id = %d.", + current_request_info_->request_id())); blink::VideoDeviceCaptureCapabilities capabilities; capabilities.device_capabilities = @@ -744,12 +775,25 @@ void UserMediaProcessor::SelectVideoDeviceSettings( settings.device_id(); current_request_info_->SetVideoCaptureSettings( settings, false /* is_content_capture */); - GenerateStreamForCurrentRequestInfo(); + + if (current_request_info_->web_request().Audio()) { + base::Optional<base::UnguessableToken> audio_session_id = + DetermineExistingAudioSessionId(); + GenerateStreamForCurrentRequestInfo( + audio_session_id, audio_session_id.has_value() + ? StreamSelectionStrategy::SEARCH_BY_SESSION_ID + : StreamSelectionStrategy::FORCE_NEW_STREAM); + } else { + GenerateStreamForCurrentRequestInfo(); + } } void UserMediaProcessor::SelectVideoContentSettings() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(current_request_info_); + blink::WebRtcLogMessage( + base::StringPrintf("UMP::SelectVideoContentSettings. request_id = %d.", + current_request_info_->request_id())); gfx::Size screen_size = GetScreenSize(); blink::VideoCaptureSettings settings = blink::SelectSettingsVideoContentCapture( @@ -781,7 +825,7 @@ void UserMediaProcessor::GenerateStreamForCurrentRequestInfo( DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(current_request_info_); blink::WebRtcLogMessage(base::StringPrintf( - "UMCI::GenerateStreamForCurrentRequestInfo. request_id=%d, " + "UMP::GenerateStreamForCurrentRequestInfo. request_id=%d, " "audio device id=\"%s\", video device id=\"%s\"", current_request_info_->request_id(), current_request_info_->stream_controls()->audio.device_id.c_str(), @@ -805,9 +849,7 @@ UserMediaProcessor::GetMediaStreamDeviceObserver() { media_stream_device_observer_for_testing_; if (frame_) { // Can be null for tests. auto* web_frame = static_cast<WebLocalFrame*>(WebFrame::FromFrame(frame_)); - DCHECK(web_frame); - - if (!web_frame->Client()) + if (!web_frame || !web_frame->Client()) return nullptr; // TODO(704136): Move ownership of |WebMediaStreamDeviceObserver| out of @@ -827,7 +869,6 @@ void UserMediaProcessor::OnStreamGenerated( const Vector<MediaStreamDevice>& audio_devices, const Vector<MediaStreamDevice>& video_devices) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (result != MediaStreamRequestResult::OK) { OnStreamGenerationFailed(request_id, result); return; @@ -840,13 +881,16 @@ void UserMediaProcessor::OnStreamGenerated( OnStreamGeneratedForCancelledRequest(audio_devices, video_devices); return; } + blink::WebRtcLogMessage( + base::StringPrintf("UMP::OnStreamGenerated. request_id = %d.", + current_request_info_->request_id())); current_request_info_->set_state(RequestInfo::State::GENERATED); for (const auto* devices : {&audio_devices, &video_devices}) { for (const auto& device : *devices) { blink::WebRtcLogMessage(base::StringPrintf( - "UMCI::OnStreamGenerated. request_id=%d, device id=\"%s\", " + "UMP::OnStreamGenerated. request_id=%d, device id=\"%s\", " "device name=\"%s\"", request_id, device.id.c_str(), device.name.c_str())); } @@ -905,7 +949,8 @@ gfx::Size UserMediaProcessor::GetScreenSize() { gfx::Size screen_size(blink::kDefaultScreenCastWidth, blink::kDefaultScreenCastHeight); if (frame_) { // Can be null in tests. - blink::WebScreenInfo info = frame_->GetChromeClient().GetScreenInfo(); + blink::WebScreenInfo info = + frame_->GetChromeClient().GetScreenInfo(*frame_); screen_size = gfx::Size(info.rect.width, info.rect.height); } return screen_size; @@ -914,6 +959,7 @@ gfx::Size UserMediaProcessor::GetScreenSize() { void UserMediaProcessor::OnStreamGeneratedForCancelledRequest( const Vector<MediaStreamDevice>& audio_devices, const Vector<MediaStreamDevice>& video_devices) { + blink::WebRtcLogMessage("UMP::OnStreamGeneratedForCancelledRequest."); // Only stop the device if the device is not used in another MediaStream. for (auto* it = audio_devices.begin(); it != audio_devices.end(); ++it) { if (!FindLocalSource(*it)) { @@ -986,6 +1032,9 @@ void UserMediaProcessor::OnStreamGenerationFailed( // MediaStreamDispatcherHost is processing the request. return; } + blink::WebRtcLogMessage( + base::StringPrintf("UMP::OnStreamGenerationFailed. request_id = %d.", + current_request_info_->request_id())); GetUserMediaRequestFailed(result); DeleteWebRequest(current_request_info_->web_request()); @@ -1341,7 +1390,7 @@ void UserMediaProcessor::GetUserMediaRequestSucceeded( DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(IsCurrentRequestInfo(web_request)); blink::WebRtcLogMessage( - base::StringPrintf("UMCI::GetUserMediaRequestSucceeded. request_id=%d", + base::StringPrintf("UMP::GetUserMediaRequestSucceeded. request_id=%d", current_request_info_->request_id())); // Completing the getUserMedia request can lead to that the RenderFrame and @@ -1370,7 +1419,7 @@ void UserMediaProcessor::GetUserMediaRequestFailed( DCHECK(current_request_info_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); blink::WebRtcLogMessage( - base::StringPrintf("UMCI::GetUserMediaRequestFailed. request_id=%d", + base::StringPrintf("UMP::GetUserMediaRequestFailed. request_id=%d", current_request_info_->request_id())); // Completing the getUserMedia request can lead to that the RenderFrame and @@ -1644,13 +1693,13 @@ bool UserMediaProcessor::HasActiveSources() const { blink::mojom::blink::MediaStreamDispatcherHost* UserMediaProcessor::GetMediaStreamDispatcherHost() { if (!dispatcher_host_) { - frame_->GetInterfaceProvider().GetInterface( + frame_->GetBrowserInterfaceBroker().GetInterface( dispatcher_host_.BindNewPipeAndPassReceiver()); } return dispatcher_host_.get(); } -const blink::mojom::blink::MediaDevicesDispatcherHostPtr& +blink::mojom::blink::MediaDevicesDispatcherHost* UserMediaProcessor::GetMediaDevicesDispatcher() { return media_devices_dispatcher_cb_.Run(); } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.h b/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.h index ed09fff493a..c3771147295 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_processor.h @@ -57,10 +57,10 @@ struct UserMediaRequestInfo { // UserMediaProcessor must be created, called and destroyed on the main // render thread. There should be only one UserMediaProcessor per frame. class MODULES_EXPORT UserMediaProcessor - : public GarbageCollectedFinalized<UserMediaProcessor> { + : public GarbageCollected<UserMediaProcessor> { public: using MediaDevicesDispatcherCallback = base::RepeatingCallback< - const blink::mojom::blink::MediaDevicesDispatcherHostPtr&()>; + blink::mojom::blink::MediaDevicesDispatcherHost*()>; // |web_frame| must outlive this instance. UserMediaProcessor(LocalFrame* frame, MediaDevicesDispatcherCallback media_devices_dispatcher_cb, @@ -248,8 +248,7 @@ class MODULES_EXPORT UserMediaProcessor blink::mojom::blink::MediaStreamDispatcherHost* GetMediaStreamDispatcherHost(); - const blink::mojom::blink::MediaDevicesDispatcherHostPtr& - GetMediaDevicesDispatcher(); + blink::mojom::blink::MediaDevicesDispatcherHost* GetMediaDevicesDispatcher(); void SetupAudioInput(); void SelectAudioDeviceSettings( @@ -290,13 +289,12 @@ class MODULES_EXPORT UserMediaProcessor mojo::Remote<blink::mojom::blink::MediaStreamDispatcherHost> dispatcher_host_; // UserMedia requests are processed sequentially. |current_request_info_| - // contains the request currently being processed, if any, and - // |pending_request_infos_| is a list of queued requests. + // contains the request currently being processed. Member<RequestInfo> current_request_info_; MediaDevicesDispatcherCallback media_devices_dispatcher_cb_; base::OnceClosure request_completed_cb_; - WeakMember<LocalFrame> frame_; + Member<LocalFrame> frame_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; THREAD_CHECKER(thread_checker_); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.h b/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.h index ad9a97403c3..59f35b6e83f 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.h @@ -49,12 +49,12 @@ class MediaStreamDescriptor; class UserMediaController; class MODULES_EXPORT UserMediaRequest final - : public GarbageCollectedFinalized<UserMediaRequest>, + : public GarbageCollected<UserMediaRequest>, public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(UserMediaRequest); public: - class Callbacks : public GarbageCollectedFinalized<Callbacks> { + class Callbacks : public GarbageCollected<Callbacks> { public: virtual ~Callbacks() = default; diff --git a/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc b/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc index 5b993e58d95..da67cdfc6a5 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter.cc @@ -71,11 +71,6 @@ struct ComputedSettings { base::TimeTicks last_update_timestamp; }; -// Empty method used for keeping a reference to the original media::VideoFrame -// in VideoFrameResolutionAdapter::DeliverFrame if cropping is needed. -// The reference to |frame| is kept in the closure that calls this method. -void TrackReleaseOriginalFrame(scoped_refptr<media::VideoFrame> frame) {} - int ClampToValidDimension(int dimension) { return std::min(static_cast<int>(media::limits::kMaxDimension), std::max(0, dimension)); @@ -317,9 +312,15 @@ void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame( return; } - // TODO(perkj): Allow cropping / scaling of textures once - // https://crbug/362521 is fixed. - if (frame->HasTextures()) { + // If the frame is a texture not backed up by GPU memory we don't apply + // cropping/scaling and deliver the frame as-is, leaving it up to the + // destination to rescale it. Otherwise, cropping and scaling is soft-applied + // before delivery for efficiency. + // + // TODO(crbug.com/362521): Allow cropping/scaling of non-GPU memory backed + // textures. + if (frame->HasTextures() && + frame->storage_type() != media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) { DoDeliverFrame(std::move(frame), estimated_capture_time); return; } @@ -337,15 +338,13 @@ void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame( media::ComputeLetterboxRegion(frame->visible_rect(), desired_size); video_frame = media::VideoFrame::WrapVideoFrame( - *frame, frame->format(), region_in_frame, desired_size); + frame, frame->format(), region_in_frame, desired_size); if (!video_frame) { PostFrameDroppedToMainTaskRunner( media::VideoCaptureFrameDropReason:: kResolutionAdapterWrappingFrameForCroppingFailed); return; } - video_frame->AddDestructionObserver(ConvertToBaseOnceCallback( - CrossThreadBindOnce(&TrackReleaseOriginalFrame, frame))); DVLOG(3) << "desired size " << desired_size.ToString() << " output natural size " diff --git a/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter_unittest.cc b/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter_unittest.cc index 4afe674e335..a5fd5db6b48 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter_unittest.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/video_track_adapter_unittest.cc @@ -6,9 +6,15 @@ #include <limits> +#include "base/synchronization/waitable_event.h" +#include "base/test/bind_test_util.h" +#include "base/threading/thread.h" #include "media/base/limits.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/web/modules/mediastream/mock_media_stream_video_source.h" #include "third_party/blink/public/web/modules/mediastream/video_track_adapter_settings.h" +#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" +#include "third_party/blink/renderer/platform/testing/video_frame_utils.h" namespace blink { @@ -189,4 +195,158 @@ TEST(VideoTrackAdapterTest, NoRescaling) { EXPECT_EQ(desired_size.height(), kInputHeight); } +class VideoTrackAdapterFixtureTest : public ::testing::Test { + public: + VideoTrackAdapterFixtureTest() + : testing_render_thread_("TestingRenderThread"), + frame_received_(base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED) {} + ~VideoTrackAdapterFixtureTest() override = default; + + protected: + void SetUp() override { testing_render_thread_.Start(); } + + void TearDown() override { + if (track_added_) { + testing_render_thread_.task_runner()->PostTask( + FROM_HERE, base::BindOnce(&VideoTrackAdapter::RemoveTrack, adapter_, + null_track_.get())); + } + testing_render_thread_.Stop(); + } + + void CreateAdapter(const media::VideoCaptureFormat& capture_format) { + mock_source_ = + std::make_unique<MockMediaStreamVideoSource>(capture_format, false); + + // Create the VideoTrackAdapter instance on |testing_render_thread_|. + base::WaitableEvent adapter_created( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + testing_render_thread_.task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting([&]() { + adapter_ = base::MakeRefCounted<VideoTrackAdapter>( + platform_support_->GetIOTaskRunner(), mock_source_->GetWeakPtr()); + adapter_created.Signal(); + })); + adapter_created.Wait(); + } + + // Create or re-configure the dummy |null_track_| with the given + // |adapter_settings|. + void ConfigureTrack(const VideoTrackAdapterSettings& adapter_settings) { + if (!track_added_) { + testing_render_thread_.task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + &VideoTrackAdapter::AddTrack, adapter_, null_track_.get(), + base::BindRepeating( + &VideoTrackAdapterFixtureTest::OnFrameDelivered, + base::Unretained(this)), + base::DoNothing(), base::DoNothing(), adapter_settings)); + track_added_ = true; + } else { + testing_render_thread_.task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&VideoTrackAdapter::ReconfigureTrack, adapter_, + null_track_.get(), adapter_settings)); + } + } + + void SetFrameValidationCallback(VideoCaptureDeliverFrameCB callback) { + frame_validation_callback_ = std::move(callback); + } + + // Deliver |frame| to |adapter_| and wait until OnFrameDelivered signals that + // it receives the processed frame. + void DeliverAndValidateFrame(scoped_refptr<media::VideoFrame> frame, + base::TimeTicks estimated_capture_time) { + auto deliver_frame = [&]() { + platform_support_->GetIOTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&VideoTrackAdapter::DeliverFrameOnIO, + adapter_, frame, estimated_capture_time)); + }; + + frame_received_.Reset(); + // Bounce the call to DeliverFrameOnIO off |testing_render_thread_| to + // synchronize with the AddTrackOnIO / ReconfigureTrackOnIO that would be + // invoked through ConfigureTrack. + testing_render_thread_.task_runner()->PostTask( + FROM_HERE, base::BindLambdaForTesting(deliver_frame)); + frame_received_.Wait(); + } + + void OnFrameDelivered(scoped_refptr<media::VideoFrame> frame, + base::TimeTicks estimated_capture_time) { + if (frame_validation_callback_) { + frame_validation_callback_.Run(frame, estimated_capture_time); + } + frame_received_.Signal(); + } + + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> + platform_support_; + base::Thread testing_render_thread_; + std::unique_ptr<MockMediaStreamVideoSource> mock_source_; + scoped_refptr<VideoTrackAdapter> adapter_; + + base::WaitableEvent frame_received_; + VideoCaptureDeliverFrameCB frame_validation_callback_; + + // For testing we use a nullptr for MediaStreamVideoTrack. + std::unique_ptr<MediaStreamVideoTrack> null_track_ = nullptr; + bool track_added_ = false; +}; + +TEST_F(VideoTrackAdapterFixtureTest, DeliverFrame_GpuMemoryBuffer) { + // Attributes for the original input frame. + const gfx::Size kCodedSize(1280, 960); + const gfx::Rect kVisibleRect(0, 120, 1280, 720); + const gfx::Size kNaturalSize(1280, 720); + const double kFrameRate = 30.0; + auto gmb_frame = + CreateTestFrame(kCodedSize, kVisibleRect, kNaturalSize, + media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER); + + // Initialize the VideoTrackAdapter to handle GpuMemoryBuffer. NV12 is the + // only pixel format supported at the moment. + const media::VideoCaptureFormat stream_format(kCodedSize, kFrameRate, + media::PIXEL_FORMAT_NV12); + CreateAdapter(stream_format); + + // Keep the desired size the same as the natural size of the original frame. + VideoTrackAdapterSettings settings_nonscaled(kNaturalSize, kFrameRate); + ConfigureTrack(settings_nonscaled); + auto check_nonscaled = [&](scoped_refptr<media::VideoFrame> frame, + base::TimeTicks estimated_capture_time) { + // We should get the original frame as-is here. + EXPECT_EQ(frame->storage_type(), + media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER); + EXPECT_EQ(frame->GetGpuMemoryBuffer(), gmb_frame->GetGpuMemoryBuffer()); + EXPECT_EQ(frame->coded_size(), kCodedSize); + EXPECT_EQ(frame->visible_rect(), kVisibleRect); + EXPECT_EQ(frame->natural_size(), kNaturalSize); + }; + SetFrameValidationCallback(base::BindLambdaForTesting(check_nonscaled)); + DeliverAndValidateFrame(gmb_frame, base::TimeTicks()); + + // Scale the original frame by a factor of 0.5x. + const gfx::Size kDesiredSize(640, 360); + VideoTrackAdapterSettings settings_scaled(kDesiredSize, kFrameRate); + ConfigureTrack(settings_scaled); + auto check_scaled = [&](scoped_refptr<media::VideoFrame> frame, + base::TimeTicks estimated_capture_time) { + // The original frame should be wrapped in a new frame, with |kDesiredSize| + // exposed as natural size of the wrapped frame. + EXPECT_EQ(frame->storage_type(), + media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER); + EXPECT_EQ(frame->GetGpuMemoryBuffer(), gmb_frame->GetGpuMemoryBuffer()); + EXPECT_EQ(frame->coded_size(), kCodedSize); + EXPECT_EQ(frame->visible_rect(), kVisibleRect); + EXPECT_EQ(frame->natural_size(), kDesiredSize); + }; + SetFrameValidationCallback(base::BindLambdaForTesting(check_scaled)); + DeliverAndValidateFrame(gmb_frame, base::TimeTicks()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc index 8e453c820e6..7729f46a6e1 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc @@ -55,7 +55,6 @@ scoped_refptr<media::VideoFrame> CopyFrame( DCHECK(frame->format() == media::PIXEL_FORMAT_ARGB || frame->format() == media::PIXEL_FORMAT_XRGB || frame->format() == media::PIXEL_FORMAT_I420 || - frame->format() == media::PIXEL_FORMAT_UYVY || frame->format() == media::PIXEL_FORMAT_NV12); new_frame = media::VideoFrame::CreateFrame( media::PIXEL_FORMAT_I420, frame->coded_size(), frame->visible_rect(), @@ -564,8 +563,11 @@ void WebMediaPlayerMSCompositor::SetCurrentFrame( is_first_frame = false; if (!current_frame_->metadata()->GetRotation( - media::VideoFrameMetadata::ROTATION, ¤t_video_rotation) || - current_video_rotation == *new_rotation) { + media::VideoFrameMetadata::ROTATION, ¤t_video_rotation)) { + // Assume VIDEO_ROTATION_0 for current frame without video rotation. + current_video_rotation = media::VIDEO_ROTATION_0; + } + if (current_video_rotation == *new_rotation) { new_rotation.reset(); } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc index 8ad00796a99..4322ed2379d 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_test.cc @@ -344,8 +344,12 @@ void MockMediaStreamVideoRenderer::QueueFrames( frame_size, gfx::Rect(frame_size), frame_size, base::TimeDelta::FromMilliseconds(token)); - frame->metadata()->SetRotation(media::VideoFrameMetadata::ROTATION, - rotation); + // MediaStreamRemoteVideoSource does not explicitly set the rotation + // for unrotated frames, so that is not done here either. + if (rotation != media::VIDEO_ROTATION_0) { + frame->metadata()->SetRotation(media::VideoFrameMetadata::ROTATION, + rotation); + } frame->metadata()->SetTimeTicks( media::VideoFrameMetadata::Key::REFERENCE_TIME, base::TimeTicks::Now() + base::TimeDelta::FromMilliseconds(token)); @@ -582,10 +586,11 @@ class WebMediaPlayerMSTest void ActivateViewportIntersectionMonitoring(bool activate) override {} void MediaRemotingStarted( const WebString& remote_device_friendly_name) override {} - void MediaRemotingStopped(WebLocalizedString::Name error_msg) override {} + void MediaRemotingStopped(int error_code) override {} void RequestPlay() override {} void RequestPause() override {} void RequestMuted(bool muted) override {} + Features GetFeatures() override { return Features(); } // Implementation of cc::VideoFrameProvider::Client void StopUsingProvider() override; @@ -1066,6 +1071,24 @@ TEST_P(WebMediaPlayerMSTest, RotationChange) { EXPECT_EQ(kStandardHeight, natural_size.height); EXPECT_EQ(kStandardWidth, natural_size.width); + // Change rotation again. + tokens[0] = 66; + timestamps = std::vector<int>(tokens, tokens + base::size(tokens)); + provider->QueueFrames(timestamps, false, false, 17, media::VIDEO_ROTATION_90); + if (enable_surface_layer_for_video_) { + EXPECT_CALL(*submitter_ptr_, SetRotation(media::VIDEO_ROTATION_90)); + } else { + EXPECT_CALL(*this, DoSetCcLayer(true)); + EXPECT_CALL(*this, DoStopRendering()); + EXPECT_CALL(*this, DoStartRendering()); + } + message_loop_controller_.RunAndWaitForStatus( + media::PipelineStatus::PIPELINE_OK); + base::RunLoop().RunUntilIdle(); + natural_size = player_->NaturalSize(); + EXPECT_EQ(kStandardHeight, natural_size.width); + EXPECT_EQ(kStandardWidth, natural_size.height); + testing::Mock::VerifyAndClearExpectations(this); EXPECT_CALL(*this, DoSetCcLayer(false)); diff --git a/chromium/third_party/blink/renderer/modules/modules.gni b/chromium/third_party/blink/renderer/modules/modules.gni index 3d3ee40c96e..30d8be51c8e 100644 --- a/chromium/third_party/blink/renderer/modules/modules.gni +++ b/chromium/third_party/blink/renderer/modules/modules.gni @@ -8,9 +8,7 @@ # to the huge and slow lists of sources. If sharing is necessary, make a # separate .gni. import("//build/config/jumbo.gni") -import("//build/split_static_library.gni") import("//third_party/blink/renderer/config.gni") - blink_modules_output_dir = "$root_gen_dir/third_party/blink/renderer/modules" # Defines a part of blink modules. This is either a source set or a static @@ -25,11 +23,7 @@ template("blink_modules_sources") { if (is_component_build) { target_type = "source_set" } else { - if (!defined(invoker.split_count)) { - target_type = "static_library" - } else { - target_type = "split_static_library" - } + target_type = "static_library" } target("jumbo_" + target_type, target_name) { @@ -45,17 +39,9 @@ template("blink_modules_sources") { if (defined(invoker.deps)) { deps += invoker.deps } - if (target_type == "split_static_library") { - split_count = invoker.split_count - } # Take everything else not handled above from the invoker. - forward_variables_from(invoker, - "*", - [ - "deps", - "split_count", - ]) + forward_variables_from(invoker, "*", [ "deps" ]) } } set_defaults("blink_modules_sources") { diff --git a/chromium/third_party/blink/renderer/modules/modules_idl_files.gni b/chromium/third_party/blink/renderer/modules/modules_idl_files.gni index 6209ed0706c..fe8647ee296 100644 --- a/chromium/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/chromium/third_party/blink/renderer/modules/modules_idl_files.gni @@ -74,7 +74,6 @@ modules_idl_files = "background_sync/periodic_sync_event.idl", "background_sync/periodic_sync_manager.idl", "background_sync/sync_manager.idl", - "badging/experimental_badge.idl", "battery/battery_manager.idl", "bluetooth/bluetooth.idl", "bluetooth/bluetooth_advertising_event.idl", @@ -99,6 +98,8 @@ modules_idl_files = "canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl", "clipboard/clipboard.idl", "clipboard/clipboard_item.idl", + "compression/compression_stream.idl", + "compression/decompression_stream.idl", "contacts_picker/contacts_manager.idl", "content_index/content_index.idl", "content_index/content_index_event.idl", @@ -163,10 +164,10 @@ modules_idl_files = "gamepad/gamepad_haptic_actuator.idl", "gamepad/gamepad_list.idl", "gamepad/gamepad_pose.idl", - "geolocation/coordinates.idl", "geolocation/geolocation.idl", - "geolocation/position.idl", - "geolocation/position_error.idl", + "geolocation/geolocation_coordinates.idl", + "geolocation/geolocation_position.idl", + "geolocation/geolocation_position_error.idl", "hid/hid.idl", "hid/hid_collection_info.idl", "hid/hid_connection_event.idl", @@ -193,7 +194,6 @@ modules_idl_files = "indexeddb/idb_request.idl", "indexeddb/idb_transaction.idl", "indexeddb/idb_version_change_event.idl", - "installedapp/related_application.idl", "keyboard/keyboard.idl", "keyboard/keyboard_layout_map.idl", "locks/lock.idl", @@ -354,6 +354,8 @@ modules_idl_files = "vr/vr_pose.idl", "vr/vr_stage_parameters.idl", "wake_lock/wake_lock.idl", + "wake_lock/wake_lock_event.idl", + "wake_lock/wake_lock_sentinel.idl", "webaudio/analyser_node.idl", "webaudio/audio_buffer.idl", "webaudio/audio_buffer_source_node.idl", @@ -467,6 +469,7 @@ modules_idl_files = "webgpu/gpu_compute_pass_encoder.idl", "webgpu/gpu_compute_pipeline.idl", "webgpu/gpu_device.idl", + "webgpu/gpu_device_lost_info.idl", "webgpu/gpu_fence.idl", "webgpu/gpu_out_of_memory_error.idl", "webgpu/gpu_pipeline_layout.idl", @@ -573,7 +576,6 @@ modules_dictionary_idl_files = "background_sync/background_sync_options.idl", "background_sync/sync_event_init.idl", "background_sync/periodic_sync_event_init.idl", - "badging/badge_options.idl", "bluetooth/bluetooth_advertising_event_init.idl", "bluetooth/bluetooth_le_scan_filter_init.idl", "bluetooth/bluetooth_le_scan_options.idl", @@ -647,6 +649,7 @@ modules_dictionary_idl_files = "indexeddb/idb_observer_init.idl", "indexeddb/idb_transaction_options.idl", "indexeddb/idb_version_change_event_init.idl", + "installedapp/related_application.idl", "locks/lock_info.idl", "locks/lock_manager_snapshot.idl", "locks/lock_options.idl", @@ -707,6 +710,7 @@ modules_dictionary_idl_files = "payments/image_object.idl", "payments/merchant_validation_event_init.idl", "payments/payer_errors.idl", + "payments/payment_address_init.idl", "payments/payment_currency_amount.idl", "payments/payment_details_base.idl", "payments/payment_details_init.idl", @@ -799,7 +803,7 @@ modules_dictionary_idl_files = "storage/storage_event_init.idl", "vr/vr_display_event_init.idl", "vr/vr_layer_init.idl", - "wake_lock/wake_lock_request_options.idl", + "wake_lock/wake_lock_event_init.idl", "webaudio/analyser_options.idl", "webaudio/audio_buffer_options.idl", "webaudio/audio_buffer_source_options.idl", @@ -836,22 +840,25 @@ modules_dictionary_idl_files = "webgpu/gpu_bind_group_layout_descriptor.idl", "webgpu/gpu_blend_descriptor.idl", "webgpu/gpu_buffer_binding.idl", + "webgpu/gpu_command_buffer_descriptor.idl", "webgpu/gpu_buffer_copy_view.idl", "webgpu/gpu_buffer_descriptor.idl", - "webgpu/gpu_color.idl", + "webgpu/gpu_color_dict.idl", "webgpu/gpu_color_state_descriptor.idl", "webgpu/gpu_command_encoder_descriptor.idl", "webgpu/gpu_compute_pipeline_descriptor.idl", + "webgpu/gpu_compute_pass_descriptor.idl", "webgpu/gpu_depth_stencil_state_descriptor.idl", "webgpu/gpu_device_descriptor.idl", "webgpu/gpu_extensions.idl", - "webgpu/gpu_extent_3d.idl", + "webgpu/gpu_extent_3d_dict.idl", "webgpu/gpu_fence_descriptor.idl", "webgpu/gpu_limits.idl", - "webgpu/gpu_origin_3d.idl", + "webgpu/gpu_object_descriptor_base.idl", + "webgpu/gpu_origin_3d_dict.idl", "webgpu/gpu_pipeline_descriptor_base.idl", "webgpu/gpu_pipeline_layout_descriptor.idl", - "webgpu/gpu_pipeline_stage_descriptor.idl", + "webgpu/gpu_programmable_stage_descriptor.idl", "webgpu/gpu_rasterization_state_descriptor.idl", "webgpu/gpu_render_bundle_descriptor.idl", "webgpu/gpu_render_bundle_encoder_descriptor.idl", @@ -918,6 +925,7 @@ modules_dependency_idl_files = "background_fetch/service_worker_registration_background_fetch.idl", "background_sync/service_worker_global_scope_sync.idl", "background_sync/service_worker_registration_sync.idl", + "badging/navigator_badge.idl", "battery/navigator_battery.idl", "beacon/navigator_beacon.idl", "bluetooth/navigator_bluetooth.idl", @@ -1005,9 +1013,13 @@ modules_dependency_idl_files = "storage/window_storage.idl", "vibration/navigator_vibration.idl", "vr/navigator_vr.idl", + "wake_lock/navigator_wake_lock.idl", + "wake_lock/worker_navigator_wake_lock.idl", "webdatabase/window_web_database.idl", "webgl/webgl2_rendering_context_base.idl", "webgl/webgl_rendering_context_base.idl", + "webgpu/gpu_programmable_pass_encoder.idl", + "webgpu/gpu_render_encoder_base.idl", "webgpu/navigator_gpu.idl", "webmidi/navigator_web_midi.idl", "webshare/navigator_share.idl", diff --git a/chromium/third_party/blink/renderer/modules/modules_initializer.cc b/chromium/third_party/blink/renderer/modules/modules_initializer.cc index 40aca4e435f..30b024c531c 100644 --- a/chromium/third_party/blink/renderer/modules/modules_initializer.cc +++ b/chromium/third_party/blink/renderer/modules/modules_initializer.cc @@ -7,6 +7,7 @@ #include <memory> #include "base/memory/ptr_util.h" +#include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom-blink.h" #include "third_party/blink/public/platform/interface_registry.h" #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/public/platform/web_string.h" @@ -28,7 +29,6 @@ #include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/core/workers/worker_clients.h" #include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h" #include "third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h" #include "third_party/blink/renderer/modules/app_banner/app_banner_controller.h" @@ -50,7 +50,7 @@ #include "third_party/blink/renderer/modules/event_target_modules_names.h" #include "third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h" #include "third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.h" -#include "third_party/blink/renderer/modules/filesystem/local_file_system_client.h" +#include "third_party/blink/renderer/modules/filesystem/local_file_system.h" #include "third_party/blink/renderer/modules/gamepad/navigator_gamepad.h" #include "third_party/blink/renderer/modules/image_downloader/image_downloader_impl.h" #include "third_party/blink/renderer/modules/indexed_db_names.h" @@ -83,23 +83,19 @@ #include "third_party/blink/renderer/modules/webdatabase/inspector_database_agent.h" #include "third_party/blink/renderer/modules/webdatabase/web_database_host.h" #include "third_party/blink/renderer/modules/webdatabase/web_database_impl.h" -#include "third_party/blink/renderer/modules/worklet/animation_and_paint_worklet_thread.h" -#include "third_party/blink/renderer/modules/xr/navigator_xr.h" -#if defined(SUPPORT_WEBGL2_COMPUTE_CONTEXT) -#include "third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h" -#endif -#include "third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h" #include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h" #include "third_party/blink/renderer/modules/webgl/webgl_rendering_context.h" #include "third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h" +#include "third_party/blink/renderer/modules/worklet/animation_and_paint_worklet_thread.h" +#include "third_party/blink/renderer/modules/xr/navigator_xr.h" #include "third_party/blink/renderer/platform/mojo/mojo_helper.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" -#if defined(TOUCHLESS_MEDIA_CONTROLS) -#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" +#if defined(SUPPORT_WEBGL2_COMPUTE_CONTEXT) +#include "third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h" #endif namespace blink { @@ -182,7 +178,7 @@ void ModulesInitializer::InstallSupplements(LocalFrame& frame) const { ProvidePushMessagingClientTo( frame, MakeGarbageCollected<PushMessagingClient>(frame)); ProvideUserMediaTo(frame); - ProvideLocalFileSystemTo(frame, std::make_unique<LocalFileSystemClient>()); + ProvideLocalFileSystemTo(frame); ScreenOrientationControllerImpl::ProvideTo(frame); if (RuntimeEnabledFeatures::PresentationEnabled()) @@ -199,19 +195,14 @@ void ModulesInitializer::InstallSupplements(LocalFrame& frame) const { } void ModulesInitializer::ProvideLocalFileSystemToWorker( - WorkerClients& worker_clients) const { - ::blink::ProvideLocalFileSystemToWorker( - &worker_clients, std::make_unique<LocalFileSystemClient>()); + WorkerGlobalScope& worker_global_scope) const { + ::blink::ProvideLocalFileSystemToWorker(worker_global_scope); } MediaControls* ModulesInitializer::CreateMediaControls( HTMLMediaElement& media_element, ShadowRoot& shadow_root) const { -#if defined(TOUCHLESS_MEDIA_CONTROLS) - return MediaControlsTouchlessImpl::Create(media_element, shadow_root); -#else return MediaControlsImpl::Create(media_element, shadow_root); -#endif } PictureInPictureController* diff --git a/chromium/third_party/blink/renderer/modules/modules_initializer.h b/chromium/third_party/blink/renderer/modules/modules_initializer.h index 1eec6b30a79..12753f6e0d0 100644 --- a/chromium/third_party/blink/renderer/modules/modules_initializer.h +++ b/chromium/third_party/blink/renderer/modules/modules_initializer.h @@ -22,7 +22,7 @@ class MODULES_EXPORT ModulesInitializer : public CoreInitializer { private: void InstallSupplements(LocalFrame&) const override; - void ProvideLocalFileSystemToWorker(WorkerClients&) const override; + void ProvideLocalFileSystemToWorker(WorkerGlobalScope&) const override; MediaControls* CreateMediaControls(HTMLMediaElement&, ShadowRoot&) const override; PictureInPictureController* CreatePictureInPictureController( diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/BUILD.gn b/chromium/third_party/blink/renderer/modules/native_file_system/BUILD.gn index 40f58658bd4..6f07c5a9a0e 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/native_file_system/BUILD.gn @@ -26,3 +26,23 @@ blink_modules_sources("native_file_system") { "//third_party/blink/renderer/platform", ] } + +jumbo_source_set("unit_tests") { + testonly = true + sources = [ + "window_native_file_system_test.cc", + ] + + configs += [ + "//third_party/blink/renderer:config", + "//third_party/blink/renderer:inside_blink", + "//third_party/blink/renderer/core:blink_core_pch", + ] + + deps = [ + "//testing/gtest", + "//third_party/blink/renderer/modules", + "//third_party/blink/renderer/platform", + "//third_party/blink/renderer/platform/wtf", + ] +} diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.cc index 8fd7e9c296e..5110bb82089 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.cc +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.cc @@ -4,10 +4,12 @@ #include "third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_manager.mojom-blink.h" +#include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/fileapi/file_error.h" @@ -28,10 +30,12 @@ constexpr const char kSandboxRootDirectoryName[] = ""; using mojom::blink::NativeFileSystemErrorPtr; NativeFileSystemDirectoryHandle::NativeFileSystemDirectoryHandle( + ExecutionContext* context, const String& name, - RevocableInterfacePtr<mojom::blink::NativeFileSystemDirectoryHandle> - mojo_ptr) - : NativeFileSystemHandle(name), mojo_ptr_(std::move(mojo_ptr)) { + mojo::PendingRemote<mojom::blink::NativeFileSystemDirectoryHandle> mojo_ptr) + : NativeFileSystemHandle(context, name), + mojo_ptr_(std::move(mojo_ptr), + context->GetTaskRunner(TaskType::kMiscPlatformAPI)) { DCHECK(mojo_ptr_); } @@ -57,10 +61,7 @@ ScriptPromise NativeFileSystemDirectoryHandle::getFile( return; } resolver->Resolve(MakeGarbageCollected<NativeFileSystemFileHandle>( - name, - RevocableInterfacePtr<mojom::blink::NativeFileSystemFileHandle>( - std::move(handle), context->GetInterfaceInvalidator(), - context->GetTaskRunner(TaskType::kMiscPlatformAPI)))); + context, name, std::move(handle))); }, WrapPersistent(resolver), name)); @@ -74,12 +75,19 @@ ScriptPromise NativeFileSystemDirectoryHandle::getDirectory( auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise result = resolver->Promise(); + if (!mojo_ptr_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError)); + return result; + } + mojo_ptr_->GetDirectory( name, options->create(), WTF::Bind( [](ScriptPromiseResolver* resolver, const String& name, NativeFileSystemErrorPtr result, - mojom::blink::NativeFileSystemDirectoryHandlePtr handle) { + mojo::PendingRemote<mojom::blink::NativeFileSystemDirectoryHandle> + handle) { ExecutionContext* context = resolver->GetExecutionContext(); if (!context) return; @@ -89,12 +97,7 @@ ScriptPromise NativeFileSystemDirectoryHandle::getDirectory( } resolver->Resolve( MakeGarbageCollected<NativeFileSystemDirectoryHandle>( - name, - RevocableInterfacePtr< - mojom::blink::NativeFileSystemDirectoryHandle>( - handle.PassInterface(), - context->GetInterfaceInvalidator(), - context->GetTaskRunner(TaskType::kMiscPlatformAPI)))); + context, name, std::move(handle))); }, WrapPersistent(resolver), name)); @@ -124,7 +127,7 @@ ScriptValue NativeFileSystemDirectoryHandle::getEntries( .ToChecked()) { return ScriptValue(); } - return ScriptValue(script_state, result); + return ScriptValue(script_state->GetIsolate(), result); } ScriptPromise NativeFileSystemDirectoryHandle::removeEntry( @@ -134,6 +137,12 @@ ScriptPromise NativeFileSystemDirectoryHandle::removeEntry( auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise result = resolver->Promise(); + if (!mojo_ptr_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError)); + return result; + } + mojo_ptr_->RemoveEntry( name, options->recursive(), WTF::Bind( @@ -170,7 +179,8 @@ ScriptPromise NativeFileSystemDirectoryHandle::getSystemDirectory( [](ScriptPromiseResolver* resolver, mojo::Remote<mojom::blink::NativeFileSystemManager>, NativeFileSystemErrorPtr result, - mojom::blink::NativeFileSystemDirectoryHandlePtr handle) { + mojo::PendingRemote<mojom::blink::NativeFileSystemDirectoryHandle> + handle) { ExecutionContext* context = resolver->GetExecutionContext(); if (!context) return; @@ -179,27 +189,28 @@ ScriptPromise NativeFileSystemDirectoryHandle::getSystemDirectory( return; } resolver->Resolve(MakeGarbageCollected<NativeFileSystemDirectoryHandle>( - kSandboxRootDirectoryName, - RevocableInterfacePtr< - mojom::blink::NativeFileSystemDirectoryHandle>( - handle.PassInterface(), context->GetInterfaceInvalidator(), - context->GetTaskRunner(TaskType::kMiscPlatformAPI)))); + context, kSandboxRootDirectoryName, std::move(handle))); }, WrapPersistent(resolver), std::move(manager))); return result; } -mojom::blink::NativeFileSystemTransferTokenPtr +mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> NativeFileSystemDirectoryHandle::Transfer() { - mojom::blink::NativeFileSystemTransferTokenPtr result; - mojo_ptr_->Transfer(mojo::MakeRequest(&result)); + mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> result; + if (mojo_ptr_) + mojo_ptr_->Transfer(result.InitWithNewPipeAndPassReceiver()); return result; } void NativeFileSystemDirectoryHandle::QueryPermissionImpl( bool writable, base::OnceCallback<void(mojom::blink::PermissionStatus)> callback) { + if (!mojo_ptr_) { + std::move(callback).Run(mojom::blink::PermissionStatus::DENIED); + return; + } mojo_ptr_->GetPermissionStatus(writable, std::move(callback)); } @@ -207,7 +218,20 @@ void NativeFileSystemDirectoryHandle::RequestPermissionImpl( bool writable, base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr, mojom::blink::PermissionStatus)> callback) { + if (!mojo_ptr_) { + std::move(callback).Run( + mojom::blink::NativeFileSystemError::New( + mojom::blink::NativeFileSystemStatus::kInvalidState, + base::File::Error::FILE_ERROR_FAILED, "Context Destroyed"), + mojom::blink::PermissionStatus::DENIED); + return; + } + mojo_ptr_->RequestPermission(writable, std::move(callback)); } +void NativeFileSystemDirectoryHandle::ContextDestroyed(ExecutionContext*) { + mojo_ptr_.reset(); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h index 14e9b3eeb75..8c037ea4114 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h @@ -5,9 +5,10 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_DIRECTORY_HANDLE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_DIRECTORY_HANDLE_H_ +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_directory_handle.mojom-blink.h" #include "third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h" -#include "third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h" namespace blink { class FileSystemGetDirectoryOptions; @@ -20,8 +21,9 @@ class NativeFileSystemDirectoryHandle final : public NativeFileSystemHandle { public: NativeFileSystemDirectoryHandle( + ExecutionContext* context, const String& name, - RevocableInterfacePtr<mojom::blink::NativeFileSystemDirectoryHandle>); + mojo::PendingRemote<mojom::blink::NativeFileSystemDirectoryHandle>); bool isDirectory() const override { return true; } @@ -39,12 +41,15 @@ class NativeFileSystemDirectoryHandle final : public NativeFileSystemHandle { static ScriptPromise getSystemDirectory(ScriptState*, const GetSystemDirectoryOptions*); - mojom::blink::NativeFileSystemTransferTokenPtr Transfer() override; + mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> Transfer() + override; mojom::blink::NativeFileSystemDirectoryHandle* MojoHandle() { return mojo_ptr_.get(); } + void ContextDestroyed(ExecutionContext*) override; + private: void QueryPermissionImpl( bool writable, @@ -54,8 +59,7 @@ class NativeFileSystemDirectoryHandle final : public NativeFileSystemHandle { base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr, mojom::blink::PermissionStatus)>) override; - RevocableInterfacePtr<mojom::blink::NativeFileSystemDirectoryHandle> - mojo_ptr_; + mojo::Remote<mojom::blink::NativeFileSystemDirectoryHandle> mojo_ptr_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.h index 93d5f13db88..7a7200b71e8 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.h +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_DIRECTORY_ITERATOR_H_ #include "base/files/file.h" -#include "third_party/blink/public/mojom/native_file_system/native_file_system_directory_handle.mojom-blink.h" +#include "third_party/blink/public/mojom/native_file_system/native_file_system_directory_handle.mojom-blink-forward.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -29,9 +29,6 @@ class NativeFileSystemDirectoryIterator final ExecutionContext* execution_context); ScriptPromise next(ScriptState*); - // TODO(mek): This return method should cancel the backend directory iteration - // operation, to avoid doing useless work. - void IteratorReturn() {} void Trace(Visitor*) override; diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.idl b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.idl index 5be49e4cb44..85924a5e68f 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.idl +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.idl @@ -10,5 +10,4 @@ RuntimeEnabled=NativeFileSystem ] interface NativeFileSystemDirectoryIterator { [CallWith=ScriptState] Promise<any> next(); - [ImplementedAs=IteratorReturn] void return(); }; diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_error.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_error.cc index dcbbcc127a9..8abe64a21ff 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_error.cc +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_error.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/native_file_system/native_file_system_error.h" +#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_error.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_error.h index ea63282ad17..362018649cd 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_error.h +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_error.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_ERROR_H_ #include "base/files/file.h" -#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h" +#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink-forward.h" namespace blink { class ScriptPromiseResolver; diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc index 8dd25fcb796..9799925d4a9 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.cc @@ -21,9 +21,12 @@ namespace blink { using mojom::blink::NativeFileSystemErrorPtr; NativeFileSystemFileHandle::NativeFileSystemFileHandle( + ExecutionContext* context, const String& name, - RevocableInterfacePtr<mojom::blink::NativeFileSystemFileHandle> mojo_ptr) - : NativeFileSystemHandle(name), mojo_ptr_(std::move(mojo_ptr)) { + mojo::PendingRemote<mojom::blink::NativeFileSystemFileHandle> mojo_ptr) + : NativeFileSystemHandle(context, name), + mojo_ptr_(std::move(mojo_ptr), + context->GetTaskRunner(TaskType::kMiscPlatformAPI)) { DCHECK(mojo_ptr_); } @@ -33,6 +36,12 @@ ScriptPromise NativeFileSystemFileHandle::createWriter( auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise result = resolver->Promise(); + if (!mojo_ptr_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError)); + return result; + } + mojo_ptr_->CreateFileWriter( options->keepExistingData(), WTF::Bind( @@ -48,9 +57,7 @@ ScriptPromise NativeFileSystemFileHandle::createWriter( return; } resolver->Resolve(MakeGarbageCollected<NativeFileSystemWriter>( - RevocableInterfacePtr<mojom::blink::NativeFileSystemFileWriter>( - std::move(writer), context->GetInterfaceInvalidator(), - context->GetTaskRunner(TaskType::kMiscPlatformAPI)))); + context, std::move(writer))); }, WrapPersistent(resolver))); @@ -61,6 +68,12 @@ ScriptPromise NativeFileSystemFileHandle::getFile(ScriptState* script_state) { auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise result = resolver->Promise(); + if (!mojo_ptr_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError)); + return result; + } + mojo_ptr_->AsBlob(WTF::Bind( [](ScriptPromiseResolver* resolver, const String& name, NativeFileSystemErrorPtr result, @@ -76,16 +89,25 @@ ScriptPromise NativeFileSystemFileHandle::getFile(ScriptState* script_state) { return result; } -mojom::blink::NativeFileSystemTransferTokenPtr +mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> NativeFileSystemFileHandle::Transfer() { - mojom::blink::NativeFileSystemTransferTokenPtr result; - mojo_ptr_->Transfer(mojo::MakeRequest(&result)); + mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> result; + if (mojo_ptr_) + mojo_ptr_->Transfer(result.InitWithNewPipeAndPassReceiver()); return result; } +void NativeFileSystemFileHandle::ContextDestroyed(ExecutionContext*) { + mojo_ptr_.reset(); +} + void NativeFileSystemFileHandle::QueryPermissionImpl( bool writable, base::OnceCallback<void(mojom::blink::PermissionStatus)> callback) { + if (!mojo_ptr_) { + std::move(callback).Run(mojom::blink::PermissionStatus::DENIED); + return; + } mojo_ptr_->GetPermissionStatus(writable, std::move(callback)); } @@ -93,6 +115,15 @@ void NativeFileSystemFileHandle::RequestPermissionImpl( bool writable, base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr, mojom::blink::PermissionStatus)> callback) { + if (!mojo_ptr_) { + std::move(callback).Run( + mojom::blink::NativeFileSystemError::New( + mojom::blink::NativeFileSystemStatus::kInvalidState, + base::File::Error::FILE_ERROR_FAILED, "Context Destroyed"), + mojom::blink::PermissionStatus::DENIED); + return; + } + mojo_ptr_->RequestPermission(writable, std::move(callback)); } diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h index 4f7abf5b9a7..81686cd2490 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h @@ -5,9 +5,10 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_FILE_HANDLE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_FILE_HANDLE_H_ +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_file_handle.mojom-blink.h" #include "third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h" -#include "third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h" namespace blink { class FileSystemCreateWriterOptions; @@ -17,8 +18,9 @@ class NativeFileSystemFileHandle final : public NativeFileSystemHandle { public: NativeFileSystemFileHandle( + ExecutionContext* context, const String& name, - RevocableInterfacePtr<mojom::blink::NativeFileSystemFileHandle>); + mojo::PendingRemote<mojom::blink::NativeFileSystemFileHandle>); bool isFile() const override { return true; } @@ -26,7 +28,10 @@ class NativeFileSystemFileHandle final : public NativeFileSystemHandle { const FileSystemCreateWriterOptions* options); ScriptPromise getFile(ScriptState*); - mojom::blink::NativeFileSystemTransferTokenPtr Transfer() override; + mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> Transfer() + override; + + void ContextDestroyed(ExecutionContext*) override; mojom::blink::NativeFileSystemFileHandle* MojoHandle() { return mojo_ptr_.get(); @@ -41,7 +46,7 @@ class NativeFileSystemFileHandle final : public NativeFileSystemHandle { base::OnceCallback<void(mojom::blink::NativeFileSystemErrorPtr, mojom::blink::PermissionStatus)>) override; - RevocableInterfacePtr<mojom::blink::NativeFileSystemFileHandle> mojo_ptr_; + mojo::Remote<mojom::blink::NativeFileSystemFileHandle> mojo_ptr_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.cc index 20222927f8d..634b1ecbe14 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.cc +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h" +#include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/fileapi/file_error.h" @@ -12,15 +13,16 @@ #include "third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h" #include "third_party/blink/renderer/modules/native_file_system/native_file_system_error.h" #include "third_party/blink/renderer/modules/native_file_system/native_file_system_file_handle.h" -#include "third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h" #include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { using mojom::blink::NativeFileSystemEntryPtr; using mojom::blink::NativeFileSystemErrorPtr; -NativeFileSystemHandle::NativeFileSystemHandle(const String& name) - : name_(name) {} +NativeFileSystemHandle::NativeFileSystemHandle( + ExecutionContext* execution_context, + const String& name) + : ContextLifecycleObserver(execution_context), name_(name) {} // static NativeFileSystemHandle* NativeFileSystemHandle::CreateFromMojoEntry( @@ -28,18 +30,10 @@ NativeFileSystemHandle* NativeFileSystemHandle::CreateFromMojoEntry( ExecutionContext* execution_context) { if (e->entry_handle->is_file()) { return MakeGarbageCollected<NativeFileSystemFileHandle>( - e->name, - RevocableInterfacePtr<mojom::blink::NativeFileSystemFileHandle>( - std::move(e->entry_handle->get_file()), - execution_context->GetInterfaceInvalidator(), - execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI))); + execution_context, e->name, std::move(e->entry_handle->get_file())); } return MakeGarbageCollected<NativeFileSystemDirectoryHandle>( - e->name, - RevocableInterfacePtr<mojom::blink::NativeFileSystemDirectoryHandle>( - std::move(e->entry_handle->get_directory()), - execution_context->GetInterfaceInvalidator(), - execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI))); + execution_context, e->name, std::move(e->entry_handle->get_directory())); } namespace { @@ -97,4 +91,9 @@ ScriptPromise NativeFileSystemHandle::requestPermission( return result; } +void NativeFileSystemHandle::Trace(Visitor* visitor) { + ScriptWrappable::Trace(visitor); + ContextLifecycleObserver::Trace(visitor); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h index b93edad2f7e..1491d217a5a 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_handle.h @@ -5,11 +5,13 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_HANDLE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_HANDLE_H_ +#include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_directory_handle.mojom-blink-forward.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink-forward.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_transfer_token.mojom-blink-forward.h" #include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -19,11 +21,14 @@ namespace blink { class ExecutionContext; class FileSystemHandlePermissionDescriptor; -class NativeFileSystemHandle : public ScriptWrappable { +class NativeFileSystemHandle : public ScriptWrappable, + public ContextLifecycleObserver { DEFINE_WRAPPERTYPEINFO(); + USING_GARBAGE_COLLECTED_MIXIN(NativeFileSystemHandle); public: - explicit NativeFileSystemHandle(const String& name); + NativeFileSystemHandle(ExecutionContext* execution_context, + const String& name); static NativeFileSystemHandle* CreateFromMojoEntry( mojom::blink::NativeFileSystemEntryPtr, ExecutionContext* execution_context); @@ -37,7 +42,12 @@ class NativeFileSystemHandle : public ScriptWrappable { ScriptPromise requestPermission(ScriptState*, const FileSystemHandlePermissionDescriptor*); - virtual mojom::blink::NativeFileSystemTransferTokenPtr Transfer() = 0; + // Grab a handle to a transfer token. This may return an invalid PendingRemote + // if the context is already destroyed. + virtual mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> + Transfer() = 0; + + void Trace(Visitor*) override; private: virtual void QueryPermissionImpl( diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc index 2d69acc7036..7d9b73fce32 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc @@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view_or_blob_or_usv_string.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/v8_blob.h" @@ -26,9 +27,12 @@ namespace blink { NativeFileSystemWriter::NativeFileSystemWriter( - RevocableInterfacePtr<mojom::blink::NativeFileSystemFileWriter> mojo_ptr) - : mojo_ptr_(std::move(mojo_ptr)) { - DCHECK(mojo_ptr_); + ExecutionContext* context, + mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter> + writer_pending_remote) + : ContextLifecycleObserver(context), + writer_remote_(std::move(writer_pending_remote)) { + DCHECK(writer_remote_); } ScriptPromise NativeFileSystemWriter::write( @@ -66,7 +70,7 @@ ScriptPromise NativeFileSystemWriter::write( ScriptPromise NativeFileSystemWriter::WriteBlob(ScriptState* script_state, uint64_t position, Blob* blob) { - if (!mojo_ptr_ || pending_operation_) { + if (!writer_remote_ || pending_operation_) { return ScriptPromise::RejectWithDOMException( script_state, MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError)); @@ -74,14 +78,14 @@ ScriptPromise NativeFileSystemWriter::WriteBlob(ScriptState* script_state, pending_operation_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise result = pending_operation_->Promise(); - mojo_ptr_->Write( + writer_remote_->Write( position, blob->AsMojoBlob(), WTF::Bind(&NativeFileSystemWriter::WriteComplete, WrapPersistent(this))); return result; } class NativeFileSystemWriter::StreamWriterClient - : public GarbageCollectedFinalized<StreamWriterClient>, + : public GarbageCollected<StreamWriterClient>, public FetchDataLoader::Client { USING_GARBAGE_COLLECTED_MIXIN(StreamWriterClient); @@ -171,7 +175,7 @@ ScriptPromise NativeFileSystemWriter::WriteStream( uint64_t position, ReadableStream* stream, ExceptionState& exception_state) { - if (!mojo_ptr_ || pending_operation_) { + if (!writer_remote_ || pending_operation_) { return ScriptPromise::RejectWithDOMException( script_state, MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError)); @@ -191,7 +195,7 @@ ScriptPromise NativeFileSystemWriter::WriteStream( ScriptPromise result = pending_operation_->Promise(); auto* client = MakeGarbageCollected<StreamWriterClient>(this); stream_loader_->Start(consumer, client); - mojo_ptr_->WriteStream( + writer_remote_->WriteStream( position, client->TakeDataPipe(), WTF::Bind(&StreamWriterClient::WriteComplete, WrapPersistent(client))); return result; @@ -199,7 +203,7 @@ ScriptPromise NativeFileSystemWriter::WriteStream( ScriptPromise NativeFileSystemWriter::truncate(ScriptState* script_state, uint64_t size) { - if (!mojo_ptr_ || pending_operation_) { + if (!writer_remote_ || pending_operation_) { return ScriptPromise::RejectWithDOMException( script_state, MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError)); @@ -207,13 +211,14 @@ ScriptPromise NativeFileSystemWriter::truncate(ScriptState* script_state, pending_operation_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise result = pending_operation_->Promise(); - mojo_ptr_->Truncate(size, WTF::Bind(&NativeFileSystemWriter::TruncateComplete, - WrapPersistent(this))); + writer_remote_->Truncate(size, + WTF::Bind(&NativeFileSystemWriter::TruncateComplete, + WrapPersistent(this))); return result; } ScriptPromise NativeFileSystemWriter::close(ScriptState* script_state) { - if (!mojo_ptr_ || pending_operation_) { + if (!writer_remote_ || pending_operation_) { return ScriptPromise::RejectWithDOMException( script_state, MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError)); @@ -221,7 +226,7 @@ ScriptPromise NativeFileSystemWriter::close(ScriptState* script_state) { pending_operation_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise result = pending_operation_->Promise(); - mojo_ptr_->Close( + writer_remote_->Close( WTF::Bind(&NativeFileSystemWriter::CloseComplete, WrapPersistent(this))); return result; @@ -229,6 +234,7 @@ ScriptPromise NativeFileSystemWriter::close(ScriptState* script_state) { void NativeFileSystemWriter::Trace(Visitor* visitor) { ScriptWrappable::Trace(visitor); + ContextLifecycleObserver::Trace(visitor); visitor->Trace(file_); visitor->Trace(pending_operation_); visitor->Trace(stream_loader_); @@ -257,7 +263,11 @@ void NativeFileSystemWriter::CloseComplete( pending_operation_ = nullptr; // We close the mojo pipe because we intend this writer to be discarded after // close. Subsequent operations will fail. - mojo_ptr_ = nullptr; + writer_remote_.reset(); +} + +void NativeFileSystemWriter::ContextDestroyed(ExecutionContext*) { + writer_remote_.reset(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h index ba363d2902b..f7de9e038ad 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h @@ -5,11 +5,12 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_WRITER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_WRITER_H_ -#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink-forward.h" #include "third_party/blink/public/mojom/native_file_system/native_file_system_file_writer.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view_or_blob_or_usv_string.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/mojo/revocable_interface_ptr.h" namespace blink { @@ -22,12 +23,15 @@ class ScriptPromiseResolver; class ScriptState; class NativeFileSystemFileHandle; -class NativeFileSystemWriter final : public ScriptWrappable { +class NativeFileSystemWriter final : public ScriptWrappable, + public ContextLifecycleObserver { DEFINE_WRAPPERTYPEINFO(); + USING_GARBAGE_COLLECTED_MIXIN(NativeFileSystemWriter); public: - explicit NativeFileSystemWriter( - RevocableInterfacePtr<mojom::blink::NativeFileSystemFileWriter>); + NativeFileSystemWriter( + ExecutionContext* context, + mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter>); ScriptPromise write(ScriptState*, uint64_t position, @@ -37,6 +41,7 @@ class NativeFileSystemWriter final : public ScriptWrappable { ScriptPromise close(ScriptState*); void Trace(Visitor*) override; + void ContextDestroyed(ExecutionContext*) override; private: class StreamWriterClient; @@ -52,7 +57,7 @@ class NativeFileSystemWriter final : public ScriptWrappable { void TruncateComplete(mojom::blink::NativeFileSystemErrorPtr result); void CloseComplete(mojom::blink::NativeFileSystemErrorPtr result); - RevocableInterfacePtr<mojom::blink::NativeFileSystemFileWriter> mojo_ptr_; + mojo::Remote<mojom::blink::NativeFileSystemFileWriter> writer_remote_; Member<NativeFileSystemFileHandle> file_; Member<ScriptPromiseResolver> pending_operation_; diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.cc b/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.cc index c4218a1c9cb..9e587365504 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.cc +++ b/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.cc @@ -12,8 +12,10 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/fileapi/file_error.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/modules/native_file_system/choose_file_system_entries_options.h" #include "third_party/blink/renderer/modules/native_file_system/choose_file_system_entries_options_accepts.h" #include "third_party/blink/renderer/modules/native_file_system/native_file_system_directory_handle.h" @@ -75,7 +77,8 @@ ScriptPromise WindowNativeFileSystem::chooseFileSystemEntries( MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError)); } - if (!window.GetFrame() || window.GetFrame()->IsCrossOriginSubframe()) { + LocalFrame* local_frame = window.GetFrame(); + if (!local_frame || local_frame->IsCrossOriginSubframe()) { return ScriptPromise::RejectWithDOMException( script_state, MakeGarbageCollected<DOMException>( @@ -83,7 +86,7 @@ ScriptPromise WindowNativeFileSystem::chooseFileSystemEntries( "Cross origin sub frames aren't allowed to show a file picker.")); } - if (!LocalFrame::HasTransientUserActivation(window.GetFrame())) { + if (!LocalFrame::HasTransientUserActivation(local_frame)) { return ScriptPromise::RejectWithDOMException( script_state, MakeGarbageCollected<DOMException>( @@ -119,6 +122,7 @@ ScriptPromise WindowNativeFileSystem::chooseFileSystemEntries( [](ScriptPromiseResolver* resolver, mojo::Remote<mojom::blink::NativeFileSystemManager>, const ChooseFileSystemEntriesOptions* options, + LocalFrame* local_frame, mojom::blink::NativeFileSystemErrorPtr file_operation_result, Vector<mojom::blink::NativeFileSystemEntryPtr> entries) { ExecutionContext* context = resolver->GetExecutionContext(); @@ -130,6 +134,17 @@ ScriptPromise WindowNativeFileSystem::chooseFileSystemEntries( *file_operation_result); return; } + + // While it would be better to not trust the renderer process, + // we're doing this here to avoid potential mojo message pipe + // ordering problems, where the frame activation state + // reconciliation messages would compete with concurrent Native File + // System messages to the browser. + // TODO(https://crbug.com/1017270): Remove this after spec change, + // or when activation moves to browser. + LocalFrame::NotifyUserActivation(local_frame, + UserGestureToken::kNewGesture); + if (options->multiple()) { HeapVector<Member<NativeFileSystemHandle>> results; results.ReserveInitialCapacity(entries.size()); @@ -144,8 +159,8 @@ ScriptPromise WindowNativeFileSystem::chooseFileSystemEntries( std::move(entries[0]), context)); } }, - WrapPersistent(resolver), std::move(manager), - WrapPersistent(options))); + WrapPersistent(resolver), std::move(manager), WrapPersistent(options), + WrapPersistent(local_frame))); return resolver_result; } diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system_test.cc b/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system_test.cc new file mode 100644 index 00000000000..4fdcf6ca64c --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system_test.cc @@ -0,0 +1,216 @@ +// 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. + +#include "third_party/blink/renderer/modules/native_file_system/window_native_file_system.h" + +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/native_file_system/native_file_system_directory_handle.mojom-blink.h" +#include "third_party/blink/public/mojom/native_file_system/native_file_system_error.mojom-blink.h" +#include "third_party/blink/public/mojom/native_file_system/native_file_system_file_handle.mojom-blink.h" +#include "third_party/blink/public/mojom/native_file_system/native_file_system_manager.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/script_controller.h" +#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/html/forms/html_button_element.h" +#include "third_party/blink/renderer/core/html/html_element.h" +#include "third_party/blink/renderer/core/testing/page_test_base.h" +#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" + +namespace blink { + +class MockNativeFileSystemManager + : public mojom::blink::NativeFileSystemManager { + public: + MockNativeFileSystemManager(service_manager::InterfaceProvider* provider, + base::OnceClosure reached_callback) + : reached_callback_(std::move(reached_callback)), provider_(provider) { + service_manager::InterfaceProvider::TestApi(provider_).SetBinderForName( + mojom::blink::NativeFileSystemManager::Name_, + WTF::BindRepeating( + &MockNativeFileSystemManager::BindNativeFileSystemManager, + WTF::Unretained(this))); + } + MockNativeFileSystemManager(service_manager::InterfaceProvider* provider) + : provider_(provider) { + service_manager::InterfaceProvider::TestApi(provider_).SetBinderForName( + mojom::blink::NativeFileSystemManager::Name_, + WTF::BindRepeating( + &MockNativeFileSystemManager::BindNativeFileSystemManager, + WTF::Unretained(this))); + } + ~MockNativeFileSystemManager() override { + service_manager::InterfaceProvider::TestApi(provider_).SetBinderForName( + mojom::blink::NativeFileSystemManager::Name_, {}); + } + + using ChooseEntriesResponseCallback = + base::OnceCallback<void(ChooseEntriesCallback callback)>; + + void SetQuitClosure(base::OnceClosure reached_callback) { + reached_callback_ = std::move(reached_callback); + } + + // Unused for these tests. + void GetSandboxedFileSystem( + GetSandboxedFileSystemCallback callback) override {} + + void ChooseEntries( + mojom::ChooseFileSystemEntryType type, + WTF::Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts, + bool include_accepts_all, + ChooseEntriesCallback callback) override { + if (choose_entries_response_callback_) { + std::move(choose_entries_response_callback_).Run(std::move(callback)); + } + + if (reached_callback_) + std::move(reached_callback_).Run(); + } + + void SetChooseEntriesResponse(ChooseEntriesResponseCallback callback) { + choose_entries_response_callback_ = std::move(callback); + } + + private: + void BindNativeFileSystemManager(mojo::ScopedMessagePipeHandle handle) { + receivers_.Add(this, + mojo::PendingReceiver<mojom::blink::NativeFileSystemManager>( + std::move(handle))); + } + + base::OnceClosure reached_callback_; + ChooseEntriesResponseCallback choose_entries_response_callback_; + mojo::ReceiverSet<mojom::blink::NativeFileSystemManager> receivers_; + service_manager::InterfaceProvider* provider_; +}; + +class WindowNativeFileSystemTest : public PageTestBase { + public: + void SetUp() override { + PageTestBase::SetUp(); + Navigate("http://localhost"); + GetDocument().GetSettings()->SetScriptEnabled(true); + } + + void Navigate(const String& destinationUrl) { + const KURL& url = KURL(NullURL(), destinationUrl); + auto navigation_params = + WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(), url); + GetDocument().GetFrame()->Loader().CommitNavigation( + std::move(navigation_params), /*extra_data=*/nullptr); + blink::test::RunPendingTasks(); + ASSERT_EQ(url.GetString(), GetDocument().Url().GetString()); + } +}; + +TEST_F(WindowNativeFileSystemTest, UserActivationRequiredOtherwiseDenied) { + LocalFrame* frame = &GetFrame(); + EXPECT_FALSE(frame->HasBeenActivated()); + + MockNativeFileSystemManager manager(&frame->GetInterfaceProvider()); + manager.SetChooseEntriesResponse(WTF::Bind( + [](MockNativeFileSystemManager::ChooseEntriesCallback callback) { + FAIL(); + })); + GetFrame().GetScriptController().ExecuteScriptInMainWorld( + "window.chooseFileSystemEntries({type: 'openFile'});"); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(frame->HasBeenActivated()); +} + +TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesSuccessful) { + LocalFrame* frame = &GetFrame(); + EXPECT_FALSE(frame->HasBeenActivated()); + + LocalFrame::NotifyUserActivation(frame, UserGestureToken::kNewGesture); + EXPECT_TRUE(frame->HasBeenActivated()); + + base::RunLoop manager_run_loop; + MockNativeFileSystemManager manager(&frame->GetInterfaceProvider(), + manager_run_loop.QuitClosure()); + manager.SetChooseEntriesResponse(WTF::Bind( + [](MockNativeFileSystemManager::ChooseEntriesCallback callback) { + auto error = mojom::blink::NativeFileSystemError::New(); + error->status = mojom::blink::NativeFileSystemStatus::kOk; + error->message = ""; + + mojo::PendingRemote<mojom::blink::NativeFileSystemFileHandle> + pending_remote; + ignore_result(pending_remote.InitWithNewPipeAndPassReceiver()); + auto handle = mojom::blink::NativeFileSystemHandle::NewFile( + std::move(pending_remote)); + auto entry = mojom::blink::NativeFileSystemEntry::New(std::move(handle), + "foo.txt"); + Vector<mojom::blink::NativeFileSystemEntryPtr> entries; + entries.push_back(std::move(entry)); + + std::move(callback).Run(std::move(error), std::move(entries)); + })); + GetFrame().GetScriptController().ExecuteScriptInMainWorld( + "window.chooseFileSystemEntries({type: 'openFile'});"); + manager_run_loop.Run(); + + // Mock Manager finished sending data over the mojo pipe. + // Clearing the user activation. + frame->ClearActivation(); + EXPECT_FALSE(frame->HasBeenActivated()); + + // Let blink-side receiver process the response and set the user activation + // again. + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(frame->HasBeenActivated()); +} + +TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesErrors) { + LocalFrame* frame = &GetFrame(); + EXPECT_FALSE(frame->HasBeenActivated()); + + using mojom::blink::NativeFileSystemStatus; + + NativeFileSystemStatus statuses[] = { + NativeFileSystemStatus::kPermissionDenied, + NativeFileSystemStatus::kInvalidState, + NativeFileSystemStatus::kInvalidArgument, + NativeFileSystemStatus::kOperationFailed, + // kOperationAborted is when the user cancels the file selection. + NativeFileSystemStatus::kOperationAborted, + }; + MockNativeFileSystemManager manager(&frame->GetInterfaceProvider()); + + for (const NativeFileSystemStatus& status : statuses) { + LocalFrame::NotifyUserActivation(frame, UserGestureToken::kNewGesture); + EXPECT_TRUE(frame->HasBeenActivated()); + + base::RunLoop manager_run_loop; + manager.SetQuitClosure(manager_run_loop.QuitClosure()); + manager.SetChooseEntriesResponse(WTF::Bind( + [](mojom::blink::NativeFileSystemStatus status, + MockNativeFileSystemManager::ChooseEntriesCallback callback) { + auto error = mojom::blink::NativeFileSystemError::New(); + error->status = status; + error->message = ""; + Vector<mojom::blink::NativeFileSystemEntryPtr> entries; + + std::move(callback).Run(std::move(error), std::move(entries)); + }, + status)); + GetFrame().GetScriptController().ExecuteScriptInMainWorld( + "window.chooseFileSystemEntries({type: 'openFile'});"); + manager_run_loop.Run(); + + // Mock Manager finished sending data over the mojo pipe. + // Clearing the user activation. + frame->ClearActivation(); + EXPECT_FALSE(frame->HasBeenActivated()); + + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(frame->HasBeenActivated()); + } +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h index 32a4bc3ef24..0abb5f1a16c 100644 --- a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h +++ b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h @@ -41,7 +41,7 @@ class NavigatorContentUtilsClient; // It is owned by Navigator, and an instance is created lazily by calling // NavigatorContentUtils::From() via [register/unregister]ProtocolHandler. class MODULES_EXPORT NavigatorContentUtils final - : public GarbageCollectedFinalized<NavigatorContentUtils>, + : public GarbageCollected<NavigatorContentUtils>, public Supplement<Navigator> { USING_GARBAGE_COLLECTED_MIXIN(NavigatorContentUtils); diff --git a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.h b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.h index 98f1abb3128..0f299809ada 100644 --- a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.h +++ b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.h @@ -15,7 +15,7 @@ class KURL; class WebLocalFrameImpl; class MODULES_EXPORT NavigatorContentUtilsClient - : public GarbageCollectedFinalized<NavigatorContentUtilsClient> { + : public GarbageCollected<NavigatorContentUtilsClient> { public: explicit NavigatorContentUtilsClient(WebLocalFrameImpl*); virtual ~NavigatorContentUtilsClient() = default; diff --git a/chromium/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.cc b/chromium/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.cc index df7f64fe007..b4a199e6faf 100644 --- a/chromium/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.cc +++ b/chromium/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.cc @@ -70,8 +70,6 @@ void InternalsNetInfo::setNetworkConnectionInfoOverride( } GetNetworkStateNotifier().SetNetworkConnectionInfoOverride( on_line, webtype, web_effective_type, http_rtt_msec, downlink_max_mbps); - internals.GetFrame()->Client()->SetEffectiveConnectionTypeForTesting( - web_effective_type); } void InternalsNetInfo::setSaveDataEnabled(Internals&, bool enabled) { diff --git a/chromium/third_party/blink/renderer/modules/nfc/BUILD.gn b/chromium/third_party/blink/renderer/modules/nfc/BUILD.gn index bb111904cf8..2ee6df3bd57 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/nfc/BUILD.gn @@ -10,8 +10,6 @@ blink_modules_sources("nfc") { "ndef_message.h", "ndef_record.cc", "ndef_record.h", - "nfc_constants.cc", - "nfc_constants.h", "nfc_error_event.cc", "nfc_error_event.h", "nfc_proxy.cc", diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc index 3c6f763c421..c30cffd66f3 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc @@ -59,7 +59,7 @@ NDEFMessage::NDEFMessage() = default; NDEFMessage::NDEFMessage(const device::mojom::blink::NDEFMessage& message) : url_(message.url) { for (wtf_size_t i = 0; i < message.data.size(); ++i) { - records_.push_back(MakeGarbageCollected<NDEFRecord>(message.data[i])); + records_.push_back(MakeGarbageCollected<NDEFRecord>(*message.data[i])); } } diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc index 1bd4656a7d3..eb8e936ecd0 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc @@ -13,6 +13,8 @@ #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/network/http_parsers.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" +#include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h" #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" namespace blink { @@ -26,12 +28,52 @@ WTF::Vector<uint8_t> GetUTF8DataFromString(const String& string) { return data; } +// https://w3c.github.io/web-nfc/#the-ndefrecordtype-string +// Derives a formatted custom type for the external type record from |input|. +// Returns a null string for an invalid |input|. +// +// TODO(https://crbug.com/520391): Refine the validation algorithm here +// accordingly once there is a conclusion on some case-sensitive things at +// https://github.com/w3c/web-nfc/issues/331. +String ValidateCustomRecordType(const String& input) { + static const String kOtherCharsForCustomType("()+,-:=@;$_!*'."); + + if (input.IsEmpty()) + return String(); + + // Finds the separator ':'. + wtf_size_t colon_index = input.find(':'); + if (colon_index == kNotFound) + return String(); + + // Derives the domain (FQDN) from the part before ':'. + String left = input.Left(colon_index); + bool success = false; + String domain = SecurityOrigin::CanonicalizeHost(left, &success); + if (!success || domain.IsEmpty()) + return String(); + + // Validates the part after ':'. + String right = input.Substring(colon_index + 1); + if (right.length() == 0) + return String(); + for (wtf_size_t i = 0; i < right.length(); i++) { + if (!IsASCIIAlphanumeric(right[i]) && + !kOtherCharsForCustomType.Contains(right[i])) { + return String(); + } + } + + return domain + ':' + right; +} + static NDEFRecord* CreateTextRecord(const String& media_type, const ScriptValue& data, ExceptionState& exception_state) { // https://w3c.github.io/web-nfc/#mapping-string-to-ndef if (data.IsEmpty() || !data.V8Value()->IsString()) { - exception_state.ThrowTypeError(kNfcTextRecordTypeError); + exception_state.ThrowTypeError( + "The data for 'text' NDEFRecords must be a String."); return nullptr; } @@ -43,10 +85,10 @@ static NDEFRecord* CreateTextRecord(const String& media_type, // always uses "lang=en-US;charset=UTF-8" when pushing the record to a NFC // tag. if (mime_type.IsEmpty()) { - mime_type = kNfcPlainTextMimeType; - } else if (!mime_type.StartsWithIgnoringASCIICase(kNfcPlainTextMimePrefix)) { + mime_type = "text/plain"; + } else if (!mime_type.StartsWithIgnoringASCIICase("text/")) { exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, - kNfcTextRecordMediaTypeError); + "Invalid media type for 'text' record."); return nullptr; } @@ -60,7 +102,8 @@ static NDEFRecord* CreateUrlRecord(const String& media_type, ExceptionState& exception_state) { // https://w3c.github.io/web-nfc/#mapping-url-to-ndef if (data.IsEmpty() || !data.V8Value()->IsString()) { - exception_state.ThrowTypeError(kNfcUrlRecordTypeError); + exception_state.ThrowTypeError( + "The data for 'url' NDEFRecord must be a String."); return nullptr; } @@ -68,7 +111,7 @@ static NDEFRecord* CreateUrlRecord(const String& media_type, String url = ToCoreString(data.V8Value().As<v8::String>()); if (!KURL(NullURL(), url).IsValid()) { exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, - kNfcUrlRecordParseError); + "Cannot parse data for 'url' record."); return nullptr; } return MakeGarbageCollected<NDEFRecord>("url", media_type, @@ -80,22 +123,22 @@ static NDEFRecord* CreateJsonRecord(const String& media_type, ExceptionState& exception_state) { // https://w3c.github.io/web-nfc/#mapping-json-to-ndef if (data.IsEmpty()) { - exception_state.ThrowTypeError(kNfcJsonRecordNoDataError); + exception_state.ThrowTypeError( + "The data for 'json' NDEFRecord is missing."); return nullptr; } // ExtractMIMETypeFromMediaType() ignores parameters of the MIME type. String mime_type = ExtractMIMETypeFromMediaType(AtomicString(media_type)); if (mime_type.IsEmpty()) { - mime_type = kNfcJsonMimeType; - } else if (mime_type != kNfcJsonMimeType && - mime_type != kNfcJsonTextMimeType && - !mime_type.EndsWithIgnoringASCIICase(kNfcJsonMimePostfix)) { + mime_type = "application/json"; + } else if (mime_type != "application/json" && mime_type != "text/json" && + !mime_type.EndsWithIgnoringASCIICase("+json")) { // According to https://mimesniff.spec.whatwg.org/#json-mime-type, a JSON // MIME type is any MIME type whose subtype ends in "+json" or whose // essence is "application/json" or "text/json". exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, - kNfcJsonRecordMediaTypeError); + "Invalid media type for 'json' record."); return nullptr; } @@ -120,14 +163,15 @@ static NDEFRecord* CreateOpaqueRecord(const String& media_type, ExceptionState& exception_state) { // https://w3c.github.io/web-nfc/#mapping-binary-data-to-ndef if (data.IsEmpty() || !data.V8Value()->IsArrayBuffer()) { - exception_state.ThrowTypeError(kNfcOpaqueRecordTypeError); + exception_state.ThrowTypeError( + "The data for 'opaque' NDEFRecord must be an ArrayBuffer."); return nullptr; } // ExtractMIMETypeFromMediaType() ignores parameters of the MIME type. String mime_type = ExtractMIMETypeFromMediaType(AtomicString(media_type)); if (mime_type.IsEmpty()) { - mime_type = kNfcOpaqueMimeType; + mime_type = "application/octet-stream"; } DOMArrayBuffer* array_buffer = V8ArrayBuffer::ToImpl(data.V8Value().As<v8::Object>()); @@ -138,6 +182,25 @@ static NDEFRecord* CreateOpaqueRecord(const String& media_type, std::move(bytes)); } +static NDEFRecord* CreateExternalRecord(const String& custom_type, + const ScriptValue& data, + ExceptionState& exception_state) { + // https://w3c.github.io/web-nfc/#dfn-map-external-data-to-ndef + if (data.IsEmpty() || !data.V8Value()->IsArrayBuffer()) { + exception_state.ThrowTypeError( + "The data for external type NDEFRecord must be an ArrayBuffer."); + return nullptr; + } + + DOMArrayBuffer* array_buffer = + V8ArrayBuffer::ToImpl(data.V8Value().As<v8::Object>()); + WTF::Vector<uint8_t> bytes; + bytes.Append(static_cast<uint8_t*>(array_buffer->Data()), + array_buffer->ByteLength()); + return MakeGarbageCollected<NDEFRecord>( + custom_type, "application/octet-stream", std::move(bytes)); +} + } // namespace // static @@ -175,10 +238,18 @@ NDEFRecord* NDEFRecord::Create(const NDEFRecordInit* init, return CreateJsonRecord(init->mediaType(), init->data(), exception_state); } else if (record_type == "opaque") { return CreateOpaqueRecord(init->mediaType(), init->data(), exception_state); + } else if (record_type == "smart-poster") { + // TODO(https://crbug.com/520391): Support creating smart-poster records. + exception_state.ThrowTypeError("smart-poster type is not supported yet"); + return nullptr; + } else { + String formated_type = ValidateCustomRecordType(record_type); + if (!formated_type.IsNull()) + return CreateExternalRecord(formated_type, init->data(), exception_state); } - NOTREACHED(); - return nullptr; + exception_state.ThrowTypeError("Unknown NDEFRecord type."); + return nullptr; } NDEFRecord::NDEFRecord(const String& record_type, @@ -190,19 +261,19 @@ NDEFRecord::NDEFRecord(const String& record_type, NDEFRecord::NDEFRecord(const String& text) : record_type_("text"), - media_type_(StringView(kNfcPlainTextMimeType) + kNfcCharSetUTF8), + media_type_("text/plain;charset=UTF-8"), data_(GetUTF8DataFromString(text)) {} NDEFRecord::NDEFRecord(DOMArrayBuffer* array_buffer) - : record_type_("opaque"), media_type_(kNfcOpaqueMimeType) { + : record_type_("opaque"), media_type_("application/octet-stream") { data_.Append(static_cast<uint8_t*>(array_buffer->Data()), array_buffer->ByteLength()); } -NDEFRecord::NDEFRecord(const device::mojom::blink::NDEFRecordPtr& record) - : record_type_(NDEFRecordTypeToString(record->record_type)), - media_type_(record->media_type), - data_(record->data) {} +NDEFRecord::NDEFRecord(const device::mojom::blink::NDEFRecord& record) + : record_type_(record.record_type), + media_type_(record.media_type), + data_(record.data) {} const String& NDEFRecord::recordType() const { return record_type_; @@ -212,10 +283,8 @@ const String& NDEFRecord::mediaType() const { return media_type_; } -String NDEFRecord::toText() const { - device::mojom::blink::NDEFRecordType type = - StringToNDEFRecordType(record_type_); - if (type == device::mojom::blink::NDEFRecordType::EMPTY) +String NDEFRecord::text() const { + if (record_type_ == "empty") return String(); // TODO(https://crbug.com/520391): Support utf-16 decoding for 'TEXT' record @@ -224,25 +293,25 @@ String NDEFRecord::toText() const { return String::FromUTF8WithLatin1Fallback(data_.data(), data_.size()); } -DOMArrayBuffer* NDEFRecord::toArrayBuffer() const { - device::mojom::blink::NDEFRecordType type = - StringToNDEFRecordType(record_type_); - if (type != device::mojom::blink::NDEFRecordType::JSON && - type != device::mojom::blink::NDEFRecordType::OPAQUE_RECORD) { +DOMArrayBuffer* NDEFRecord::arrayBuffer() const { + if (record_type_ == "empty" || record_type_ == "text" || + record_type_ == "url") { return nullptr; } + DCHECK(record_type_ == "json" || record_type_ == "opaque" || + !ValidateCustomRecordType(record_type_).IsNull()); return DOMArrayBuffer::Create(data_.data(), data_.size()); } -ScriptValue NDEFRecord::toJSON(ScriptState* script_state, - ExceptionState& exception_state) const { - device::mojom::blink::NDEFRecordType type = - StringToNDEFRecordType(record_type_); - if (type != device::mojom::blink::NDEFRecordType::JSON && - type != device::mojom::blink::NDEFRecordType::OPAQUE_RECORD) { - return ScriptValue::CreateNull(script_state); +ScriptValue NDEFRecord::json(ScriptState* script_state, + ExceptionState& exception_state) const { + if (record_type_ == "empty" || record_type_ == "text" || + record_type_ == "url") { + return ScriptValue::CreateNull(script_state->GetIsolate()); } + DCHECK(record_type_ == "json" || record_type_ == "opaque" || + !ValidateCustomRecordType(record_type_).IsNull()); ScriptState::Scope scope(script_state); v8::Local<v8::Value> json_object = FromJSONString( @@ -250,8 +319,8 @@ ScriptValue NDEFRecord::toJSON(ScriptState* script_state, String::FromUTF8WithLatin1Fallback(data_.data(), data_.size()), exception_state); if (exception_state.HadException()) - return ScriptValue::CreateNull(script_state); - return ScriptValue(script_state, json_object); + return ScriptValue::CreateNull(script_state->GetIsolate()); + return ScriptValue(script_state->GetIsolate(), json_object); } const WTF::Vector<uint8_t>& NDEFRecord::data() const { diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.h b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.h index d79185d7462..a77a38276d0 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.h +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.h @@ -33,13 +33,13 @@ class MODULES_EXPORT NDEFRecord final : public ScriptWrappable { explicit NDEFRecord(DOMArrayBuffer*); NDEFRecord(const String&, const String&, WTF::Vector<uint8_t>); - explicit NDEFRecord(const device::mojom::blink::NDEFRecordPtr&); + explicit NDEFRecord(const device::mojom::blink::NDEFRecord&); const String& recordType() const; const String& mediaType() const; - String toText() const; - DOMArrayBuffer* toArrayBuffer() const; - ScriptValue toJSON(ScriptState*, ExceptionState&) const; + String text() const; + DOMArrayBuffer* arrayBuffer() const; + ScriptValue json(ScriptState*, ExceptionState&) const; const WTF::Vector<uint8_t>& data() const; diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.idl b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.idl index 8a7a3336844..e751a681c8c 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.idl +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.idl @@ -13,7 +13,7 @@ ] interface NDEFRecord { readonly attribute NDEFRecordType recordType; readonly attribute USVString mediaType; - USVString? toText(); - [NewObject] ArrayBuffer? toArrayBuffer(); - [CallWith=ScriptState, RaisesException] object? toJSON(); + USVString? text(); + [NewObject] ArrayBuffer? arrayBuffer(); + [CallWith=ScriptState, RaisesException] object? json(); }; diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_record_init.idl b/chromium/third_party/blink/renderer/modules/nfc/ndef_record_init.idl index 0bb871c321b..af2d2f1e3a8 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_record_init.idl +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_record_init.idl @@ -2,12 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/web-nfc/#dom-ndefrecordinit +// https://w3c.github.io/web-nfc/#the-ndefrecordtype-string -enum NDEFRecordType { "empty", "text", "url", "json", "opaque" }; +typedef DOMString NDEFRecordType; typedef any NDEFRecordData; +// https://w3c.github.io/web-nfc/#dom-ndefrecordinit + dictionary NDEFRecordInit { NDEFRecordType recordType; USVString mediaType; diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_constants.cc b/chromium/third_party/blink/renderer/modules/nfc/nfc_constants.cc deleted file mode 100644 index 6961e4ad108..00000000000 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_constants.cc +++ /dev/null @@ -1,61 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/nfc/nfc_constants.h" - -namespace blink { - -const char kNfcJsonMimePostfix[] = "+json"; -const char kNfcJsonMimePrefix[] = "application/"; -const char kNfcJsonMimeType[] = "application/json"; -const char kNfcJsonTextMimeType[] = "text/json"; -const char kNfcOpaqueMimeType[] = "application/octet-stream"; -const char kNfcPlainTextMimeType[] = "text/plain"; -const char kNfcPlainTextMimePrefix[] = "text/"; -const char kNfcProtocolHttps[] = "https"; -const char kNfcCharSetUTF8[] = ";charset=UTF-8"; - -// Error messages. -const char kNfcNotAllowed[] = "NFC operation not allowed."; -const char kNfcNotSupported[] = - "No NFC adapter or cannot establish connection."; -const char kNfcNotReadable[] = "NFC is not enabled."; -const char kNfcTextRecordTypeError[] = - "The data for 'text' NDEFRecords must be of String."; -const char kNfcSetIdError[] = "Cannot set WebNFC Id."; -const char kNfcTextRecordMediaTypeError[] = - "Invalid media type for 'text' record."; -const char kNfcUrlRecordTypeError[] = - "The data for 'url' NDEFRecord must be of String type."; -const char kNfcUrlRecordParseError[] = "Cannot parse data for 'url' record."; -const char kNfcJsonRecordNoDataError[] = - "The data for 'json' NDEFRecord is missing."; -const char kNfcJsonRecordStringifyError[] = - "Cannot stringify data for 'json' record."; -const char kNfcJsonRecordMediaTypeError[] = - "Invalid media type for 'json' record."; -const char kNfcOpaqueRecordTypeError[] = - "The data for 'opaque' NDEFRecord must be of ArrayBuffer type."; -const char kNfcRecordTypeError[] = "Unknown NDEFRecord type."; -const char kNfcRecordDataError[] = "Nonempty NDEFRecord must have data."; -const char kNfcRecordError[] = "Invalid NDEFRecordType was provided."; -const char kNfcMsgTypeError[] = "Invalid NDEFMessageSource type was provided."; -const char kNfcEmptyMsg[] = "Empty NDEFMessage was provided."; -const char kNfcInvalidMsg[] = "Invalid NFC message was provided."; -const char kNfcMsgConvertError[] = "Cannot convert NDEFMessage."; -const char kNfcMsgMaxSizeError[] = - "NDEFMessage exceeds maximum supported size."; -const char kNfcUrlPatternError[] = "Invalid URL pattern was provided."; -const char kNfcInvalidPushTimeout[] = - "Invalid NFCPushOptions.timeout value was provided."; -const char kNfcWatchIdNotFound[] = "Provided watch id cannot be found."; -const char kNfcAccessInNonTopFrame[] = - "NFC interfaces are only avaliable in a top-level browsing context"; -const char kNfcCancelled[] = "The NFC operation was cancelled."; -const char kNfcTimeout[] = "NFC operation has timed out."; -const char kNfcUnknownError[] = "An unknown NFC error has occurred."; -const char kNfcDataTransferError[] = "NFC data transfer error has occurred."; -const char kNfcNoModificationAllowed[] = "NFC operation cannot be cancelled."; - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_constants.h b/chromium/third_party/blink/renderer/modules/nfc/nfc_constants.h deleted file mode 100644 index 8196666b4fd..00000000000 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_constants.h +++ /dev/null @@ -1,54 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_NFC_NFC_CONSTANTS_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_NFC_NFC_CONSTANTS_H_ - - -namespace blink { - -extern const char kNfcJsonMimePostfix[]; -extern const char kNfcJsonMimePrefix[]; -extern const char kNfcJsonMimeType[]; -extern const char kNfcJsonTextMimeType[]; -extern const char kNfcOpaqueMimeType[]; -extern const char kNfcPlainTextMimeType[]; -extern const char kNfcPlainTextMimePrefix[]; -extern const char kNfcProtocolHttps[]; -extern const char kNfcCharSetUTF8[]; - -// Error messages. -extern const char kNfcNotAllowed[]; -extern const char kNfcNotSupported[]; -extern const char kNfcNotReadable[]; -extern const char kNfcTextRecordTypeError[]; -extern const char kNfcSetIdError[]; -extern const char kNfcTextRecordMediaTypeError[]; -extern const char kNfcUrlRecordTypeError[]; -extern const char kNfcUrlRecordParseError[]; -extern const char kNfcJsonRecordNoDataError[]; -extern const char kNfcJsonRecordStringifyError[]; -extern const char kNfcJsonRecordMediaTypeError[]; -extern const char kNfcOpaqueRecordTypeError[]; -extern const char kNfcRecordTypeError[]; -extern const char kNfcRecordDataError[]; -extern const char kNfcRecordError[]; -extern const char kNfcMsgTypeError[]; -extern const char kNfcEmptyMsg[]; -extern const char kNfcInvalidMsg[]; -extern const char kNfcMsgConvertError[]; -extern const char kNfcMsgMaxSizeError[]; -extern const char kNfcUrlPatternError[]; -extern const char kNfcInvalidPushTimeout[]; -extern const char kNfcWatchIdNotFound[]; -extern const char kNfcAccessInNonTopFrame[]; -extern const char kNfcCancelled[]; -extern const char kNfcTimeout[]; -extern const char kNfcUnknownError[]; -extern const char kNfcDataTransferError[]; -extern const char kNfcNoModificationAllowed[]; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NFC_NFC_CONSTANTS_H_ diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc index df9306051fa..58c193ebb73 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc @@ -6,7 +6,7 @@ #include <utility> -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/core/page/focus_controller.h" #include "third_party/blink/renderer/modules/nfc/nfc_reader.h" #include "third_party/blink/renderer/modules/nfc/nfc_type_converters.h" @@ -188,7 +188,7 @@ void NFCProxy::EnsureMojoConnection() { if (nfc_remote_) return; - GetSupplementable()->GetInterfaceProvider()->GetInterface( + GetSupplementable()->GetBrowserInterfaceBroker().GetInterface( nfc_remote_.BindNewPipeAndPassReceiver()); nfc_remote_.set_disconnect_handler( WTF::Bind(&NFCProxy::OnMojoConnectionError, WrapWeakPersistent(this))); diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h index 1362c6ec97a..95009090abd 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h @@ -23,12 +23,11 @@ class NFCWriter; // This is a proxy class used by NFCWriter(s) and NFCReader(s) to connect // to implementation of device::mojom::blink::NFC interface. -class MODULES_EXPORT NFCProxy final - : public GarbageCollectedFinalized<NFCProxy>, - public PageVisibilityObserver, - public FocusChangedObserver, - public Supplement<Document>, - public device::mojom::blink::NFCClient { +class MODULES_EXPORT NFCProxy final : public GarbageCollected<NFCProxy>, + public PageVisibilityObserver, + public FocusChangedObserver, + public Supplement<Document>, + public device::mojom::blink::NFCClient { USING_GARBAGE_COLLECTED_MIXIN(NFCProxy); USING_PRE_FINALIZER(NFCProxy, Dispose); diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy_test.cc b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy_test.cc index 2a2ac6859a5..eac4afaff36 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy_test.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy_test.cc @@ -8,9 +8,10 @@ #include "base/run_loop.h" #include "base/test/bind_test_util.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" -#include "services/service_manager/public/cpp/interface_provider.h" #include "testing/gmock/include/gmock/gmock.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/modules/nfc/nfc_proxy.h" @@ -62,7 +63,8 @@ class FakeNfcService : public device::mojom::blink::NFC { void BindRequest(mojo::ScopedMessagePipeHandle handle) { DCHECK(!receiver_.is_bound()); - receiver_.Bind(device::mojom::blink::NFCRequest(std::move(handle))); + receiver_.Bind( + mojo::PendingReceiver<device::mojom::blink::NFC>(std::move(handle))); receiver_.set_disconnect_handler( WTF::Bind(&FakeNfcService::OnConnectionError, WTF::Unretained(this))); } @@ -152,15 +154,17 @@ class NFCProxyTest : public PageTestBase { void SetUp() override { PageTestBase::SetUp(IntSize()); - - service_manager::InterfaceProvider::TestApi test_api( - GetDocument().GetInterfaceProvider()); - test_api.SetBinderForName( + GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting( device::mojom::blink::NFC::Name_, WTF::BindRepeating(&FakeNfcService::BindRequest, WTF::Unretained(nfc_service()))); } + void TearDown() override { + GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting( + device::mojom::blink::NFC::Name_, {}); + } + FakeNfcService* nfc_service() { return nfc_service_.get(); } void DestroyNfcService() { nfc_service_.reset(); } @@ -187,7 +191,7 @@ TEST_F(NFCProxyTest, SuccessfulPath) { auto record = device::mojom::blink::NDEFRecord::New(); WTF::Vector<uint8_t> record_data( {0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10}); - record->record_type = device::mojom::blink::NDEFRecordType::OPAQUE_RECORD; + record->record_type = "opaque"; record->data = WTF::Vector<uint8_t>(record_data); message->data.push_back(std::move(record)); diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_push_options.idl b/chromium/third_party/blink/renderer/modules/nfc/nfc_push_options.idl index 39da64fce2c..2156206ce72 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_push_options.idl +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_push_options.idl @@ -11,5 +11,4 @@ dictionary NFCPushOptions { unrestricted double timeout; // in ms boolean ignoreRead = true; AbortSignal? signal; - NDEFCompatibility compatibility = "nfc-forum"; }; diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_reader.cc b/chromium/third_party/blink/renderer/modules/nfc/nfc_reader.cc index 1cc7e8cb5c1..5fbab481088 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_reader.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_reader.cc @@ -10,7 +10,6 @@ #include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/modules/event_target_modules.h" #include "third_party/blink/renderer/modules/nfc/ndef_message.h" -#include "third_party/blink/renderer/modules/nfc/nfc_constants.h" #include "third_party/blink/renderer/modules/nfc/nfc_error_event.h" #include "third_party/blink/renderer/modules/nfc/nfc_proxy.h" #include "third_party/blink/renderer/modules/nfc/nfc_reading_event.h" @@ -26,7 +25,11 @@ NFCReader* NFCReader::Create(ExecutionContext* context) { } NFCReader::NFCReader(ExecutionContext* context) - : ContextLifecycleObserver(context) {} + : ContextLifecycleObserver(context) { + // Call GetNFCProxy to create a proxy. This guarantees no allocation will + // be needed when calling HasPendingActivity later during gc tracing. + GetNfcProxy(); +} NFCReader::~NFCReader() = default; @@ -63,11 +66,11 @@ void NFCReader::scan(const NFCScanOptions* options) { // pattern, fire a NFCErrorEvent with "SyntaxError" DOMException, then return. if (options->hasURL() && !options->url().IsEmpty()) { KURL pattern_url(options->url()); - if (!pattern_url.IsValid() || pattern_url.Protocol() != kNfcProtocolHttps) { + if (!pattern_url.IsValid() || pattern_url.Protocol() != "https") { DispatchEvent(*MakeGarbageCollected<NFCErrorEvent>( - event_type_names::kError, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError, - kNfcUrlPatternError))); + event_type_names::kError, MakeGarbageCollected<DOMException>( + DOMExceptionCode::kSyntaxError, + "Invalid URL pattern was provided."))); return; } } @@ -112,7 +115,8 @@ bool NFCReader::CheckSecurity() { DispatchEvent(*MakeGarbageCollected<NFCErrorEvent>( event_type_names::kError, MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotAllowedError, - kNfcAccessInNonTopFrame))); + "NFC interfaces are only avaliable " + "in a top-level browsing context"))); return false; } return true; diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_scan_options.idl b/chromium/third_party/blink/renderer/modules/nfc/nfc_scan_options.idl index 71113658a3c..af62a8eb6e2 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_scan_options.idl +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_scan_options.idl @@ -2,15 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - -// http://w3c.github.io/web-nfc/#dom-ndefcompatibility -enum NDEFCompatibility { "nfc-forum", "vendor", "any" }; - // https://w3c.github.io/web-nfc/#the-nfcscanoptions-dictionary dictionary NFCScanOptions { AbortSignal? signal; USVString url = ""; NDEFRecordType? recordType; USVString mediaType = ""; - NDEFCompatibility compatibility = "nfc-forum"; }; diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.cc b/chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.cc index 37e932d7195..a11da094ed6 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_type_converters.cc @@ -30,8 +30,8 @@ namespace mojo { NDEFRecordPtr TypeConverter<NDEFRecordPtr, ::blink::NDEFRecord*>::Convert( const ::blink::NDEFRecord* record) { - return NDEFRecord::New(blink::StringToNDEFRecordType(record->recordType()), - record->mediaType(), record->data()); + return NDEFRecord::New(record->recordType(), record->mediaType(), + record->data()); } NDEFMessagePtr TypeConverter<NDEFMessagePtr, ::blink::NDEFMessage*>::Convert( @@ -52,13 +52,10 @@ TypeConverter<NFCPushOptionsPtr, const blink::NFCPushOptions*>::Convert( const blink::NFCPushOptions* pushOptions) { // https://w3c.github.io/web-nfc/#the-nfcpushoptions-dictionary // Default values for NFCPushOptions dictionary are: - // target = 'any', timeout = Infinity, ignoreRead = true, - // compatibility = "nfc-forum" + // target = 'any', timeout = Infinity, ignoreRead = true NFCPushOptionsPtr pushOptionsPtr = NFCPushOptions::New(); pushOptionsPtr->target = blink::StringToNFCPushTarget(pushOptions->target()); pushOptionsPtr->ignore_read = pushOptions->ignoreRead(); - pushOptionsPtr->compatibility = - blink::StringToNDEFCompatibility(pushOptions->compatibility()); if (pushOptions->hasTimeout()) pushOptionsPtr->timeout = pushOptions->timeout(); @@ -73,17 +70,14 @@ TypeConverter<NFCScanOptionsPtr, const blink::NFCScanOptions*>::Convert( const blink::NFCScanOptions* scanOptions) { // https://w3c.github.io/web-nfc/#dom-nfcscanoptions // Default values for NFCScanOptions dictionary are: - // url = "", recordType = null, mediaType = "", compatibility = "nfc-forum" + // url = "", recordType = null, mediaType = "" NFCScanOptionsPtr scanOptionsPtr = NFCScanOptions::New(); scanOptionsPtr->url = scanOptions->url(); scanOptionsPtr->media_type = scanOptions->mediaType(); - scanOptionsPtr->compatibility = - blink::StringToNDEFCompatibility(scanOptions->compatibility()); if (scanOptions->hasRecordType()) { scanOptionsPtr->record_filter = NDEFRecordTypeFilter::New(); - scanOptionsPtr->record_filter->record_type = - blink::StringToNDEFRecordType(scanOptions->recordType()); + scanOptionsPtr->record_filter->record_type = scanOptions->recordType(); } return scanOptionsPtr; diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.cc b/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.cc index a8b7b21e14e..32477ef23bd 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.cc @@ -9,28 +9,25 @@ #include "services/device/public/mojom/nfc.mojom-blink.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" -#include "third_party/blink/renderer/modules/nfc/nfc_constants.h" #include "third_party/blink/renderer/modules/nfc/nfc_type_converters.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" -using device::mojom::blink::NDEFCompatibility; -using device::mojom::blink::NDEFRecordType; using device::mojom::blink::NFCPushTarget; namespace blink { -size_t GetNDEFMessageSize(const device::mojom::blink::NDEFMessagePtr& message) { - size_t message_size = message->url.CharactersSizeInBytes(); - for (wtf_size_t i = 0; i < message->data.size(); ++i) { - message_size += message->data[i]->media_type.CharactersSizeInBytes(); - message_size += message->data[i]->data.size(); +size_t GetNDEFMessageSize(const device::mojom::blink::NDEFMessage& message) { + size_t message_size = message.url.CharactersSizeInBytes(); + for (wtf_size_t i = 0; i < message.data.size(); ++i) { + message_size += message.data[i]->media_type.CharactersSizeInBytes(); + message_size += message.data[i]->data.size(); } return message_size; } bool SetNDEFMessageURL(const String& origin, - device::mojom::blink::NDEFMessagePtr& message) { + device::mojom::blink::NDEFMessage* message) { KURL origin_url(origin); if (!message->url.IsEmpty() && origin_url.CanSetPathname()) { @@ -41,58 +38,6 @@ bool SetNDEFMessageURL(const String& origin, return origin_url.IsValid(); } -String NDEFRecordTypeToString(const NDEFRecordType& type) { - switch (type) { - case NDEFRecordType::TEXT: - return "text"; - case NDEFRecordType::URL: - return "url"; - case NDEFRecordType::JSON: - return "json"; - case NDEFRecordType::OPAQUE_RECORD: - return "opaque"; - case NDEFRecordType::EMPTY: - return "empty"; - } - - NOTREACHED(); - return String(); -} - -NDEFCompatibility StringToNDEFCompatibility(const String& compatibility) { - if (compatibility == "nfc-forum") - return NDEFCompatibility::NFC_FORUM; - - if (compatibility == "vendor") - return NDEFCompatibility::VENDOR; - - if (compatibility == "any") - return NDEFCompatibility::ANY; - - NOTREACHED(); - return NDEFCompatibility::NFC_FORUM; -} - -NDEFRecordType StringToNDEFRecordType(const String& recordType) { - if (recordType == "empty") - return NDEFRecordType::EMPTY; - - if (recordType == "text") - return NDEFRecordType::TEXT; - - if (recordType == "url") - return NDEFRecordType::URL; - - if (recordType == "json") - return NDEFRecordType::JSON; - - if (recordType == "opaque") - return NDEFRecordType::OPAQUE_RECORD; - - NOTREACHED(); - return NDEFRecordType::EMPTY; -} - NFCPushTarget StringToNFCPushTarget(const String& target) { if (target == "tag") return NFCPushTarget::TAG; @@ -108,32 +53,35 @@ DOMException* NFCErrorTypeToDOMException( switch (error_type) { case device::mojom::blink::NFCErrorType::NOT_ALLOWED: return MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotAllowedError, kNfcNotAllowed); + DOMExceptionCode::kNotAllowedError, "NFC operation not allowed."); case device::mojom::blink::NFCErrorType::NOT_SUPPORTED: return MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotSupportedError, kNfcNotSupported); + DOMExceptionCode::kNotSupportedError, + "No NFC adapter or cannot establish connection."); case device::mojom::blink::NFCErrorType::NOT_READABLE: return MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotReadableError, kNfcNotReadable); + DOMExceptionCode::kNotReadableError, "NFC is not enabled."); case device::mojom::blink::NFCErrorType::NOT_FOUND: return MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotFoundError, kNfcWatchIdNotFound); + DOMExceptionCode::kNotFoundError, + "Provided watch id cannot be found."); case device::mojom::blink::NFCErrorType::INVALID_MESSAGE: - return MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError, - kNfcInvalidMsg); + return MakeGarbageCollected<DOMException>( + DOMExceptionCode::kSyntaxError, "Invalid NFC message was provided."); case device::mojom::blink::NFCErrorType::OPERATION_CANCELLED: - return MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError, - kNfcCancelled); + return MakeGarbageCollected<DOMException>( + DOMExceptionCode::kAbortError, "The NFC operation was cancelled."); case device::mojom::blink::NFCErrorType::TIMER_EXPIRED: return MakeGarbageCollected<DOMException>(DOMExceptionCode::kTimeoutError, - kNfcTimeout); + "NFC operation has timed out."); case device::mojom::blink::NFCErrorType::CANNOT_CANCEL: return MakeGarbageCollected<DOMException>( DOMExceptionCode::kNoModificationAllowedError, - kNfcNoModificationAllowed); + "NFC operation cannot be cancelled."); case device::mojom::blink::NFCErrorType::IO_ERROR: - return MakeGarbageCollected<DOMException>(DOMExceptionCode::kNetworkError, - kNfcDataTransferError); + return MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNetworkError, + "NFC data transfer error has occurred."); } NOTREACHED(); // Don't need to handle the case after a NOTREACHED(). diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.h b/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.h index a8aabb0b421..5c1954eb1dc 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.h +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_utils.h @@ -9,26 +9,16 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/modules/nfc/ndef_message.h" #include "third_party/blink/renderer/modules/nfc/ndef_record.h" -#include "third_party/blink/renderer/modules/nfc/nfc_constants.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { class DOMException; -size_t GetNDEFMessageSize(const device::mojom::blink::NDEFMessagePtr& message); +size_t GetNDEFMessageSize(const device::mojom::blink::NDEFMessage& message); bool SetNDEFMessageURL(const String& origin, - device::mojom::blink::NDEFMessagePtr& message); - -WTF::String NDEFRecordTypeToString( - const device::mojom::blink::NDEFRecordType& type); - -device::mojom::blink::NDEFCompatibility StringToNDEFCompatibility( - const WTF::String& compatibility); - -device::mojom::blink::NDEFRecordType StringToNDEFRecordType( - const WTF::String& recordType); + device::mojom::blink::NDEFMessage* message); device::mojom::blink::NFCPushTarget StringToNFCPushTarget( const WTF::String& target); diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_writer.cc b/chromium/third_party/blink/renderer/modules/nfc/nfc_writer.cc index 899a656800f..a69c3e2ae5a 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_writer.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_writer.cc @@ -45,15 +45,17 @@ ScriptPromise NFCWriter::push(ScriptState* script_state, return ScriptPromise::RejectWithDOMException( script_state, MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotAllowedError, - kNfcAccessInNonTopFrame)); + "NFC interfaces are only avaliable " + "in a top-level browsing context")); } if (options->hasSignal() && options->signal()->aborted()) { // If signal’s aborted flag is set, then reject p with an "AbortError" // DOMException and return p. return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kAbortError, kNfcCancelled)); + script_state, + MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError, + "The NFC operation was cancelled.")); } // 9. If timeout value is NaN or negative, reject promise with "TypeError" @@ -61,8 +63,10 @@ ScriptPromise NFCWriter::push(ScriptState* script_state, if (options->hasTimeout() && (std::isnan(options->timeout()) || options->timeout() < 0)) { return ScriptPromise::Reject( - script_state, V8ThrowException::CreateTypeError( - script_state->GetIsolate(), kNfcInvalidPushTimeout)); + script_state, + V8ThrowException::CreateTypeError( + script_state->GetIsolate(), + "Invalid NFCPushOptions.timeout value was provided.")); } // Step 10.8: Run "create Web NFC message", if this throws an exception, @@ -75,27 +79,29 @@ ScriptPromise NFCWriter::push(ScriptState* script_state, // If NDEFMessage.records is empty, reject promise with TypeError if (ndef_message->records().size() == 0) { - return ScriptPromise::Reject(script_state, - V8ThrowException::CreateTypeError( - script_state->GetIsolate(), kNfcEmptyMsg)); + return ScriptPromise::Reject( + script_state, + V8ThrowException::CreateTypeError(script_state->GetIsolate(), + "Empty NDEFMessage was provided.")); } auto message = device::mojom::blink::NDEFMessage::From(ndef_message); DCHECK(message); if (!SetNDEFMessageURL(execution_context->GetSecurityOrigin()->ToString(), - message)) { + message.get())) { return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kSyntaxError, kNfcSetIdError)); + script_state, + MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError, + "Cannot set WebNFC Id.")); } - if (GetNDEFMessageSize(message) > + if (GetNDEFMessageSize(*message) > device::mojom::blink::NDEFMessage::kMaxSize) { return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - kNfcMsgMaxSizeError)); + script_state, MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNotSupportedError, + "NDEFMessage exceeds maximum supported size.")); } auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); diff --git a/chromium/third_party/blink/renderer/modules/nfc/nfc_writer.h b/chromium/third_party/blink/renderer/modules/nfc/nfc_writer.h index 1c80c29a266..9a3ad6687cb 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_writer.h +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_writer.h @@ -7,7 +7,6 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" -#include "third_party/blink/renderer/modules/nfc/nfc_constants.h" #include "third_party/blink/renderer/modules/nfc/nfc_proxy.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/heap_allocator.h" diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification.cc b/chromium/third_party/blink/renderer/modules/notifications/notification.cc index 88db76541d9..4337c4e4e53 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification.cc +++ b/chromium/third_party/blink/renderer/modules/notifications/notification.cc @@ -35,7 +35,7 @@ #include "base/unguessable_token.h" #include "mojo/public/cpp/bindings/pending_remote.h" -#include "third_party/blink/public/platform/modules/notifications/web_notification_constants.h" +#include "third_party/blink/public/common/notifications/notification_constants.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" @@ -353,7 +353,7 @@ ScriptValue Notification::data(ScriptState* script_state) { scoped_refptr<SerializedScriptValue> serialized_value = SerializedScriptValue::Create(data, length); - return ScriptValue(script_state, + return ScriptValue(script_state->GetIsolate(), serialized_value->Deserialize(script_state->GetIsolate())); } @@ -469,7 +469,7 @@ ScriptPromise Notification::requestPermission( } uint32_t Notification::maxActions() { - return kWebNotificationMaxActions; + return kNotificationMaxActions; } DispatchEventResult Notification::DispatchEventInternal(Event& event) { diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification.h b/chromium/third_party/blink/renderer/modules/notifications/notification.h index 11347c60522..b45101ea0ec 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification.h +++ b/chromium/third_party/blink/renderer/modules/notifications/notification.h @@ -33,8 +33,8 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "third_party/blink/public/mojom/notifications/notification_service.mojom-blink.h" -#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" -#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h" +#include "third_party/blink/public/mojom/permissions/permission.mojom-blink-forward.h" +#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc index 6a8c94a70d2..2a9d4cb2952 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc +++ b/chromium/third_party/blink/renderer/modules/notifications/notification_data_test.cc @@ -38,7 +38,7 @@ const bool kNotificationRenotify = true; const bool kNotificationSilent = false; const bool kNotificationRequireInteraction = true; -const mojom::blink::NotificationActionType kWebNotificationActionType = +const mojom::blink::NotificationActionType kBlinkNotificationActionType = mojom::blink::NotificationActionType::TEXT; const char kNotificationActionType[] = "text"; const char kNotificationActionAction[] = "my_action"; @@ -157,7 +157,7 @@ TEST_F(NotificationDataTest, ReflectProperties) { notification_data->require_interaction); EXPECT_EQ(actions.size(), notification_data->actions->size()); for (const auto& action : notification_data->actions.value()) { - EXPECT_EQ(kWebNotificationActionType, action->type); + EXPECT_EQ(kBlinkNotificationActionType, action->type); EXPECT_EQ(kNotificationActionAction, action->action); EXPECT_EQ(kNotificationActionTitle, action->title); EXPECT_EQ(kNotificationActionPlaceholder, action->placeholder); diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h index f43f45ac2bd..da9fb1f6d75 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h +++ b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h @@ -25,9 +25,8 @@ class ScriptState; // connecting and communicating with the Mojo notification service. // // TODO(peter): Make the NotificationManager responsible for resource loading. -class NotificationManager final - : public GarbageCollectedFinalized<NotificationManager>, - public Supplement<ExecutionContext> { +class NotificationManager final : public GarbageCollected<NotificationManager>, + public Supplement<ExecutionContext> { USING_GARBAGE_COLLECTED_MIXIN(NotificationManager); public: diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc index d29d8a4efc9..be77a72dbd8 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc +++ b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc @@ -8,7 +8,9 @@ #include "base/optional.h" #include "base/time/time.h" -#include "third_party/blink/public/platform/modules/notifications/web_notification_constants.h" +#include "third_party/blink/public/common/notifications/notification_constants.h" +#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" +#include "third_party/blink/public/mojom/notifications/notification.mojom-blink.h" #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" @@ -26,15 +28,14 @@ enum class NotificationIconType { kImage, kIcon, kBadge, kActionIcon }; WebSize GetIconDimensions(NotificationIconType type) { switch (type) { case NotificationIconType::kImage: - return {kWebNotificationMaxImageWidthPx, - kWebNotificationMaxImageHeightPx}; + return {kNotificationMaxImageWidthPx, kNotificationMaxImageHeightPx}; case NotificationIconType::kIcon: - return {kWebNotificationMaxIconSizePx, kWebNotificationMaxIconSizePx}; + return {kNotificationMaxIconSizePx, kNotificationMaxIconSizePx}; case NotificationIconType::kBadge: - return {kWebNotificationMaxBadgeSizePx, kWebNotificationMaxBadgeSizePx}; + return {kNotificationMaxBadgeSizePx, kNotificationMaxBadgeSizePx}; case NotificationIconType::kActionIcon: - return {kWebNotificationMaxActionIconSizePx, - kWebNotificationMaxActionIconSizePx}; + return {kNotificationMaxActionIconSizePx, + kNotificationMaxActionIconSizePx}; } } diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h index c9a70fa540d..c772d116ecd 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h +++ b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader.h @@ -7,7 +7,7 @@ #include <memory> -#include "third_party/blink/public/mojom/notifications/notification.mojom-blink.h" +#include "third_party/blink/public/mojom/notifications/notification.mojom-blink-forward.h" #include "third_party/blink/renderer/core/loader/threaded_icon_loader.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -26,7 +26,7 @@ struct WebSize; // Fetches the resources specified in a given NotificationData. Uses a // callback to notify the caller when all fetches have finished. class MODULES_EXPORT NotificationResourcesLoader final - : public GarbageCollectedFinalized<NotificationResourcesLoader> { + : public GarbageCollected<NotificationResourcesLoader> { USING_PRE_FINALIZER(NotificationResourcesLoader, Stop); public: diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc index 35c641476f9..e46ec6de3de 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc +++ b/chromium/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc @@ -6,7 +6,8 @@ #include <memory> #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/platform/modules/notifications/web_notification_constants.h" +#include "third_party/blink/public/common/notifications/notification_constants.h" +#include "third_party/blink/public/mojom/notifications/notification.mojom-blink.h" #include "third_party/blink/public/platform/web_url_loader_mock_factory.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -148,19 +149,19 @@ TEST_F(NotificationResourcesLoaderTest, LargeIconsAreScaledDown) { ASSERT_TRUE(Resources()); ASSERT_FALSE(Resources()->icon.drawsNothing()); - ASSERT_EQ(kWebNotificationMaxIconSizePx, Resources()->icon.width()); - ASSERT_EQ(kWebNotificationMaxIconSizePx, Resources()->icon.height()); + ASSERT_EQ(kNotificationMaxIconSizePx, Resources()->icon.width()); + ASSERT_EQ(kNotificationMaxIconSizePx, Resources()->icon.height()); ASSERT_FALSE(Resources()->badge.drawsNothing()); - ASSERT_EQ(kWebNotificationMaxBadgeSizePx, Resources()->badge.width()); - ASSERT_EQ(kWebNotificationMaxBadgeSizePx, Resources()->badge.height()); + ASSERT_EQ(kNotificationMaxBadgeSizePx, Resources()->badge.width()); + ASSERT_EQ(kNotificationMaxBadgeSizePx, Resources()->badge.height()); ASSERT_TRUE(Resources()->action_icons.has_value()); auto& action_icons = Resources()->action_icons.value(); ASSERT_EQ(1u, action_icons.size()); ASSERT_FALSE(action_icons[0].drawsNothing()); - ASSERT_EQ(kWebNotificationMaxActionIconSizePx, action_icons[0].width()); - ASSERT_EQ(kWebNotificationMaxActionIconSizePx, action_icons[0].height()); + ASSERT_EQ(kNotificationMaxActionIconSizePx, action_icons[0].width()); + ASSERT_EQ(kNotificationMaxActionIconSizePx, action_icons[0].height()); } TEST_F(NotificationResourcesLoaderTest, DownscalingPreserves3_1AspectRatio) { @@ -173,8 +174,8 @@ TEST_F(NotificationResourcesLoaderTest, DownscalingPreserves3_1AspectRatio) { ASSERT_TRUE(Resources()); ASSERT_FALSE(Resources()->image.drawsNothing()); - ASSERT_EQ(kWebNotificationMaxImageWidthPx, Resources()->image.width()); - ASSERT_EQ(kWebNotificationMaxImageWidthPx / 3, Resources()->image.height()); + ASSERT_EQ(kNotificationMaxImageWidthPx, Resources()->image.width()); + ASSERT_EQ(kNotificationMaxImageWidthPx / 3, Resources()->image.height()); } TEST_F(NotificationResourcesLoaderTest, DownscalingPreserves3_2AspectRatio) { @@ -187,9 +188,8 @@ TEST_F(NotificationResourcesLoaderTest, DownscalingPreserves3_2AspectRatio) { ASSERT_TRUE(Resources()); ASSERT_FALSE(Resources()->image.drawsNothing()); - ASSERT_EQ(kWebNotificationMaxImageHeightPx * 3 / 2, - Resources()->image.width()); - ASSERT_EQ(kWebNotificationMaxImageHeightPx, Resources()->image.height()); + ASSERT_EQ(kNotificationMaxImageHeightPx * 3 / 2, Resources()->image.width()); + ASSERT_EQ(kNotificationMaxImageHeightPx, Resources()->image.height()); } TEST_F(NotificationResourcesLoaderTest, EmptyDataYieldsEmptyResources) { diff --git a/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h b/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h index 8b2424e910e..ae6680b15b7 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h +++ b/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.h @@ -9,7 +9,7 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" -#include "third_party/blink/public/mojom/notifications/notification.mojom-blink.h" +#include "third_party/blink/public/mojom/notifications/notification.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" diff --git a/chromium/third_party/blink/renderer/modules/p2p/BUILD.gn b/chromium/third_party/blink/renderer/modules/p2p/BUILD.gn new file mode 100644 index 00000000000..4253a358859 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/p2p/BUILD.gn @@ -0,0 +1,12 @@ +# 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. + +import("//third_party/blink/renderer/modules/modules.gni") + +blink_modules_sources("p2p") { + sources = [ + "port_allocator.cc", + "port_allocator.h", + ] +} diff --git a/chromium/third_party/blink/renderer/modules/p2p/DEPS b/chromium/third_party/blink/renderer/modules/p2p/DEPS new file mode 100644 index 00000000000..0e460b98eb3 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/p2p/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + # TODO(crbug.com/787254): Remove use of GURL. + "+url/gurl.h", +] diff --git a/chromium/third_party/blink/renderer/modules/p2p/port_allocator.cc b/chromium/third_party/blink/renderer/modules/p2p/port_allocator.cc new file mode 100644 index 00000000000..b12fadda106 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/p2p/port_allocator.cc @@ -0,0 +1,60 @@ +// 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. + +#include "third_party/blink/renderer/modules/p2p/port_allocator.h" + +#include <stdint.h> + +#include <memory> +#include <utility> + +#include "base/logging.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/platform/p2p/socket_dispatcher.h" + +namespace blink { + +P2PPortAllocator::P2PPortAllocator( + const scoped_refptr<P2PSocketDispatcher>& socket_dispatcher, + std::unique_ptr<rtc::NetworkManager> network_manager, + rtc::PacketSocketFactory* socket_factory, + const Config& config, + const GURL& origin) + : cricket::BasicPortAllocator(network_manager.get(), socket_factory), + network_manager_(std::move(network_manager)), + socket_dispatcher_(socket_dispatcher), + config_(config), + origin_(origin) { + DCHECK(socket_dispatcher); + DCHECK(network_manager_); + DCHECK(socket_factory); + uint32_t flags = 0; + if (!config_.enable_multiple_routes) { + flags |= cricket::PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION; + } + if (!config_.enable_default_local_candidate) { + flags |= cricket::PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE; + } + if (!config_.enable_nonproxied_udp) { + flags |= cricket::PORTALLOCATOR_DISABLE_UDP | + cricket::PORTALLOCATOR_DISABLE_STUN | + cricket::PORTALLOCATOR_DISABLE_UDP_RELAY; + } + set_flags(flags); + set_allow_tcp_listen(false); + bool enable_webrtc_stun_origin = + Platform::Current()->IsWebRtcStunOriginEnabled(); + if (enable_webrtc_stun_origin) { + set_origin(origin_.spec()); + } +} + +P2PPortAllocator::~P2PPortAllocator() {} + +void P2PPortAllocator::Initialize() { + BasicPortAllocator::Initialize(); + network_manager_->Initialize(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/p2p/port_allocator.h b/chromium/third_party/blink/renderer/modules/p2p/port_allocator.h new file mode 100644 index 00000000000..0358e1672be --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/p2p/port_allocator.h @@ -0,0 +1,62 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_MODULES_P2P_PORT_ALLOCATOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_P2P_PORT_ALLOCATOR_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/webrtc/p2p/client/basic_port_allocator.h" +#include "url/gurl.h" + +namespace blink { + +class P2PSocketDispatcher; + +class MODULES_EXPORT P2PPortAllocator : public cricket::BasicPortAllocator { + public: + struct Config { + // Enable non-proxied UDP-based transport when set to true. When set to + // false, it effectively disables all UDP traffic until UDP-supporting proxy + // RETURN is available in the future. + bool enable_nonproxied_udp = true; + + // Request binding to individual NICs. Whether multiple routes is allowed is + // subject to the permission check on mic/camera. When specified as false or + // the permission request is denied, it still uses the default local address + // to generate a single local candidate. TODO(guoweis): Rename this to + // |request_multiple_routes|. + bool enable_multiple_routes = true; + + // Enable exposing the default local address when set to true. This is + // only in effect when the |enable_multiple_routes| is false or the + // permission check of mic/camera is denied. + bool enable_default_local_candidate = true; + }; + + P2PPortAllocator(const scoped_refptr<P2PSocketDispatcher>& socket_dispatcher, + std::unique_ptr<rtc::NetworkManager> network_manager, + rtc::PacketSocketFactory* socket_factory, + const Config& config, + const GURL& origin); + ~P2PPortAllocator() override; + + // Will also initialize the network manager passed into the constructor. + void Initialize() override; + + private: + std::unique_ptr<rtc::NetworkManager> network_manager_; + scoped_refptr<P2PSocketDispatcher> socket_dispatcher_; + Config config_; + GURL origin_; + + DISALLOW_COPY_AND_ASSIGN(P2PPortAllocator); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_P2P_PORT_ALLOCATOR_H_ diff --git a/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.h b/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.h index dd2844e5685..112e23f1d28 100644 --- a/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.h +++ b/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_ABORT_PAYMENT_RESPOND_WITH_OBSERVER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_ABORT_PAYMENT_RESPOND_WITH_OBSERVER_H_ -#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/service_worker/respond_with_observer.h" diff --git a/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.cc b/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.cc index 6f3ca2d6c48..96d7c5fd9c5 100644 --- a/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.cc +++ b/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.cc @@ -41,6 +41,7 @@ void BasicCardHelper::ParseBasiccardData( const ScriptValue& input, Vector<BasicCardNetwork>& supported_networks_output, Vector<BasicCardType>& supported_types_output, + bool* has_supported_card_types, ExceptionState& exception_state) { DCHECK(!input.IsEmpty()); @@ -68,6 +69,10 @@ void BasicCardHelper::ParseBasiccardData( } if (basic_card->hasSupportedTypes()) { + if (has_supported_card_types) { + *has_supported_card_types = true; + } + if (basic_card->supportedTypes().size() > PaymentRequest::kMaxListSize) { exception_state.ThrowTypeError( "basic-card supportedTypes cannot be longer than 1024 elements"); diff --git a/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.h b/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.h index f764cbd7214..67b7a83f3da 100644 --- a/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.h +++ b/chromium/third_party/blink/renderer/modules/payments/basic_card_helper.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_BASIC_CARD_HELPER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_BASIC_CARD_HELPER_H_ -#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h" +#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -20,11 +20,15 @@ class BasicCardHelper { // Parse 'basic-card' data in |input| and store result in // |supported_networks_output| and |supported_types_output| or throw // exception. + // + // If |has_supported_card_types| is not null, then it is set to true if the + // basic-card specific method data has the "supportedTypes" field. static void ParseBasiccardData( const ScriptValue& input, Vector<::payments::mojom::blink::BasicCardNetwork>& supported_networks_output, Vector<::payments::mojom::blink::BasicCardType>& supported_types_output, + bool* has_supported_card_types, ExceptionState&); // Check whether |input| is 'basic-card' network name. diff --git a/chromium/third_party/blink/renderer/modules/payments/basic_card_request.idl b/chromium/third_party/blink/renderer/modules/payments/basic_card_request.idl index 8269e80e16b..9bd0aeb9b2b 100644 --- a/chromium/third_party/blink/renderer/modules/payments/basic_card_request.idl +++ b/chromium/third_party/blink/renderer/modules/payments/basic_card_request.idl @@ -12,5 +12,5 @@ enum BasicCardType { dictionary BasicCardRequest { sequence<DOMString> supportedNetworks; - [MeasureAs=BasicCardType] sequence<BasicCardType> supportedTypes; + sequence<BasicCardType> supportedTypes; }; diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h index 6df64fdf5d1..4adbd591a0f 100644 --- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h +++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_CAN_MAKE_PAYMENT_RESPOND_WITH_OBSERVER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_CAN_MAKE_PAYMENT_RESPOND_WITH_OBSERVER_H_ -#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/service_worker/respond_with_observer.h" diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_address_init.idl b/chromium/third_party/blink/renderer/modules/payments/payment_address_init.idl new file mode 100644 index 00000000000..fb7733fa217 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/payment_address_init.idl @@ -0,0 +1,18 @@ +// 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://w3c.github.io/payment-request/#dom-addressinit + +dictionary PaymentAddressInit { + DOMString country; + sequence<DOMString> addressLine; + DOMString region; + DOMString city; + DOMString dependentLocality; + DOMString postalCode; + DOMString sortingCode; + DOMString organization; + DOMString recipient; + DOMString phone; +};
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h b/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h index 253ce3d52b0..92733d22ab7 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h @@ -17,7 +17,7 @@ class ScriptState; class ServiceWorkerRegistration; class PaymentAppServiceWorkerRegistration final - : public GarbageCollectedFinalized<PaymentAppServiceWorkerRegistration>, + : public GarbageCollected<PaymentAppServiceWorkerRegistration>, public Supplement<ServiceWorkerRegistration> { USING_GARBAGE_COLLECTED_MIXIN(PaymentAppServiceWorkerRegistration); diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc b/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc index 6d652458039..031ee99b7b5 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/payments/payment_event_data_conversion.h" +#include "third_party/blink/public/mojom/payments/payment_app.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h" #include "third_party/blink/renderer/modules/payments/can_make_payment_event_init.h" #include "third_party/blink/renderer/modules/payments/payment_currency_amount.h" @@ -62,7 +63,7 @@ ScriptValue StringDataToScriptValue(ScriptState* script_state, .ToLocal(&v8_value)) { return ScriptValue(); } - return ScriptValue(script_state, v8_value); + return ScriptValue(script_state->GetIsolate(), v8_value); } PaymentMethodData* ToPaymentMethodData( @@ -76,6 +77,44 @@ PaymentMethodData* ToPaymentMethodData( return method_data; } +PaymentOptions* ToPaymentOptions( + payments::mojom::blink::PaymentOptionsPtr options) { + DCHECK(options); + PaymentOptions* payment_options = PaymentOptions::Create(); + payment_options->setRequestPayerName(options->request_payer_name); + payment_options->setRequestPayerEmail(options->request_payer_email); + payment_options->setRequestPayerPhone(options->request_payer_phone); + payment_options->setRequestShipping(options->request_shipping); + + String shipping_type = ""; + switch (options->shipping_type) { + case payments::mojom::PaymentShippingType::SHIPPING: + shipping_type = "shipping"; + break; + case payments::mojom::PaymentShippingType::DELIVERY: + shipping_type = "delivery"; + break; + case payments::mojom::PaymentShippingType::PICKUP: + shipping_type = "pickup"; + break; + } + payment_options->setShippingType(shipping_type); + return payment_options; +} + +PaymentShippingOption* ToShippingOption( + payments::mojom::blink::PaymentShippingOptionPtr option) { + DCHECK(option); + PaymentShippingOption* shipping_option = PaymentShippingOption::Create(); + + shipping_option->setAmount( + ToPaymentCurrencyAmount(std::move(option->amount))); + shipping_option->setLabel(option->label); + shipping_option->setId(option->id); + shipping_option->setSelected(option->selected); + return shipping_option; +} + } // namespace PaymentRequestEventInit* PaymentEventDataConversion::ToPaymentRequestEventInit( @@ -107,6 +146,21 @@ PaymentRequestEventInit* PaymentEventDataConversion::ToPaymentRequestEventInit( } event_init->setModifiers(modifiers); event_init->setInstrumentKey(event_data->instrument_key); + + bool request_shipping = false; + if (event_data->payment_options) { + request_shipping = event_data->payment_options->request_shipping; + event_init->setPaymentOptions( + ToPaymentOptions(std::move(event_data->payment_options))); + } + if (event_data->shipping_options.has_value() && request_shipping) { + HeapVector<Member<PaymentShippingOption>> shipping_options; + for (auto& option : event_data->shipping_options.value()) { + shipping_options.push_back(ToShippingOption(std::move(option))); + } + event_init->setShippingOptions(shipping_options); + } + return event_init; } diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.h b/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.h index 7fd5625ae41..c9d4999e9aa 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_EVENT_DATA_CONVERSION_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_EVENT_DATA_CONVERSION_H_ -#include "third_party/blink/public/mojom/payments/payment_app.mojom-blink.h" +#include "third_party/blink/public/mojom/payments/payment_app.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/payments/can_make_payment_event_init.h" #include "third_party/blink/renderer/modules/payments/payment_request_event_init.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc b/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc index 150e10dc1ca..dbb6d2ea472 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_event_data_conversion_test.cc @@ -6,6 +6,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/payments/payment_app.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" @@ -42,6 +43,27 @@ CreateCanMakePaymentEventDataForTest() { return event_data; } +static payments::mojom::blink::PaymentOptionsPtr CreatePaymentOptionsForTest() { + auto payment_options = payments::mojom::blink::PaymentOptions::New(); + payment_options->request_payer_name = true; + payment_options->request_payer_email = true; + payment_options->request_payer_phone = true; + payment_options->request_shipping = true; + payment_options->shipping_type = + payments::mojom::PaymentShippingType::DELIVERY; + return payment_options; +} + +static payments::mojom::blink::PaymentShippingOptionPtr +CreateShippingOptionForTest() { + auto shipping_option = payments::mojom::blink::PaymentShippingOption::New(); + shipping_option->amount = CreatePaymentCurrencyAmountForTest(); + shipping_option->label = String::FromUTF8("shipping-option-label"); + shipping_option->id = String::FromUTF8("shipping-option-id"); + shipping_option->selected = true; + return shipping_option; +} + static payments::mojom::blink::PaymentRequestEventDataPtr CreatePaymentRequestEventDataForTest() { auto event_data = payments::mojom::blink::PaymentRequestEventData::New(); @@ -53,6 +75,10 @@ CreatePaymentRequestEventDataForTest() { event_data->method_data = std::move(method_data); event_data->total = CreatePaymentCurrencyAmountForTest(); event_data->instrument_key = String::FromUTF8("payment-instrument-key"); + event_data->payment_options = CreatePaymentOptionsForTest(); + Vector<payments::mojom::blink::PaymentShippingOptionPtr> shipping_options; + shipping_options.push_back(CreateShippingOptionForTest()); + event_data->shipping_options = std::move(shipping_options); return event_data; } @@ -124,6 +150,34 @@ TEST(PaymentEventDataConversionTest, ToPaymentRequestEventData) { ASSERT_TRUE(data->hasInstrumentKey()); EXPECT_EQ("payment-instrument-key", data->instrumentKey()); + + // paymentOptions + ASSERT_TRUE(data->hasPaymentOptions()); + ASSERT_TRUE(data->paymentOptions()->hasRequestPayerName()); + ASSERT_TRUE(data->paymentOptions()->requestPayerName()); + ASSERT_TRUE(data->paymentOptions()->hasRequestPayerEmail()); + ASSERT_TRUE(data->paymentOptions()->requestPayerEmail()); + ASSERT_TRUE(data->paymentOptions()->hasRequestPayerPhone()); + ASSERT_TRUE(data->paymentOptions()->requestPayerPhone()); + ASSERT_TRUE(data->paymentOptions()->hasRequestShipping()); + ASSERT_TRUE(data->paymentOptions()->requestShipping()); + ASSERT_TRUE(data->paymentOptions()->hasShippingType()); + EXPECT_EQ("delivery", data->paymentOptions()->shippingType()); + + // shippingOptions + ASSERT_TRUE(data->hasShippingOptions()); + EXPECT_EQ(1UL, data->shippingOptions().size()); + ASSERT_TRUE(data->shippingOptions().front()->hasAmount()); + ASSERT_TRUE(data->shippingOptions().front()->amount()->hasCurrency()); + EXPECT_EQ("USD", data->shippingOptions().front()->amount()->currency()); + ASSERT_TRUE(data->shippingOptions().front()->amount()->hasValue()); + EXPECT_EQ("9.99", data->shippingOptions().front()->amount()->value()); + ASSERT_TRUE(data->shippingOptions().front()->hasLabel()); + EXPECT_EQ("shipping-option-label", data->shippingOptions().front()->label()); + ASSERT_TRUE(data->shippingOptions().front()->hasId()); + EXPECT_EQ("shipping-option-id", data->shippingOptions().front()->id()); + ASSERT_TRUE(data->shippingOptions().front()->hasSelected()); + ASSERT_TRUE(data->shippingOptions().front()->selected()); } } // namespace diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_handler_response.idl b/chromium/third_party/blink/renderer/modules/payments/payment_handler_response.idl index 0327bd0649d..6f17e0d6e2a 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_handler_response.idl +++ b/chromium/third_party/blink/renderer/modules/payments/payment_handler_response.idl @@ -7,4 +7,9 @@ dictionary PaymentHandlerResponse { DOMString methodName; object details; + [RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] DOMString? payerName; + [RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] DOMString? payerEmail; + [RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] DOMString? payerPhone; + [RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] PaymentAddressInit shippingAddress; + [RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] DOMString? shippingOption; }; diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.cc b/chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.cc index 96f625bc201..57ce848c25e 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/payments/payment_handler_utils.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/inspector/console_message.h" diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.h b/chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.h index 63a4fae2ea4..d1d824ff1a6 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_handler_utils.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_HANDLER_UTILS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_HANDLER_UTILS_H_ -#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc index 20350d57861..fb39539a370 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc @@ -97,8 +97,8 @@ ScriptPromise RejectNotAllowedToUsePaymentFeatures(ScriptState* script_state) { // referenced by |PaymentInstrument| will not be traced through the callback and // can be prematurely destroyed. // TODO(keishi): Remove this conversion if IDLDictionaryBase situation changes. -class PaymentInstrumentParameter - : public GarbageCollectedFinalized<PaymentInstrumentParameter> { +class PaymentInstrumentParameter final + : public GarbageCollected<PaymentInstrumentParameter> { public: explicit PaymentInstrumentParameter(const PaymentInstrument* instrument) : has_icons_(instrument->hasIcons()), @@ -124,7 +124,10 @@ class PaymentInstrumentParameter bool has_name() const { return has_name_; } const String& name() const { return name_; } - void Trace(blink::Visitor* visitor) { visitor->Trace(icons_); } + void Trace(blink::Visitor* visitor) { + visitor->Trace(icons_); + visitor->Trace(capabilities_); + } private: bool has_icons_; @@ -362,7 +365,8 @@ void PaymentInstruments::OnRequestPermission( "PaymentInstruments", "set"); BasicCardHelper::ParseBasiccardData( details->capabilities(), instrument->supported_networks, - instrument->supported_types, exception_state); + instrument->supported_types, /*has_supported_card_types=*/nullptr, + exception_state); if (exception_state.HadException()) { resolver->Reject(exception_state); return; @@ -424,7 +428,7 @@ void PaymentInstruments::onGetPaymentInstrument( ExceptionState::kGetterContext, "PaymentInstruments", "get"); instrument->setCapabilities( - ScriptValue(resolver->GetScriptState(), + ScriptValue(resolver->GetScriptState()->GetIsolate(), FromJSONString(resolver->GetScriptState()->GetIsolate(), resolver->GetScriptState()->GetContext(), stored_instrument->stringified_capabilities, diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_manager.cc b/chromium/third_party/blink/renderer/modules/payments/payment_manager.cc index 0952de3b256..029f5ce7901 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_manager.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_manager.cc @@ -4,8 +4,9 @@ #include "third_party/blink/renderer/modules/payments/payment_manager.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/modules/payments/payment_instruments.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h" @@ -34,9 +35,55 @@ void PaymentManager::setUserHint(const String& user_hint) { manager_->SetUserHint(user_hint_); } +ScriptPromise PaymentManager::enableDelegations( + ScriptState* script_state, + const Vector<String>& stringified_delegations) { + if (!script_state->ContextIsValid()) { + return ScriptPromise::RejectWithDOMException( + script_state, MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, + "Cannot enable payment delegations")); + } + + if (enable_delegations_resolver_) { + return ScriptPromise::RejectWithDOMException( + script_state, MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, + "Cannot call enableDelegations() again until " + "the previous enableDelegations() is finished")); + } + + Vector<payments::mojom::blink::PaymentDelegation> delegations; + for (auto delegation : stringified_delegations) { + if (delegation == "shippingAddress") { + delegations.emplace_back( + payments::mojom::blink::PaymentDelegation::SHIPPING_ADDRESS); + } else if (delegation == "payerName") { + delegations.emplace_back( + payments::mojom::blink::PaymentDelegation::PAYER_NAME); + } else if (delegation == "payerPhone") { + delegations.emplace_back( + payments::mojom::blink::PaymentDelegation::PAYER_PHONE); + } else { + DCHECK_EQ("payerEmail", delegation); + delegations.emplace_back( + payments::mojom::blink::PaymentDelegation::PAYER_EMAIL); + } + } + + manager_->EnableDelegations( + std::move(delegations), + WTF::Bind(&PaymentManager::OnEnableDelegationsResponse, + WrapPersistent(this))); + enable_delegations_resolver_ = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + return enable_delegations_resolver_->Promise(); +} + void PaymentManager::Trace(blink::Visitor* visitor) { visitor->Trace(registration_); visitor->Trace(instruments_); + visitor->Trace(enable_delegations_resolver_); ScriptWrappable::Trace(visitor); } @@ -45,10 +92,9 @@ PaymentManager::PaymentManager(ServiceWorkerRegistration* registration) DCHECK(registration); if (ExecutionContext* context = registration->GetExecutionContext()) { - if (auto* interface_provider = context->GetInterfaceProvider()) { - interface_provider->GetInterface(manager_.BindNewPipeAndPassReceiver( - context->GetTaskRunner(TaskType::kUserInteraction))); - } + context->GetBrowserInterfaceBroker().GetInterface( + manager_.BindNewPipeAndPassReceiver( + context->GetTaskRunner(TaskType::kUserInteraction))); } manager_.set_disconnect_handler(WTF::Bind( @@ -57,7 +103,18 @@ PaymentManager::PaymentManager(ServiceWorkerRegistration* registration) registration_->scope()); } +void PaymentManager::OnEnableDelegationsResponse( + payments::mojom::blink::PaymentHandlerStatus status) { + DCHECK(enable_delegations_resolver_); + enable_delegations_resolver_->Resolve( + status == payments::mojom::blink::PaymentHandlerStatus::SUCCESS); + enable_delegations_resolver_.Clear(); +} + void PaymentManager::OnServiceConnectionError() { + if (enable_delegations_resolver_) + enable_delegations_resolver_.Clear(); + manager_.reset(); } diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_manager.h b/chromium/third_party/blink/renderer/modules/payments/payment_manager.h index edd7cc80a7d..d60f8bcc1c6 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_manager.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_manager.h @@ -8,7 +8,6 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/payments/payment_app.mojom-blink.h" -#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -16,6 +15,9 @@ namespace blink { class PaymentInstruments; +class ScriptPromiseResolver; +class ScriptPromise; +class ScriptState; class ServiceWorkerRegistration; class MODULES_EXPORT PaymentManager final : public ScriptWrappable { @@ -33,13 +35,21 @@ class MODULES_EXPORT PaymentManager final : public ScriptWrappable { void Trace(blink::Visitor*) override; + ScriptPromise enableDelegations( + ScriptState*, + const Vector<String>& stringified_delegations); + private: void OnServiceConnectionError(); + void OnEnableDelegationsResponse( + payments::mojom::blink::PaymentHandlerStatus status); + Member<ServiceWorkerRegistration> registration_; mojo::Remote<payments::mojom::blink::PaymentManager> manager_; Member<PaymentInstruments> instruments_; String user_hint_; + Member<ScriptPromiseResolver> enable_delegations_resolver_; DISALLOW_COPY_AND_ASSIGN(PaymentManager); }; diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_manager.idl b/chromium/third_party/blink/renderer/modules/payments/payment_manager.idl index e213febce24..10b88279dc2 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_manager.idl +++ b/chromium/third_party/blink/renderer/modules/payments/payment_manager.idl @@ -4,10 +4,18 @@ // https://w3c.github.io/webpayments-payment-apps-api/#idl-def-paymentappmanager +enum PaymentDelegation { + "shippingAddress", + "payerName", + "payerPhone", + "payerEmail", +}; + [ RuntimeEnabled=PaymentApp, ConstructorCallWith=ExecutionContext ] interface PaymentManager { [SameObject] readonly attribute PaymentInstruments instruments; attribute DOMString userHint; + [CallWith=ScriptState, RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] Promise<void> enableDelegations(FrozenArray<PaymentDelegation> delegations); }; diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc index 1a3b8e6d0eb..47c8e2dd397 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.cc @@ -28,8 +28,8 @@ const String& PaymentMethodChangeEvent::methodName() const { const ScriptValue PaymentMethodChangeEvent::methodDetails( ScriptState* script_state) const { if (method_details_.IsEmpty()) - return ScriptValue::CreateNull(script_state); - return ScriptValue(script_state, + return ScriptValue::CreateNull(script_state->GetIsolate()); + return ScriptValue(script_state->GetIsolate(), method_details_.GetAcrossWorld(script_state)); } diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_response.idl b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_response.idl index 17f7d2abe8c..46100b01d76 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_response.idl +++ b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_response.idl @@ -3,10 +3,15 @@ // found in the LICENSE file. // https://w3c.github.io/payment-handler/#dom-paymentmethodchangeresponse +// Todo(sahel): Change the link to the updated spec. crbug.com/984694 +// Todo(sahel): Rename PaymentMethodChangeResponse to +// PaymentRequestDetailsUpdate which is a more generic name. crbug.com/984694 dictionary PaymentMethodChangeResponse { DOMString error; PaymentCurrencyAmount total; FrozenArray<PaymentDetailsModifier> modifiers; + FrozenArray<PaymentShippingOption> shippingOptions; object paymentMethodErrors; + AddressErrors shippingAddressErrors; }; diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request.cc index 8bae47431cd..56e4baa064a 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.cc @@ -11,8 +11,7 @@ #include "base/location.h" #include "base/stl_util.h" #include "build/build_config.h" -#include "mojo/public/cpp/bindings/interface_request.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h" @@ -393,19 +392,13 @@ void SetAndroidPayMethodData(v8::Isolate* isolate, output->api_version = android_pay->apiVersion(); } -// Parses basic-card data to avoid parsing JSON in the browser. -void SetBasicCardMethodData(const ScriptValue& input, - PaymentMethodDataPtr& output, - ExceptionState& exception_state) { - BasicCardHelper::ParseBasiccardData(input, output->supported_networks, - output->supported_types, exception_state); -} - -void StringifyAndParseMethodSpecificData(v8::Isolate* isolate, - const String& supported_method, - const ScriptValue& input, - PaymentMethodDataPtr& output, - ExceptionState& exception_state) { +void StringifyAndParseMethodSpecificData( + v8::Isolate* isolate, + const String& supported_method, + const ScriptValue& input, + PaymentMethodDataPtr& output, + bool* basic_card_has_supported_card_types, + ExceptionState& exception_state) { PaymentsValidators::ValidateAndStringifyObject( isolate, "Payment method data", input, output->stringified_data, exception_state); @@ -423,13 +416,17 @@ void StringifyAndParseMethodSpecificData(v8::Isolate* isolate, } if (supported_method == "basic-card") { - SetBasicCardMethodData(input, output, exception_state); + // Parses basic-card data to avoid parsing JSON in the browser. + BasicCardHelper::ParseBasiccardData( + input, output->supported_networks, output->supported_types, + basic_card_has_supported_card_types, exception_state); } } void ValidateAndConvertPaymentDetailsModifiers( const HeapVector<Member<PaymentDetailsModifier>>& input, Vector<PaymentDetailsModifierPtr>& output, + bool* basic_card_has_supported_card_types, ExecutionContext& execution_context, ExceptionState& exception_state) { if (input.size() > PaymentRequest::kMaxListSize) { @@ -469,19 +466,22 @@ void ValidateAndConvertPaymentDetailsModifiers( if (modifier->hasData() && !modifier->data().IsEmpty()) { StringifyAndParseMethodSpecificData( execution_context.GetIsolate(), modifier->supportedMethod(), - modifier->data(), output.back()->method_data, exception_state); + modifier->data(), output.back()->method_data, + basic_card_has_supported_card_types, exception_state); } else { output.back()->method_data->stringified_data = ""; } } } -void ValidateAndConvertPaymentDetailsBase(const PaymentDetailsBase* input, - const PaymentOptions* options, - PaymentDetailsPtr& output, - String& shipping_option_output, - ExecutionContext& execution_context, - ExceptionState& exception_state) { +void ValidateAndConvertPaymentDetailsBase( + const PaymentDetailsBase* input, + const PaymentOptions* options, + PaymentDetailsPtr& output, + String& shipping_option_output, + bool* basic_card_has_supported_card_types, + ExecutionContext& execution_context, + ExceptionState& exception_state) { if (input->hasDisplayItems()) { output->display_items = Vector<PaymentItemPtr>(); ValidateAndConvertDisplayItems(input->displayItems(), "display items", @@ -507,26 +507,29 @@ void ValidateAndConvertPaymentDetailsBase(const PaymentDetailsBase* input, if (input->hasModifiers()) { output->modifiers = Vector<PaymentDetailsModifierPtr>(); ValidateAndConvertPaymentDetailsModifiers( - input->modifiers(), *output->modifiers, execution_context, + input->modifiers(), *output->modifiers, + basic_card_has_supported_card_types, execution_context, exception_state); } } -void ValidateAndConvertPaymentDetailsInit(const PaymentDetailsInit* input, - const PaymentOptions* options, - PaymentDetailsPtr& output, - String& shipping_option_output, - ExecutionContext& execution_context, - ExceptionState& exception_state) { +void ValidateAndConvertPaymentDetailsInit( + const PaymentDetailsInit* input, + const PaymentOptions* options, + PaymentDetailsPtr& output, + String& shipping_option_output, + bool* basic_card_has_supported_card_types, + ExecutionContext& execution_context, + ExceptionState& exception_state) { DCHECK(input->hasTotal()); ValidateAndConvertTotal(input->total(), "total", output->total, execution_context, exception_state); if (exception_state.HadException()) return; - ValidateAndConvertPaymentDetailsBase(input, options, output, - shipping_option_output, - execution_context, exception_state); + ValidateAndConvertPaymentDetailsBase( + input, options, output, shipping_option_output, + basic_card_has_supported_card_types, execution_context, exception_state); } void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate* input, @@ -535,9 +538,9 @@ void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate* input, String& shipping_option_output, ExecutionContext& execution_context, ExceptionState& exception_state) { - ValidateAndConvertPaymentDetailsBase(input, options, output, - shipping_option_output, - execution_context, exception_state); + ValidateAndConvertPaymentDetailsBase( + input, options, output, shipping_option_output, + /*has_supported_card_types=*/nullptr, execution_context, exception_state); if (exception_state.HadException()) return; @@ -585,6 +588,7 @@ void ValidateAndConvertPaymentMethodData( bool& skip_to_gpay_ready, Vector<payments::mojom::blink::PaymentMethodDataPtr>& output, HashSet<String>& method_names, + bool* basic_card_has_supported_card_types, ExecutionContext& execution_context, ExceptionState& exception_state) { if (input.IsEmpty()) { @@ -621,7 +625,7 @@ void ValidateAndConvertPaymentMethodData( StringifyAndParseMethodSpecificData( execution_context.GetIsolate(), payment_method_data->supportedMethod(), payment_method_data->data(), - output.back(), exception_state); + output.back(), basic_card_has_supported_card_types, exception_state); if (exception_state.HadException()) continue; @@ -719,6 +723,10 @@ ScriptPromise PaymentRequest::show(ScriptState* script_state, WebFeature::kPaymentRequestShowWithoutGesture); } + if (basic_card_has_supported_card_types_) { + UseCounter::Count(GetExecutionContext(), WebFeature::kBasicCardType); + } + // TODO(crbug.com/779126): add support for handling payment requests in // immersive mode. if (GetFrame()->GetDocument()->GetSettings()->GetImmersiveModeEnabled()) { @@ -1088,7 +1096,8 @@ PaymentRequest::PaymentRequest( execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI), this, &PaymentRequest::OnUpdatePaymentDetailsTimeout), - is_waiting_for_show_promise_to_resolve_(false) { + is_waiting_for_show_promise_to_resolve_(false), + basic_card_has_supported_card_types_(false) { DCHECK(GetExecutionContext()->IsSecureContext()); if (!AllowedToUsePaymentRequest(execution_context)) { @@ -1118,13 +1127,15 @@ PaymentRequest::PaymentRequest( Vector<payments::mojom::blink::PaymentMethodDataPtr> validated_method_data; ValidateAndConvertPaymentMethodData(method_data, options_, skip_to_gpay_ready, validated_method_data, method_names_, + &basic_card_has_supported_card_types_, *GetExecutionContext(), exception_state); if (exception_state.HadException()) return; ValidateAndConvertPaymentDetailsInit(details, options_, validated_details, - shipping_option_, *GetExecutionContext(), - exception_state); + shipping_option_, + &basic_card_has_supported_card_types_, + *GetExecutionContext(), exception_state); if (exception_state.HadException()) return; @@ -1151,9 +1162,9 @@ PaymentRequest::PaymentRequest( scoped_refptr<base::SingleThreadTaskRunner> task_runner = execution_context->GetTaskRunner(TaskType::kUserInteraction); - GetFrame()->GetInterfaceProvider().GetInterface( - mojo::MakeRequest(&payment_provider_, task_runner)); - payment_provider_.set_connection_error_handler( + GetFrame()->GetBrowserInterfaceBroker().GetInterface( + payment_provider_.BindNewPipeAndPassReceiver(task_runner)); + payment_provider_.set_disconnect_handler( WTF::Bind(&PaymentRequest::OnConnectionError, WrapWeakPersistent(this))); UseCounter::Count(execution_context, WebFeature::kPaymentRequestInitialized); @@ -1211,7 +1222,8 @@ void PaymentRequest::OnPaymentMethodChange(const String& method_name, ClearResolversAndCloseMojoConnection(); return; } - init->setMethodDetails(ScriptValue(script_state, parsed_value)); + init->setMethodDetails( + ScriptValue(script_state->GetIsolate(), parsed_value)); } PaymentRequestUpdateEvent* event = PaymentMethodChangeEvent::Create( diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request.h b/chromium/third_party/blink/renderer/modules/payments/payment_request.h index 25442453ba2..2315ff65bfa 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.h @@ -7,8 +7,9 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" -#include "components/payments/mojom/payment_request_data.mojom-blink.h" +#include "components/payments/mojom/payment_request_data.mojom-blink-forward.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" @@ -165,12 +166,13 @@ class MODULES_EXPORT PaymentRequest final Member<ScriptPromiseResolver> abort_resolver_; Member<ScriptPromiseResolver> can_make_payment_resolver_; Member<ScriptPromiseResolver> has_enrolled_instrument_resolver_; - payments::mojom::blink::PaymentRequestPtr payment_provider_; + mojo::Remote<payments::mojom::blink::PaymentRequest> payment_provider_; mojo::Receiver<payments::mojom::blink::PaymentRequestClient> client_receiver_{ this}; TaskRunnerTimer<PaymentRequest> complete_timer_; TaskRunnerTimer<PaymentRequest> update_payment_details_timer_; bool is_waiting_for_show_promise_to_resolve_; + bool basic_card_has_supported_card_types_; DISALLOW_COPY_AND_ASSIGN(PaymentRequest); }; diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc index df182783f30..163e87e5109 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.cc @@ -6,6 +6,7 @@ #include <utility> +#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h" #include "third_party/blink/public/platform/interface_provider.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" @@ -60,6 +61,12 @@ PaymentRequestEvent::PaymentRequestEvent( ? initializer->modifiers() : HeapVector<Member<PaymentDetailsModifier>>()), instrument_key_(initializer->instrumentKey()), + payment_options_(initializer->hasPaymentOptions() + ? initializer->paymentOptions() + : PaymentOptions::Create()), + shipping_options_(initializer->hasShippingOptions() + ? initializer->shippingOptions() + : HeapVector<Member<PaymentShippingOption>>()), observer_(respond_with_observer) { if (!host.is_valid()) return; @@ -105,6 +112,19 @@ const String& PaymentRequestEvent::instrumentKey() const { return instrument_key_; } +const ScriptValue PaymentRequestEvent::paymentOptions( + ScriptState* script_state) const { + if (!payment_options_) + return ScriptValue::CreateNull(script_state->GetIsolate()); + return ScriptValue::From(script_state, payment_options_); +} + +const HeapVector<Member<PaymentShippingOption>>& +PaymentRequestEvent::shippingOptions(bool& is_null) const { + is_null = shipping_options_.IsEmpty(); + return shipping_options_; +} + ScriptPromise PaymentRequestEvent::openWindow(ScriptState* script_state, const String& url) { auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); @@ -161,12 +181,12 @@ ScriptPromise PaymentRequestEvent::changePaymentMethod( const String& method_name, const ScriptValue& method_details, ExceptionState& exception_state) { - if (change_payment_method_resolver_) { + if (change_payment_request_details_resolver_) { return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, - "Waiting for response to the previous payment method change")); + script_state, MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, + "Waiting for response to the previous payment " + "request details change")); } if (!payment_handler_host_.is_bound()) { @@ -188,11 +208,106 @@ ScriptPromise PaymentRequestEvent::changePaymentMethod( method_data->method_name = method_name; payment_handler_host_->ChangePaymentMethod( std::move(method_data), - WTF::Bind(&PaymentRequestEvent::OnChangePaymentMethodResponse, + WTF::Bind(&PaymentRequestEvent::OnChangePaymentRequestDetailsResponse, + WrapWeakPersistent(this))); + change_payment_request_details_resolver_ = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + return change_payment_request_details_resolver_->Promise(); +} + +ScriptPromise PaymentRequestEvent::changeShippingAddress( + ScriptState* script_state, + PaymentAddressInit* shipping_address) { + if (change_payment_request_details_resolver_) { + return ScriptPromise::RejectWithDOMException( + script_state, MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, + "Waiting for response to the previous payment " + "request details change")); + } + + if (!payment_handler_host_.is_bound()) { + return ScriptPromise::RejectWithDOMException( + script_state, MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, + "No corresponding PaymentRequest object found")); + } + if (!shipping_address) { + return ScriptPromise::RejectWithDOMException( + script_state, + MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError, + "Shipping address cannot be null")); + } + + auto shipping_address_ptr = payments::mojom::blink::PaymentAddress::New(); + shipping_address_ptr->country = shipping_address->country(); + shipping_address_ptr->address_line = shipping_address->addressLine(); + shipping_address_ptr->region = shipping_address->region(); + shipping_address_ptr->city = shipping_address->city(); + shipping_address_ptr->dependent_locality = + shipping_address->dependentLocality(); + shipping_address_ptr->postal_code = shipping_address->postalCode(); + shipping_address_ptr->sorting_code = shipping_address->sortingCode(); + shipping_address_ptr->organization = shipping_address->organization(); + shipping_address_ptr->recipient = shipping_address->recipient(); + shipping_address_ptr->phone = shipping_address->phone(); + String shipping_address_error; + if (!PaymentsValidators::IsValidShippingAddress(shipping_address_ptr, + &shipping_address_error)) { + return ScriptPromise::RejectWithDOMException( + script_state, + MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError, + shipping_address_error)); + } + + payment_handler_host_->ChangeShippingAddress( + std::move(shipping_address_ptr), + WTF::Bind(&PaymentRequestEvent::OnChangePaymentRequestDetailsResponse, WrapWeakPersistent(this))); - change_payment_method_resolver_ = + change_payment_request_details_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - return change_payment_method_resolver_->Promise(); + return change_payment_request_details_resolver_->Promise(); +} + +ScriptPromise PaymentRequestEvent::changeShippingOption( + ScriptState* script_state, + const String& shipping_option_id) { + if (change_payment_request_details_resolver_) { + return ScriptPromise::RejectWithDOMException( + script_state, MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, + "Waiting for response to the previous payment " + "request details change")); + } + + if (!payment_handler_host_.is_bound()) { + return ScriptPromise::RejectWithDOMException( + script_state, MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, + "No corresponding PaymentRequest object found")); + } + + bool shipping_option_id_is_valid = false; + for (const auto& option : shipping_options_) { + if (option->id() == shipping_option_id) { + shipping_option_id_is_valid = true; + break; + } + } + if (!shipping_option_id_is_valid) { + return ScriptPromise::RejectWithDOMException( + script_state, MakeGarbageCollected<DOMException>( + DOMExceptionCode::kSyntaxError, + "Shipping option identifier is invalid")); + } + + payment_handler_host_->ChangeShippingOption( + shipping_option_id, + WTF::Bind(&PaymentRequestEvent::OnChangePaymentRequestDetailsResponse, + WrapWeakPersistent(this))); + change_payment_request_details_resolver_ = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + return change_payment_request_details_resolver_->Promise(); } void PaymentRequestEvent::respondWith(ScriptState* script_state, @@ -215,14 +330,16 @@ void PaymentRequestEvent::Trace(blink::Visitor* visitor) { visitor->Trace(method_data_); visitor->Trace(total_); visitor->Trace(modifiers_); - visitor->Trace(change_payment_method_resolver_); + visitor->Trace(payment_options_); + visitor->Trace(shipping_options_); + visitor->Trace(change_payment_request_details_resolver_); visitor->Trace(observer_); ExtendableEvent::Trace(visitor); } -void PaymentRequestEvent::OnChangePaymentMethodResponse( +void PaymentRequestEvent::OnChangePaymentRequestDetailsResponse( payments::mojom::blink::PaymentMethodChangeResponsePtr response) { - if (!change_payment_method_resolver_) + if (!change_payment_request_details_resolver_) return; auto* dictionary = MakeGarbageCollected<PaymentMethodChangeResponse>(); @@ -237,7 +354,8 @@ void PaymentRequestEvent::OnChangePaymentMethodResponse( dictionary->setTotal(total); } - ScriptState* script_state = change_payment_method_resolver_->GetScriptState(); + ScriptState* script_state = + change_payment_request_details_resolver_->GetScriptState(); ScriptState::Scope scope(script_state); ExceptionState exception_state(script_state->GetIsolate(), ExceptionState::kConstructionContext, @@ -268,48 +386,96 @@ void PaymentRequestEvent::OnChangePaymentMethodResponse( script_state->GetIsolate(), script_state->GetContext(), response_modifier->method_data->stringified_data, exception_state); if (exception_state.HadException()) { - change_payment_method_resolver_->Reject( + change_payment_request_details_resolver_->Reject( MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError, exception_state.Message())); - change_payment_method_resolver_.Clear(); + change_payment_request_details_resolver_.Clear(); return; } - mod->setData(ScriptValue(script_state, parsed_value)); + mod->setData(ScriptValue(script_state->GetIsolate(), parsed_value)); modifiers->emplace_back(mod); } } dictionary->setModifiers(*modifiers); } + if (response->shipping_options) { + auto* shipping_options = + MakeGarbageCollected<HeapVector<Member<PaymentShippingOption>>>(); + for (const auto& response_shipping_option : *response->shipping_options) { + if (!response_shipping_option) + continue; + + auto* shipping_option = MakeGarbageCollected<PaymentShippingOption>(); + auto* amount = MakeGarbageCollected<PaymentCurrencyAmount>(); + amount->setCurrency(response_shipping_option->amount->currency); + amount->setValue(response_shipping_option->amount->value); + shipping_option->setAmount(amount); + shipping_option->setId(response_shipping_option->id); + shipping_option->setLabel(response_shipping_option->label); + shipping_option->setSelected(response_shipping_option->selected); + shipping_options->emplace_back(shipping_option); + } + dictionary->setShippingOptions(*shipping_options); + } + if (response->stringified_payment_method_errors && !response->stringified_payment_method_errors.IsEmpty()) { v8::Local<v8::Value> parsed_value = FromJSONString( script_state->GetIsolate(), script_state->GetContext(), response->stringified_payment_method_errors, exception_state); if (exception_state.HadException()) { - change_payment_method_resolver_->Reject( + change_payment_request_details_resolver_->Reject( MakeGarbageCollected<DOMException>(DOMExceptionCode::kSyntaxError, exception_state.Message())); - change_payment_method_resolver_.Clear(); + change_payment_request_details_resolver_.Clear(); return; } - dictionary->setPaymentMethodErrors(ScriptValue(script_state, parsed_value)); + dictionary->setPaymentMethodErrors( + ScriptValue(script_state->GetIsolate(), parsed_value)); + } + + if (response->shipping_address_errors) { + auto* shipping_address_errors = MakeGarbageCollected<AddressErrors>(); + shipping_address_errors->setAddressLine( + response->shipping_address_errors->address_line); + shipping_address_errors->setCity(response->shipping_address_errors->city); + shipping_address_errors->setCountry( + response->shipping_address_errors->country); + shipping_address_errors->setDependentLocality( + response->shipping_address_errors->dependent_locality); + shipping_address_errors->setOrganization( + response->shipping_address_errors->organization); + shipping_address_errors->setPhone(response->shipping_address_errors->phone); + shipping_address_errors->setPostalCode( + response->shipping_address_errors->postal_code); + shipping_address_errors->setRecipient( + response->shipping_address_errors->recipient); + shipping_address_errors->setRegion( + response->shipping_address_errors->region); + shipping_address_errors->setSortingCode( + response->shipping_address_errors->sorting_code); + dictionary->setShippingAddressErrors(shipping_address_errors); } - change_payment_method_resolver_->Resolve( + change_payment_request_details_resolver_->Resolve( dictionary->hasError() || dictionary->hasTotal() || - dictionary->hasModifiers() || dictionary->hasPaymentMethodErrors() + dictionary->hasModifiers() || + dictionary->hasPaymentMethodErrors() || + dictionary->hasShippingOptions() || + dictionary->hasShippingAddressErrors() ? dictionary : nullptr); - change_payment_method_resolver_.Clear(); + change_payment_request_details_resolver_.Clear(); } void PaymentRequestEvent::OnHostConnectionError() { - if (change_payment_method_resolver_) { - change_payment_method_resolver_->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kAbortError, "Browser process disconnected")); + if (change_payment_request_details_resolver_) { + change_payment_request_details_resolver_->Reject( + MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError, + "Browser process disconnected")); } - change_payment_method_resolver_.Clear(); + change_payment_request_details_resolver_.Clear(); payment_handler_host_.reset(); } diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.h b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.h index ca798d6e2f9..6d65dbff6d4 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.h @@ -11,6 +11,7 @@ #include "third_party/blink/public/mojom/payments/payment_handler_host.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/modules/event_modules.h" +#include "third_party/blink/renderer/modules/payments/payment_address_init.h" #include "third_party/blink/renderer/modules/payments/payment_request_event_init.h" #include "third_party/blink/renderer/modules/service_worker/extendable_event.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -56,6 +57,9 @@ class MODULES_EXPORT PaymentRequestEvent final : public ExtendableEvent { const ScriptValue total(ScriptState*) const; const HeapVector<Member<PaymentDetailsModifier>>& modifiers() const; const String& instrumentKey() const; + const ScriptValue paymentOptions(ScriptState*) const; + const HeapVector<Member<PaymentShippingOption>>& shippingOptions( + bool& is_null) const; ScriptPromise openWindow(ScriptState*, const String& url); ScriptPromise changePaymentMethod(ScriptState*, @@ -65,12 +69,16 @@ class MODULES_EXPORT PaymentRequestEvent final : public ExtendableEvent { const String& method_name, const ScriptValue& method_details, ExceptionState& exception_state); + ScriptPromise changeShippingAddress(ScriptState*, + PaymentAddressInit* shippingAddress); + ScriptPromise changeShippingOption(ScriptState*, + const String& shipping_option_id); void respondWith(ScriptState*, ScriptPromise, ExceptionState&); void Trace(blink::Visitor*) override; private: - void OnChangePaymentMethodResponse( + void OnChangePaymentRequestDetailsResponse( payments::mojom::blink::PaymentMethodChangeResponsePtr); void OnHostConnectionError(); @@ -81,8 +89,10 @@ class MODULES_EXPORT PaymentRequestEvent final : public ExtendableEvent { Member<PaymentCurrencyAmount> total_; HeapVector<Member<PaymentDetailsModifier>> modifiers_; String instrument_key_; + Member<PaymentOptions> payment_options_; + HeapVector<Member<PaymentShippingOption>> shipping_options_; - Member<ScriptPromiseResolver> change_payment_method_resolver_; + Member<ScriptPromiseResolver> change_payment_request_details_resolver_; Member<RespondWithObserver> observer_; mojo::Remote<payments::mojom::blink::PaymentHandlerHost> payment_handler_host_; diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.idl b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.idl index 51d8824b490..2aac585f76f 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request_event.idl +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_event.idl @@ -16,8 +16,12 @@ [CallWith=ScriptState] readonly attribute object total; readonly attribute FrozenArray<PaymentDetailsModifier> modifiers; readonly attribute DOMString instrumentKey; + [CallWith=ScriptState, RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] readonly attribute object? paymentOptions; + [RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] readonly attribute FrozenArray<PaymentShippingOption>? shippingOptions; [CallWith=ScriptState] Promise<WindowClient?> openWindow(USVString url); [CallWith=ScriptState, RaisesException, RuntimeEnabled=PaymentHandlerChangePaymentMethod] Promise<PaymentMethodChangeResponse?> changePaymentMethod(DOMString methodName, optional object? methodDetails = null); [CallWith=ScriptState, RaisesException] void respondWith(Promise<PaymentResponse> response); + [CallWith=ScriptState, RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] Promise<PaymentMethodChangeResponse?> changeShippingAddress(PaymentAddressInit shippingAddress); + [CallWith=ScriptState, RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] Promise<PaymentMethodChangeResponse?> changeShippingOption(DOMString shippingOption); }; diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_event_init.idl b/chromium/third_party/blink/renderer/modules/payments/payment_request_event_init.idl index ffc0e9e9cca..d15da9f9d6b 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request_event_init.idl +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_event_init.idl @@ -12,4 +12,6 @@ dictionary PaymentRequestEventInit : ExtendableEventInit { PaymentCurrencyAmount total; sequence<PaymentDetailsModifier> modifiers; DOMString instrumentKey; + [RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] PaymentOptions paymentOptions; + [RuntimeEnabled=PaymentHandlerHandlesShippingAndContact] sequence<PaymentShippingOption> shippingOptions; }; diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc index 966c70a7519..76b75d106ed 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.cc @@ -6,11 +6,14 @@ #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_address.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_handler_response.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/modules/payments/payment_address.h" #include "third_party/blink/renderer/modules/payments/payment_handler_response.h" #include "third_party/blink/renderer/modules/payments/payment_handler_utils.h" +#include "third_party/blink/renderer/modules/payments/payments_validators.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h" #include "third_party/blink/renderer/modules/service_worker/wait_until_observer.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -35,10 +38,10 @@ void PaymentRequestRespondWithObserver::OnResponseRejected( mojom::ServiceWorkerResponseError error) { PaymentHandlerUtils::ReportResponseError(GetExecutionContext(), "PaymentRequestEvent", error); - Respond("", "", - error == mojom::ServiceWorkerResponseError::kPromiseRejected - ? PaymentEventResponseType::PAYMENT_EVENT_REJECT - : PaymentEventResponseType::PAYMENT_EVENT_INTERNAL_ERROR); + BlankResponseWithError( + error == mojom::ServiceWorkerResponseError::kPromiseRejected + ? PaymentEventResponseType::PAYMENT_EVENT_REJECT + : PaymentEventResponseType::PAYMENT_EVENT_INTERNAL_ERROR); } void PaymentRequestRespondWithObserver::OnResponseFulfilled( @@ -72,18 +75,19 @@ void PaymentRequestRespondWithObserver::OnResponseFulfilled( } if (!response->hasMethodName() || response->methodName().IsEmpty()) { - Respond("", "", PaymentEventResponseType::PAYMENT_METHOD_NAME_EMPTY); + BlankResponseWithError(PaymentEventResponseType::PAYMENT_METHOD_NAME_EMPTY); return; } if (!response->hasDetails()) { - Respond("", "", PaymentEventResponseType::PAYMENT_DETAILS_ABSENT); + BlankResponseWithError(PaymentEventResponseType::PAYMENT_DETAILS_ABSENT); return; } if (response->details().IsNull() || !response->details().IsObject() || response->details().IsEmpty()) { - Respond("", "", PaymentEventResponseType::PAYMENT_DETAILS_NOT_OBJECT); + BlankResponseWithError( + PaymentEventResponseType::PAYMENT_DETAILS_NOT_OBJECT); return; } @@ -96,19 +100,76 @@ void PaymentRequestRespondWithObserver::OnResponseFulfilled( mojom::ConsoleMessageLevel::kError, "Failed to stringify PaymentHandlerResponse.details in payment " "response.")); - Respond("", "", PaymentEventResponseType::PAYMENT_DETAILS_STRINGIFY_ERROR); + BlankResponseWithError( + PaymentEventResponseType::PAYMENT_DETAILS_STRINGIFY_ERROR); return; } String details = ToCoreString(details_value); DCHECK(!details.IsEmpty()); + String payer_name = response->hasPayerName() ? response->payerName() : ""; + if (should_have_payer_name_ && payer_name.IsEmpty()) { + BlankResponseWithError(PaymentEventResponseType::PAYER_NAME_EMPTY); + return; + } + + String payer_email = response->hasPayerEmail() ? response->payerEmail() : ""; + if (should_have_payer_email_ && payer_email.IsEmpty()) { + BlankResponseWithError(PaymentEventResponseType::PAYER_EMAIL_EMPTY); + return; + } + + String payer_phone = response->hasPayerPhone() ? response->payerPhone() : ""; + if (should_have_payer_phone_ && payer_phone.IsEmpty()) { + BlankResponseWithError(PaymentEventResponseType::PAYER_PHONE_EMPTY); + return; + } + + if (should_have_shipping_info_ && !response->hasShippingAddress()) { + BlankResponseWithError(PaymentEventResponseType::SHIPPING_ADDRESS_INVALID); + return; + } + + payments::mojom::blink::PaymentAddressPtr shipping_address_ptr = + should_have_shipping_info_ ? payments::mojom::blink::PaymentAddress::New() + : nullptr; + if (should_have_shipping_info_) { + auto* shipping_address = response->shippingAddress(); + shipping_address_ptr->country = shipping_address->country(); + shipping_address_ptr->address_line = shipping_address->addressLine(); + shipping_address_ptr->region = shipping_address->region(); + shipping_address_ptr->city = shipping_address->city(); + shipping_address_ptr->dependent_locality = + shipping_address->dependentLocality(); + shipping_address_ptr->postal_code = shipping_address->postalCode(); + shipping_address_ptr->sorting_code = shipping_address->sortingCode(); + shipping_address_ptr->organization = shipping_address->organization(); + shipping_address_ptr->recipient = shipping_address->recipient(); + shipping_address_ptr->phone = shipping_address->phone(); + if (!PaymentsValidators::IsValidShippingAddress( + shipping_address_ptr, nullptr /* = optional_error_message */)) { + BlankResponseWithError( + PaymentEventResponseType::SHIPPING_ADDRESS_INVALID); + return; + } + } + + String selected_shipping_option_id = + response->hasShippingOption() ? response->shippingOption() : ""; + if (should_have_shipping_info_ && selected_shipping_option_id.IsEmpty()) { + BlankResponseWithError(PaymentEventResponseType::SHIPPING_OPTION_EMPTY); + return; + } + Respond(response->methodName(), details, - PaymentEventResponseType::PAYMENT_EVENT_SUCCESS); + PaymentEventResponseType::PAYMENT_EVENT_SUCCESS, payer_name, + payer_email, payer_phone, std::move(shipping_address_ptr), + selected_shipping_option_id); } void PaymentRequestRespondWithObserver::OnNoResponse() { - Respond("", "", PaymentEventResponseType::PAYMENT_EVENT_NO_RESPONSE); + BlankResponseWithError(PaymentEventResponseType::PAYMENT_EVENT_NO_RESPONSE); } PaymentRequestRespondWithObserver::PaymentRequestRespondWithObserver( @@ -124,12 +185,25 @@ void PaymentRequestRespondWithObserver::Trace(blink::Visitor* visitor) { void PaymentRequestRespondWithObserver::Respond( const String& method_name, const String& stringified_details, - PaymentEventResponseType response_type) { + PaymentEventResponseType response_type, + const String& payer_name, + const String& payer_email, + const String& payer_phone, + payments::mojom::blink::PaymentAddressPtr shipping_address, + const String& selected_shipping_option_id) { DCHECK(GetExecutionContext()); To<ServiceWorkerGlobalScope>(GetExecutionContext()) ->RespondToPaymentRequestEvent( - event_id_, payments::mojom::blink::PaymentHandlerResponse::New( - method_name, stringified_details, response_type)); + event_id_, + payments::mojom::blink::PaymentHandlerResponse::New( + method_name, stringified_details, response_type, payer_name, + payer_email, payer_phone, std::move(shipping_address), + selected_shipping_option_id)); +} + +void PaymentRequestRespondWithObserver::BlankResponseWithError( + PaymentEventResponseType response_type) { + Respond("", "", response_type, "", "", "", nullptr, ""); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h b/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h index 3eaf4d7451b..a9428dc89fc 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_respond_with_observer.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_REQUEST_RESPOND_WITH_OBSERVER_H_ #include "third_party/blink/public/mojom/payments/payment_app.mojom-blink.h" -#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/service_worker/respond_with_observer.h" @@ -41,10 +41,34 @@ class MODULES_EXPORT PaymentRequestRespondWithObserver final void Trace(blink::Visitor*) override; + void set_should_have_payer_name(bool should_have_payer_name) { + should_have_payer_name_ = should_have_payer_name; + } + void set_should_have_payer_email(bool should_have_payer_email) { + should_have_payer_email_ = should_have_payer_email; + } + void set_should_have_payer_phone(bool should_have_payer_phone) { + should_have_payer_phone_ = should_have_payer_phone; + } + void set_should_have_shipping_info(bool should_have_shipping_info) { + should_have_shipping_info_ = should_have_shipping_info; + } + private: void Respond(const String& method_name, const String& stringified_details, - payments::mojom::blink::PaymentEventResponseType response_type); + payments::mojom::blink::PaymentEventResponseType response_type, + const String& payer_name, + const String& payer_email, + const String& payer_phone, + payments::mojom::blink::PaymentAddressPtr shipping_address, + const String& selected_shipping_option_id); + void BlankResponseWithError( + payments::mojom::blink::PaymentEventResponseType response_type); + bool should_have_payer_name_ = false; + bool should_have_payer_email_ = false; + bool should_have_payer_phone_ = false; + bool should_have_shipping_info_ = false; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc index e52fcb33c47..930831f133b 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event_test.cc @@ -21,7 +21,7 @@ namespace blink { namespace { -class MockPaymentRequest : public GarbageCollectedFinalized<MockPaymentRequest>, +class MockPaymentRequest : public GarbageCollected<MockPaymentRequest>, public PaymentRequestDelegate { USING_GARBAGE_COLLECTED_MIXIN(MockPaymentRequest); diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_response.cc b/chromium/third_party/blink/renderer/modules/payments/payment_response.cc index 0116fdc0351..e95bb6f80d3 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_response.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.cc @@ -104,7 +104,8 @@ ScriptValue PaymentResponse::toJSONForBinding(ScriptState* script_state) const { } ScriptValue PaymentResponse::details(ScriptState* script_state) const { - return ScriptValue(script_state, details_.GetAcrossWorld(script_state)); + return ScriptValue(script_state->GetIsolate(), + details_.GetAcrossWorld(script_state)); } ScriptPromise PaymentResponse::complete(ScriptState* script_state, diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_response.h b/chromium/third_party/blink/renderer/modules/payments/payment_response.h index 05af654dcbc..c890b371325 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_response.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_PAYMENT_RESPONSE_H_ #include "base/macros.h" -#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h" +#include "third_party/blink/public/mojom/payments/payment_request.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc b/chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc index 38928418d6f..35d6d02f1c4 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_response_test.cc @@ -25,7 +25,7 @@ namespace blink { namespace { class MockPaymentStateResolver final - : public GarbageCollectedFinalized<MockPaymentStateResolver>, + : public GarbageCollected<MockPaymentStateResolver>, public PaymentStateResolver { USING_GARBAGE_COLLECTED_MIXIN(MockPaymentStateResolver); @@ -42,7 +42,9 @@ class MockPaymentStateResolver final ScriptPromise(ScriptState*, const PaymentValidationErrors* errorFields)); - void Trace(blink::Visitor* visitor) override {} + void Trace(blink::Visitor* visitor) override { + visitor->Trace(dummy_promise_); + } private: ScriptPromise dummy_promise_; @@ -80,7 +82,7 @@ TEST(PaymentResponseTest, DataCopiedOver) { ASSERT_TRUE(details.V8Value()->IsObject()); ScriptValue transaction_id( - scope.GetScriptState(), + scope.GetIsolate(), details.V8Value() .As<v8::Object>() ->Get(scope.GetContext(), diff --git a/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils.cc b/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils.cc index 761da35f933..1a7f1426e13 100644 --- a/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils.cc +++ b/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils.cc @@ -35,9 +35,11 @@ bool PatchGooglePayContactRequestV1(const PaymentOptions& options, JSONObject* output, bool* phone_requested, bool* name_requested) { - if (options.requestPayerName()) { + if (options.requestPayerName() || options.requestPayerPhone()) { const JSONObject* card_requirements = output->GetJSONObject("cardRequirements"); + // Phone number is returned as part of billing address, so + // |billingAddressRequired| must be set even if name is not requested. if (!card_requirements || !card_requirements->BooleanProperty("billingAddressRequired", false)) { GetJSONObjectOrInsert(output, "cardRequirements") @@ -169,8 +171,10 @@ bool SkipToGPayUtils::PatchPaymentMethodData( return false; int api_version; - if (!object->GetInteger("apiVersion", &api_version)) - return false; + if (!object->GetInteger("apiVersion", &api_version)) { + // Some API v1 clients don't explicitly specify "apiVersion". + api_version = 1; + } bool success = true; diff --git a/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils_test.cc b/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils_test.cc index c53660dd0b8..0d56ae8025d 100644 --- a/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils_test.cc +++ b/chromium/third_party/blink/renderer/modules/payments/skip_to_gpay_utils_test.cc @@ -1,3 +1,7 @@ +// 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. + #include "third_party/blink/renderer/modules/payments/skip_to_gpay_utils.h" #include <memory> @@ -62,12 +66,13 @@ TEST(SkipToGPayUtilsTest, NothingRequested) { } } -TEST(SkipToGPayUtilsTest, InvalidInputData_MissingApiVersion) { +TEST(SkipToGPayUtilsTest, MissingApiVersionConsideredV1) { auto* options = PaymentOptions::Create(); PaymentMethodDataPtr output = MakeTestPaymentMethodData(); + output->stringified_data = "{}"; - ASSERT_FALSE(SkipToGPayUtils::PatchPaymentMethodData(*options, output)); - EXPECT_TRUE(output->gpay_bridge_data.is_null()); + ASSERT_TRUE(SkipToGPayUtils::PatchPaymentMethodData(*options, output)); + EXPECT_EQ("{}", output->gpay_bridge_data->stringified_data); } TEST(SkipToGPayUtilsTest, InvalidInputData_NotJSON) { @@ -132,6 +137,49 @@ TEST(SkipToGPayUtilsTest, RequestEverything) { } } +TEST(SkipToGPayUtilsTest, RequestPhoneOnly) { + auto* options = PaymentOptions::Create(); + options->setRequestPayerPhone(true); + + { + PaymentMethodDataPtr output = MakeTestPaymentMethodData(); + output->stringified_data = kInputDataV1; + + ASSERT_TRUE(SkipToGPayUtils::PatchPaymentMethodData(*options, output)); + + EXPECT_EQ( + "{\"apiVersion\":1,\"cardRequirements\":{\"billingAddressRequired\":" + "true},\"phoneNumberRequired\":true}", + output->gpay_bridge_data->stringified_data); + EXPECT_TRUE(output->gpay_bridge_data->phone_requested); + // Phone number can only be requested as part of billing address, which + // implies that name will be requested too. + EXPECT_TRUE(output->gpay_bridge_data->name_requested); + EXPECT_FALSE(output->gpay_bridge_data->email_requested); + EXPECT_FALSE(output->gpay_bridge_data->shipping_requested); + EXPECT_EQ(kInputDataV1, output->stringified_data); + } + { + PaymentMethodDataPtr output = MakeTestPaymentMethodData(); + output->stringified_data = kInputDataV2; + + ASSERT_TRUE(SkipToGPayUtils::PatchPaymentMethodData(*options, output)); + + EXPECT_EQ( + "{\"apiVersion\":2,\"apiVersionMinor\":0,\"allowedPaymentMethods\":[{" + "\"type\":\"CARD\",\"parameters\":{\"billingAddressRequired\":true," + "\"billingAddressParameters\":{\"phoneNumberRequired\":true}}}]}", + output->gpay_bridge_data->stringified_data); + EXPECT_TRUE(output->gpay_bridge_data->phone_requested); + // Phone number can only be requested as part of billing address, which + // implies that name will be requested too. + EXPECT_TRUE(output->gpay_bridge_data->name_requested); + EXPECT_FALSE(output->gpay_bridge_data->email_requested); + EXPECT_FALSE(output->gpay_bridge_data->shipping_requested); + EXPECT_EQ(kInputDataV2, output->stringified_data); + } +} + TEST(SkipToGPayUtilsTest, ShippingAlreadyRequested) { auto* options = PaymentOptions::Create(); options->setRequestPayerName(true); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn index 98cef042aaa..32ce674d4be 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn @@ -53,8 +53,12 @@ blink_modules_sources("peerconnection") { "call_setup_state_tracker.cc", "call_setup_state_tracker.h", "media_stream_remote_video_source.cc", + "media_stream_video_webrtc_sink.cc", + "peer_connection_dependency_factory.cc", "rtc_certificate.cc", "rtc_certificate.h", + "rtc_certificate_generator.cc", + "rtc_certificate_generator.h", "rtc_data_channel.cc", "rtc_data_channel.h", "rtc_data_channel_event.cc", @@ -93,10 +97,13 @@ blink_modules_sources("peerconnection") { "rtc_quic_transport.h", "rtc_rtp_receiver.cc", "rtc_rtp_receiver.h", + "rtc_rtp_receiver_impl.cc", "rtc_rtp_sender.cc", "rtc_rtp_sender.h", + "rtc_rtp_sender_impl.cc", "rtc_rtp_transceiver.cc", "rtc_rtp_transceiver.h", + "rtc_rtp_transceiver_impl.cc", "rtc_sctp_transport.cc", "rtc_sctp_transport.h", "rtc_session_description.cc", @@ -120,12 +127,37 @@ blink_modules_sources("peerconnection") { "rtc_void_request_promise_impl.h", "rtc_void_request_script_promise_resolver_impl.cc", "rtc_void_request_script_promise_resolver_impl.h", + "transceiver_state_surfacer.cc", "web_rtc_stats_report_callback_resolver.cc", "web_rtc_stats_report_callback_resolver.h", + "webrtc_media_stream_track_adapter.cc", + "webrtc_media_stream_track_adapter_map.cc", ] public_deps = [ "//third_party/webrtc/api:ice_transport_factory", + "//third_party/webrtc/api:rtc_error", "//third_party/webrtc/api:scoped_refptr", ] } + +jumbo_source_set("test_support") { + testonly = true + + sources = [ + "fake_rtc_rtp_transceiver_impl.cc", + "mock_data_channel_impl.cc", + "mock_peer_connection_dependency_factory.cc", + "mock_peer_connection_impl.cc", + "mock_web_rtc_peer_connection_handler_client.cc", + "webrtc_stats_report_obtainer.cc", + ] + + deps = [ + "//base", + "//base/test:test_support", + "//testing/gmock", + "//third_party/blink/public:test_headers", + "//third_party/webrtc_overrides:init_webrtc", + ] +} diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/DEPS b/chromium/third_party/blink/renderer/modules/peerconnection/DEPS index f84dc56c481..c0f90696a5f 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/DEPS +++ b/chromium/third_party/blink/renderer/modules/peerconnection/DEPS @@ -1,5 +1,4 @@ include_rules = [ - "+services/metrics/public/cpp/ukm_builders.h", "-third_party/blink/renderer/modules", "+third_party/blink/renderer/modules/crypto", "+third_party/blink/renderer/modules/event_modules.h", @@ -7,15 +6,25 @@ include_rules = [ "+third_party/blink/renderer/modules/mediastream", "+third_party/blink/renderer/modules/modules_export.h", "+third_party/blink/renderer/modules/peerconnection", + "+third_party/blink/renderer/modules/p2p", + + "+crypto/openssl_util.h", + "+jingle/glue/thread_wrapper.h", "+media/base", + "+media/media_buildflags.h", + "+media/video/gpu_video_accelerator_factories.h", "+net/third_party/quiche/src/quic", "+net/quic/chromium", "+net/quic", "+net/test", + "+services/metrics/public/cpp/ukm_builders.h", ] specific_include_rules = { - "rtc_data_channel_test\.cc" : [ + ".*test\.cc" : [ "+base/run_loop.h", + "+base/test/bind_test_util.h", + "+base/test/test_timeouts.h", + "+ui/gfx/color_space.h", ], } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS b/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS index 347366aa979..f2eebf81dfc 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS +++ b/chromium/third_party/blink/renderer/modules/peerconnection/OWNERS @@ -1,6 +1,7 @@ guidou@chromium.org hbos@chromium.org orphis@chromium.org +sergeyu@chromium.org steveanton@chromium.org tommi@chromium.org diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_unittest.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_unittest.cc index eec9ff8f259..ca3088c22ff 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_unittest.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_stream_unittest.cc @@ -174,7 +174,23 @@ TEST_F(P2PQuicStreamTest, StreamClosedAfterReceivingReset) { quic::QuicRstStreamFrame rst_frame(quic::kInvalidControlFrameId, kStreamId, quic::QUIC_STREAM_CANCELLED, 0); + if (!VersionHasIetfQuicFrames(connection_->version().transport_version)) { + // Google RST_STREAM closes the stream in both directions. A RST_STREAM + // is then sent to the peer to communicate the final byte offset. + EXPECT_CALL(session_, + SendRstStream(kStreamId, quic::QUIC_RST_ACKNOWLEDGEMENT, 0)); + } stream_->OnStreamReset(rst_frame); + if (VersionHasIetfQuicFrames(connection_->version().transport_version)) { + // In IETF QUIC, the RST_STREAM only closes the stream in one direction. + // A STOP_SENDING frame in require to induce the a RST_STREAM being + // send to close the other direction. + EXPECT_CALL(*connection_, SendControlFrame(_)); + EXPECT_CALL(*connection_, OnStreamReset(kStreamId, testing::_)); + quic::QuicStopSendingFrame stop_sending_frame(quic::kInvalidControlFrameId, + kStreamId, 0); + session_.OnStopSendingFrame(stop_sending_frame); + } EXPECT_TRUE(stream_->IsClosedForTesting()); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc new file mode 100644 index 00000000000..c0b8bdf7acc --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.cc @@ -0,0 +1,257 @@ +// 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 <utility> + +#include "third_party/blink/public/web/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h" + +namespace blink { + +blink::WebMediaStreamTrack CreateWebMediaStreamTrack( + const std::string& id, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + blink::WebMediaStreamSource web_source; + web_source.Initialize(blink::WebString::FromUTF8(id), + blink::WebMediaStreamSource::kTypeAudio, + blink::WebString::FromUTF8("audio_track"), false); + std::unique_ptr<blink::MediaStreamAudioSource> audio_source_ptr = + std::make_unique<blink::MediaStreamAudioSource>( + std::move(task_runner), true /* is_local_source */); + blink::MediaStreamAudioSource* audio_source = audio_source_ptr.get(); + // Takes ownership of |audio_source_ptr|. + web_source.SetPlatformSource(std::move(audio_source_ptr)); + + blink::WebMediaStreamTrack web_track; + web_track.Initialize(web_source.Id(), web_source); + audio_source->ConnectToTrack(web_track); + return web_track; +} + +FakeRTCRtpSenderImpl::FakeRTCRtpSenderImpl( + base::Optional<std::string> track_id, + std::vector<std::string> stream_ids, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : track_id_(std::move(track_id)), + stream_ids_(std::move(stream_ids)), + task_runner_(task_runner) {} + +FakeRTCRtpSenderImpl::FakeRTCRtpSenderImpl(const FakeRTCRtpSenderImpl&) = + default; + +FakeRTCRtpSenderImpl::~FakeRTCRtpSenderImpl() {} + +FakeRTCRtpSenderImpl& FakeRTCRtpSenderImpl::operator=( + const FakeRTCRtpSenderImpl&) = default; + +std::unique_ptr<blink::WebRTCRtpSender> FakeRTCRtpSenderImpl::ShallowCopy() + const { + return std::make_unique<FakeRTCRtpSenderImpl>(*this); +} + +uintptr_t FakeRTCRtpSenderImpl::Id() const { + NOTIMPLEMENTED(); + return 0; +} + +rtc::scoped_refptr<webrtc::DtlsTransportInterface> +FakeRTCRtpSenderImpl::DtlsTransport() { + NOTIMPLEMENTED(); + return nullptr; +} + +webrtc::DtlsTransportInformation +FakeRTCRtpSenderImpl::DtlsTransportInformation() { + NOTIMPLEMENTED(); + static webrtc::DtlsTransportInformation dummy( + webrtc::DtlsTransportState::kNew); + return dummy; +} + +blink::WebMediaStreamTrack FakeRTCRtpSenderImpl::Track() const { + return track_id_ ? CreateWebMediaStreamTrack(*track_id_, task_runner_) + : blink::WebMediaStreamTrack(); // null +} + +blink::WebVector<blink::WebString> FakeRTCRtpSenderImpl::StreamIds() const { + blink::WebVector<blink::WebString> web_stream_ids(stream_ids_.size()); + for (size_t i = 0; i < stream_ids_.size(); ++i) { + web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids_[i]); + } + return web_stream_ids; +} + +void FakeRTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track, + blink::WebRTCVoidRequest request) { + NOTIMPLEMENTED(); +} + +std::unique_ptr<blink::WebRTCDTMFSenderHandler> +FakeRTCRtpSenderImpl::GetDtmfSender() const { + NOTIMPLEMENTED(); + return nullptr; +} + +std::unique_ptr<webrtc::RtpParameters> FakeRTCRtpSenderImpl::GetParameters() + const { + NOTIMPLEMENTED(); + return nullptr; +} + +void FakeRTCRtpSenderImpl::SetParameters( + blink::WebVector<webrtc::RtpEncodingParameters>, + webrtc::DegradationPreference, + blink::WebRTCVoidRequest) { + NOTIMPLEMENTED(); +} + +void FakeRTCRtpSenderImpl::GetStats( + blink::WebRTCStatsReportCallback, + const blink::WebVector<webrtc::NonStandardGroupId>&) { + NOTIMPLEMENTED(); +} + +void FakeRTCRtpSenderImpl::SetStreams( + const blink::WebVector<blink::WebString>& stream_ids) { + NOTIMPLEMENTED(); +} + +FakeRTCRtpReceiverImpl::FakeRTCRtpReceiverImpl( + const std::string& track_id, + std::vector<std::string> stream_ids, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : track_(CreateWebMediaStreamTrack(track_id, task_runner)), + stream_ids_(std::move(stream_ids)) {} + +FakeRTCRtpReceiverImpl::FakeRTCRtpReceiverImpl(const FakeRTCRtpReceiverImpl&) = + default; + +FakeRTCRtpReceiverImpl::~FakeRTCRtpReceiverImpl() {} + +FakeRTCRtpReceiverImpl& FakeRTCRtpReceiverImpl::operator=( + const FakeRTCRtpReceiverImpl&) = default; + +std::unique_ptr<blink::WebRTCRtpReceiver> FakeRTCRtpReceiverImpl::ShallowCopy() + const { + return std::make_unique<FakeRTCRtpReceiverImpl>(*this); +} + +uintptr_t FakeRTCRtpReceiverImpl::Id() const { + NOTIMPLEMENTED(); + return 0; +} + +rtc::scoped_refptr<webrtc::DtlsTransportInterface> +FakeRTCRtpReceiverImpl::DtlsTransport() { + NOTIMPLEMENTED(); + return nullptr; +} + +webrtc::DtlsTransportInformation +FakeRTCRtpReceiverImpl::DtlsTransportInformation() { + NOTIMPLEMENTED(); + static webrtc::DtlsTransportInformation dummy( + webrtc::DtlsTransportState::kNew); + return dummy; +} + +const blink::WebMediaStreamTrack& FakeRTCRtpReceiverImpl::Track() const { + return track_; +} + +blink::WebVector<blink::WebString> FakeRTCRtpReceiverImpl::StreamIds() const { + blink::WebVector<blink::WebString> web_stream_ids(stream_ids_.size()); + for (size_t i = 0; i < stream_ids_.size(); ++i) { + web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids_[i]); + } + return web_stream_ids; +} + +blink::WebVector<std::unique_ptr<blink::WebRTCRtpSource>> +FakeRTCRtpReceiverImpl::GetSources() { + NOTIMPLEMENTED(); + return {}; +} + +void FakeRTCRtpReceiverImpl::GetStats( + blink::WebRTCStatsReportCallback, + const blink::WebVector<webrtc::NonStandardGroupId>&) { + NOTIMPLEMENTED(); +} + +std::unique_ptr<webrtc::RtpParameters> FakeRTCRtpReceiverImpl::GetParameters() + const { + NOTIMPLEMENTED(); + return nullptr; +} + +void FakeRTCRtpReceiverImpl::SetJitterBufferMinimumDelay( + base::Optional<double> delay_seconds) { + NOTIMPLEMENTED(); +} + +FakeRTCRtpTransceiverImpl::FakeRTCRtpTransceiverImpl( + base::Optional<std::string> mid, + FakeRTCRtpSenderImpl sender, + FakeRTCRtpReceiverImpl receiver, + bool stopped, + webrtc::RtpTransceiverDirection direction, + base::Optional<webrtc::RtpTransceiverDirection> current_direction) + : mid_(std::move(mid)), + sender_(std::move(sender)), + receiver_(std::move(receiver)), + stopped_(stopped), + direction_(std::move(direction)), + current_direction_(std::move(current_direction)) {} + +FakeRTCRtpTransceiverImpl::~FakeRTCRtpTransceiverImpl() {} + +blink::WebRTCRtpTransceiverImplementationType +FakeRTCRtpTransceiverImpl::ImplementationType() const { + return blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver; +} + +uintptr_t FakeRTCRtpTransceiverImpl::Id() const { + NOTIMPLEMENTED(); + return 0u; +} + +blink::WebString FakeRTCRtpTransceiverImpl::Mid() const { + return mid_ ? blink::WebString::FromUTF8(*mid_) : blink::WebString(); +} + +std::unique_ptr<blink::WebRTCRtpSender> FakeRTCRtpTransceiverImpl::Sender() + const { + return sender_.ShallowCopy(); +} + +std::unique_ptr<blink::WebRTCRtpReceiver> FakeRTCRtpTransceiverImpl::Receiver() + const { + return receiver_.ShallowCopy(); +} + +bool FakeRTCRtpTransceiverImpl::Stopped() const { + return stopped_; +} + +webrtc::RtpTransceiverDirection FakeRTCRtpTransceiverImpl::Direction() const { + return direction_; +} + +void FakeRTCRtpTransceiverImpl::SetDirection( + webrtc::RtpTransceiverDirection direction) { + NOTIMPLEMENTED(); +} + +base::Optional<webrtc::RtpTransceiverDirection> +FakeRTCRtpTransceiverImpl::CurrentDirection() const { + return current_direction_; +} + +base::Optional<webrtc::RtpTransceiverDirection> +FakeRTCRtpTransceiverImpl::FiredDirection() const { + NOTIMPLEMENTED(); + return base::nullopt; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc new file mode 100644 index 00000000000..2e9aa9ddfbf --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source_test.cc @@ -0,0 +1,234 @@ +// Copyright 2014 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 "third_party/blink/public/web/modules/peerconnection/media_stream_remote_video_source.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" +#include "media/base/video_frame.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h" +#include "third_party/blink/public/platform/modules/webrtc/track_observer.h" +#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" +#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" +#include "third_party/blink/public/web/modules/mediastream/mock_media_stream_video_sink.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_dependency_factory.h" +#include "third_party/blink/public/web/web_heap.h" +#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" +#include "third_party/webrtc/api/video/color_space.h" +#include "third_party/webrtc/api/video/i420_buffer.h" +#include "ui/gfx/color_space.h" + +namespace blink { + +ACTION_P(RunClosure, closure) { + closure.Run(); +} + +class MediaStreamRemoteVideoSourceUnderTest + : public blink::MediaStreamRemoteVideoSource { + public: + explicit MediaStreamRemoteVideoSourceUnderTest( + std::unique_ptr<blink::TrackObserver> observer) + : MediaStreamRemoteVideoSource(std::move(observer)) {} + using MediaStreamRemoteVideoSource::SinkInterfaceForTesting; + using MediaStreamRemoteVideoSource::StartSourceImpl; +}; + +class MediaStreamRemoteVideoSourceTest : public ::testing::Test { + public: + MediaStreamRemoteVideoSourceTest() + : mock_factory_(new blink::MockPeerConnectionDependencyFactory()), + webrtc_video_track_(blink::MockWebRtcVideoTrack::Create("test")), + remote_source_(nullptr), + number_of_successful_track_starts_(0), + number_of_failed_track_starts_(0) {} + + void SetUp() override { + scoped_refptr<base::SingleThreadTaskRunner> main_thread = + blink::scheduler::GetSingleThreadTaskRunnerForTesting(); + + base::WaitableEvent waitable_event( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + + std::unique_ptr<blink::TrackObserver> track_observer; + mock_factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + [](scoped_refptr<base::SingleThreadTaskRunner> main_thread, + webrtc::MediaStreamTrackInterface* webrtc_track, + std::unique_ptr<blink::TrackObserver>* track_observer, + base::WaitableEvent* waitable_event) { + track_observer->reset( + new blink::TrackObserver(main_thread, webrtc_track)); + waitable_event->Signal(); + }, + main_thread, base::Unretained(webrtc_video_track_.get()), + base::Unretained(&track_observer), + base::Unretained(&waitable_event))); + waitable_event.Wait(); + + remote_source_ = + new MediaStreamRemoteVideoSourceUnderTest(std::move(track_observer)); + web_source_.Initialize(blink::WebString::FromASCII("dummy_source_id"), + blink::WebMediaStreamSource::kTypeVideo, + blink::WebString::FromASCII("dummy_source_name"), + true /* remote */); + web_source_.SetPlatformSource(base::WrapUnique(remote_source_)); + } + + void TearDown() override { + remote_source_->OnSourceTerminated(); + web_source_.Reset(); + blink::WebHeap::CollectAllGarbageForTesting(); + } + + MediaStreamRemoteVideoSourceUnderTest* source() { return remote_source_; } + + blink::MediaStreamVideoTrack* CreateTrack() { + bool enabled = true; + return new blink::MediaStreamVideoTrack( + source(), + base::Bind(&MediaStreamRemoteVideoSourceTest::OnTrackStarted, + base::Unretained(this)), + enabled); + } + + int NumberOfSuccessConstraintsCallbacks() const { + return number_of_successful_track_starts_; + } + + int NumberOfFailedConstraintsCallbacks() const { + return number_of_failed_track_starts_; + } + + void StopWebRtcTrack() { + base::WaitableEvent waitable_event( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + mock_factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + [](blink::MockWebRtcVideoTrack* video_track, + base::WaitableEvent* waitable_event) { + video_track->SetEnded(); + waitable_event->Signal(); + }, + base::Unretained(static_cast<blink::MockWebRtcVideoTrack*>( + webrtc_video_track_.get())), + base::Unretained(&waitable_event))); + waitable_event.Wait(); + } + + const blink::WebMediaStreamSource& webkit_source() const { + return web_source_; + } + + private: + void OnTrackStarted(blink::WebPlatformMediaStreamSource* source, + blink::mojom::MediaStreamRequestResult result, + const blink::WebString& result_name) { + ASSERT_EQ(source, remote_source_); + if (result == blink::mojom::MediaStreamRequestResult::OK) + ++number_of_successful_track_starts_; + else + ++number_of_failed_track_starts_; + } + + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; + std::unique_ptr<blink::MockPeerConnectionDependencyFactory> mock_factory_; + scoped_refptr<webrtc::VideoTrackInterface> webrtc_video_track_; + // |remote_source_| is owned by |web_source_|. + MediaStreamRemoteVideoSourceUnderTest* remote_source_; + blink::WebMediaStreamSource web_source_; + int number_of_successful_track_starts_; + int number_of_failed_track_starts_; +}; + +TEST_F(MediaStreamRemoteVideoSourceTest, StartTrack) { + std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack()); + EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks()); + + blink::MockMediaStreamVideoSink sink; + track->AddSink(&sink, sink.GetDeliverFrameCB(), false); + base::RunLoop run_loop; + base::Closure quit_closure = run_loop.QuitClosure(); + EXPECT_CALL(sink, OnVideoFrame()) + .WillOnce(RunClosure(std::move(quit_closure))); + rtc::scoped_refptr<webrtc::I420Buffer> buffer( + new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240)); + + webrtc::I420Buffer::SetBlack(buffer); + + source()->SinkInterfaceForTesting()->OnFrame( + webrtc::VideoFrame::Builder() + .set_video_frame_buffer(buffer) + .set_rotation(webrtc::kVideoRotation_0) + .set_timestamp_us(1000) + .build()); + run_loop.Run(); + + EXPECT_EQ(1, sink.number_of_frames()); + track->RemoveSink(&sink); +} + +TEST_F(MediaStreamRemoteVideoSourceTest, RemoteTrackStop) { + std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack()); + + blink::MockMediaStreamVideoSink sink; + track->AddSink(&sink, sink.GetDeliverFrameCB(), false); + EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive, sink.state()); + EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive, + webkit_source().GetReadyState()); + StopWebRtcTrack(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded, + webkit_source().GetReadyState()); + EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded, sink.state()); + + track->RemoveSink(&sink); +} + +TEST_F(MediaStreamRemoteVideoSourceTest, PreservesColorSpace) { + std::unique_ptr<blink::MediaStreamVideoTrack> track(CreateTrack()); + blink::MockMediaStreamVideoSink sink; + track->AddSink(&sink, sink.GetDeliverFrameCB(), false); + + base::RunLoop run_loop; + EXPECT_CALL(sink, OnVideoFrame()) + .WillOnce(RunClosure(run_loop.QuitClosure())); + rtc::scoped_refptr<webrtc::I420Buffer> buffer( + new rtc::RefCountedObject<webrtc::I420Buffer>(320, 240)); + webrtc::ColorSpace kColorSpace(webrtc::ColorSpace::PrimaryID::kSMPTE240M, + webrtc::ColorSpace::TransferID::kSMPTE240M, + webrtc::ColorSpace::MatrixID::kSMPTE240M, + webrtc::ColorSpace::RangeID::kLimited); + const webrtc::VideoFrame& input_frame = + webrtc::VideoFrame::Builder() + .set_video_frame_buffer(buffer) + .set_timestamp_ms(0) + .set_rotation(webrtc::kVideoRotation_0) + .set_color_space(kColorSpace) + .build(); + source()->SinkInterfaceForTesting()->OnFrame(input_frame); + run_loop.Run(); + + EXPECT_EQ(1, sink.number_of_frames()); + scoped_refptr<media::VideoFrame> output_frame = sink.last_frame(); + EXPECT_TRUE(output_frame); + EXPECT_TRUE(output_frame->ColorSpace() == + gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTE240M, + gfx::ColorSpace::TransferID::SMPTE240M, + gfx::ColorSpace::MatrixID::SMPTE240M, + gfx::ColorSpace::RangeID::LIMITED)); + track->RemoveSink(&sink); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc new file mode 100644 index 00000000000..729d72c5465 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc @@ -0,0 +1,314 @@ +// Copyright 2014 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 "third_party/blink/public/web/modules/peerconnection/media_stream_video_webrtc_sink.h" + +#include <algorithm> +#include <memory> + +#include "base/bind.h" +#include "base/location.h" +#include "base/numerics/safe_conversions.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/lock.h" +#include "base/timer/timer.h" +#include "media/base/limits.h" +#include "third_party/blink/public/platform/modules/peerconnection/webrtc_video_track_source.h" +#include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h" +#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" +#include "third_party/blink/public/web/modules/mediastream/web_media_stream_utils.h" +#include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h" +#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" +#include "third_party/webrtc/api/video_track_source_proxy.h" + +namespace blink { + +namespace { + +absl::optional<bool> ToAbslOptionalBool(const base::Optional<bool>& value) { + return value ? absl::optional<bool>(*value) : absl::nullopt; +} + +} // namespace + +namespace { + +// The default number of microseconds that should elapse since the last video +// frame was received, before requesting a refresh frame. +const int64_t kDefaultRefreshIntervalMicros = + base::Time::kMicrosecondsPerSecond; + +// A lower-bound for the refresh interval. +const int64_t kLowerBoundRefreshIntervalMicros = + base::Time::kMicrosecondsPerSecond / media::limits::kMaxFramesPerSecond; + +webrtc::VideoTrackInterface::ContentHint ContentHintTypeToWebRtcContentHint( + WebMediaStreamTrack::ContentHintType content_hint) { + switch (content_hint) { + case WebMediaStreamTrack::ContentHintType::kNone: + return webrtc::VideoTrackInterface::ContentHint::kNone; + case WebMediaStreamTrack::ContentHintType::kAudioSpeech: + case WebMediaStreamTrack::ContentHintType::kAudioMusic: + NOTREACHED(); + break; + case WebMediaStreamTrack::ContentHintType::kVideoMotion: + return webrtc::VideoTrackInterface::ContentHint::kFluid; + case WebMediaStreamTrack::ContentHintType::kVideoDetail: + return webrtc::VideoTrackInterface::ContentHint::kDetailed; + case WebMediaStreamTrack::ContentHintType::kVideoText: + return webrtc::VideoTrackInterface::ContentHint::kText; + } + NOTREACHED(); + return webrtc::VideoTrackInterface::ContentHint::kNone; +} + +} // namespace + +// Simple help class used for receiving video frames on the IO-thread from a +// MediaStreamVideoTrack and forward the frames to a WebRtcVideoCapturerAdapter +// on libjingle's worker thread. WebRtcVideoCapturerAdapter implements a video +// capturer for libjingle. +class MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter + : public WTF::ThreadSafeRefCounted<WebRtcVideoSourceAdapter> { + public: + WebRtcVideoSourceAdapter( + const scoped_refptr<base::SingleThreadTaskRunner>& + libjingle_worker_thread, + const scoped_refptr<WebRtcVideoTrackSource>& source, + base::TimeDelta refresh_interval, + const base::RepeatingClosure& refresh_callback, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + // MediaStreamVideoWebRtcSink can be destroyed on the main render thread or + // libjingles worker thread since it posts video frames on that thread. But + // |video_source_| must be released on the main render thread before the + // PeerConnectionFactory has been destroyed. The only way to ensure that is to + // make sure |video_source_| is released when MediaStreamVideoWebRtcSink() is + // destroyed. + void ReleaseSourceOnMainThread(); + + void OnVideoFrameOnIO(scoped_refptr<media::VideoFrame> frame, + base::TimeTicks estimated_capture_time); + + private: + friend class WTF::ThreadSafeRefCounted<WebRtcVideoSourceAdapter>; + + void OnVideoFrameOnWorkerThread(scoped_refptr<media::VideoFrame> frame); + + virtual ~WebRtcVideoSourceAdapter(); + + // Called whenever a video frame was just delivered on the IO thread. This + // restarts the delay period before the |refresh_timer_| will fire the next + // time. + void ResetRefreshTimerOnMainThread(); + + scoped_refptr<base::SingleThreadTaskRunner> render_task_runner_; + + // |render_thread_checker_| is bound to the main render thread. + THREAD_CHECKER(render_thread_checker_); + // Used to DCHECK that frames are called on the IO-thread. + THREAD_CHECKER(io_thread_checker_); + + // Used for posting frames to libjingle's worker thread. Accessed on the + // IO-thread. + scoped_refptr<base::SingleThreadTaskRunner> libjingle_worker_thread_; + + scoped_refptr<WebRtcVideoTrackSource> video_source_; + + // Used to protect |video_source_|. It is taken by libjingle's worker + // thread for each video frame that is delivered but only taken on the + // main render thread in ReleaseSourceOnMainThread() when + // the owning MediaStreamVideoWebRtcSink is being destroyed. + base::Lock video_source_stop_lock_; + + // Requests a refresh frame at regular intervals. The delay on this timer is + // reset each time a frame is received so that it will not fire for at least + // an additional period. This means refresh frames will only be requested when + // the source has halted delivery (e.g., a screen capturer stops sending + // frames because the screen is not being updated). + // + // This mechanism solves a number of problems. First, it will ensure that + // remote clients that join a distributed session receive a first video frame + // in a timely manner. Second, it will allow WebRTC's internal bandwidth + // estimation logic to maintain a more optimal state, since sending a video + // frame will "prime it." Third, it allows lossy encoders to clean up + // artifacts in a still image. http://crbug.com/486274 + base::RepeatingTimer refresh_timer_; +}; + +MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter( + const scoped_refptr<base::SingleThreadTaskRunner>& libjingle_worker_thread, + const scoped_refptr<WebRtcVideoTrackSource>& source, + base::TimeDelta refresh_interval, + const base::RepeatingClosure& refresh_callback, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : render_task_runner_(std::move(task_runner)), + libjingle_worker_thread_(libjingle_worker_thread), + video_source_(source) { + DCHECK(render_task_runner_->RunsTasksInCurrentSequence()); + DETACH_FROM_THREAD(io_thread_checker_); + if (!refresh_interval.is_zero()) { + VLOG(1) << "Starting frame refresh timer with interval " + << refresh_interval.InMillisecondsF() << " ms."; + refresh_timer_.Start(FROM_HERE, refresh_interval, refresh_callback); + } +} + +MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter:: + ~WebRtcVideoSourceAdapter() { + DVLOG(3) << "~WebRtcVideoSourceAdapter()"; + DCHECK(!video_source_); + // This object can be destroyed on the main render thread or libjingles worker + // thread since it posts video frames on that thread. But |video_source_| must + // be released on the main render thread before the PeerConnectionFactory has + // been destroyed. The only way to ensure that is to make sure |video_source_| + // is released when MediaStreamVideoWebRtcSink() is destroyed. +} + +void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter:: + ResetRefreshTimerOnMainThread() { + DCHECK_CALLED_ON_VALID_THREAD(render_thread_checker_); + if (refresh_timer_.IsRunning()) + refresh_timer_.Reset(); +} + +void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter:: + ReleaseSourceOnMainThread() { + DCHECK_CALLED_ON_VALID_THREAD(render_thread_checker_); + // Since frames are posted to the worker thread, this object might be deleted + // on that thread. However, since |video_source_| was created on the render + // thread, it should be released on the render thread. + base::AutoLock auto_lock(video_source_stop_lock_); + video_source_ = nullptr; +} + +void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::OnVideoFrameOnIO( + scoped_refptr<media::VideoFrame> frame, + base::TimeTicks estimated_capture_time) { + DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); + render_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&WebRtcVideoSourceAdapter::ResetRefreshTimerOnMainThread, + this)); + libjingle_worker_thread_->PostTask( + FROM_HERE, + base::BindOnce(&WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread, + this, std::move(frame))); +} + +void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter:: + OnVideoFrameOnWorkerThread(scoped_refptr<media::VideoFrame> frame) { + DCHECK(libjingle_worker_thread_->BelongsToCurrentThread()); + base::AutoLock auto_lock(video_source_stop_lock_); + if (video_source_) + video_source_->OnFrameCaptured(std::move(frame)); +} + +MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink( + const WebMediaStreamTrack& track, + PeerConnectionDependencyFactory* factory, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + MediaStreamVideoTrack* video_track = + MediaStreamVideoTrack::GetVideoTrack(track); + DCHECK(video_track); + + absl::optional<bool> needs_denoising = + ToAbslOptionalBool(video_track->noise_reduction()); + + bool is_screencast = video_track->is_screencast(); + base::Optional<double> min_frame_rate = video_track->min_frame_rate(); + base::Optional<double> max_frame_rate = video_track->max_frame_rate(); + + // Enable automatic frame refreshes for the screen capture sources, which will + // stop producing frames whenever screen content is not changing. Check the + // frameRate constraint to determine the rate of refreshes. If a minimum + // frameRate is provided, use that. Otherwise, use the maximum frameRate if it + // happens to be less than the default. + base::TimeDelta refresh_interval = base::TimeDelta::FromMicroseconds(0); + if (is_screencast) { + // Start with the default refresh interval, and refine based on constraints. + refresh_interval = + base::TimeDelta::FromMicroseconds(kDefaultRefreshIntervalMicros); + if (min_frame_rate.has_value()) { + refresh_interval = + base::TimeDelta::FromMicroseconds(base::saturated_cast<int64_t>( + base::Time::kMicrosecondsPerSecond / *min_frame_rate)); + } + if (max_frame_rate.has_value()) { + const base::TimeDelta alternate_refresh_interval = + base::TimeDelta::FromMicroseconds(base::saturated_cast<int64_t>( + base::Time::kMicrosecondsPerSecond / *max_frame_rate)); + refresh_interval = std::max(refresh_interval, alternate_refresh_interval); + } + if (refresh_interval.InMicroseconds() < kLowerBoundRefreshIntervalMicros) { + refresh_interval = + base::TimeDelta::FromMicroseconds(kLowerBoundRefreshIntervalMicros); + } + } + + // TODO(pbos): Consolidate WebRtcVideoCapturerAdapter into WebRtcVideoSource + // by removing the need for and dependency on a cricket::VideoCapturer. + video_source_ = scoped_refptr<WebRtcVideoTrackSource>( + new rtc::RefCountedObject<WebRtcVideoTrackSource>(is_screencast, + needs_denoising)); + + // TODO(pbos): Consolidate the local video track with the source proxy and + // move into PeerConnectionDependencyFactory. This now separately holds on a + // reference to the proxy object because + // PeerConnectionFactory::CreateVideoTrack doesn't do reference counting. + video_source_proxy_ = + factory->CreateVideoTrackSourceProxy(video_source_.get()); + video_track_ = factory->CreateLocalVideoTrack(track.Id().Utf8(), + video_source_proxy_.get()); + + video_track_->set_content_hint( + ContentHintTypeToWebRtcContentHint(track.ContentHint())); + video_track_->set_enabled(track.IsEnabled()); + + source_adapter_ = base::MakeRefCounted<WebRtcVideoSourceAdapter>( + factory->GetWebRtcWorkerThread(), video_source_.get(), refresh_interval, + base::Bind(&MediaStreamVideoWebRtcSink::RequestRefreshFrame, + weak_factory_.GetWeakPtr()), + std::move(task_runner)); + + MediaStreamVideoSink::ConnectToTrack( + track, + base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, source_adapter_), + false); + + DVLOG(3) << "MediaStreamVideoWebRtcSink ctor() : is_screencast " + << is_screencast; +} + +MediaStreamVideoWebRtcSink::~MediaStreamVideoWebRtcSink() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DVLOG(3) << "MediaStreamVideoWebRtcSink dtor()."; + weak_factory_.InvalidateWeakPtrs(); + MediaStreamVideoSink::DisconnectFromTrack(); + source_adapter_->ReleaseSourceOnMainThread(); +} + +void MediaStreamVideoWebRtcSink::OnEnabledChanged(bool enabled) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + video_track_->set_enabled(enabled); +} + +void MediaStreamVideoWebRtcSink::OnContentHintChanged( + WebMediaStreamTrack::ContentHintType content_hint) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + video_track_->set_content_hint( + ContentHintTypeToWebRtcContentHint(content_hint)); +} + +void MediaStreamVideoWebRtcSink::RequestRefreshFrame() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + RequestRefreshFrameFromVideoTrack(connected_track()); +} + +absl::optional<bool> +MediaStreamVideoWebRtcSink::SourceNeedsDenoisingForTesting() const { + return video_source_->needs_denoising(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink_test.cc new file mode 100644 index 00000000000..9e3d3bdf7f1 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink_test.cc @@ -0,0 +1,59 @@ +// Copyright 2016 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 "third_party/blink/public/web/modules/peerconnection/media_stream_video_webrtc_sink.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" +#include "third_party/blink/public/web/modules/mediastream/mock_media_stream_registry.h" +#include "third_party/blink/public/web/modules/mediastream/video_track_adapter_settings.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_dependency_factory.h" +#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" + +namespace blink { + +class MediaStreamVideoWebRtcSinkTest : public ::testing::Test { + public: + void SetVideoTrack() { + registry_.Init(); + registry_.AddVideoTrack("test video track"); + blink::WebVector<blink::WebMediaStreamTrack> video_tracks = + registry_.test_stream().VideoTracks(); + track_ = video_tracks[0]; + // TODO(hta): Verify that track_ is valid. When constraints produce + // no valid format, using the track will cause a crash. + } + + void SetVideoTrack(const base::Optional<bool>& noise_reduction) { + registry_.Init(); + registry_.AddVideoTrack("test video track", + blink::VideoTrackAdapterSettings(), noise_reduction, + false, 0.0); + blink::WebVector<blink::WebMediaStreamTrack> video_tracks = + registry_.test_stream().VideoTracks(); + track_ = video_tracks[0]; + // TODO(hta): Verify that track_ is valid. When constraints produce + // no valid format, using the track will cause a crash. + } + + protected: + blink::WebMediaStreamTrack track_; + blink::MockPeerConnectionDependencyFactory dependency_factory_; + + private: + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; + + blink::MockMediaStreamRegistry registry_; +}; + +TEST_F(MediaStreamVideoWebRtcSinkTest, NoiseReductionDefaultsToNotSet) { + SetVideoTrack(); + blink::MediaStreamVideoWebRtcSink my_sink( + track_, &dependency_factory_, + blink::scheduler::GetSingleThreadTaskRunnerForTesting()); + EXPECT_TRUE(my_sink.webrtc_video_track()); + EXPECT_FALSE(my_sink.SourceNeedsDenoisingForTesting()); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_data_channel_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_data_channel_impl.cc new file mode 100644 index 00000000000..45ccb313a70 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_data_channel_impl.cc @@ -0,0 +1,98 @@ +// Copyright 2014 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 "third_party/blink/public/web/modules/peerconnection/mock_data_channel_impl.h" + +#include "base/logging.h" + +namespace blink { + +MockDataChannel::MockDataChannel(const std::string& label, + const webrtc::DataChannelInit* config) + : label_(label), + reliable_(config->reliable), + state_(webrtc::DataChannelInterface::kConnecting), + config_(*config), + observer_(nullptr) {} + +MockDataChannel::~MockDataChannel() {} + +void MockDataChannel::RegisterObserver(webrtc::DataChannelObserver* observer) { + observer_ = observer; +} + +void MockDataChannel::UnregisterObserver() { + observer_ = nullptr; +} + +std::string MockDataChannel::label() const { + return label_; +} + +bool MockDataChannel::reliable() const { + return reliable_; +} + +bool MockDataChannel::ordered() const { + return config_.ordered; +} + +std::string MockDataChannel::protocol() const { + return config_.protocol; +} + +bool MockDataChannel::negotiated() const { + return config_.negotiated; +} + +int MockDataChannel::id() const { + NOTIMPLEMENTED(); + return 0; +} + +MockDataChannel::DataState MockDataChannel::state() const { + return state_; +} + +uint32_t MockDataChannel::messages_sent() const { + NOTIMPLEMENTED(); + return 0; +} + +uint64_t MockDataChannel::bytes_sent() const { + NOTIMPLEMENTED(); + return 0; +} + +uint32_t MockDataChannel::messages_received() const { + NOTIMPLEMENTED(); + return 0; +} + +uint64_t MockDataChannel::bytes_received() const { + NOTIMPLEMENTED(); + return 0; +} + +// For testing. +void MockDataChannel::changeState(DataState state) { + state_ = state; + if (observer_) + observer_->OnStateChange(); +} + +uint64_t MockDataChannel::buffered_amount() const { + NOTIMPLEMENTED(); + return 0; +} + +void MockDataChannel::Close() { + changeState(webrtc::DataChannelInterface::kClosing); +} + +bool MockDataChannel::Send(const webrtc::DataBuffer& buffer) { + return state_ == webrtc::DataChannelInterface::kOpen; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc new file mode 100644 index 00000000000..61cfc6289cd --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.cc @@ -0,0 +1,391 @@ +// Copyright 2014 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 "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_dependency_factory.h" + +#include <stddef.h> + +#include "base/single_thread_task_runner.h" +#include "third_party/blink/public/platform/web_media_stream_track.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_impl.h" +#include "third_party/webrtc/api/media_stream_interface.h" +#include "third_party/webrtc/api/scoped_refptr.h" + +using webrtc::AudioSourceInterface; +using webrtc::AudioTrackInterface; +using webrtc::AudioTrackVector; +using webrtc::IceCandidateCollection; +using webrtc::IceCandidateInterface; +using webrtc::MediaStreamInterface; +using webrtc::ObserverInterface; +using webrtc::SessionDescriptionInterface; +using webrtc::VideoTrackInterface; +using webrtc::VideoTrackSourceInterface; +using webrtc::VideoTrackVector; + +namespace blink { + +template <class V> +static typename V::iterator FindTrack(V* vector, const std::string& track_id) { + auto it = vector->begin(); + for (; it != vector->end(); ++it) { + if ((*it)->id() == track_id) { + break; + } + } + return it; +} + +MockWebRtcAudioSource::MockWebRtcAudioSource(bool is_remote) + : is_remote_(is_remote) {} +void MockWebRtcAudioSource::RegisterObserver(ObserverInterface* observer) {} +void MockWebRtcAudioSource::UnregisterObserver(ObserverInterface* observer) {} + +MockWebRtcAudioSource::SourceState MockWebRtcAudioSource::state() const { + return SourceState::kLive; +} + +bool MockWebRtcAudioSource::remote() const { + return is_remote_; +} + +MockMediaStream::MockMediaStream(const std::string& id) : id_(id) {} + +bool MockMediaStream::AddTrack(AudioTrackInterface* track) { + audio_track_vector_.push_back(track); + NotifyObservers(); + return true; +} + +bool MockMediaStream::AddTrack(VideoTrackInterface* track) { + video_track_vector_.push_back(track); + NotifyObservers(); + return true; +} + +bool MockMediaStream::RemoveTrack(AudioTrackInterface* track) { + auto it = FindTrack(&audio_track_vector_, track->id()); + if (it == audio_track_vector_.end()) + return false; + audio_track_vector_.erase(it); + NotifyObservers(); + return true; +} + +bool MockMediaStream::RemoveTrack(VideoTrackInterface* track) { + auto it = FindTrack(&video_track_vector_, track->id()); + if (it == video_track_vector_.end()) + return false; + video_track_vector_.erase(it); + NotifyObservers(); + return true; +} + +std::string MockMediaStream::id() const { + return id_; +} + +AudioTrackVector MockMediaStream::GetAudioTracks() { + return audio_track_vector_; +} + +VideoTrackVector MockMediaStream::GetVideoTracks() { + return video_track_vector_; +} + +rtc::scoped_refptr<AudioTrackInterface> MockMediaStream::FindAudioTrack( + const std::string& track_id) { + auto it = FindTrack(&audio_track_vector_, track_id); + return it == audio_track_vector_.end() ? nullptr : *it; +} + +rtc::scoped_refptr<VideoTrackInterface> MockMediaStream::FindVideoTrack( + const std::string& track_id) { + auto it = FindTrack(&video_track_vector_, track_id); + return it == video_track_vector_.end() ? nullptr : *it; +} + +void MockMediaStream::RegisterObserver(ObserverInterface* observer) { + DCHECK(observers_.find(observer) == observers_.end()); + observers_.insert(observer); +} + +void MockMediaStream::UnregisterObserver(ObserverInterface* observer) { + auto it = observers_.find(observer); + DCHECK(it != observers_.end()); + observers_.erase(it); +} + +void MockMediaStream::NotifyObservers() { + for (auto it = observers_.begin(); it != observers_.end(); ++it) { + (*it)->OnChanged(); + } +} + +MockMediaStream::~MockMediaStream() {} + +scoped_refptr<MockWebRtcAudioTrack> MockWebRtcAudioTrack::Create( + const std::string& id) { + return new rtc::RefCountedObject<MockWebRtcAudioTrack>(id); +} + +MockWebRtcAudioTrack::MockWebRtcAudioTrack(const std::string& id) + : id_(id), + source_(new rtc::RefCountedObject<MockWebRtcAudioSource>(true)), + enabled_(true), + state_(webrtc::MediaStreamTrackInterface::kLive) {} + +MockWebRtcAudioTrack::~MockWebRtcAudioTrack() {} + +std::string MockWebRtcAudioTrack::kind() const { + return kAudioKind; +} + +webrtc::AudioSourceInterface* MockWebRtcAudioTrack::GetSource() const { + return source_.get(); +} + +std::string MockWebRtcAudioTrack::id() const { + return id_; +} + +bool MockWebRtcAudioTrack::enabled() const { + return enabled_; +} + +MockWebRtcVideoTrack::TrackState MockWebRtcAudioTrack::state() const { + return state_; +} + +bool MockWebRtcAudioTrack::set_enabled(bool enable) { + enabled_ = enable; + return true; +} + +void MockWebRtcAudioTrack::RegisterObserver(ObserverInterface* observer) { + DCHECK(observers_.find(observer) == observers_.end()); + observers_.insert(observer); +} + +void MockWebRtcAudioTrack::UnregisterObserver(ObserverInterface* observer) { + DCHECK(observers_.find(observer) != observers_.end()); + observers_.erase(observer); +} + +void MockWebRtcAudioTrack::SetEnded() { + DCHECK_EQ(webrtc::MediaStreamTrackInterface::kLive, state_); + state_ = webrtc::MediaStreamTrackInterface::kEnded; + for (auto* o : observers_) + o->OnChanged(); +} + +MockWebRtcVideoTrack::MockWebRtcVideoTrack( + const std::string& id, + webrtc::VideoTrackSourceInterface* source) + : id_(id), + source_(source), + enabled_(true), + state_(webrtc::MediaStreamTrackInterface::kLive), + sink_(nullptr) {} + +MockWebRtcVideoTrack::~MockWebRtcVideoTrack() {} + +scoped_refptr<MockWebRtcVideoTrack> MockWebRtcVideoTrack::Create( + const std::string& id) { + return new rtc::RefCountedObject<MockWebRtcVideoTrack>(id, nullptr); +} + +void MockWebRtcVideoTrack::AddOrUpdateSink( + rtc::VideoSinkInterface<webrtc::VideoFrame>* sink, + const rtc::VideoSinkWants& wants) { + DCHECK(!sink_); + sink_ = sink; +} + +void MockWebRtcVideoTrack::RemoveSink( + rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) { + DCHECK(sink_ == sink); + sink_ = nullptr; +} + +VideoTrackSourceInterface* MockWebRtcVideoTrack::GetSource() const { + return source_.get(); +} + +std::string MockWebRtcVideoTrack::kind() const { + return kVideoKind; +} + +std::string MockWebRtcVideoTrack::id() const { + return id_; +} + +bool MockWebRtcVideoTrack::enabled() const { + return enabled_; +} + +MockWebRtcVideoTrack::TrackState MockWebRtcVideoTrack::state() const { + return state_; +} + +bool MockWebRtcVideoTrack::set_enabled(bool enable) { + enabled_ = enable; + return true; +} + +void MockWebRtcVideoTrack::RegisterObserver(ObserverInterface* observer) { + DCHECK(observers_.find(observer) == observers_.end()); + observers_.insert(observer); +} + +void MockWebRtcVideoTrack::UnregisterObserver(ObserverInterface* observer) { + DCHECK(observers_.find(observer) != observers_.end()); + observers_.erase(observer); +} + +void MockWebRtcVideoTrack::SetEnded() { + DCHECK_EQ(webrtc::MediaStreamTrackInterface::kLive, state_); + state_ = webrtc::MediaStreamTrackInterface::kEnded; + for (auto* o : observers_) + o->OnChanged(); +} + +class MockSessionDescription : public SessionDescriptionInterface { + public: + MockSessionDescription(const std::string& type, const std::string& sdp) + : type_(type), sdp_(sdp) {} + ~MockSessionDescription() override {} + cricket::SessionDescription* description() override { + NOTIMPLEMENTED(); + return nullptr; + } + const cricket::SessionDescription* description() const override { + NOTIMPLEMENTED(); + return nullptr; + } + std::string session_id() const override { + NOTIMPLEMENTED(); + return std::string(); + } + std::string session_version() const override { + NOTIMPLEMENTED(); + return std::string(); + } + std::string type() const override { return type_; } + bool AddCandidate(const IceCandidateInterface* candidate) override { + NOTIMPLEMENTED(); + return false; + } + size_t number_of_mediasections() const override { + NOTIMPLEMENTED(); + return 0; + } + const IceCandidateCollection* candidates( + size_t mediasection_index) const override { + NOTIMPLEMENTED(); + return nullptr; + } + + bool ToString(std::string* out) const override { + *out = sdp_; + return true; + } + + private: + std::string type_; + std::string sdp_; +}; + +class MockIceCandidate : public IceCandidateInterface { + public: + MockIceCandidate(const std::string& sdp_mid, + int sdp_mline_index, + const std::string& sdp) + : sdp_mid_(sdp_mid), sdp_mline_index_(sdp_mline_index), sdp_(sdp) { + // Assign an valid address to |candidate_| to pass assert in code. + candidate_.set_address(rtc::SocketAddress("127.0.0.1", 5000)); + } + ~MockIceCandidate() override {} + std::string sdp_mid() const override { return sdp_mid_; } + int sdp_mline_index() const override { return sdp_mline_index_; } + const cricket::Candidate& candidate() const override { return candidate_; } + bool ToString(std::string* out) const override { + *out = sdp_; + return true; + } + + private: + std::string sdp_mid_; + int sdp_mline_index_; + std::string sdp_; + cricket::Candidate candidate_; +}; + +MockPeerConnectionDependencyFactory::MockPeerConnectionDependencyFactory() + : blink::PeerConnectionDependencyFactory( + /*create_p2p_socket_dispatcher =*/false), + signaling_thread_("MockPCFactory WebRtc Signaling Thread") { + EnsureWebRtcAudioDeviceImpl(); + CHECK(signaling_thread_.Start()); +} + +MockPeerConnectionDependencyFactory::~MockPeerConnectionDependencyFactory() {} + +scoped_refptr<webrtc::PeerConnectionInterface> +MockPeerConnectionDependencyFactory::CreatePeerConnection( + const webrtc::PeerConnectionInterface::RTCConfiguration& config, + blink::WebLocalFrame* frame, + webrtc::PeerConnectionObserver* observer) { + return new rtc::RefCountedObject<MockPeerConnectionImpl>(this, observer); +} + +scoped_refptr<webrtc::VideoTrackSourceInterface> +MockPeerConnectionDependencyFactory::CreateVideoTrackSourceProxy( + webrtc::VideoTrackSourceInterface* source) { + return nullptr; +} +scoped_refptr<webrtc::MediaStreamInterface> +MockPeerConnectionDependencyFactory::CreateLocalMediaStream( + const std::string& label) { + return new rtc::RefCountedObject<MockMediaStream>(label); +} + +scoped_refptr<webrtc::VideoTrackInterface> +MockPeerConnectionDependencyFactory::CreateLocalVideoTrack( + const std::string& id, + webrtc::VideoTrackSourceInterface* source) { + scoped_refptr<webrtc::VideoTrackInterface> track( + new rtc::RefCountedObject<MockWebRtcVideoTrack>(id, source)); + return track; +} + +SessionDescriptionInterface* +MockPeerConnectionDependencyFactory::CreateSessionDescription( + const std::string& type, + const std::string& sdp, + webrtc::SdpParseError* error) { + if (fail_to_create_session_description_) + return nullptr; + return new MockSessionDescription(type, sdp); +} + +webrtc::IceCandidateInterface* +MockPeerConnectionDependencyFactory::CreateIceCandidate( + const std::string& sdp_mid, + int sdp_mline_index, + const std::string& sdp) { + return new MockIceCandidate(sdp_mid, sdp_mline_index, sdp); +} + +scoped_refptr<base::SingleThreadTaskRunner> +MockPeerConnectionDependencyFactory::GetWebRtcSignalingTaskRunner() { + return signaling_thread_.task_runner(); +} + +void MockPeerConnectionDependencyFactory::SetFailToCreateSessionDescription( + bool fail) { + fail_to_create_session_description_ = fail; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc new file mode 100644 index 00000000000..ad7a995d010 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.cc @@ -0,0 +1,532 @@ +// 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. + +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_impl.h" + +#include <stddef.h> + +#include <utility> +#include <vector> + +#include "base/logging.h" +#include "base/stl_util.h" +#include "third_party/blink/public/platform/modules/peerconnection/webrtc_util.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_data_channel_impl.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_dependency_factory.h" +#include "third_party/webrtc/api/rtp_receiver_interface.h" +#include "third_party/webrtc/rtc_base/ref_counted_object.h" + +using testing::_; +using webrtc::AudioTrackInterface; +using webrtc::CreateSessionDescriptionObserver; +using webrtc::DtmfSenderInterface; +using webrtc::DtmfSenderObserverInterface; +using webrtc::IceCandidateInterface; +using webrtc::MediaStreamInterface; +using webrtc::PeerConnectionInterface; +using webrtc::SessionDescriptionInterface; +using webrtc::SetSessionDescriptionObserver; + +namespace blink { + +class MockStreamCollection : public webrtc::StreamCollectionInterface { + public: + size_t count() override { return streams_.size(); } + MediaStreamInterface* at(size_t index) override { return streams_[index]; } + MediaStreamInterface* find(const std::string& id) override { + for (size_t i = 0; i < streams_.size(); ++i) { + if (streams_[i]->id() == id) + return streams_[i]; + } + return nullptr; + } + webrtc::MediaStreamTrackInterface* FindAudioTrack( + const std::string& id) override { + for (size_t i = 0; i < streams_.size(); ++i) { + webrtc::MediaStreamTrackInterface* track = + streams_.at(i)->FindAudioTrack(id); + if (track) + return track; + } + return nullptr; + } + webrtc::MediaStreamTrackInterface* FindVideoTrack( + const std::string& id) override { + for (size_t i = 0; i < streams_.size(); ++i) { + webrtc::MediaStreamTrackInterface* track = + streams_.at(i)->FindVideoTrack(id); + if (track) + return track; + } + return nullptr; + } + void AddStream(MediaStreamInterface* stream) { streams_.push_back(stream); } + void RemoveStream(MediaStreamInterface* stream) { + auto it = streams_.begin(); + for (; it != streams_.end(); ++it) { + if (it->get() == stream) { + streams_.erase(it); + break; + } + } + } + + protected: + ~MockStreamCollection() override {} + + private: + typedef std::vector<rtc::scoped_refptr<MediaStreamInterface>> StreamVector; + StreamVector streams_; +}; + +class MockDtmfSender : public DtmfSenderInterface { + public: + void RegisterObserver(DtmfSenderObserverInterface* observer) override { + observer_ = observer; + } + void UnregisterObserver() override { observer_ = nullptr; } + bool CanInsertDtmf() override { return true; } + bool InsertDtmf(const std::string& tones, + int duration, + int inter_tone_gap) override { + tones_ = tones; + duration_ = duration; + inter_tone_gap_ = inter_tone_gap; + return true; + } + std::string tones() const override { return tones_; } + int duration() const override { return duration_; } + int inter_tone_gap() const override { return inter_tone_gap_; } + + private: + DtmfSenderObserverInterface* observer_ = nullptr; + std::string tones_; + int duration_ = 0; + int inter_tone_gap_ = 0; +}; + +FakeRtpSender::FakeRtpSender( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + std::vector<std::string> stream_ids) + : track_(std::move(track)), stream_ids_(std::move(stream_ids)) {} + +FakeRtpSender::~FakeRtpSender() {} + +bool FakeRtpSender::SetTrack(webrtc::MediaStreamTrackInterface* track) { + NOTIMPLEMENTED(); + return false; +} + +rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> FakeRtpSender::track() + const { + return track_; +} + +rtc::scoped_refptr<webrtc::DtlsTransportInterface> +FakeRtpSender::dtls_transport() const { + return transport_; +} + +uint32_t FakeRtpSender::ssrc() const { + NOTIMPLEMENTED(); + return 0; +} + +cricket::MediaType FakeRtpSender::media_type() const { + NOTIMPLEMENTED(); + return cricket::MEDIA_TYPE_AUDIO; +} + +std::string FakeRtpSender::id() const { + NOTIMPLEMENTED(); + return ""; +} + +std::vector<std::string> FakeRtpSender::stream_ids() const { + return stream_ids_; +} + +std::vector<webrtc::RtpEncodingParameters> FakeRtpSender::init_send_encodings() + const { + return {}; +} + +webrtc::RtpParameters FakeRtpSender::GetParameters() const { + NOTIMPLEMENTED(); + return webrtc::RtpParameters(); +} + +webrtc::RTCError FakeRtpSender::SetParameters( + const webrtc::RtpParameters& parameters) { + NOTIMPLEMENTED(); + return webrtc::RTCError::OK(); +} + +rtc::scoped_refptr<webrtc::DtmfSenderInterface> FakeRtpSender::GetDtmfSender() + const { + return new rtc::RefCountedObject<MockDtmfSender>(); +} + +FakeRtpReceiver::FakeRtpReceiver( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams) + : track_(std::move(track)), streams_(std::move(streams)) {} + +FakeRtpReceiver::~FakeRtpReceiver() {} + +rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> FakeRtpReceiver::track() + const { + return track_; +} + +rtc::scoped_refptr<webrtc::DtlsTransportInterface> +FakeRtpReceiver::dtls_transport() const { + return transport_; +} + +std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> +FakeRtpReceiver::streams() const { + return streams_; +} + +std::vector<std::string> FakeRtpReceiver::stream_ids() const { + std::vector<std::string> stream_ids; + for (const auto& stream : streams_) + stream_ids.push_back(stream->id()); + return stream_ids; +} + +cricket::MediaType FakeRtpReceiver::media_type() const { + NOTIMPLEMENTED(); + return cricket::MEDIA_TYPE_AUDIO; +} + +std::string FakeRtpReceiver::id() const { + NOTIMPLEMENTED(); + return ""; +} + +webrtc::RtpParameters FakeRtpReceiver::GetParameters() const { + NOTIMPLEMENTED(); + return webrtc::RtpParameters(); +} + +bool FakeRtpReceiver::SetParameters(const webrtc::RtpParameters& parameters) { + NOTIMPLEMENTED(); + return false; +} + +void FakeRtpReceiver::SetObserver( + webrtc::RtpReceiverObserverInterface* observer) { + NOTIMPLEMENTED(); +} + +void FakeRtpReceiver::SetJitterBufferMinimumDelay( + absl::optional<double> delay_seconds) { + NOTIMPLEMENTED(); +} + +std::vector<webrtc::RtpSource> FakeRtpReceiver::GetSources() const { + NOTIMPLEMENTED(); + return std::vector<webrtc::RtpSource>(); +} + +FakeRtpTransceiver::FakeRtpTransceiver( + cricket::MediaType media_type, + rtc::scoped_refptr<FakeRtpSender> sender, + rtc::scoped_refptr<FakeRtpReceiver> receiver, + base::Optional<std::string> mid, + bool stopped, + webrtc::RtpTransceiverDirection direction, + base::Optional<webrtc::RtpTransceiverDirection> current_direction) + : media_type_(media_type), + sender_(std::move(sender)), + receiver_(std::move(receiver)), + mid_(blink::ToAbslOptional(std::move(mid))), + stopped_(stopped), + direction_(direction), + current_direction_(blink::ToAbslOptional(current_direction)) {} + +FakeRtpTransceiver::~FakeRtpTransceiver() {} + +cricket::MediaType FakeRtpTransceiver::media_type() const { + return media_type_; +} + +absl::optional<std::string> FakeRtpTransceiver::mid() const { + return mid_; +} + +rtc::scoped_refptr<webrtc::RtpSenderInterface> FakeRtpTransceiver::sender() + const { + return sender_; +} + +rtc::scoped_refptr<webrtc::RtpReceiverInterface> FakeRtpTransceiver::receiver() + const { + return receiver_; +} + +bool FakeRtpTransceiver::stopped() const { + return stopped_; +} + +webrtc::RtpTransceiverDirection FakeRtpTransceiver::direction() const { + return direction_; +} + +void FakeRtpTransceiver::SetDirection( + webrtc::RtpTransceiverDirection new_direction) { + NOTIMPLEMENTED(); +} + +absl::optional<webrtc::RtpTransceiverDirection> +FakeRtpTransceiver::current_direction() const { + return current_direction_; +} + +void FakeRtpTransceiver::Stop() { + NOTIMPLEMENTED(); +} + +void FakeRtpTransceiver::SetTransport( + rtc::scoped_refptr<webrtc::DtlsTransportInterface> transport) { + sender_->SetTransport(transport); + receiver_->SetTransport(transport); +} + +FakeDtlsTransport::FakeDtlsTransport() {} + +rtc::scoped_refptr<webrtc::IceTransportInterface> +FakeDtlsTransport::ice_transport() { + return nullptr; +} + +webrtc::DtlsTransportInformation FakeDtlsTransport::Information() { + return webrtc::DtlsTransportInformation(webrtc::DtlsTransportState::kNew); +} + +const char MockPeerConnectionImpl::kDummyOffer[] = "dummy offer"; +const char MockPeerConnectionImpl::kDummyAnswer[] = "dummy answer"; + +MockPeerConnectionImpl::MockPeerConnectionImpl( + MockPeerConnectionDependencyFactory* factory, + webrtc::PeerConnectionObserver* observer) + : dependency_factory_(factory), + remote_streams_(new rtc::RefCountedObject<MockStreamCollection>), + hint_audio_(false), + hint_video_(false), + getstats_result_(true), + sdp_mline_index_(-1), + observer_(observer) { + ON_CALL(*this, SetLocalDescription(_, _)) + .WillByDefault(testing::Invoke( + this, &MockPeerConnectionImpl::SetLocalDescriptionWorker)); + // TODO(hbos): Remove once no longer mandatory to implement. + ON_CALL(*this, SetRemoteDescription(_, _)) + .WillByDefault(testing::Invoke( + this, &MockPeerConnectionImpl::SetRemoteDescriptionWorker)); + ON_CALL(*this, SetRemoteDescriptionForMock(_, _)) + .WillByDefault(testing::Invoke( + [this]( + std::unique_ptr<webrtc::SessionDescriptionInterface>* desc, + rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface>* + observer) { + SetRemoteDescriptionWorker(nullptr, desc->release()); + })); +} + +MockPeerConnectionImpl::~MockPeerConnectionImpl() {} + +webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> +MockPeerConnectionImpl::AddTrack( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + const std::vector<std::string>& stream_ids) { + DCHECK(track); + DCHECK_EQ(1u, stream_ids.size()); + for (const auto& sender : senders_) { + if (sender->track() == track) + return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER); + } + for (const auto& stream_id : stream_ids) { + if (!base::Contains(local_stream_ids_, stream_id)) { + stream_label_ = stream_id; + local_stream_ids_.push_back(stream_id); + } + } + auto* sender = new rtc::RefCountedObject<FakeRtpSender>(track, stream_ids); + senders_.push_back(sender); + return rtc::scoped_refptr<webrtc::RtpSenderInterface>(sender); +} + +bool MockPeerConnectionImpl::RemoveTrack(webrtc::RtpSenderInterface* s) { + rtc::scoped_refptr<FakeRtpSender> sender = static_cast<FakeRtpSender*>(s); + auto it = std::find(senders_.begin(), senders_.end(), sender); + if (it == senders_.end()) + return false; + senders_.erase(it); + auto track = sender->track(); + + for (const auto& stream_id : sender->stream_ids()) { + auto local_stream_it = std::find(local_stream_ids_.begin(), + local_stream_ids_.end(), stream_id); + if (local_stream_it != local_stream_ids_.end()) + local_stream_ids_.erase(local_stream_it); + } + return true; +} + +std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> +MockPeerConnectionImpl::GetSenders() const { + std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> senders; + for (const auto& sender : senders_) + senders.push_back(sender); + return senders; +} + +std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> +MockPeerConnectionImpl::GetReceivers() const { + std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> receivers; + for (size_t i = 0; i < remote_streams_->count(); ++i) { + for (const auto& audio_track : remote_streams_->at(i)->GetAudioTracks()) { + receivers.push_back( + new rtc::RefCountedObject<FakeRtpReceiver>(audio_track)); + } + for (const auto& video_track : remote_streams_->at(i)->GetVideoTracks()) { + receivers.push_back( + new rtc::RefCountedObject<FakeRtpReceiver>(video_track)); + } + } + return receivers; +} + +rtc::scoped_refptr<webrtc::DataChannelInterface> +MockPeerConnectionImpl::CreateDataChannel( + const std::string& label, + const webrtc::DataChannelInit* config) { + return new rtc::RefCountedObject<blink::MockDataChannel>(label, config); +} + +bool MockPeerConnectionImpl::GetStats(webrtc::StatsObserver* observer, + webrtc::MediaStreamTrackInterface* track, + StatsOutputLevel level) { + if (!getstats_result_) + return false; + + DCHECK_EQ(kStatsOutputLevelStandard, level); + webrtc::StatsReport report1(webrtc::StatsReport::NewTypedId( + webrtc::StatsReport::kStatsReportTypeSsrc, "1234")); + webrtc::StatsReport report2(webrtc::StatsReport::NewTypedId( + webrtc::StatsReport::kStatsReportTypeSession, "nontrack")); + report1.set_timestamp(42); + report1.AddString(webrtc::StatsReport::kStatsValueNameFingerprint, + "trackvalue"); + + webrtc::StatsReports reports; + reports.push_back(&report1); + + // If selector is given, we pass back one report. + // If selector is not given, we pass back two. + if (!track) { + report2.set_timestamp(44); + report2.AddString(webrtc::StatsReport::kStatsValueNameFingerprintAlgorithm, + "somevalue"); + reports.push_back(&report2); + } + + // Note that the callback is synchronous, not asynchronous; it will + // happen before the request call completes. + observer->OnComplete(reports); + + return true; +} + +void MockPeerConnectionImpl::GetStats( + webrtc::RTCStatsCollectorCallback* callback) { + DCHECK(callback); + DCHECK(stats_report_); + callback->OnStatsDelivered(stats_report_); +} + +void MockPeerConnectionImpl::GetStats( + rtc::scoped_refptr<webrtc::RtpSenderInterface> selector, + rtc::scoped_refptr<webrtc::RTCStatsCollectorCallback> callback) { + callback->OnStatsDelivered(stats_report_); +} + +void MockPeerConnectionImpl::GetStats( + rtc::scoped_refptr<webrtc::RtpReceiverInterface> selector, + rtc::scoped_refptr<webrtc::RTCStatsCollectorCallback> callback) { + callback->OnStatsDelivered(stats_report_); +} + +void MockPeerConnectionImpl::SetGetStatsReport(webrtc::RTCStatsReport* report) { + stats_report_ = report; +} + +const webrtc::SessionDescriptionInterface* +MockPeerConnectionImpl::local_description() const { + return local_desc_.get(); +} + +const webrtc::SessionDescriptionInterface* +MockPeerConnectionImpl::remote_description() const { + return remote_desc_.get(); +} + +void MockPeerConnectionImpl::AddRemoteStream(MediaStreamInterface* stream) { + remote_streams_->AddStream(stream); +} + +void MockPeerConnectionImpl::CreateOffer( + CreateSessionDescriptionObserver* observer, + const RTCOfferAnswerOptions& options) { + DCHECK(observer); + created_sessiondescription_.reset( + dependency_factory_->CreateSessionDescription("unknown", kDummyOffer, + nullptr)); +} + +void MockPeerConnectionImpl::CreateAnswer( + CreateSessionDescriptionObserver* observer, + const RTCOfferAnswerOptions& options) { + DCHECK(observer); + created_sessiondescription_.reset( + dependency_factory_->CreateSessionDescription("unknown", kDummyAnswer, + nullptr)); +} + +void MockPeerConnectionImpl::SetLocalDescriptionWorker( + SetSessionDescriptionObserver* observer, + SessionDescriptionInterface* desc) { + desc->ToString(&description_sdp_); + local_desc_.reset(desc); +} + +void MockPeerConnectionImpl::SetRemoteDescriptionWorker( + SetSessionDescriptionObserver* observer, + SessionDescriptionInterface* desc) { + desc->ToString(&description_sdp_); + remote_desc_.reset(desc); +} + +webrtc::RTCError MockPeerConnectionImpl::SetConfiguration( + const RTCConfiguration& configuration) { + return webrtc::RTCError(setconfiguration_error_type_); +} + +bool MockPeerConnectionImpl::AddIceCandidate( + const IceCandidateInterface* candidate) { + sdp_mid_ = candidate->sdp_mid(); + sdp_mline_index_ = candidate->sdp_mline_index(); + return candidate->ToString(&ice_sdp_); +} + +webrtc::RTCError MockPeerConnectionImpl::SetBitrate( + const webrtc::BitrateSettings& bitrate) { + NOTIMPLEMENTED(); + return webrtc::RTCError::OK(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.cc new file mode 100644 index 00000000000..81cfc282750 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.cc @@ -0,0 +1,52 @@ +// 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. +#include "third_party/blink/public/web/modules/peerconnection/mock_web_rtc_peer_connection_handler_client.h" + +#include "base/logging.h" +#include "third_party/blink/public/platform/web_media_stream.h" +#include "third_party/blink/public/platform/web_rtc_rtp_receiver.h" +#include "third_party/blink/public/platform/web_string.h" + +using testing::_; + +namespace blink { + +MockWebRTCPeerConnectionHandlerClient::MockWebRTCPeerConnectionHandlerClient() { + ON_CALL(*this, DidGenerateICECandidate(_)) + .WillByDefault( + testing::Invoke(this, &MockWebRTCPeerConnectionHandlerClient:: + didGenerateICECandidateWorker)); + ON_CALL(*this, DidAddReceiverPlanBForMock(_)) + .WillByDefault(testing::Invoke( + this, &MockWebRTCPeerConnectionHandlerClient::didAddReceiverWorker)); + ON_CALL(*this, DidRemoveReceiverPlanBForMock(_)) + .WillByDefault(testing::Invoke( + this, + &MockWebRTCPeerConnectionHandlerClient::didRemoveReceiverWorker)); +} + +MockWebRTCPeerConnectionHandlerClient:: + ~MockWebRTCPeerConnectionHandlerClient() {} + +void MockWebRTCPeerConnectionHandlerClient::didGenerateICECandidateWorker( + scoped_refptr<blink::WebRTCICECandidate> candidate) { + candidate_sdp_ = candidate->Candidate().Utf8(); + candidate_mline_index_ = candidate->SdpMLineIndex(); + candidate_mid_ = candidate->SdpMid().Utf8(); +} + +void MockWebRTCPeerConnectionHandlerClient::didAddReceiverWorker( + std::unique_ptr<blink::WebRTCRtpReceiver>* web_rtp_receiver) { + blink::WebVector<blink::WebString> stream_ids = + (*web_rtp_receiver)->StreamIds(); + DCHECK_EQ(1u, stream_ids.size()); + remote_stream_id_ = stream_ids[0]; +} + +void MockWebRTCPeerConnectionHandlerClient::didRemoveReceiverWorker( + std::unique_ptr<blink::WebRTCRtpReceiver>* web_rtp_receiver) { + remote_stream_id_ = blink::WebString(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc new file mode 100644 index 00000000000..6629b036989 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc @@ -0,0 +1,652 @@ +// Copyright 2014 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 "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h" + +#include <stddef.h> + +#include <memory> +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/synchronization/waitable_event.h" +#include "build/build_config.h" +#include "crypto/openssl_util.h" +#include "jingle/glue/thread_wrapper.h" +#include "media/base/media_permission.h" +#include "media/media_buildflags.h" +#include "media/video/gpu_video_accelerator_factories.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/peerconnection/webrtc_ip_handling_policy.h" +#include "third_party/blink/public/platform/modules/peerconnection/audio_codec_factory.h" +#include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/web_media_constraints.h" +#include "third_party/blink/public/platform/web_media_stream.h" +#include "third_party/blink/public/platform/web_media_stream_source.h" +#include "third_party/blink/public/platform/web_media_stream_track.h" +#include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h" +#include "third_party/blink/public/platform/web_url.h" +#include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h" +#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" +#include "third_party/blink/public/web/modules/webrtc/webrtc_audio_device_impl.h" +#include "third_party/blink/public/web/web_document.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/renderer/modules/p2p/port_allocator.h" +#include "third_party/blink/renderer/platform/p2p/empty_network_manager.h" +#include "third_party/blink/renderer/platform/p2p/filtering_network_manager.h" +#include "third_party/blink/renderer/platform/p2p/ipc_network_manager.h" +#include "third_party/blink/renderer/platform/p2p/ipc_socket_factory.h" +#include "third_party/blink/renderer/platform/p2p/mdns_responder_adapter.h" +#include "third_party/blink/renderer/platform/p2p/socket_dispatcher.h" +#include "third_party/blink/renderer/platform/peerconnection/stun_field_trial.h" +#include "third_party/blink/renderer/platform/peerconnection/video_codec_factory.h" +#include "third_party/webrtc/api/call/call_factory_interface.h" +#include "third_party/webrtc/api/peer_connection_interface.h" +#include "third_party/webrtc/api/rtc_event_log/rtc_event_log_factory.h" +#include "third_party/webrtc/api/video_track_source_proxy.h" +#include "third_party/webrtc/media/engine/fake_video_codec_factory.h" +#include "third_party/webrtc/media/engine/multiplex_codec_factory.h" +#include "third_party/webrtc/media/engine/webrtc_media_engine.h" +#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h" +#include "third_party/webrtc/modules/video_coding/codecs/h264/include/h264.h" +#include "third_party/webrtc/rtc_base/ref_counted_object.h" +#include "third_party/webrtc/rtc_base/ssl_adapter.h" +#include "third_party/webrtc_overrides/task_queue_factory.h" + +namespace blink { + +namespace { + +enum WebRTCIPHandlingPolicy { + DEFAULT, + DEFAULT_PUBLIC_AND_PRIVATE_INTERFACES, + DEFAULT_PUBLIC_INTERFACE_ONLY, + DISABLE_NON_PROXIED_UDP, +}; + +WebRTCIPHandlingPolicy GetWebRTCIPHandlingPolicy( + const std::string& preference) { + if (preference == blink::kWebRTCIPHandlingDefaultPublicAndPrivateInterfaces) + return DEFAULT_PUBLIC_AND_PRIVATE_INTERFACES; + if (preference == blink::kWebRTCIPHandlingDefaultPublicInterfaceOnly) + return DEFAULT_PUBLIC_INTERFACE_ONLY; + if (preference == blink::kWebRTCIPHandlingDisableNonProxiedUdp) + return DISABLE_NON_PROXIED_UDP; + return DEFAULT; +} + +bool IsValidPortRange(uint16_t min_port, uint16_t max_port) { + DCHECK(min_port <= max_port); + return min_port != 0 && max_port != 0; +} + +// PeerConnectionDependencies wants to own the factory, so we provide a simple +// object that delegates calls to the IpcPacketSocketFactory. +// TODO(zstein): Move the creation logic from IpcPacketSocketFactory in to this +// class. +class ProxyAsyncResolverFactory final : public webrtc::AsyncResolverFactory { + public: + ProxyAsyncResolverFactory(IpcPacketSocketFactory* ipc_psf) + : ipc_psf_(ipc_psf) { + DCHECK(ipc_psf); + } + + rtc::AsyncResolverInterface* Create() override { + return ipc_psf_->CreateAsyncResolver(); + } + + private: + IpcPacketSocketFactory* ipc_psf_; +}; + +} // namespace + +PeerConnectionDependencyFactory::PeerConnectionDependencyFactory( + bool create_p2p_socket_dispatcher) + : network_manager_(nullptr), + p2p_socket_dispatcher_( + create_p2p_socket_dispatcher ? new P2PSocketDispatcher() : nullptr), + signaling_thread_(nullptr), + worker_thread_(nullptr), + chrome_signaling_thread_("Chrome_libJingle_Signaling"), + chrome_worker_thread_("Chrome_libJingle_WorkerThread") { + TryScheduleStunProbeTrial(); +} + +PeerConnectionDependencyFactory::~PeerConnectionDependencyFactory() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DVLOG(1) << "~PeerConnectionDependencyFactory()"; + DCHECK(!pc_factory_); +} + +PeerConnectionDependencyFactory* +PeerConnectionDependencyFactory::GetInstance() { + DEFINE_STATIC_LOCAL(PeerConnectionDependencyFactory, instance, + (/*create_p2p_socket_dispatcher= */ true)); + return &instance; +} + +std::unique_ptr<blink::WebRTCPeerConnectionHandler> +PeerConnectionDependencyFactory::CreateRTCPeerConnectionHandler( + blink::WebRTCPeerConnectionHandlerClient* client, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + return blink::Platform::Current()->CreateRTCPeerConnectionHandler( + client, std::move(task_runner)); +} + +const scoped_refptr<webrtc::PeerConnectionFactoryInterface>& +PeerConnectionDependencyFactory::GetPcFactory() { + if (!pc_factory_.get()) + CreatePeerConnectionFactory(); + CHECK(pc_factory_.get()); + return pc_factory_; +} + +void PeerConnectionDependencyFactory::WillDestroyCurrentMessageLoop() { + CleanupPeerConnectionFactory(); +} + +void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() { + DCHECK(!pc_factory_.get()); + DCHECK(!signaling_thread_); + DCHECK(!worker_thread_); + DCHECK(!network_manager_); + DCHECK(!socket_factory_); + DCHECK(!chrome_signaling_thread_.IsRunning()); + DCHECK(!chrome_worker_thread_.IsRunning()); + + DVLOG(1) << "PeerConnectionDependencyFactory::CreatePeerConnectionFactory()"; + +#if BUILDFLAG(RTC_USE_H264) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) + // Building /w |rtc_use_h264|, is the corresponding run-time feature enabled? + if (!base::FeatureList::IsEnabled( + blink::features::kWebRtcH264WithOpenH264FFmpeg)) { + // Feature is to be disabled. + webrtc::DisableRtcUseH264(); + } +#else + webrtc::DisableRtcUseH264(); +#endif // BUILDFLAG(RTC_USE_H264) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) + + base::MessageLoopCurrent::Get()->AddDestructionObserver(this); + // To allow sending to the signaling/worker threads. + jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); + jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); + + EnsureWebRtcAudioDeviceImpl(); + + CHECK(chrome_signaling_thread_.Start()); + CHECK(chrome_worker_thread_.Start()); + + base::WaitableEvent start_worker_event( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + chrome_worker_thread_.task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&PeerConnectionDependencyFactory::InitializeWorkerThread, + base::Unretained(this), &worker_thread_, + &start_worker_event)); + + base::WaitableEvent create_network_manager_event( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + std::unique_ptr<MdnsResponderAdapter> mdns_responder; +#if BUILDFLAG(ENABLE_MDNS) + if (base::FeatureList::IsEnabled( + blink::features::kWebRtcHideLocalIpsWithMdns)) { + // Note that MdnsResponderAdapter is created on the main thread to have + // access to the connector to the service manager. + mdns_responder = std::make_unique<MdnsResponderAdapter>(); + } +#endif // BUILDFLAG(ENABLE_MDNS) + chrome_worker_thread_.task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&PeerConnectionDependencyFactory:: + CreateIpcNetworkManagerOnWorkerThread, + base::Unretained(this), &create_network_manager_event, + std::move(mdns_responder))); + + start_worker_event.Wait(); + create_network_manager_event.Wait(); + + CHECK(worker_thread_); + + // Init SSL, which will be needed by PeerConnection. + if (!rtc::InitializeSSL()) { + LOG(ERROR) << "Failed on InitializeSSL."; + NOTREACHED(); + return; + } + + base::WaitableEvent start_signaling_event( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + chrome_signaling_thread_.task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + &PeerConnectionDependencyFactory::InitializeSignalingThread, + base::Unretained(this), blink::Platform::Current()->GetGpuFactories(), + &start_signaling_event)); + + start_signaling_event.Wait(); + CHECK(signaling_thread_); +} + +void PeerConnectionDependencyFactory::InitializeSignalingThread( + media::GpuVideoAcceleratorFactories* gpu_factories, + base::WaitableEvent* event) { + DCHECK(chrome_signaling_thread_.task_runner()->BelongsToCurrentThread()); + DCHECK(worker_thread_); + DCHECK(p2p_socket_dispatcher_.get()); + + jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); + jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); + signaling_thread_ = jingle_glue::JingleThreadWrapper::current(); + + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("webrtc_peer_connection", R"( + semantics { + sender: "WebRTC" + description: + "WebRTC is an API that provides web applications with Real Time " + "Communication (RTC) capabilities. It is used to establish a " + "secure session with a remote peer, transmitting and receiving " + "audio, video and potentially other data." + trigger: + "Application creates an RTCPeerConnection and connects it to a " + "remote peer by exchanging an SDP offer and answer." + data: + "Media encrypted using DTLS-SRTP, and protocol-level messages for " + "the various subprotocols employed by WebRTC (including ICE, DTLS, " + "RTCP, etc.). Note that ICE connectivity checks may leak the " + "user's IP address(es), subject to the restrictions/guidance in " + "https://datatracker.ietf.org/doc/draft-ietf-rtcweb-ip-handling." + destination: OTHER + destination_other: + "A destination determined by the web application that created the " + "connection." + } + policy { + cookies_allowed: NO + setting: + "This feature cannot be disabled in settings, but it won't be used " + "unless the application creates an RTCPeerConnection. Media can " + "only be captured with user's consent, but data may be sent " + "withouth that." + policy_exception_justification: + "Not implemented. 'WebRtcUdpPortRange' policy can limit the range " + "of ports used by WebRTC, but there is no policy to generally " + "block it." + } + )"); + socket_factory_.reset(new IpcPacketSocketFactory(p2p_socket_dispatcher_.get(), + traffic_annotation)); + + std::unique_ptr<webrtc::VideoEncoderFactory> webrtc_encoder_factory = + blink::CreateWebrtcVideoEncoderFactory(gpu_factories); + std::unique_ptr<webrtc::VideoDecoderFactory> webrtc_decoder_factory = + blink::CreateWebrtcVideoDecoderFactory(gpu_factories); + + // Enable Multiplex codec in SDP optionally. + if (base::FeatureList::IsEnabled(blink::features::kWebRtcMultiplexCodec)) { + webrtc_encoder_factory = std::make_unique<webrtc::MultiplexEncoderFactory>( + std::move(webrtc_encoder_factory)); + webrtc_decoder_factory = std::make_unique<webrtc::MultiplexDecoderFactory>( + std::move(webrtc_decoder_factory)); + } + + if (blink::Platform::Current()->UsesFakeCodecForPeerConnection()) { + webrtc_encoder_factory = + std::make_unique<webrtc::FakeVideoEncoderFactory>(); + webrtc_decoder_factory = + std::make_unique<webrtc::FakeVideoDecoderFactory>(); + } + + webrtc::PeerConnectionFactoryDependencies pcf_deps; + pcf_deps.worker_thread = worker_thread_; + pcf_deps.network_thread = worker_thread_; + pcf_deps.signaling_thread = signaling_thread_; + pcf_deps.task_queue_factory = CreateWebRtcTaskQueueFactory(); + pcf_deps.call_factory = webrtc::CreateCallFactory(); + pcf_deps.event_log_factory = std::make_unique<webrtc::RtcEventLogFactory>( + pcf_deps.task_queue_factory.get()); + cricket::MediaEngineDependencies media_deps; + media_deps.task_queue_factory = pcf_deps.task_queue_factory.get(); + media_deps.adm = audio_device_.get(); + media_deps.audio_encoder_factory = blink::CreateWebrtcAudioEncoderFactory(); + media_deps.audio_decoder_factory = blink::CreateWebrtcAudioDecoderFactory(); + media_deps.video_encoder_factory = std::move(webrtc_encoder_factory); + media_deps.video_decoder_factory = std::move(webrtc_decoder_factory); + media_deps.audio_processing = webrtc::AudioProcessingBuilder().Create(); + pcf_deps.media_engine = cricket::CreateMediaEngine(std::move(media_deps)); + pc_factory_ = webrtc::CreateModularPeerConnectionFactory(std::move(pcf_deps)); + CHECK(pc_factory_.get()); + + webrtc::PeerConnectionFactoryInterface::Options factory_options; + factory_options.disable_sctp_data_channels = false; + factory_options.disable_encryption = + !blink::Platform::Current()->IsWebRtcEncryptionEnabled(); + pc_factory_->SetOptions(factory_options); + + event->Signal(); +} + +bool PeerConnectionDependencyFactory::PeerConnectionFactoryCreated() { + return !!pc_factory_; +} + +scoped_refptr<webrtc::PeerConnectionInterface> +PeerConnectionDependencyFactory::CreatePeerConnection( + const webrtc::PeerConnectionInterface::RTCConfiguration& config, + blink::WebLocalFrame* web_frame, + webrtc::PeerConnectionObserver* observer) { + CHECK(web_frame); + CHECK(observer); + if (!GetPcFactory().get()) + return nullptr; + + webrtc::PeerConnectionDependencies dependencies(observer); + dependencies.allocator = CreatePortAllocator(web_frame); + dependencies.async_resolver_factory = CreateAsyncResolverFactory(); + return GetPcFactory() + ->CreatePeerConnection(config, std::move(dependencies)) + .get(); +} + +std::unique_ptr<cricket::PortAllocator> +PeerConnectionDependencyFactory::CreatePortAllocator( + blink::WebLocalFrame* web_frame) { + DCHECK(web_frame); + + // Copy the flag from Preference associated with this WebLocalFrame. + P2PPortAllocator::Config port_config; + uint16_t min_port = 0; + uint16_t max_port = 0; + bool allow_mdns_obfuscation = true; + + // |media_permission| will be called to check mic/camera permission. If at + // least one of them is granted, P2PPortAllocator is allowed to gather local + // host IP addresses as ICE candidates. |media_permission| could be nullptr, + // which means the permission will be granted automatically. This could be the + // case when either the experiment is not enabled or the preference is not + // enforced. + // + // Note on |media_permission| lifetime: |media_permission| is owned by a frame + // (RenderFrameImpl). It is also stored as an indirect member of + // RTCPeerConnectionHandler (through PeerConnection/PeerConnectionInterface -> + // P2PPortAllocator -> FilteringNetworkManager -> |media_permission|). + // The RTCPeerConnectionHandler is owned as RTCPeerConnection::m_peerHandler + // in Blink, which will be reset in RTCPeerConnection::stop(). Since + // ActiveDOMObject::stop() is guaranteed to be called before a frame is + // detached, it is impossible for RTCPeerConnectionHandler to outlive the + // frame. Therefore using a raw pointer of |media_permission| is safe here. + media::MediaPermission* media_permission = nullptr; + if (!blink::Platform::Current()->ShouldEnforceWebRTCRoutingPreferences()) { + port_config.enable_multiple_routes = true; + port_config.enable_nonproxied_udp = true; + VLOG(3) << "WebRTC routing preferences will not be enforced"; + } else { + if (web_frame && web_frame->View()) { + blink::WebString webrtc_ip_handling_policy; + blink::Platform::Current()->GetWebRTCRendererPreferences( + web_frame, &webrtc_ip_handling_policy, &min_port, &max_port, + &allow_mdns_obfuscation); + + // TODO(guoweis): |enable_multiple_routes| should be renamed to + // |request_multiple_routes|. Whether local IP addresses could be + // collected depends on if mic/camera permission is granted for this + // origin. + WebRTCIPHandlingPolicy policy = + GetWebRTCIPHandlingPolicy(webrtc_ip_handling_policy.Utf8()); + switch (policy) { + // TODO(guoweis): specify the flag of disabling local candidate + // collection when webrtc is updated. + case DEFAULT_PUBLIC_INTERFACE_ONLY: + case DEFAULT_PUBLIC_AND_PRIVATE_INTERFACES: + port_config.enable_multiple_routes = false; + port_config.enable_nonproxied_udp = true; + port_config.enable_default_local_candidate = + (policy == DEFAULT_PUBLIC_AND_PRIVATE_INTERFACES); + break; + case DISABLE_NON_PROXIED_UDP: + port_config.enable_multiple_routes = false; + port_config.enable_nonproxied_udp = false; + break; + case DEFAULT: + port_config.enable_multiple_routes = true; + port_config.enable_nonproxied_udp = true; + break; + } + + VLOG(3) << "WebRTC routing preferences: " + << "policy: " << policy + << ", multiple_routes: " << port_config.enable_multiple_routes + << ", nonproxied_udp: " << port_config.enable_nonproxied_udp + << ", min_udp_port: " << min_port + << ", max_udp_port: " << max_port + << ", allow_mdns_obfuscation: " << allow_mdns_obfuscation; + } + if (port_config.enable_multiple_routes) { + media_permission = + blink::Platform::Current()->GetWebRTCMediaPermission(web_frame); + } + } + + // Now that this file is within Blink, it can not rely on WebURL's + // GURL() operator directly. Hence, as per the comment on gurl.h, the + // following GURL ctor is used instead. + WebURL document_url = web_frame->GetDocument().Url(); + const GURL& requesting_origin = + GURL(document_url.GetString().Utf8(), document_url.GetParsed(), + document_url.IsValid()) + .GetOrigin(); + + std::unique_ptr<rtc::NetworkManager> network_manager; + if (port_config.enable_multiple_routes) { + network_manager = std::make_unique<blink::FilteringNetworkManager>( + network_manager_.get(), requesting_origin, media_permission, + allow_mdns_obfuscation); + } else { + network_manager = + std::make_unique<blink::EmptyNetworkManager>(network_manager_.get()); + } + auto port_allocator = std::make_unique<P2PPortAllocator>( + p2p_socket_dispatcher_, std::move(network_manager), socket_factory_.get(), + port_config, requesting_origin); + if (IsValidPortRange(min_port, max_port)) + port_allocator->SetPortRange(min_port, max_port); + + return port_allocator; +} + +std::unique_ptr<webrtc::AsyncResolverFactory> +PeerConnectionDependencyFactory::CreateAsyncResolverFactory() { + return std::make_unique<ProxyAsyncResolverFactory>(socket_factory_.get()); +} + +scoped_refptr<webrtc::MediaStreamInterface> +PeerConnectionDependencyFactory::CreateLocalMediaStream( + const std::string& label) { + return GetPcFactory()->CreateLocalMediaStream(label).get(); +} + +scoped_refptr<webrtc::VideoTrackSourceInterface> +PeerConnectionDependencyFactory::CreateVideoTrackSourceProxy( + webrtc::VideoTrackSourceInterface* source) { + // PeerConnectionFactory needs to be instantiated to make sure that + // signaling_thread_ and worker_thread_ exist. + if (!PeerConnectionFactoryCreated()) + CreatePeerConnectionFactory(); + + return webrtc::VideoTrackSourceProxy::Create(signaling_thread_, + worker_thread_, source) + .get(); +} + +scoped_refptr<webrtc::VideoTrackInterface> +PeerConnectionDependencyFactory::CreateLocalVideoTrack( + const std::string& id, + webrtc::VideoTrackSourceInterface* source) { + return GetPcFactory()->CreateVideoTrack(id, source).get(); +} + +webrtc::SessionDescriptionInterface* +PeerConnectionDependencyFactory::CreateSessionDescription( + const std::string& type, + const std::string& sdp, + webrtc::SdpParseError* error) { + return webrtc::CreateSessionDescription(type, sdp, error); +} + +webrtc::IceCandidateInterface* +PeerConnectionDependencyFactory::CreateIceCandidate(const std::string& sdp_mid, + int sdp_mline_index, + const std::string& sdp) { + return webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, sdp, nullptr); +} + +blink::WebRtcAudioDeviceImpl* +PeerConnectionDependencyFactory::GetWebRtcAudioDevice() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + EnsureWebRtcAudioDeviceImpl(); + return audio_device_.get(); +} + +void PeerConnectionDependencyFactory::InitializeWorkerThread( + rtc::Thread** thread, + base::WaitableEvent* event) { + jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); + jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); + *thread = jingle_glue::JingleThreadWrapper::current(); + event->Signal(); +} + +void PeerConnectionDependencyFactory::TryScheduleStunProbeTrial() { + base::Optional<std::string> params = + blink::Platform::Current()->WebRtcStunProbeTrialParameter(); + if (!params) + return; + + GetPcFactory(); + + chrome_worker_thread_.task_runner()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + &PeerConnectionDependencyFactory::StartStunProbeTrialOnWorkerThread, + base::Unretained(this), *params), + base::TimeDelta::FromMilliseconds(blink::kExperimentStartDelayMs)); +} + +void PeerConnectionDependencyFactory::StartStunProbeTrialOnWorkerThread( + const std::string& params) { + DCHECK(network_manager_); + DCHECK(chrome_worker_thread_.task_runner()->BelongsToCurrentThread()); + stun_trial_.reset(new blink::StunProberTrial(network_manager_.get(), params, + socket_factory_.get())); +} + +void PeerConnectionDependencyFactory::CreateIpcNetworkManagerOnWorkerThread( + base::WaitableEvent* event, + std::unique_ptr<MdnsResponderAdapter> mdns_responder) { + DCHECK(chrome_worker_thread_.task_runner()->BelongsToCurrentThread()); + network_manager_ = std::make_unique<blink::IpcNetworkManager>( + p2p_socket_dispatcher_.get(), std::move(mdns_responder)); + event->Signal(); +} + +void PeerConnectionDependencyFactory::DeleteIpcNetworkManager() { + DCHECK(chrome_worker_thread_.task_runner()->BelongsToCurrentThread()); + network_manager_.reset(); +} + +void PeerConnectionDependencyFactory::CleanupPeerConnectionFactory() { + DVLOG(1) << "PeerConnectionDependencyFactory::CleanupPeerConnectionFactory()"; + pc_factory_ = nullptr; + if (network_manager_) { + // The network manager needs to free its resources on the thread they were + // created, which is the worked thread. + if (chrome_worker_thread_.IsRunning()) { + chrome_worker_thread_.task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + &PeerConnectionDependencyFactory::DeleteIpcNetworkManager, + base::Unretained(this))); + // Stopping the thread will wait until all tasks have been + // processed before returning. We wait for the above task to finish before + // letting the the function continue to avoid any potential race issues. + chrome_worker_thread_.Stop(); + } else { + NOTREACHED() << "Worker thread not running."; + } + } +} + +void PeerConnectionDependencyFactory::EnsureInitialized() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + GetPcFactory(); +} + +scoped_refptr<base::SingleThreadTaskRunner> +PeerConnectionDependencyFactory::GetWebRtcWorkerThread() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return chrome_worker_thread_.IsRunning() ? chrome_worker_thread_.task_runner() + : nullptr; +} + +rtc::Thread* PeerConnectionDependencyFactory::GetWebRtcWorkerThreadRtcThread() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + EnsureInitialized(); + return chrome_worker_thread_.IsRunning() ? worker_thread_ : nullptr; +} + +scoped_refptr<base::SingleThreadTaskRunner> +PeerConnectionDependencyFactory::GetWebRtcSignalingTaskRunner() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + EnsureInitialized(); + return chrome_signaling_thread_.IsRunning() + ? chrome_signaling_thread_.task_runner() + : nullptr; +} + +void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (audio_device_.get()) + return; + + audio_device_ = new rtc::RefCountedObject<blink::WebRtcAudioDeviceImpl>(); +} + +std::unique_ptr<webrtc::RtpCapabilities> +PeerConnectionDependencyFactory::GetSenderCapabilities( + const std::string& kind) { + if (kind == "audio") { + return std::make_unique<webrtc::RtpCapabilities>( + GetPcFactory()->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO)); + } else if (kind == "video") { + return std::make_unique<webrtc::RtpCapabilities>( + GetPcFactory()->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO)); + } + return nullptr; +} + +std::unique_ptr<webrtc::RtpCapabilities> +PeerConnectionDependencyFactory::GetReceiverCapabilities( + const std::string& kind) { + if (kind == "audio") { + return std::make_unique<webrtc::RtpCapabilities>( + GetPcFactory()->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_AUDIO)); + } else if (kind == "video") { + return std::make_unique<webrtc::RtpCapabilities>( + GetPcFactory()->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_VIDEO)); + } + return nullptr; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc new file mode 100644 index 00000000000..a0db11483f9 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc @@ -0,0 +1,152 @@ +// Copyright (c) 2015 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 "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h" + +#include <string> +#include <utility> + +#include "base/bind.h" +#include "base/macros.h" +#include "base/single_thread_task_runner.h" +#include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h" +#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" +#include "third_party/webrtc/api/scoped_refptr.h" +#include "third_party/webrtc/rtc_base/rtc_certificate.h" +#include "third_party/webrtc/rtc_base/rtc_certificate_generator.h" + +namespace blink { +namespace { + +rtc::KeyParams WebRTCKeyParamsToKeyParams( + const blink::WebRTCKeyParams& key_params) { + switch (key_params.KeyType()) { + case blink::kWebRTCKeyTypeRSA: + return rtc::KeyParams::RSA(key_params.RsaParams().mod_length, + key_params.RsaParams().pub_exp); + case blink::kWebRTCKeyTypeECDSA: + return rtc::KeyParams::ECDSA( + static_cast<rtc::ECCurve>(key_params.EcCurve())); + default: + NOTREACHED(); + return rtc::KeyParams(); + } +} + +// A certificate generation request spawned by +// |GenerateCertificateWithOptionalExpiration|. This +// is handled by a separate class so that reference counting can keep the +// request alive independently of the |RTCCertificateGenerator| that spawned it. +class RTCCertificateGeneratorRequest + : public WTF::ThreadSafeRefCounted<RTCCertificateGeneratorRequest> { + public: + RTCCertificateGeneratorRequest( + const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& worker_thread) + : main_thread_(main_thread), worker_thread_(worker_thread) { + DCHECK(main_thread_); + DCHECK(worker_thread_); + } + + void GenerateCertificateAsync( + const blink::WebRTCKeyParams& key_params, + const absl::optional<uint64_t>& expires_ms, + blink::RTCCertificateCallback completion_callback) { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(completion_callback); + + worker_thread_->PostTask( + FROM_HERE, + base::BindOnce( + &RTCCertificateGeneratorRequest::GenerateCertificateOnWorkerThread, + this, key_params, expires_ms, std::move(completion_callback))); + } + + private: + friend class WTF::ThreadSafeRefCounted<RTCCertificateGeneratorRequest>; + ~RTCCertificateGeneratorRequest() {} + + void GenerateCertificateOnWorkerThread( + const blink::WebRTCKeyParams key_params, + const absl::optional<uint64_t> expires_ms, + blink::RTCCertificateCallback completion_callback) { + DCHECK(worker_thread_->BelongsToCurrentThread()); + + rtc::scoped_refptr<rtc::RTCCertificate> certificate = + rtc::RTCCertificateGenerator::GenerateCertificate( + WebRTCKeyParamsToKeyParams(key_params), expires_ms); + + main_thread_->PostTask( + FROM_HERE, + base::BindOnce(&RTCCertificateGeneratorRequest::DoCallbackOnMainThread, + this, std::move(completion_callback), certificate)); + } + + void DoCallbackOnMainThread( + blink::RTCCertificateCallback completion_callback, + rtc::scoped_refptr<rtc::RTCCertificate> certificate) { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(completion_callback); + std::move(completion_callback).Run(std::move(certificate)); + } + + // The main thread is the renderer thread. + const scoped_refptr<base::SingleThreadTaskRunner> main_thread_; + // The WebRTC worker thread. + const scoped_refptr<base::SingleThreadTaskRunner> worker_thread_; +}; + +void GenerateCertificateWithOptionalExpiration( + const blink::WebRTCKeyParams& key_params, + const absl::optional<uint64_t>& expires_ms, + blink::RTCCertificateCallback completion_callback, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + DCHECK(WebRTCKeyParamsToKeyParams(key_params).IsValid()); + auto* pc_dependency_factory = + blink::PeerConnectionDependencyFactory::GetInstance(); + pc_dependency_factory->EnsureInitialized(); + + scoped_refptr<RTCCertificateGeneratorRequest> request = + base::MakeRefCounted<RTCCertificateGeneratorRequest>( + task_runner, pc_dependency_factory->GetWebRtcWorkerThread()); + request->GenerateCertificateAsync(key_params, expires_ms, + std::move(completion_callback)); +} + +} // namespace + +void RTCCertificateGenerator::GenerateCertificate( + const blink::WebRTCKeyParams& key_params, + blink::RTCCertificateCallback completion_callback, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + GenerateCertificateWithOptionalExpiration( + key_params, absl::nullopt, std::move(completion_callback), task_runner); +} + +void RTCCertificateGenerator::GenerateCertificateWithExpiration( + const blink::WebRTCKeyParams& key_params, + uint64_t expires_ms, + blink::RTCCertificateCallback completion_callback, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + GenerateCertificateWithOptionalExpiration( + key_params, expires_ms, std::move(completion_callback), task_runner); +} + +bool RTCCertificateGenerator::IsSupportedKeyParams( + const blink::WebRTCKeyParams& key_params) { + return WebRTCKeyParamsToKeyParams(key_params).IsValid(); +} + +rtc::scoped_refptr<rtc::RTCCertificate> RTCCertificateGenerator::FromPEM( + blink::WebString pem_private_key, + blink::WebString pem_certificate) { + rtc::scoped_refptr<rtc::RTCCertificate> certificate = + rtc::RTCCertificate::FromPEM(rtc::RTCCertificatePEM( + pem_private_key.Utf8(), pem_certificate.Utf8())); + if (!certificate) + return nullptr; + return certificate; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h new file mode 100644 index 00000000000..726b2398449 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h @@ -0,0 +1,65 @@ +// Copyright (c) 2015 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 THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_CERTIFICATE_GENERATOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_CERTIFICATE_GENERATOR_H_ + +#include <memory> + +#include "base/macros.h" +#include "third_party/blink/public/platform/web_rtc_key_params.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/webrtc/api/peer_connection_interface.h" + +namespace base { +class SingleThreadTaskRunner; +} + +namespace blink { + +using RTCCertificateCallback = + base::OnceCallback<void(rtc::scoped_refptr<rtc::RTCCertificate>)>; + +// Chromium's WebRTCCertificateGenerator implementation; uses the +// PeerConnectionIdentityStore/SSLIdentity::Generate to generate the identity, +// rtc::RTCCertificate and blink::RTCCertificate. +// +// TODO(crbug.com/787254): Convert use of WebString to WTF::String. +class MODULES_EXPORT RTCCertificateGenerator { + public: + RTCCertificateGenerator() {} + ~RTCCertificateGenerator() {} + + // Start generating a certificate asynchronously. |observer| is invoked on the + // same thread that called generateCertificate when the operation is + // completed. + void GenerateCertificate( + const blink::WebRTCKeyParams& key_params, + blink::RTCCertificateCallback completion_callback, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + void GenerateCertificateWithExpiration( + const blink::WebRTCKeyParams& key_params, + uint64_t expires_ms, + blink::RTCCertificateCallback completion_callback, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + // Determines if the parameters are supported by |GenerateCertificate|. + // For example, if the number of bits of some parameter is too small or too + // large we may want to reject it for security or performance reasons. + bool IsSupportedKeyParams(const blink::WebRTCKeyParams& key_params); + + // Creates a certificate from the PEM strings. See also + // |rtc::RTCCertificate::ToPEM|. + rtc::scoped_refptr<rtc::RTCCertificate> FromPEM( + blink::WebString pem_private_key, + blink::WebString pem_certificate); + + private: + DISALLOW_COPY_AND_ASSIGN(RTCCertificateGenerator); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_CERTIFICATE_GENERATOR_H_ diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc index b0c16615fc6..c7a6438a5b5 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc @@ -10,6 +10,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/scoped_refptr.h" +#include "base/run_loop.h" #include "base/test/test_simple_task_runner.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/dom/events/event.h" diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc index d2a2c691817..12a81819132 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/events/event.h" @@ -64,8 +65,8 @@ class DtlsIceTransportAdapterCrossThreadFactory : ice_transport_(ice_transport) {} void InitializeOnMainThread(LocalFrame& frame) override { DCHECK(!worker_thread_rtc_thread_); - worker_thread_rtc_thread_ = - Platform::Current()->GetWebRtcWorkerThreadRtcThread(); + worker_thread_rtc_thread_ = PeerConnectionDependencyFactory::GetInstance() + ->GetWebRtcWorkerThreadRtcThread(); } std::unique_ptr<IceTransportAdapter> ConstructOnWorkerThread( @@ -88,12 +89,17 @@ class DefaultIceTransportAdapterCrossThreadFactory DCHECK(!port_allocator_); DCHECK(!worker_thread_rtc_thread_); DCHECK(!async_resolver_factory_); - port_allocator_ = Platform::Current()->CreateWebRtcPortAllocator( + + auto* rtc_dependency_factory = + blink::PeerConnectionDependencyFactory::GetInstance(); + rtc_dependency_factory->EnsureInitialized(); + port_allocator_ = rtc_dependency_factory->CreatePortAllocator( frame.Client()->GetWebFrame()); + async_resolver_factory_ = Platform::Current()->CreateWebRtcAsyncResolverFactory(); - worker_thread_rtc_thread_ = - Platform::Current()->GetWebRtcWorkerThreadRtcThread(); + worker_thread_rtc_thread_ = PeerConnectionDependencyFactory::GetInstance() + ->GetWebRtcWorkerThreadRtcThread(); } std::unique_ptr<IceTransportAdapter> ConstructOnWorkerThread( diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index a40b6f03b4a..26cec8dd675 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc @@ -45,7 +45,6 @@ #include "third_party/blink/public/platform/web_crypto_algorithm_params.h" #include "third_party/blink/public/platform/web_media_stream.h" #include "third_party/blink/public/platform/web_rtc_answer_options.h" -#include "third_party/blink/public/platform/web_rtc_certificate_generator.h" #include "third_party/blink/public/platform/web_rtc_data_channel_init.h" #include "third_party/blink/public/platform/web_rtc_ice_candidate.h" #include "third_party/blink/public/platform/web_rtc_key_params.h" @@ -79,6 +78,7 @@ #include "third_party/blink/renderer/modules/mediastream/media_stream_event.h" #include "third_party/blink/renderer/modules/mediastream/user_media_controller.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_answer_options.h" +#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_configuration.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h" @@ -1670,8 +1670,7 @@ ScriptPromise RTCPeerConnection::generateCertificate( } DCHECK(key_params.has_value()); - std::unique_ptr<WebRTCCertificateGenerator> certificate_generator = - Platform::Current()->CreateRTCCertificateGenerator(); + auto certificate_generator = std::make_unique<RTCCertificateGenerator>(); // |keyParams| was successfully constructed, but does the certificate // generator support these parameters? @@ -1995,20 +1994,21 @@ bool RTCPeerConnection::IsRemoteStream(MediaStream* stream) const { ScriptPromise RTCPeerConnection::getStats(ScriptState* script_state, ExceptionState& exception_state) { - return getStats( - script_state, - ScriptValue(script_state, v8::Undefined(script_state->GetIsolate())), - ScriptValue(script_state, v8::Undefined(script_state->GetIsolate())), - exception_state); + return getStats(script_state, + ScriptValue(script_state->GetIsolate(), + v8::Undefined(script_state->GetIsolate())), + ScriptValue(script_state->GetIsolate(), + v8::Undefined(script_state->GetIsolate())), + exception_state); } ScriptPromise RTCPeerConnection::getStats(ScriptState* script_state, ScriptValue callback_or_selector, ExceptionState& exception_state) { - return getStats( - script_state, std::move(callback_or_selector), - ScriptValue(script_state, v8::Undefined(script_state->GetIsolate())), - exception_state); + return getStats(script_state, std::move(callback_or_selector), + ScriptValue(script_state->GetIsolate(), + v8::Undefined(script_state->GetIsolate())), + exception_state); } ScriptPromise RTCPeerConnection::getStats(ScriptState* script_state, diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h index 939d2821393..0e205e4259a 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h @@ -372,7 +372,7 @@ class MODULES_EXPORT RTCPeerConnection final GetTrackRemoveStreamAndGCWithPersistentStream); typedef base::OnceCallback<bool()> BoolFunction; - class EventWrapper : public GarbageCollectedFinalized<EventWrapper> { + class EventWrapper final : public GarbageCollected<EventWrapper> { public: EventWrapper(Event*, BoolFunction); // Returns true if |m_setupFunction| returns true or it is null. diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc index 6efc41f5bb5..cd4b886c183 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc @@ -7,6 +7,7 @@ #include "third_party/blink/public/platform/web_media_stream.h" #include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/public/platform/web_rtc_rtp_source.h" +#include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h" #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h" @@ -46,25 +47,23 @@ RTCDtlsTransport* RTCRtpReceiver::rtcpTransport() { return nullptr; } -double RTCRtpReceiver::jitterBufferDelayHint(bool& is_null, ExceptionState&) { - is_null = !jitter_buffer_delay_hint_.has_value(); - return jitter_buffer_delay_hint_.value_or(0.0); +double RTCRtpReceiver::playoutDelayHint(bool& is_null, ExceptionState&) { + is_null = !playout_delay_hint_.has_value(); + return playout_delay_hint_.value_or(0.0); } -void RTCRtpReceiver::setJitterBufferDelayHint(double value, - bool is_null, - ExceptionState& exception_state) { +void RTCRtpReceiver::setPlayoutDelayHint(double value, + bool is_null, + ExceptionState& exception_state) { base::Optional<double> hint = is_null ? base::nullopt : base::Optional<double>(value); if (hint && *hint < 0.0) { - exception_state.ThrowDOMException( - DOMExceptionCode::kInvalidAccessError, - "jitterBufferDelayHint can't be negative"); + exception_state.ThrowTypeError("playoutDelayHint can't be negative"); return; } - jitter_buffer_delay_hint_ = hint; - receiver_->SetJitterBufferMinimumDelay(jitter_buffer_delay_hint_); + playout_delay_hint_ = hint; + receiver_->SetJitterBufferMinimumDelay(playout_delay_hint_); } HeapVector<Member<RTCRtpSynchronizationSource>> @@ -188,7 +187,8 @@ RTCRtpCapabilities* RTCRtpReceiver::getCapabilities(const String& kind) { HeapVector<Member<RTCRtpHeaderExtensionCapability>>()); std::unique_ptr<webrtc::RtpCapabilities> rtc_capabilities = - blink::Platform::Current()->GetRtpSenderCapabilities(kind); + PeerConnectionDependencyFactory::GetInstance()->GetSenderCapabilities( + kind.Utf8()); HeapVector<Member<RTCRtpCodecCapability>> codecs; codecs.ReserveInitialCapacity( diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h index 79d311ec4fa..83b396bcea8 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h @@ -43,8 +43,8 @@ class RTCRtpReceiver final : public ScriptWrappable { MediaStreamTrack* track() const; RTCDtlsTransport* transport(); RTCDtlsTransport* rtcpTransport(); - double jitterBufferDelayHint(bool&, ExceptionState&); - void setJitterBufferDelayHint(double, bool, ExceptionState&); + double playoutDelayHint(bool&, ExceptionState&); + void setPlayoutDelayHint(double, bool, ExceptionState&); RTCRtpReceiveParameters* getParameters(); HeapVector<Member<RTCRtpSynchronizationSource>> getSynchronizationSources(); HeapVector<Member<RTCRtpContributingSource>> getContributingSources(); @@ -77,7 +77,7 @@ class RTCRtpReceiver final : public ScriptWrappable { // Hint to the WebRTC Jitter Buffer about desired playout delay. Actual // observed delay may differ depending on the congestion control. |nullopt| // means default value must be used. - base::Optional<double> jitter_buffer_delay_hint_; + base::Optional<double> playout_delay_hint_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl index 82ea2e89359..0d88ea811ef 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl @@ -8,7 +8,8 @@ interface RTCRtpReceiver { readonly attribute MediaStreamTrack track; [RuntimeEnabled=RTCDtlsTransport] readonly attribute RTCDtlsTransport? transport; [RuntimeEnabled=RTCDtlsTransport] readonly attribute RTCDtlsTransport? rtcpTransport; - [RaisesException, RuntimeEnabled=RtcJitterBufferDelayHint, Measure] attribute double? jitterBufferDelayHint; + // https://henbos.github.io/webrtc-extensions/#dom-rtcrtpreceiver-playoutdelayhint + [RaisesException, Measure] attribute double? playoutDelayHint; static RTCRtpCapabilities? getCapabilities(DOMString kind); RTCRtpReceiveParameters getParameters(); sequence<RTCRtpSynchronizationSource> getSynchronizationSources(); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc new file mode 100644 index 00000000000..f3dba4fa581 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.cc @@ -0,0 +1,386 @@ +// Copyright (c) 2017 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 "third_party/blink/public/web/modules/peerconnection/rtc_rtp_receiver_impl.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "third_party/blink/public/platform/modules/peerconnection/webrtc_util.h" +#include "third_party/blink/public/platform/web_rtc_rtp_source.h" +#include "third_party/blink/public/platform/web_rtc_stats.h" +#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" +#include "third_party/webrtc/api/scoped_refptr.h" + +namespace blink { + +RtpReceiverState::RtpReceiverState( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver, + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + track_ref, + std::vector<std::string> stream_id) + : main_task_runner_(std::move(main_task_runner)), + signaling_task_runner_(std::move(signaling_task_runner)), + webrtc_receiver_(std::move(webrtc_receiver)), + webrtc_dtls_transport_(webrtc_receiver_->dtls_transport()), + webrtc_dtls_transport_information_(webrtc::DtlsTransportState::kNew), + is_initialized_(false), + track_ref_(std::move(track_ref)), + stream_ids_(std::move(stream_id)) { + DCHECK(main_task_runner_); + DCHECK(signaling_task_runner_); + DCHECK(webrtc_receiver_); + DCHECK(track_ref_); + if (webrtc_dtls_transport_) { + webrtc_dtls_transport_information_ = webrtc_dtls_transport_->Information(); + } +} + +RtpReceiverState::RtpReceiverState(RtpReceiverState&& other) + : main_task_runner_(other.main_task_runner_), + signaling_task_runner_(other.signaling_task_runner_), + webrtc_receiver_(std::move(other.webrtc_receiver_)), + webrtc_dtls_transport_(std::move(other.webrtc_dtls_transport_)), + webrtc_dtls_transport_information_( + other.webrtc_dtls_transport_information_), + is_initialized_(other.is_initialized_), + track_ref_(std::move(other.track_ref_)), + stream_ids_(std::move(other.stream_ids_)) { + // Explicitly null |other|'s task runners for use in destructor. + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; +} + +RtpReceiverState::~RtpReceiverState() { + // It's OK to not be on the main thread if this state has been moved, in which + // case |main_task_runner_| is null. + DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread()); +} + +RtpReceiverState& RtpReceiverState::operator=(RtpReceiverState&& other) { + DCHECK_EQ(main_task_runner_, other.main_task_runner_); + DCHECK_EQ(signaling_task_runner_, other.signaling_task_runner_); + // Explicitly null |other|'s task runners for use in destructor. + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; + webrtc_receiver_ = std::move(other.webrtc_receiver_); + webrtc_dtls_transport_ = std::move(other.webrtc_dtls_transport_); + webrtc_dtls_transport_information_ = other.webrtc_dtls_transport_information_; + track_ref_ = std::move(other.track_ref_); + stream_ids_ = std::move(other.stream_ids_); + return *this; +} + +bool RtpReceiverState::is_initialized() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return is_initialized_; +} + +void RtpReceiverState::Initialize() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + if (is_initialized_) + return; + track_ref_->InitializeOnMainThread(); + is_initialized_ = true; +} + +scoped_refptr<base::SingleThreadTaskRunner> RtpReceiverState::main_task_runner() + const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return main_task_runner_; +} + +scoped_refptr<base::SingleThreadTaskRunner> +RtpReceiverState::signaling_task_runner() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return signaling_task_runner_; +} + +scoped_refptr<webrtc::RtpReceiverInterface> RtpReceiverState::webrtc_receiver() + const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return webrtc_receiver_; +} + +rtc::scoped_refptr<webrtc::DtlsTransportInterface> +RtpReceiverState::webrtc_dtls_transport() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return webrtc_dtls_transport_; +} + +webrtc::DtlsTransportInformation +RtpReceiverState::webrtc_dtls_transport_information() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return webrtc_dtls_transport_information_; +} + +const std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>& +RtpReceiverState::track_ref() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return track_ref_; +} + +const std::vector<std::string>& RtpReceiverState::stream_ids() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return stream_ids_; +} + +class RTCRtpReceiverImpl::RTCRtpReceiverInternal + : public WTF::ThreadSafeRefCounted< + RTCRtpReceiverImpl::RTCRtpReceiverInternal, + RTCRtpReceiverImpl::RTCRtpReceiverInternalTraits> { + public: + RTCRtpReceiverInternal( + scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, + RtpReceiverState state) + : native_peer_connection_(std::move(native_peer_connection)), + main_task_runner_(state.main_task_runner()), + signaling_task_runner_(state.signaling_task_runner()), + webrtc_receiver_(state.webrtc_receiver()), + state_(std::move(state)) { + DCHECK(native_peer_connection_); + DCHECK(state_.is_initialized()); + } + + const RtpReceiverState& state() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return state_; + } + + void set_state(RtpReceiverState state) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK(state.main_task_runner() == main_task_runner_); + DCHECK(state.signaling_task_runner() == signaling_task_runner_); + DCHECK(state.webrtc_receiver() == webrtc_receiver_); + DCHECK(state.is_initialized()); + state_ = std::move(state); + } + + blink::WebVector<std::unique_ptr<blink::WebRTCRtpSource>> GetSources() { + // The webrtc_recever_ is a proxy, so this is a blocking call to the webrtc + // signalling thread. + auto webrtc_sources = webrtc_receiver_->GetSources(); + blink::WebVector<std::unique_ptr<blink::WebRTCRtpSource>> sources( + webrtc_sources.size()); + for (size_t i = 0; i < webrtc_sources.size(); ++i) { + sources[i] = blink::CreateRTCRtpSource(webrtc_sources[i]); + } + return sources; + } + + void GetStats( + blink::WebRTCStatsReportCallback callback, + const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) { + signaling_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&RTCRtpReceiverInternal::GetStatsOnSignalingThread, this, + std::move(callback), exposed_group_ids)); + } + + std::unique_ptr<webrtc::RtpParameters> GetParameters() { + return std::make_unique<webrtc::RtpParameters>( + webrtc_receiver_->GetParameters()); + } + + void SetJitterBufferMinimumDelay(base::Optional<double> delay_seconds) { + webrtc_receiver_->SetJitterBufferMinimumDelay( + blink::ToAbslOptional(delay_seconds)); + } + + private: + friend class WTF::ThreadSafeRefCounted<RTCRtpReceiverInternal, + RTCRtpReceiverInternalTraits>; + friend struct RTCRtpReceiverImpl::RTCRtpReceiverInternalTraits; + + ~RTCRtpReceiverInternal() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + } + + void GetStatsOnSignalingThread( + blink::WebRTCStatsReportCallback callback, + const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) { + native_peer_connection_->GetStats( + webrtc_receiver_.get(), + blink::CreateRTCStatsCollectorCallback( + main_task_runner_, std::move(callback), exposed_group_ids)); + } + + const scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_; + // Task runners and webrtc receiver: Same information as stored in + // |state_| but const and safe to touch on the signaling thread to + // avoid race with set_state(). + const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_; + const scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver_; + RtpReceiverState state_; +}; + +struct RTCRtpReceiverImpl::RTCRtpReceiverInternalTraits { + static void Destruct(const RTCRtpReceiverInternal* receiver) { + // RTCRtpReceiverInternal owns AdapterRefs which have to be destroyed on the + // main thread, this ensures delete always happens there. + if (!receiver->main_task_runner_->BelongsToCurrentThread()) { + receiver->main_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &RTCRtpReceiverImpl::RTCRtpReceiverInternalTraits::Destruct, + base::Unretained(receiver))); + return; + } + delete receiver; + } +}; + +uintptr_t RTCRtpReceiverImpl::getId( + const webrtc::RtpReceiverInterface* webrtc_rtp_receiver) { + return reinterpret_cast<uintptr_t>(webrtc_rtp_receiver); +} + +RTCRtpReceiverImpl::RTCRtpReceiverImpl( + scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, + RtpReceiverState state) + : internal_(base::MakeRefCounted<RTCRtpReceiverInternal>( + std::move(native_peer_connection), + std::move(state))) {} + +RTCRtpReceiverImpl::RTCRtpReceiverImpl(const RTCRtpReceiverImpl& other) + : internal_(other.internal_) {} + +RTCRtpReceiverImpl::~RTCRtpReceiverImpl() {} + +RTCRtpReceiverImpl& RTCRtpReceiverImpl::operator=( + const RTCRtpReceiverImpl& other) { + internal_ = other.internal_; + return *this; +} + +const RtpReceiverState& RTCRtpReceiverImpl::state() const { + return internal_->state(); +} + +void RTCRtpReceiverImpl::set_state(RtpReceiverState state) { + internal_->set_state(std::move(state)); +} + +std::unique_ptr<blink::WebRTCRtpReceiver> RTCRtpReceiverImpl::ShallowCopy() + const { + return std::make_unique<RTCRtpReceiverImpl>(*this); +} + +uintptr_t RTCRtpReceiverImpl::Id() const { + return getId(internal_->state().webrtc_receiver().get()); +} + +rtc::scoped_refptr<webrtc::DtlsTransportInterface> +RTCRtpReceiverImpl::DtlsTransport() { + return internal_->state().webrtc_dtls_transport(); +} + +webrtc::DtlsTransportInformation +RTCRtpReceiverImpl::DtlsTransportInformation() { + return internal_->state().webrtc_dtls_transport_information(); +} + +const blink::WebMediaStreamTrack& RTCRtpReceiverImpl::Track() const { + return internal_->state().track_ref()->web_track(); +} + +blink::WebVector<blink::WebString> RTCRtpReceiverImpl::StreamIds() const { + const auto& stream_ids = internal_->state().stream_ids(); + blink::WebVector<blink::WebString> web_stream_ids(stream_ids.size()); + for (size_t i = 0; i < stream_ids.size(); ++i) + web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids[i]); + return web_stream_ids; +} + +blink::WebVector<std::unique_ptr<blink::WebRTCRtpSource>> +RTCRtpReceiverImpl::GetSources() { + return internal_->GetSources(); +} + +void RTCRtpReceiverImpl::GetStats( + blink::WebRTCStatsReportCallback callback, + const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) { + internal_->GetStats(std::move(callback), exposed_group_ids); +} + +std::unique_ptr<webrtc::RtpParameters> RTCRtpReceiverImpl::GetParameters() + const { + return internal_->GetParameters(); +} + +void RTCRtpReceiverImpl::SetJitterBufferMinimumDelay( + base::Optional<double> delay_seconds) { + internal_->SetJitterBufferMinimumDelay(delay_seconds); +} + +RTCRtpReceiverOnlyTransceiver::RTCRtpReceiverOnlyTransceiver( + std::unique_ptr<blink::WebRTCRtpReceiver> receiver) + : receiver_(std::move(receiver)) { + DCHECK(receiver_); +} + +RTCRtpReceiverOnlyTransceiver::~RTCRtpReceiverOnlyTransceiver() {} + +blink::WebRTCRtpTransceiverImplementationType +RTCRtpReceiverOnlyTransceiver::ImplementationType() const { + return blink::WebRTCRtpTransceiverImplementationType::kPlanBReceiverOnly; +} + +uintptr_t RTCRtpReceiverOnlyTransceiver::Id() const { + NOTIMPLEMENTED(); + return 0u; +} + +blink::WebString RTCRtpReceiverOnlyTransceiver::Mid() const { + NOTIMPLEMENTED(); + return blink::WebString(); +} + +std::unique_ptr<blink::WebRTCRtpSender> RTCRtpReceiverOnlyTransceiver::Sender() + const { + NOTIMPLEMENTED(); + return nullptr; +} + +std::unique_ptr<blink::WebRTCRtpReceiver> +RTCRtpReceiverOnlyTransceiver::Receiver() const { + return receiver_->ShallowCopy(); +} + +bool RTCRtpReceiverOnlyTransceiver::Stopped() const { + NOTIMPLEMENTED(); + return false; +} + +webrtc::RtpTransceiverDirection RTCRtpReceiverOnlyTransceiver::Direction() + const { + NOTIMPLEMENTED(); + return webrtc::RtpTransceiverDirection::kSendOnly; +} + +void RTCRtpReceiverOnlyTransceiver::SetDirection( + webrtc::RtpTransceiverDirection direction) { + NOTIMPLEMENTED(); +} + +base::Optional<webrtc::RtpTransceiverDirection> +RTCRtpReceiverOnlyTransceiver::CurrentDirection() const { + NOTIMPLEMENTED(); + return webrtc::RtpTransceiverDirection::kSendOnly; +} + +base::Optional<webrtc::RtpTransceiverDirection> +RTCRtpReceiverOnlyTransceiver::FiredDirection() const { + NOTIMPLEMENTED(); + return webrtc::RtpTransceiverDirection::kSendOnly; +} + +webrtc::RTCError RTCRtpReceiverOnlyTransceiver::SetCodecPreferences( + blink::WebVector<webrtc::RtpCodecCapability>) { + NOTIMPLEMENTED(); + return {}; +} +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc new file mode 100644 index 00000000000..c0bba3eb514 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc @@ -0,0 +1,168 @@ +// Copyright (c) 2017 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 "third_party/blink/public/web/modules/peerconnection/rtc_rtp_receiver_impl.h" + +#include <memory> + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/scoped_refptr.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" +#include "third_party/blink/public/platform/web_rtc_stats.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_dependency_factory.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_impl.h" +#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h" +#include "third_party/blink/public/web/modules/peerconnection/webrtc_stats_report_obtainer.h" +#include "third_party/blink/public/web/web_heap.h" +#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" +#include "third_party/webrtc/api/stats/rtc_stats_report.h" +#include "third_party/webrtc/api/stats/rtcstats_objects.h" +#include "third_party/webrtc/api/test/mock_rtpreceiver.h" + +namespace blink { + +class RTCRtpReceiverImplTest : public ::testing::Test { + public: + void SetUp() override { + dependency_factory_.reset(new blink::MockPeerConnectionDependencyFactory()); + main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting(); + track_map_ = new blink::WebRtcMediaStreamTrackAdapterMap( + dependency_factory_.get(), main_thread_); + peer_connection_ = new rtc::RefCountedObject<blink::MockPeerConnectionImpl>( + dependency_factory_.get(), nullptr); + } + + void TearDown() override { + receiver_.reset(); + // Syncing up with the signaling thread ensures any pending operations on + // that thread are executed. If they post back to the main thread, such as + // the sender's destructor traits, this is allowed to execute before the + // test shuts down the threads. + SyncWithSignalingThread(); + blink::WebHeap::CollectAllGarbageForTesting(); + } + + // Wait for the signaling thread to perform any queued tasks, executing tasks + // posted to the current thread in the meantime while waiting. + void SyncWithSignalingThread() const { + base::RunLoop run_loop; + dependency_factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, run_loop.QuitClosure()); + run_loop.Run(); + } + + std::unique_ptr<RTCRtpReceiverImpl> CreateReceiver( + scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track) { + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + track_ref; + base::RunLoop run_loop; + dependency_factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce(&RTCRtpReceiverImplTest::CreateReceiverOnSignalingThread, + base::Unretained(this), std::move(webrtc_track), + base::Unretained(&track_ref), + base::Unretained(&run_loop))); + run_loop.Run(); + DCHECK(mock_webrtc_receiver_); + DCHECK(track_ref); + blink::RtpReceiverState state( + main_thread_, dependency_factory_->GetWebRtcSignalingTaskRunner(), + mock_webrtc_receiver_.get(), std::move(track_ref), {}); + state.Initialize(); + return std::make_unique<RTCRtpReceiverImpl>(peer_connection_.get(), + std::move(state)); + } + + scoped_refptr<blink::WebRTCStatsReportObtainer> GetStats() { + scoped_refptr<blink::WebRTCStatsReportObtainer> obtainer = + new blink::WebRTCStatsReportObtainer(); + receiver_->GetStats(obtainer->GetStatsCallbackWrapper(), {}); + return obtainer; + } + + protected: + void CreateReceiverOnSignalingThread( + scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track, + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>* + track_ref, + base::RunLoop* run_loop) { + mock_webrtc_receiver_ = + new rtc::RefCountedObject<webrtc::MockRtpReceiver>(); + *track_ref = track_map_->GetOrCreateRemoteTrackAdapter(webrtc_track); + run_loop->Quit(); + } + + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; + + std::unique_ptr<blink::MockPeerConnectionDependencyFactory> + dependency_factory_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_; + scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map_; + rtc::scoped_refptr<blink::MockPeerConnectionImpl> peer_connection_; + rtc::scoped_refptr<webrtc::MockRtpReceiver> mock_webrtc_receiver_; + std::unique_ptr<RTCRtpReceiverImpl> receiver_; +}; + +TEST_F(RTCRtpReceiverImplTest, CreateReceiver) { + scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track = + blink::MockWebRtcAudioTrack::Create("webrtc_track"); + receiver_ = CreateReceiver(webrtc_track); + EXPECT_FALSE(receiver_->Track().IsNull()); + EXPECT_EQ(receiver_->Track().Id().Utf8(), webrtc_track->id()); + EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track); +} + +TEST_F(RTCRtpReceiverImplTest, ShallowCopy) { + scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track = + blink::MockWebRtcAudioTrack::Create("webrtc_track"); + receiver_ = CreateReceiver(webrtc_track); + auto copy = std::make_unique<RTCRtpReceiverImpl>(*receiver_); + EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track); + const auto& webrtc_receiver = receiver_->state().webrtc_receiver(); + auto web_track_unique_id = receiver_->Track().UniqueId(); + // Copy is identical to original. + EXPECT_EQ(copy->state().webrtc_receiver(), webrtc_receiver); + EXPECT_EQ(copy->state().track_ref()->webrtc_track(), webrtc_track); + EXPECT_EQ(copy->Track().UniqueId(), web_track_unique_id); + // Copy keeps the internal state alive. + receiver_.reset(); + EXPECT_EQ(copy->state().webrtc_receiver(), webrtc_receiver); + EXPECT_EQ(copy->state().track_ref()->webrtc_track(), webrtc_track); + EXPECT_EQ(copy->Track().UniqueId(), web_track_unique_id); +} + +TEST_F(RTCRtpReceiverImplTest, GetStats) { + scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track = + blink::MockWebRtcAudioTrack::Create("webrtc_track"); + receiver_ = CreateReceiver(webrtc_track); + + // Make the mock return a blink version of the |webtc_report|. The mock does + // not perform any stats filtering, we just set it to a dummy value. + rtc::scoped_refptr<webrtc::RTCStatsReport> webrtc_report = + webrtc::RTCStatsReport::Create(0u); + webrtc_report->AddStats( + std::make_unique<webrtc::RTCInboundRTPStreamStats>("stats-id", 1234u)); + peer_connection_->SetGetStatsReport(webrtc_report); + + auto obtainer = GetStats(); + // Make sure the operation is async. + EXPECT_FALSE(obtainer->report()); + // Wait for the report, this performs the necessary run-loop. + auto* report = obtainer->WaitForReport(); + EXPECT_TRUE(report); + + // Verify dummy value. + EXPECT_EQ(report->Size(), 1u); + auto stats = report->GetStats(blink::WebString::FromUTF8("stats-id")); + EXPECT_TRUE(stats); + EXPECT_EQ(stats->Timestamp(), 1.234); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc index fcfb8fa98ab..bc07f07be59 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc @@ -9,8 +9,8 @@ #include <tuple> #include <utility> -#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_rtc_dtmf_sender_handler.h" +#include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_track.h" @@ -574,7 +574,8 @@ RTCRtpCapabilities* RTCRtpSender::getCapabilities(const String& kind) { HeapVector<Member<RTCRtpHeaderExtensionCapability>>()); std::unique_ptr<webrtc::RtpCapabilities> rtc_capabilities = - blink::Platform::Current()->GetRtpSenderCapabilities(kind); + PeerConnectionDependencyFactory::GetInstance()->GetSenderCapabilities( + kind.Utf8()); HeapVector<Member<RTCRtpCodecCapability>> codecs; codecs.ReserveInitialCapacity( diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc new file mode 100644 index 00000000000..6936819df49 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc @@ -0,0 +1,569 @@ +// Copyright (c) 2017 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 "third_party/blink/public/web/modules/peerconnection/rtc_rtp_sender_impl.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/logging.h" +#include "third_party/blink/public/platform/web_rtc_dtmf_sender_handler.h" +#include "third_party/blink/public/platform/web_rtc_stats.h" +#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" + +namespace blink { + +namespace { + +// TODO(hbos): Replace WebRTCVoidRequest with something resolving promises based +// on RTCError, as to surface both exception type and error message. +// https://crbug.com/790007 +void OnReplaceTrackCompleted(blink::WebRTCVoidRequest request, bool result) { + if (result) { + request.RequestSucceeded(); + } else { + request.RequestFailed( + webrtc::RTCError(webrtc::RTCErrorType::INVALID_MODIFICATION)); + } +} + +void OnSetParametersCompleted(blink::WebRTCVoidRequest request, + webrtc::RTCError result) { + if (result.ok()) + request.RequestSucceeded(); + else + request.RequestFailed(result); +} + +} // namespace + +RtpSenderState::RtpSenderState( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender, + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + track_ref, + std::vector<std::string> stream_ids) + : main_task_runner_(std::move(main_task_runner)), + signaling_task_runner_(std::move(signaling_task_runner)), + webrtc_sender_(std::move(webrtc_sender)), + webrtc_dtls_transport_(webrtc_sender_->dtls_transport()), + webrtc_dtls_transport_information_(webrtc::DtlsTransportState::kNew), + is_initialized_(false), + track_ref_(std::move(track_ref)), + stream_ids_(std::move(stream_ids)) { + DCHECK(main_task_runner_); + DCHECK(signaling_task_runner_); + DCHECK(webrtc_sender_); + if (webrtc_dtls_transport_) { + webrtc_dtls_transport_information_ = webrtc_dtls_transport_->Information(); + } +} + +RtpSenderState::RtpSenderState(RtpSenderState&& other) + : main_task_runner_(other.main_task_runner_), + signaling_task_runner_(other.signaling_task_runner_), + webrtc_sender_(std::move(other.webrtc_sender_)), + webrtc_dtls_transport_(std::move(other.webrtc_dtls_transport_)), + webrtc_dtls_transport_information_( + other.webrtc_dtls_transport_information_), + is_initialized_(other.is_initialized_), + track_ref_(std::move(other.track_ref_)), + stream_ids_(std::move(other.stream_ids_)) { + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; +} + +RtpSenderState::~RtpSenderState() { + // It's OK to not be on the main thread if this state has been moved, in which + // case |main_task_runner_| is null. + DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread()); +} + +RtpSenderState& RtpSenderState::operator=(RtpSenderState&& other) { + DCHECK_EQ(main_task_runner_, other.main_task_runner_); + DCHECK_EQ(signaling_task_runner_, other.signaling_task_runner_); + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; + webrtc_sender_ = std::move(other.webrtc_sender_); + webrtc_dtls_transport_ = std::move(other.webrtc_dtls_transport_); + webrtc_dtls_transport_information_ = other.webrtc_dtls_transport_information_; + is_initialized_ = other.is_initialized_; + track_ref_ = std::move(other.track_ref_); + stream_ids_ = std::move(other.stream_ids_); + return *this; +} + +bool RtpSenderState::is_initialized() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return is_initialized_; +} + +void RtpSenderState::Initialize() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + if (track_ref_) + track_ref_->InitializeOnMainThread(); + is_initialized_ = true; +} + +scoped_refptr<base::SingleThreadTaskRunner> RtpSenderState::main_task_runner() + const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return main_task_runner_; +} + +scoped_refptr<base::SingleThreadTaskRunner> +RtpSenderState::signaling_task_runner() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return signaling_task_runner_; +} + +scoped_refptr<webrtc::RtpSenderInterface> RtpSenderState::webrtc_sender() + const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return webrtc_sender_; +} + +rtc::scoped_refptr<webrtc::DtlsTransportInterface> +RtpSenderState::webrtc_dtls_transport() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return webrtc_dtls_transport_; +} + +webrtc::DtlsTransportInformation +RtpSenderState::webrtc_dtls_transport_information() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return webrtc_dtls_transport_information_; +} + +const std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>& +RtpSenderState::track_ref() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return track_ref_; +} + +void RtpSenderState::set_track_ref( + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + track_ref) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK(!is_initialized_ || !track_ref || track_ref->is_initialized()); + track_ref_ = std::move(track_ref); +} + +std::vector<std::string> RtpSenderState::stream_ids() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return stream_ids_; +} + +class RTCRtpSenderImpl::RTCRtpSenderInternal + : public WTF::ThreadSafeRefCounted< + RTCRtpSenderImpl::RTCRtpSenderInternal, + RTCRtpSenderImpl::RTCRtpSenderInternalTraits> { + public: + RTCRtpSenderInternal( + scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, + scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map, + RtpSenderState state) + : native_peer_connection_(std::move(native_peer_connection)), + track_map_(std::move(track_map)), + main_task_runner_(state.main_task_runner()), + signaling_task_runner_(state.signaling_task_runner()), + webrtc_sender_(state.webrtc_sender()), + state_(std::move(state)) { + DCHECK(track_map_); + DCHECK(state_.is_initialized()); + } + + const RtpSenderState& state() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return state_; + } + + void set_state(RtpSenderState state) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK_EQ(state.main_task_runner(), main_task_runner_); + DCHECK_EQ(state.signaling_task_runner(), signaling_task_runner_); + DCHECK(state.webrtc_sender() == webrtc_sender_); + DCHECK(state.is_initialized()); + state_ = std::move(state); + } + + void ReplaceTrack(blink::WebMediaStreamTrack with_track, + base::OnceCallback<void(bool)> callback) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + track_ref; + webrtc::MediaStreamTrackInterface* webrtc_track = nullptr; + if (!with_track.IsNull()) { + track_ref = track_map_->GetOrCreateLocalTrackAdapter(with_track); + webrtc_track = track_ref->webrtc_track(); + } + signaling_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&RTCRtpSenderImpl::RTCRtpSenderInternal:: + ReplaceTrackOnSignalingThread, + this, std::move(track_ref), + base::Unretained(webrtc_track), std::move(callback))); + } + + std::unique_ptr<blink::WebRTCDTMFSenderHandler> GetDtmfSender() const { + // The webrtc_sender() is a proxy, so this is a blocking call to the + // webrtc signalling thread. + DCHECK(main_task_runner_->BelongsToCurrentThread()); + auto dtmf_sender = webrtc_sender_->GetDtmfSender(); + return blink::CreateRTCDTMFSenderHandler(main_task_runner_, dtmf_sender); + } + + std::unique_ptr<webrtc::RtpParameters> GetParameters() { + // The webrtc_sender() is a proxy, so this is a blocking call to the + // webrtc signalling thread. + parameters_ = webrtc_sender_->GetParameters(); + return std::make_unique<webrtc::RtpParameters>(parameters_); + } + + void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters> encodings, + webrtc::DegradationPreference degradation_preference, + base::OnceCallback<void(webrtc::RTCError)> callback) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + + webrtc::RtpParameters new_parameters = parameters_; + + new_parameters.degradation_preference = degradation_preference; + + for (std::size_t i = 0; i < new_parameters.encodings.size(); ++i) { + // Encodings have other parameters in the native layer that aren't exposed + // to the blink layer. So instead of copying the new struct over the old + // one, we copy the members one by one over the old struct, effectively + // patching the changes done by the user. + const auto& encoding = encodings[i]; + new_parameters.encodings[i].codec_payload_type = + encoding.codec_payload_type; + new_parameters.encodings[i].dtx = encoding.dtx; + new_parameters.encodings[i].active = encoding.active; + new_parameters.encodings[i].bitrate_priority = encoding.bitrate_priority; + new_parameters.encodings[i].network_priority = encoding.network_priority; + new_parameters.encodings[i].ptime = encoding.ptime; + new_parameters.encodings[i].max_bitrate_bps = encoding.max_bitrate_bps; + new_parameters.encodings[i].max_framerate = encoding.max_framerate; + new_parameters.encodings[i].rid = encoding.rid; + new_parameters.encodings[i].scale_resolution_down_by = + encoding.scale_resolution_down_by; + } + + signaling_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&RTCRtpSenderImpl::RTCRtpSenderInternal:: + SetParametersOnSignalingThread, + this, std::move(new_parameters), std::move(callback))); + } + + void GetStats( + blink::WebRTCStatsReportCallback callback, + const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) { + signaling_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &RTCRtpSenderImpl::RTCRtpSenderInternal::GetStatsOnSignalingThread, + this, std::move(callback), exposed_group_ids)); + } + + bool RemoveFromPeerConnection(webrtc::PeerConnectionInterface* pc) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + if (!pc->RemoveTrack(webrtc_sender_.get())) + return false; + // TODO(hbos): Removing the track should null the sender's track, or we + // should do |webrtc_sender_->SetTrack(null)| but that is not allowed on a + // stopped sender. In the meantime, there is a discrepancy between layers. + // https://crbug.com/webrtc/7945 + state_.set_track_ref(nullptr); + return true; + } + + void SetStreams(std::vector<std::string> stream_ids) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + signaling_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&RTCRtpSenderImpl::RTCRtpSenderInternal:: + SetStreamsOnSignalingThread, + this, std::move(stream_ids))); + } + + private: + friend class WTF::ThreadSafeRefCounted<RTCRtpSenderInternal, + RTCRtpSenderInternalTraits>; + friend struct RTCRtpSenderImpl::RTCRtpSenderInternalTraits; + + ~RTCRtpSenderInternal() { + // Ensured by destructor traits. + DCHECK(main_task_runner_->BelongsToCurrentThread()); + } + + // |webrtc_track| is passed as an argument because |track_ref->webrtc_track()| + // cannot be accessed on the signaling thread. https://crbug.com/756436 + void ReplaceTrackOnSignalingThread( + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + track_ref, + webrtc::MediaStreamTrackInterface* webrtc_track, + base::OnceCallback<void(bool)> callback) { + DCHECK(signaling_task_runner_->BelongsToCurrentThread()); + bool result = webrtc_sender_->SetTrack(webrtc_track); + main_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &RTCRtpSenderImpl::RTCRtpSenderInternal::ReplaceTrackCallback, this, + result, std::move(track_ref), std::move(callback))); + } + + void ReplaceTrackCallback( + bool result, + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + track_ref, + base::OnceCallback<void(bool)> callback) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + if (result) + state_.set_track_ref(std::move(track_ref)); + std::move(callback).Run(result); + } + + void GetStatsOnSignalingThread( + blink::WebRTCStatsReportCallback callback, + const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) { + native_peer_connection_->GetStats( + webrtc_sender_.get(), + blink::CreateRTCStatsCollectorCallback( + main_task_runner_, std::move(callback), exposed_group_ids)); + } + + void SetParametersOnSignalingThread( + webrtc::RtpParameters parameters, + base::OnceCallback<void(webrtc::RTCError)> callback) { + DCHECK(signaling_task_runner_->BelongsToCurrentThread()); + webrtc::RTCError result = webrtc_sender_->SetParameters(parameters); + main_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &RTCRtpSenderImpl::RTCRtpSenderInternal::SetParametersCallback, + this, std::move(result), std::move(callback))); + } + + void SetParametersCallback( + webrtc::RTCError result, + base::OnceCallback<void(webrtc::RTCError)> callback) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + std::move(callback).Run(std::move(result)); + } + + void SetStreamsOnSignalingThread(std::vector<std::string> stream_ids) { + DCHECK(signaling_task_runner_->BelongsToCurrentThread()); + webrtc_sender_->SetStreams(stream_ids); + } + + const scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_; + const scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map_; + // Task runners and webrtc sender: Same information as stored in + // |state_| but const and safe to touch on the signaling thread to + // avoid race with set_state(). + const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_; + const scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender_; + RtpSenderState state_; + webrtc::RtpParameters parameters_; +}; + +struct RTCRtpSenderImpl::RTCRtpSenderInternalTraits { + static void Destruct(const RTCRtpSenderInternal* sender) { + // RTCRtpSenderInternal owns AdapterRefs which have to be destroyed on the + // main thread, this ensures delete always happens there. + if (!sender->main_task_runner_->BelongsToCurrentThread()) { + sender->main_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &RTCRtpSenderImpl::RTCRtpSenderInternalTraits::Destruct, + base::Unretained(sender))); + return; + } + delete sender; + } +}; + +uintptr_t RTCRtpSenderImpl::getId( + const webrtc::RtpSenderInterface* webrtc_sender) { + return reinterpret_cast<uintptr_t>(webrtc_sender); +} + +RTCRtpSenderImpl::RTCRtpSenderImpl( + scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, + scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map, + RtpSenderState state) + : internal_(base::MakeRefCounted<RTCRtpSenderInternal>( + std::move(native_peer_connection), + std::move(track_map), + std::move(state))) {} + +RTCRtpSenderImpl::RTCRtpSenderImpl(const RTCRtpSenderImpl& other) + : internal_(other.internal_) {} + +RTCRtpSenderImpl::~RTCRtpSenderImpl() {} + +RTCRtpSenderImpl& RTCRtpSenderImpl::operator=(const RTCRtpSenderImpl& other) { + internal_ = other.internal_; + return *this; +} + +const RtpSenderState& RTCRtpSenderImpl::state() const { + return internal_->state(); +} + +void RTCRtpSenderImpl::set_state(RtpSenderState state) { + internal_->set_state(std::move(state)); +} + +std::unique_ptr<blink::WebRTCRtpSender> RTCRtpSenderImpl::ShallowCopy() const { + return std::make_unique<RTCRtpSenderImpl>(*this); +} + +uintptr_t RTCRtpSenderImpl::Id() const { + return getId(internal_->state().webrtc_sender().get()); +} + +rtc::scoped_refptr<webrtc::DtlsTransportInterface> +RTCRtpSenderImpl::DtlsTransport() { + return internal_->state().webrtc_dtls_transport(); +} + +webrtc::DtlsTransportInformation RTCRtpSenderImpl::DtlsTransportInformation() { + return internal_->state().webrtc_dtls_transport_information(); +} + +blink::WebMediaStreamTrack RTCRtpSenderImpl::Track() const { + const auto& track_ref = internal_->state().track_ref(); + return track_ref ? track_ref->web_track() : blink::WebMediaStreamTrack(); +} + +blink::WebVector<blink::WebString> RTCRtpSenderImpl::StreamIds() const { + const auto& stream_ids = internal_->state().stream_ids(); + blink::WebVector<blink::WebString> web_stream_ids(stream_ids.size()); + for (size_t i = 0; i < stream_ids.size(); ++i) + web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids[i]); + return web_stream_ids; +} + +void RTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track, + blink::WebRTCVoidRequest request) { + internal_->ReplaceTrack( + std::move(with_track), + base::BindOnce(&OnReplaceTrackCompleted, std::move(request))); +} + +std::unique_ptr<blink::WebRTCDTMFSenderHandler> +RTCRtpSenderImpl::GetDtmfSender() const { + return internal_->GetDtmfSender(); +} + +std::unique_ptr<webrtc::RtpParameters> RTCRtpSenderImpl::GetParameters() const { + return internal_->GetParameters(); +} + +void RTCRtpSenderImpl::SetParameters( + blink::WebVector<webrtc::RtpEncodingParameters> encodings, + webrtc::DegradationPreference degradation_preference, + blink::WebRTCVoidRequest request) { + internal_->SetParameters( + std::move(encodings), degradation_preference, + base::BindOnce(&OnSetParametersCompleted, std::move(request))); +} + +void RTCRtpSenderImpl::GetStats( + blink::WebRTCStatsReportCallback callback, + const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) { + internal_->GetStats(std::move(callback), exposed_group_ids); +} + +void RTCRtpSenderImpl::SetStreams( + const blink::WebVector<blink::WebString>& stream_ids) { + std::vector<std::string> ids; + for (auto stream_id : stream_ids) + ids.emplace_back(stream_id.Utf8()); + + internal_->SetStreams(std::move(ids)); +} + +void RTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track, + base::OnceCallback<void(bool)> callback) { + internal_->ReplaceTrack(std::move(with_track), std::move(callback)); +} + +bool RTCRtpSenderImpl::RemoveFromPeerConnection( + webrtc::PeerConnectionInterface* pc) { + return internal_->RemoveFromPeerConnection(pc); +} + +RTCRtpSenderOnlyTransceiver::RTCRtpSenderOnlyTransceiver( + std::unique_ptr<blink::WebRTCRtpSender> sender) + : sender_(std::move(sender)) { + DCHECK(sender_); +} + +RTCRtpSenderOnlyTransceiver::~RTCRtpSenderOnlyTransceiver() {} + +blink::WebRTCRtpTransceiverImplementationType +RTCRtpSenderOnlyTransceiver::ImplementationType() const { + return blink::WebRTCRtpTransceiverImplementationType::kPlanBSenderOnly; +} + +uintptr_t RTCRtpSenderOnlyTransceiver::Id() const { + NOTIMPLEMENTED(); + return 0u; +} + +blink::WebString RTCRtpSenderOnlyTransceiver::Mid() const { + NOTIMPLEMENTED(); + return blink::WebString(); +} + +std::unique_ptr<blink::WebRTCRtpSender> RTCRtpSenderOnlyTransceiver::Sender() + const { + return sender_->ShallowCopy(); +} + +std::unique_ptr<blink::WebRTCRtpReceiver> +RTCRtpSenderOnlyTransceiver::Receiver() const { + NOTIMPLEMENTED(); + return nullptr; +} + +bool RTCRtpSenderOnlyTransceiver::Stopped() const { + NOTIMPLEMENTED(); + return false; +} + +webrtc::RtpTransceiverDirection RTCRtpSenderOnlyTransceiver::Direction() const { + NOTIMPLEMENTED(); + return webrtc::RtpTransceiverDirection::kSendOnly; +} + +void RTCRtpSenderOnlyTransceiver::SetDirection( + webrtc::RtpTransceiverDirection direction) { + NOTIMPLEMENTED(); +} + +base::Optional<webrtc::RtpTransceiverDirection> +RTCRtpSenderOnlyTransceiver::CurrentDirection() const { + NOTIMPLEMENTED(); + return webrtc::RtpTransceiverDirection::kSendOnly; +} + +base::Optional<webrtc::RtpTransceiverDirection> +RTCRtpSenderOnlyTransceiver::FiredDirection() const { + NOTIMPLEMENTED(); + return webrtc::RtpTransceiverDirection::kSendOnly; +} + +webrtc::RTCError RTCRtpSenderOnlyTransceiver::SetCodecPreferences( + blink::WebVector<webrtc::RtpCodecCapability>) { + NOTIMPLEMENTED(); + return {}; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc new file mode 100644 index 00000000000..e2f91b39287 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc @@ -0,0 +1,261 @@ +// Copyright (c) 2017 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 "third_party/blink/public/web/modules/peerconnection/rtc_rtp_sender_impl.h" + +#include <memory> + +#include "base/bind.h" +#include "base/memory/scoped_refptr.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "build/build_config.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" +#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" +#include "third_party/blink/public/platform/web_media_stream_source.h" +#include "third_party/blink/public/platform/web_media_stream_track.h" +#include "third_party/blink/public/platform/web_rtc_stats.h" +#include "third_party/blink/public/platform/web_rtc_void_request.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_dependency_factory.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_impl.h" +#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h" +#include "third_party/blink/public/web/modules/peerconnection/webrtc_stats_report_obtainer.h" +#include "third_party/blink/public/web/web_heap.h" +#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" +#include "third_party/webrtc/api/stats/rtc_stats_report.h" +#include "third_party/webrtc/api/stats/rtcstats_objects.h" +#include "third_party/webrtc/api/test/mock_rtpsender.h" + +using ::testing::_; +using ::testing::Return; + +namespace blink { + +class RTCRtpSenderImplTest : public ::testing::Test { + public: + void SetUp() override { + dependency_factory_.reset(new blink::MockPeerConnectionDependencyFactory()); + main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting(); + track_map_ = new blink::WebRtcMediaStreamTrackAdapterMap( + dependency_factory_.get(), main_thread_); + peer_connection_ = new rtc::RefCountedObject<blink::MockPeerConnectionImpl>( + dependency_factory_.get(), nullptr); + mock_webrtc_sender_ = new rtc::RefCountedObject<webrtc::MockRtpSender>(); + } + + void TearDown() override { + sender_.reset(); + // Syncing up with the signaling thread ensures any pending operations on + // that thread are executed. If they post back to the main thread, such as + // the sender's destructor traits, this is allowed to execute before the + // test shuts down the threads. + SyncWithSignalingThread(); + blink::WebHeap::CollectAllGarbageForTesting(); + } + + // Wait for the signaling thread to perform any queued tasks, executing tasks + // posted to the current thread in the meantime while waiting. + void SyncWithSignalingThread() const { + base::RunLoop run_loop; + dependency_factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, run_loop.QuitClosure()); + run_loop.Run(); + } + + blink::WebMediaStreamTrack CreateWebTrack(const std::string& id) { + blink::WebMediaStreamSource web_source; + web_source.Initialize( + blink::WebString::FromUTF8(id), blink::WebMediaStreamSource::kTypeAudio, + blink::WebString::FromUTF8("local_audio_track"), false); + blink::MediaStreamAudioSource* audio_source = + new blink::MediaStreamAudioSource( + blink::scheduler::GetSingleThreadTaskRunnerForTesting(), true); + // Takes ownership of |audio_source|. + web_source.SetPlatformSource(base::WrapUnique(audio_source)); + blink::WebMediaStreamTrack web_track; + web_track.Initialize(web_source.Id(), web_source); + audio_source->ConnectToTrack(web_track); + return web_track; + } + + std::unique_ptr<RTCRtpSenderImpl> CreateSender( + blink::WebMediaStreamTrack web_track) { + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + track_ref; + if (!web_track.IsNull()) { + track_ref = track_map_->GetOrCreateLocalTrackAdapter(web_track); + DCHECK(track_ref->is_initialized()); + } + RtpSenderState sender_state( + main_thread_, dependency_factory_->GetWebRtcSignalingTaskRunner(), + mock_webrtc_sender_.get(), std::move(track_ref), + std::vector<std::string>()); + sender_state.Initialize(); + return std::make_unique<RTCRtpSenderImpl>( + peer_connection_.get(), track_map_, std::move(sender_state)); + } + + // Calls replaceTrack(), which is asynchronous, returning a callback that when + // invoked waits for (run-loops) the operation to complete and returns whether + // replaceTrack() was successful. + base::OnceCallback<bool()> ReplaceTrack( + blink::WebMediaStreamTrack web_track) { + std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>(); + std::unique_ptr<bool> result_holder(new bool()); + // On complete, |*result_holder| is set with the result of replaceTrack() + // and the |run_loop| quit. + sender_->ReplaceTrack( + web_track, base::BindOnce(&RTCRtpSenderImplTest::CallbackOnComplete, + base::Unretained(this), result_holder.get(), + run_loop.get())); + // When the resulting callback is invoked, waits for |run_loop| to complete + // and returns |*result_holder|. + return base::BindOnce(&RTCRtpSenderImplTest::RunLoopAndReturnResult, + base::Unretained(this), std::move(result_holder), + std::move(run_loop)); + } + + scoped_refptr<blink::WebRTCStatsReportObtainer> CallGetStats() { + scoped_refptr<blink::WebRTCStatsReportObtainer> obtainer = + new blink::WebRTCStatsReportObtainer(); + sender_->GetStats(obtainer->GetStatsCallbackWrapper(), {}); + return obtainer; + } + + protected: + void CallbackOnComplete(bool* result_out, + base::RunLoop* run_loop, + bool result) { + *result_out = result; + run_loop->Quit(); + } + + bool RunLoopAndReturnResult(std::unique_ptr<bool> result_holder, + std::unique_ptr<base::RunLoop> run_loop) { + run_loop->Run(); + return *result_holder; + } + + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; + + std::unique_ptr<blink::MockPeerConnectionDependencyFactory> + dependency_factory_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_; + scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map_; + rtc::scoped_refptr<blink::MockPeerConnectionImpl> peer_connection_; + rtc::scoped_refptr<webrtc::MockRtpSender> mock_webrtc_sender_; + std::unique_ptr<RTCRtpSenderImpl> sender_; +}; + +TEST_F(RTCRtpSenderImplTest, CreateSender) { + auto web_track = CreateWebTrack("track_id"); + sender_ = CreateSender(web_track); + EXPECT_FALSE(sender_->Track().IsNull()); + EXPECT_EQ(web_track.UniqueId(), sender_->Track().UniqueId()); +} + +TEST_F(RTCRtpSenderImplTest, CreateSenderWithNullTrack) { + blink::WebMediaStreamTrack null_track; + sender_ = CreateSender(null_track); + EXPECT_TRUE(sender_->Track().IsNull()); +} + +TEST_F(RTCRtpSenderImplTest, ReplaceTrackSetsTrack) { + auto web_track1 = CreateWebTrack("track1"); + sender_ = CreateSender(web_track1); + + auto web_track2 = CreateWebTrack("track2"); + EXPECT_CALL(*mock_webrtc_sender_, SetTrack(_)).WillOnce(Return(true)); + auto replaceTrackRunLoopAndGetResult = ReplaceTrack(web_track2); + EXPECT_TRUE(std::move(replaceTrackRunLoopAndGetResult).Run()); + ASSERT_FALSE(sender_->Track().IsNull()); + EXPECT_EQ(web_track2.UniqueId(), sender_->Track().UniqueId()); +} + +TEST_F(RTCRtpSenderImplTest, ReplaceTrackWithNullTrack) { + auto web_track = CreateWebTrack("track_id"); + sender_ = CreateSender(web_track); + + blink::WebMediaStreamTrack null_track; + EXPECT_CALL(*mock_webrtc_sender_, SetTrack(_)).WillOnce(Return(true)); + auto replaceTrackRunLoopAndGetResult = ReplaceTrack(null_track); + EXPECT_TRUE(std::move(replaceTrackRunLoopAndGetResult).Run()); + EXPECT_TRUE(sender_->Track().IsNull()); +} + +TEST_F(RTCRtpSenderImplTest, ReplaceTrackCanFail) { + auto web_track = CreateWebTrack("track_id"); + sender_ = CreateSender(web_track); + ASSERT_FALSE(sender_->Track().IsNull()); + EXPECT_EQ(web_track.UniqueId(), sender_->Track().UniqueId()); + + blink::WebMediaStreamTrack null_track; + EXPECT_CALL(*mock_webrtc_sender_, SetTrack(_)).WillOnce(Return(false)); + auto replaceTrackRunLoopAndGetResult = ReplaceTrack(null_track); + EXPECT_FALSE(std::move(replaceTrackRunLoopAndGetResult).Run()); + // The track should not have been set. + ASSERT_FALSE(sender_->Track().IsNull()); + EXPECT_EQ(web_track.UniqueId(), sender_->Track().UniqueId()); +} + +TEST_F(RTCRtpSenderImplTest, ReplaceTrackIsNotSetSynchronously) { + auto web_track1 = CreateWebTrack("track1"); + sender_ = CreateSender(web_track1); + + auto web_track2 = CreateWebTrack("track2"); + EXPECT_CALL(*mock_webrtc_sender_, SetTrack(_)).WillOnce(Return(true)); + auto replaceTrackRunLoopAndGetResult = ReplaceTrack(web_track2); + // The track should not be set until the run loop has executed. + ASSERT_FALSE(sender_->Track().IsNull()); + EXPECT_NE(web_track2.UniqueId(), sender_->Track().UniqueId()); + // Wait for operation to run to ensure EXPECT_CALL is satisfied. + std::move(replaceTrackRunLoopAndGetResult).Run(); +} + +TEST_F(RTCRtpSenderImplTest, GetStats) { + auto web_track = CreateWebTrack("track_id"); + sender_ = CreateSender(web_track); + + // Make the mock return a blink version of the |webtc_report|. The mock does + // not perform any stats filtering, we just set it to a dummy value. + rtc::scoped_refptr<webrtc::RTCStatsReport> webrtc_report = + webrtc::RTCStatsReport::Create(0u); + webrtc_report->AddStats( + std::make_unique<webrtc::RTCOutboundRTPStreamStats>("stats-id", 1234u)); + peer_connection_->SetGetStatsReport(webrtc_report); + + auto obtainer = CallGetStats(); + // Make sure the operation is async. + EXPECT_FALSE(obtainer->report()); + // Wait for the report, this performs the necessary run-loop. + auto* report = obtainer->WaitForReport(); + EXPECT_TRUE(report); + + // Verify dummy value. + EXPECT_EQ(report->Size(), 1u); + auto stats = report->GetStats(blink::WebString::FromUTF8("stats-id")); + EXPECT_TRUE(stats); + EXPECT_EQ(stats->Timestamp(), 1.234); +} + +TEST_F(RTCRtpSenderImplTest, CopiedSenderSharesInternalStates) { + auto web_track = CreateWebTrack("track_id"); + sender_ = CreateSender(web_track); + auto copy = std::make_unique<RTCRtpSenderImpl>(*sender_); + // Copy shares original's ID. + EXPECT_EQ(sender_->Id(), copy->Id()); + + blink::WebMediaStreamTrack null_track; + EXPECT_CALL(*mock_webrtc_sender_, SetTrack(_)).WillOnce(Return(true)); + auto replaceTrackRunLoopAndGetResult = ReplaceTrack(null_track); + EXPECT_TRUE(std::move(replaceTrackRunLoopAndGetResult).Run()); + + // Both original and copy shows a modified state. + EXPECT_TRUE(sender_->Track().IsNull()); + EXPECT_TRUE(copy->Track().IsNull()); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.cc new file mode 100644 index 00000000000..0a68985d6e2 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl.cc @@ -0,0 +1,384 @@ +// 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 "third_party/blink/public/web/modules/peerconnection/rtc_rtp_transceiver_impl.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" +#include "third_party/webrtc/api/scoped_refptr.h" + +namespace blink { + +RtpTransceiverState::RtpTransceiverState( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver, + base::Optional<blink::RtpSenderState> sender_state, + base::Optional<blink::RtpReceiverState> receiver_state, + base::Optional<std::string> mid, + bool stopped, + webrtc::RtpTransceiverDirection direction, + base::Optional<webrtc::RtpTransceiverDirection> current_direction, + base::Optional<webrtc::RtpTransceiverDirection> fired_direction) + : main_task_runner_(std::move(main_task_runner)), + signaling_task_runner_(std::move(signaling_task_runner)), + webrtc_transceiver_(std::move(webrtc_transceiver)), + is_initialized_(false), + sender_state_(std::move(sender_state)), + receiver_state_(std::move(receiver_state)), + mid_(std::move(mid)), + stopped_(std::move(stopped)), + direction_(std::move(direction)), + current_direction_(std::move(current_direction)), + fired_direction_(std::move(fired_direction)) { + DCHECK(main_task_runner_); + DCHECK(signaling_task_runner_); + DCHECK(webrtc_transceiver_); +} + +RtpTransceiverState::RtpTransceiverState(RtpTransceiverState&& other) + : main_task_runner_(other.main_task_runner_), + signaling_task_runner_(other.signaling_task_runner_), + webrtc_transceiver_(std::move(other.webrtc_transceiver_)), + is_initialized_(other.is_initialized_), + sender_state_(std::move(other.sender_state_)), + receiver_state_(std::move(other.receiver_state_)), + mid_(std::move(other.mid_)), + stopped_(std::move(other.stopped_)), + direction_(std::move(other.direction_)), + current_direction_(std::move(other.current_direction_)), + fired_direction_(std::move(other.fired_direction_)) { + // Explicitly null |other|'s task runners for use in destructor. + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; +} + +RtpTransceiverState::~RtpTransceiverState() { + // It's OK to not be on the main thread if this state has been moved, in which + // case |main_task_runner_| is null. + DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread()); +} + +RtpTransceiverState& RtpTransceiverState::operator=( + RtpTransceiverState&& other) { + DCHECK_EQ(main_task_runner_, other.main_task_runner_); + DCHECK_EQ(signaling_task_runner_, other.signaling_task_runner_); + // Need to be on main thread for sender/receiver state's destructor that can + // be triggered by replacing . + DCHECK(main_task_runner_->BelongsToCurrentThread()); + // Explicitly null |other|'s task runners for use in destructor. + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; + webrtc_transceiver_ = std::move(other.webrtc_transceiver_); + is_initialized_ = other.is_initialized_; + sender_state_ = std::move(other.sender_state_); + receiver_state_ = std::move(other.receiver_state_); + mid_ = std::move(other.mid_); + stopped_ = std::move(other.stopped_); + direction_ = std::move(other.direction_); + current_direction_ = std::move(other.current_direction_); + fired_direction_ = std::move(other.fired_direction_); + return *this; +} + +bool RtpTransceiverState::is_initialized() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return is_initialized_; +} + +void RtpTransceiverState::Initialize() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + if (sender_state_) + sender_state_->Initialize(); + if (receiver_state_) + receiver_state_->Initialize(); + is_initialized_ = true; +} + +scoped_refptr<base::SingleThreadTaskRunner> +RtpTransceiverState::main_task_runner() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return main_task_runner_; +} + +scoped_refptr<base::SingleThreadTaskRunner> +RtpTransceiverState::signaling_task_runner() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return signaling_task_runner_; +} + +scoped_refptr<webrtc::RtpTransceiverInterface> +RtpTransceiverState::webrtc_transceiver() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return webrtc_transceiver_; +} + +const base::Optional<blink::RtpSenderState>& RtpTransceiverState::sender_state() + const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return sender_state_; +} + +blink::RtpSenderState RtpTransceiverState::MoveSenderState() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + base::Optional<blink::RtpSenderState> temp(base::nullopt); + sender_state_.swap(temp); + return *std::move(temp); +} + +const base::Optional<blink::RtpReceiverState>& +RtpTransceiverState::receiver_state() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return receiver_state_; +} + +blink::RtpReceiverState RtpTransceiverState::MoveReceiverState() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + base::Optional<blink::RtpReceiverState> temp(base::nullopt); + receiver_state_.swap(temp); + return *std::move(temp); +} + +base::Optional<std::string> RtpTransceiverState::mid() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return mid_; +} + +bool RtpTransceiverState::stopped() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return stopped_; +} + +webrtc::RtpTransceiverDirection RtpTransceiverState::direction() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return direction_; +} + +void RtpTransceiverState::set_direction( + webrtc::RtpTransceiverDirection direction) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + direction_ = direction; +} + +base::Optional<webrtc::RtpTransceiverDirection> +RtpTransceiverState::current_direction() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return current_direction_; +} + +base::Optional<webrtc::RtpTransceiverDirection> +RtpTransceiverState::fired_direction() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return fired_direction_; +} + +class RTCRtpTransceiverImpl::RTCRtpTransceiverInternal + : public WTF::ThreadSafeRefCounted< + RTCRtpTransceiverImpl::RTCRtpTransceiverInternal, + RTCRtpTransceiverImpl::RTCRtpTransceiverInternalTraits> { + public: + RTCRtpTransceiverInternal( + scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, + scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map, + RtpTransceiverState state) + : main_task_runner_(state.main_task_runner()), + signaling_task_runner_(state.signaling_task_runner()), + webrtc_transceiver_(state.webrtc_transceiver()), + state_(std::move(state)) { + sender_ = std::make_unique<blink::RTCRtpSenderImpl>( + native_peer_connection, track_map, state_.MoveSenderState()); + receiver_ = std::make_unique<blink::RTCRtpReceiverImpl>( + native_peer_connection, state_.MoveReceiverState()); + } + + const RtpTransceiverState& state() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return state_; + } + + void set_state(RtpTransceiverState state, + TransceiverStateUpdateMode update_mode) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK_EQ(state.main_task_runner(), main_task_runner_); + DCHECK_EQ(state.signaling_task_runner(), signaling_task_runner_); + DCHECK(state.webrtc_transceiver() == webrtc_transceiver_); + DCHECK(state.is_initialized()); + auto previous_direction = state_.direction(); + state_ = std::move(state); + auto sender_state = state_.MoveSenderState(); + if (update_mode == TransceiverStateUpdateMode::kSetDescription) { + // setLocalDescription() and setRemoteDescription() cannot modify + // "sender.track" or "direction", so this part of the state information is + // either identical to the current state or out-dated information. + // Surfacing out-dated information has caused crashes and other problems, + // see https://crbug.com/950280. + sender_state.set_track_ref(sender_->state().track_ref() + ? sender_->state().track_ref()->Copy() + : nullptr); + state_.set_direction(previous_direction); + } + sender_->set_state(std::move(sender_state)); + receiver_->set_state(state_.MoveReceiverState()); + } + + blink::RTCRtpSenderImpl* content_sender() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return sender_.get(); + } + + blink::RTCRtpReceiverImpl* content_receiver() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return receiver_.get(); + } + + void SetDirection(webrtc::RtpTransceiverDirection direction) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + // This implicitly performs a blocking invoke on the webrtc signaling thread + // due to use of PROXY references for |webrtc_transceiver_|. + webrtc_transceiver_->SetDirection(direction); + state_.set_direction(webrtc_transceiver_->direction()); + } + + webrtc::RTCError setCodecPreferences( + std::vector<webrtc::RtpCodecCapability> codec_preferences) { + return webrtc_transceiver_->SetCodecPreferences(codec_preferences); + } + + private: + friend class WTF::ThreadSafeRefCounted<RTCRtpTransceiverInternal, + RTCRtpTransceiverInternalTraits>; + friend struct RTCRtpTransceiverImpl::RTCRtpTransceiverInternalTraits; + + ~RTCRtpTransceiverInternal() { + // Ensured by destructor traits. + DCHECK(main_task_runner_->BelongsToCurrentThread()); + } + + // Task runners and webrtc transceiver: Same information as stored in |state_| + // but const and safe to touch on the signaling thread to avoid race with + // set_state(). + const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_; + const scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver_; + RtpTransceiverState state_; + std::unique_ptr<blink::RTCRtpSenderImpl> sender_; + std::unique_ptr<blink::RTCRtpReceiverImpl> receiver_; +}; + +struct RTCRtpTransceiverImpl::RTCRtpTransceiverInternalTraits { + static void Destruct(const RTCRtpTransceiverInternal* transceiver) { + // RTCRtpTransceiverInternal owns AdapterRefs which have to be destroyed on + // the main thread, this ensures delete always happens there. + if (!transceiver->main_task_runner_->BelongsToCurrentThread()) { + transceiver->main_task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &RTCRtpTransceiverImpl::RTCRtpTransceiverInternalTraits::Destruct, + base::Unretained(transceiver))); + return; + } + delete transceiver; + } +}; + +uintptr_t RTCRtpTransceiverImpl::GetId( + const webrtc::RtpTransceiverInterface* webrtc_transceiver) { + return reinterpret_cast<uintptr_t>(webrtc_transceiver); +} + +RTCRtpTransceiverImpl::RTCRtpTransceiverImpl( + scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, + scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map, + RtpTransceiverState transceiver_state) + : internal_(base::MakeRefCounted<RTCRtpTransceiverInternal>( + std::move(native_peer_connection), + std::move(track_map), + std::move(transceiver_state))) {} + +RTCRtpTransceiverImpl::RTCRtpTransceiverImpl(const RTCRtpTransceiverImpl& other) + : internal_(other.internal_) {} + +RTCRtpTransceiverImpl::~RTCRtpTransceiverImpl() {} + +RTCRtpTransceiverImpl& RTCRtpTransceiverImpl::operator=( + const RTCRtpTransceiverImpl& other) { + internal_ = other.internal_; + return *this; +} + +std::unique_ptr<RTCRtpTransceiverImpl> RTCRtpTransceiverImpl::ShallowCopy() + const { + return std::make_unique<RTCRtpTransceiverImpl>(*this); +} + +const RtpTransceiverState& RTCRtpTransceiverImpl::state() const { + return internal_->state(); +} + +blink::RTCRtpSenderImpl* RTCRtpTransceiverImpl::content_sender() { + return internal_->content_sender(); +} + +blink::RTCRtpReceiverImpl* RTCRtpTransceiverImpl::content_receiver() { + return internal_->content_receiver(); +} + +void RTCRtpTransceiverImpl::set_state(RtpTransceiverState transceiver_state, + TransceiverStateUpdateMode update_mode) { + internal_->set_state(std::move(transceiver_state), update_mode); +} + +blink::WebRTCRtpTransceiverImplementationType +RTCRtpTransceiverImpl::ImplementationType() const { + return blink::WebRTCRtpTransceiverImplementationType::kFullTransceiver; +} + +uintptr_t RTCRtpTransceiverImpl::Id() const { + return GetId(internal_->state().webrtc_transceiver().get()); +} + +blink::WebString RTCRtpTransceiverImpl::Mid() const { + const auto& mid = internal_->state().mid(); + return mid ? blink::WebString::FromUTF8(*mid) + : blink::WebString(); // IsNull() +} + +std::unique_ptr<blink::WebRTCRtpSender> RTCRtpTransceiverImpl::Sender() const { + return internal_->content_sender()->ShallowCopy(); +} + +std::unique_ptr<blink::WebRTCRtpReceiver> RTCRtpTransceiverImpl::Receiver() + const { + return internal_->content_receiver()->ShallowCopy(); +} + +bool RTCRtpTransceiverImpl::Stopped() const { + return internal_->state().stopped(); +} + +webrtc::RtpTransceiverDirection RTCRtpTransceiverImpl::Direction() const { + return internal_->state().direction(); +} + +void RTCRtpTransceiverImpl::SetDirection( + webrtc::RtpTransceiverDirection direction) { + internal_->SetDirection(direction); +} + +base::Optional<webrtc::RtpTransceiverDirection> +RTCRtpTransceiverImpl::CurrentDirection() const { + return internal_->state().current_direction(); +} + +base::Optional<webrtc::RtpTransceiverDirection> +RTCRtpTransceiverImpl::FiredDirection() const { + return internal_->state().fired_direction(); +} + +webrtc::RTCError RTCRtpTransceiverImpl::SetCodecPreferences( + blink::WebVector<webrtc::RtpCodecCapability> codec_preferences) { + return internal_->setCodecPreferences(codec_preferences.ReleaseVector()); +} +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc new file mode 100644 index 00000000000..c6210503f09 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_impl_test.cc @@ -0,0 +1,426 @@ +// 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 "third_party/blink/public/web/modules/peerconnection/rtc_rtp_transceiver_impl.h" + +#include <memory> + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/scoped_refptr.h" +#include "base/optional.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" +#include "build/build_config.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" +#include "third_party/blink/public/platform/modules/peerconnection/webrtc_util.h" +#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" +#include "third_party/blink/public/platform/web_media_stream_source.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_dependency_factory.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_impl.h" +#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h" +#include "third_party/blink/public/web/web_heap.h" +#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" +#include "third_party/webrtc/api/test/mock_rtpreceiver.h" +#include "third_party/webrtc/api/test/mock_rtpsender.h" + +namespace blink { + +class RTCRtpTransceiverImplTest : public ::testing::Test { + public: + void SetUp() override { + dependency_factory_.reset(new blink::MockPeerConnectionDependencyFactory()); + main_task_runner_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting(); + track_map_ = new blink::WebRtcMediaStreamTrackAdapterMap( + dependency_factory_.get(), main_task_runner_); + peer_connection_ = new rtc::RefCountedObject<blink::MockPeerConnectionImpl>( + dependency_factory_.get(), nullptr); + } + + void TearDown() override { + // Syncing up with the signaling thread ensures any pending operations on + // that thread are executed. If they post back to the main thread, such as + // the sender or receiver destructor traits, this is allowed to execute + // before the test shuts down the threads. + SyncWithSignalingThread(); + blink::WebHeap::CollectAllGarbageForTesting(); + } + + // Wait for the signaling thread to perform any queued tasks, executing tasks + // posted to the current thread in the meantime while waiting. + void SyncWithSignalingThread() const { + base::RunLoop run_loop; + dependency_factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, run_loop.QuitClosure()); + run_loop.Run(); + } + + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const { + return dependency_factory_->GetWebRtcSignalingTaskRunner(); + } + + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + CreateLocalTrackAndAdapter(const std::string& id) { + return track_map_->GetOrCreateLocalTrackAdapter(CreateBlinkLocalTrack(id)); + } + + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + CreateRemoteTrackAndAdapter(const std::string& id) { + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track = + blink::MockWebRtcAudioTrack::Create(id).get(); + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + track_ref; + base::RunLoop run_loop; + signaling_task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&RTCRtpTransceiverImplTest:: + CreateRemoteTrackAdapterOnSignalingThread, + base::Unretained(this), std::move(webrtc_track), + base::Unretained(&track_ref), + base::Unretained(&run_loop))); + run_loop.Run(); + DCHECK(track_ref); + return track_ref; + } + + rtc::scoped_refptr<blink::FakeRtpSender> CreateWebRtcSender( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + const std::string& stream_id) { + return new rtc::RefCountedObject<blink::FakeRtpSender>( + std::move(track), std::vector<std::string>({stream_id})); + } + + rtc::scoped_refptr<blink::FakeRtpReceiver> CreateWebRtcReceiver( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + const std::string& stream_id) { + rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream( + new rtc::RefCountedObject<blink::MockMediaStream>(stream_id)); + return new rtc::RefCountedObject<blink::FakeRtpReceiver>( + track.get(), + std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>( + {remote_stream})); + } + + rtc::scoped_refptr<blink::FakeRtpTransceiver> CreateWebRtcTransceiver( + rtc::scoped_refptr<blink::FakeRtpSender> sender, + rtc::scoped_refptr<blink::FakeRtpReceiver> receiver, + base::Optional<std::string> mid, + bool stopped, + webrtc::RtpTransceiverDirection direction, + base::Optional<webrtc::RtpTransceiverDirection> current_direction) { + DCHECK(!sender->track() || + sender->track()->kind() == receiver->track()->kind()); + return new rtc::RefCountedObject<blink::FakeRtpTransceiver>( + receiver->track()->kind() == + webrtc::MediaStreamTrackInterface::kAudioKind + ? cricket::MEDIA_TYPE_AUDIO + : cricket::MEDIA_TYPE_VIDEO, + std::move(sender), std::move(receiver), std::move(mid), stopped, + direction, std::move(current_direction)); + } + + RtpTransceiverState CreateTransceiverState( + rtc::scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver, + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + sender_track_ref, + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + receiver_track_ref) { + std::vector<std::string> receiver_stream_ids; + for (const auto& stream : webrtc_transceiver->receiver()->streams()) { + receiver_stream_ids.push_back(stream->id()); + } + return RtpTransceiverState( + main_task_runner_, signaling_task_runner(), webrtc_transceiver.get(), + blink::RtpSenderState(main_task_runner_, signaling_task_runner(), + webrtc_transceiver->sender().get(), + std::move(sender_track_ref), + webrtc_transceiver->sender()->stream_ids()), + blink::RtpReceiverState(main_task_runner_, signaling_task_runner(), + webrtc_transceiver->receiver().get(), + std::move(receiver_track_ref), + std::move(receiver_stream_ids)), + blink::ToBaseOptional(webrtc_transceiver->mid()), + webrtc_transceiver->stopped(), webrtc_transceiver->direction(), + blink::ToBaseOptional(webrtc_transceiver->current_direction()), + blink::ToBaseOptional(webrtc_transceiver->fired_direction())); + } + + protected: + blink::WebMediaStreamTrack CreateBlinkLocalTrack(const std::string& id) { + blink::WebMediaStreamSource web_source; + web_source.Initialize( + blink::WebString::FromUTF8(id), blink::WebMediaStreamSource::kTypeAudio, + blink::WebString::FromUTF8("local_audio_track"), false); + blink::MediaStreamAudioSource* audio_source = + new blink::MediaStreamAudioSource( + blink::scheduler::GetSingleThreadTaskRunnerForTesting(), true); + // Takes ownership of |audio_source|. + web_source.SetPlatformSource(base::WrapUnique(audio_source)); + + blink::WebMediaStreamTrack web_track; + web_track.Initialize(web_source.Id(), web_source); + audio_source->ConnectToTrack(web_track); + return web_track; + } + + void CreateRemoteTrackAdapterOnSignalingThread( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track, + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>* + track_ref, + base::RunLoop* run_loop) { + *track_ref = track_map_->GetOrCreateRemoteTrackAdapter(webrtc_track.get()); + run_loop->Quit(); + } + + private: + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; + + protected: + std::unique_ptr<blink::MockPeerConnectionDependencyFactory> + dependency_factory_; + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map_; + rtc::scoped_refptr<blink::MockPeerConnectionImpl> peer_connection_; +}; + +TEST_F(RTCRtpTransceiverImplTest, InitializeTransceiverState) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track"); + auto webrtc_transceiver = CreateWebRtcTransceiver( + CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream"), + CreateWebRtcReceiver(remote_track_adapter->webrtc_track(), + "remote_stream"), + base::nullopt, false, webrtc::RtpTransceiverDirection::kSendRecv, + base::nullopt); + RtpTransceiverState transceiver_state = + CreateTransceiverState(webrtc_transceiver, std::move(local_track_adapter), + std::move(remote_track_adapter)); + EXPECT_FALSE(transceiver_state.is_initialized()); + transceiver_state.Initialize(); + + EXPECT_TRUE(transceiver_state.is_initialized()); + // Inspect sender states. + const auto& sender_state = transceiver_state.sender_state(); + EXPECT_TRUE(sender_state); + EXPECT_TRUE(sender_state->is_initialized()); + const auto& webrtc_sender = webrtc_transceiver->sender(); + EXPECT_EQ(sender_state->webrtc_sender().get(), webrtc_sender.get()); + EXPECT_TRUE(sender_state->track_ref()->is_initialized()); + EXPECT_EQ(sender_state->track_ref()->webrtc_track(), + webrtc_sender->track().get()); + EXPECT_EQ(sender_state->stream_ids(), webrtc_sender->stream_ids()); + // Inspect receiver states. + const auto& receiver_state = transceiver_state.receiver_state(); + EXPECT_TRUE(receiver_state); + EXPECT_TRUE(receiver_state->is_initialized()); + const auto& webrtc_receiver = webrtc_transceiver->receiver(); + EXPECT_EQ(receiver_state->webrtc_receiver().get(), webrtc_receiver.get()); + EXPECT_TRUE(receiver_state->track_ref()->is_initialized()); + EXPECT_EQ(receiver_state->track_ref()->webrtc_track(), + webrtc_receiver->track().get()); + std::vector<std::string> receiver_stream_ids; + for (const auto& stream : webrtc_receiver->streams()) { + receiver_stream_ids.push_back(stream->id()); + } + EXPECT_EQ(receiver_state->stream_ids(), receiver_stream_ids); + // Inspect transceiver states. + EXPECT_TRUE(blink::OptionalEquals(transceiver_state.mid(), + webrtc_transceiver->mid())); + EXPECT_EQ(transceiver_state.stopped(), webrtc_transceiver->stopped()); + EXPECT_TRUE(transceiver_state.direction() == webrtc_transceiver->direction()); + EXPECT_TRUE(blink::OptionalEquals(transceiver_state.current_direction(), + webrtc_transceiver->current_direction())); + EXPECT_TRUE(blink::OptionalEquals(transceiver_state.fired_direction(), + webrtc_transceiver->fired_direction())); +} + +TEST_F(RTCRtpTransceiverImplTest, CreateTranceiver) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track"); + auto webrtc_transceiver = CreateWebRtcTransceiver( + CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream"), + CreateWebRtcReceiver(remote_track_adapter->webrtc_track(), + "remote_stream"), + base::nullopt, false, webrtc::RtpTransceiverDirection::kSendRecv, + base::nullopt); + RtpTransceiverState transceiver_state = + CreateTransceiverState(webrtc_transceiver, std::move(local_track_adapter), + std::move(remote_track_adapter)); + EXPECT_FALSE(transceiver_state.is_initialized()); + transceiver_state.Initialize(); + + RTCRtpTransceiverImpl transceiver(peer_connection_.get(), track_map_, + std::move(transceiver_state)); + EXPECT_TRUE(transceiver.Mid().IsNull()); + EXPECT_TRUE(transceiver.Sender()); + EXPECT_TRUE(transceiver.Receiver()); + EXPECT_FALSE(transceiver.Stopped()); + EXPECT_EQ(transceiver.Direction(), + webrtc::RtpTransceiverDirection::kSendRecv); + EXPECT_FALSE(transceiver.CurrentDirection()); + EXPECT_FALSE(transceiver.FiredDirection()); +} + +TEST_F(RTCRtpTransceiverImplTest, ModifyTransceiver) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track"); + auto webrtc_sender = + CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream"); + auto webrtc_receiver = CreateWebRtcReceiver( + remote_track_adapter->webrtc_track(), "remote_stream"); + auto webrtc_transceiver = CreateWebRtcTransceiver( + webrtc_sender, webrtc_receiver, base::nullopt, false, + webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt); + + // Create initial state. + RtpTransceiverState initial_transceiver_state = + CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(), + remote_track_adapter->Copy()); + EXPECT_FALSE(initial_transceiver_state.is_initialized()); + initial_transceiver_state.Initialize(); + + // Modify the webrtc transceiver and create a new state object for the + // modified state. + *webrtc_transceiver = + *CreateWebRtcTransceiver(webrtc_sender, webrtc_receiver, "MidyMacMidface", + true, webrtc::RtpTransceiverDirection::kInactive, + webrtc::RtpTransceiverDirection::kSendRecv); + RtpTransceiverState modified_transceiver_state = + CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(), + remote_track_adapter->Copy()); + EXPECT_FALSE(modified_transceiver_state.is_initialized()); + modified_transceiver_state.Initialize(); + + // Modifying the webrtc transceiver after the initial state was created should + // not have affected the transceiver state. + RTCRtpTransceiverImpl transceiver(peer_connection_.get(), track_map_, + std::move(initial_transceiver_state)); + EXPECT_TRUE(transceiver.Mid().IsNull()); + EXPECT_TRUE(transceiver.Sender()); + EXPECT_TRUE(transceiver.Receiver()); + EXPECT_FALSE(transceiver.Stopped()); + EXPECT_EQ(transceiver.Direction(), + webrtc::RtpTransceiverDirection::kSendRecv); + EXPECT_FALSE(transceiver.CurrentDirection()); + EXPECT_FALSE(transceiver.FiredDirection()); + + // Setting the state should make the transceiver state up-to-date. + transceiver.set_state(std::move(modified_transceiver_state), + TransceiverStateUpdateMode::kAll); + EXPECT_EQ(transceiver.Mid(), "MidyMacMidface"); + EXPECT_TRUE(transceiver.Sender()); + EXPECT_TRUE(transceiver.Receiver()); + EXPECT_TRUE(transceiver.Stopped()); + EXPECT_EQ(transceiver.Direction(), + webrtc::RtpTransceiverDirection::kInactive); + EXPECT_TRUE(transceiver.CurrentDirection() == + webrtc::RtpTransceiverDirection::kSendRecv); + EXPECT_FALSE(transceiver.FiredDirection()); +} + +TEST_F(RTCRtpTransceiverImplTest, ShallowCopy) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track"); + auto webrtc_sender = + CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream"); + auto webrtc_receiver = CreateWebRtcReceiver( + remote_track_adapter->webrtc_track(), "remote_stream"); + auto webrtc_transceiver = CreateWebRtcTransceiver( + webrtc_sender, webrtc_receiver, base::nullopt, false /* stopped */, + webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt); + + std::unique_ptr<RTCRtpTransceiverImpl> transceiver; + // Create transceiver. + { + RtpTransceiverState transceiver_state = + CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(), + remote_track_adapter->Copy()); + EXPECT_FALSE(transceiver_state.is_initialized()); + transceiver_state.Initialize(); + transceiver.reset(new RTCRtpTransceiverImpl( + peer_connection_.get(), track_map_, std::move(transceiver_state))); + } + DCHECK(transceiver); + EXPECT_FALSE(transceiver->Stopped()); + + std::unique_ptr<RTCRtpTransceiverImpl> shallow_copy = + transceiver->ShallowCopy(); + // Modifying the shallow copy should modify the original too since they have a + // shared internal state. + { + // Modify webrtc transceiver to be stopped. + *webrtc_transceiver = *CreateWebRtcTransceiver( + webrtc_sender, webrtc_receiver, base::nullopt, true /* stopped */, + webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt); + RtpTransceiverState transceiver_state = + CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(), + remote_track_adapter->Copy()); + EXPECT_FALSE(transceiver_state.is_initialized()); + transceiver_state.Initialize(); + // Set the state of the shallow copy. + shallow_copy->set_state(std::move(transceiver_state), + TransceiverStateUpdateMode::kAll); + } + EXPECT_TRUE(shallow_copy->Stopped()); + EXPECT_TRUE(transceiver->Stopped()); +} + +TEST_F(RTCRtpTransceiverImplTest, TransceiverStateUpdateModeSetDescription) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track"); + auto webrtc_sender = + CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream"); + auto webrtc_receiver = CreateWebRtcReceiver( + remote_track_adapter->webrtc_track(), "remote_stream"); + auto webrtc_transceiver = CreateWebRtcTransceiver( + webrtc_sender, webrtc_receiver, base::nullopt, false, + webrtc::RtpTransceiverDirection::kSendRecv, base::nullopt); + + // Create initial state. + RtpTransceiverState initial_transceiver_state = + CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(), + remote_track_adapter->Copy()); + EXPECT_FALSE(initial_transceiver_state.is_initialized()); + initial_transceiver_state.Initialize(); + + // Modify the webrtc transceiver and create a new state object for the + // modified state. + webrtc_sender->SetTrack(nullptr); + *webrtc_transceiver = + *CreateWebRtcTransceiver(webrtc_sender, webrtc_receiver, "MidyMacMidface", + true, webrtc::RtpTransceiverDirection::kInactive, + webrtc::RtpTransceiverDirection::kSendRecv); + RtpTransceiverState modified_transceiver_state = + CreateTransceiverState(webrtc_transceiver, local_track_adapter->Copy(), + remote_track_adapter->Copy()); + EXPECT_FALSE(modified_transceiver_state.is_initialized()); + modified_transceiver_state.Initialize(); + + // Construct a transceiver from the initial state. + RTCRtpTransceiverImpl transceiver(peer_connection_.get(), track_map_, + std::move(initial_transceiver_state)); + // Setting the state with TransceiverStateUpdateMode::kSetDescription should + // make the transceiver state up-to-date, except leaving + // "transceiver.direction" and "transceiver.sender.track" unmodified. + transceiver.set_state(std::move(modified_transceiver_state), + TransceiverStateUpdateMode::kSetDescription); + EXPECT_EQ(transceiver.Mid(), "MidyMacMidface"); + EXPECT_TRUE(transceiver.Sender()); + EXPECT_TRUE(transceiver.Receiver()); + EXPECT_TRUE(transceiver.Stopped()); + EXPECT_TRUE(transceiver.CurrentDirection() == + webrtc::RtpTransceiverDirection::kSendRecv); + EXPECT_FALSE(transceiver.FiredDirection()); + // The sender still has a track, even though the modified state doesn't. + EXPECT_FALSE(transceiver.Sender()->Track().IsNull()); + // The direction still "sendrecv", even though the modified state has + // "inactive". + EXPECT_EQ(transceiver.Direction(), + webrtc::RtpTransceiverDirection::kSendRecv); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.cc b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.cc new file mode 100644 index 00000000000..3d996d8ae2d --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.cc @@ -0,0 +1,240 @@ +// 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 "third_party/blink/public/web/modules/peerconnection/transceiver_state_surfacer.h" + +#include "third_party/blink/public/platform/modules/peerconnection/webrtc_util.h" +#include "third_party/webrtc/api/rtp_transceiver_interface.h" +#include "third_party/webrtc/api/sctp_transport_interface.h" + +namespace blink { + +TransceiverStateSurfacer::TransceiverStateSurfacer( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner) + : main_task_runner_(std::move(main_task_runner)), + signaling_task_runner_(std::move(signaling_task_runner)), + is_initialized_(false), + states_obtained_(false) { + DCHECK(main_task_runner_); + DCHECK(signaling_task_runner_); +} + +TransceiverStateSurfacer::TransceiverStateSurfacer( + TransceiverStateSurfacer&& other) + : main_task_runner_(other.main_task_runner_), + signaling_task_runner_(other.signaling_task_runner_), + is_initialized_(other.is_initialized_), + states_obtained_(other.states_obtained_), + sctp_transport_snapshot_(other.sctp_transport_snapshot_), + transceiver_states_(std::move(other.transceiver_states_)) { + // Explicitly null |other|'s task runners for use in destructor. + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; +} + +TransceiverStateSurfacer::~TransceiverStateSurfacer() { + // It's OK to not be on the main thread if this object has been moved, in + // which case |main_task_runner_| is null. + DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread()); +} + +TransceiverStateSurfacer& TransceiverStateSurfacer::operator=( + TransceiverStateSurfacer&& other) { + main_task_runner_ = other.main_task_runner_; + signaling_task_runner_ = other.signaling_task_runner_; + states_obtained_ = other.states_obtained_; + sctp_transport_snapshot_ = other.sctp_transport_snapshot_; + transceiver_states_ = std::move(other.transceiver_states_); + // Explicitly null |other|'s task runners for use in destructor. + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; + return *this; +} + +void TransceiverStateSurfacer::Initialize( + scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, + scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map, + std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> + webrtc_transceivers) { + DCHECK(signaling_task_runner_->BelongsToCurrentThread()); + DCHECK(!is_initialized_); + DCHECK(native_peer_connection); + sctp_transport_snapshot_.transport = + native_peer_connection->GetSctpTransport(); + if (sctp_transport_snapshot_.transport) { + sctp_transport_snapshot_.sctp_transport_state = + sctp_transport_snapshot_.transport->Information(); + if (sctp_transport_snapshot_.sctp_transport_state.dtls_transport()) { + sctp_transport_snapshot_.dtls_transport_state = + sctp_transport_snapshot_.sctp_transport_state.dtls_transport() + ->Information(); + } + } + + for (auto& webrtc_transceiver : webrtc_transceivers) { + // Create the sender state. + base::Optional<blink::RtpSenderState> sender_state; + auto webrtc_sender = webrtc_transceiver->sender(); + if (webrtc_sender) { + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + sender_track_ref; + if (webrtc_sender->track()) { + // The track adapter for this track must already exist for us to obtain + // it, since this cannot be created from the signaling thread. + // TODO(hbos): Consider either making it possible to create local track + // adapters on the signaling thread for initialization on the main + // thread or wait for Onion Souping to simplify this. + // https://crbug.com/787254 + sender_track_ref = + track_adapter_map->GetLocalTrackAdapter(webrtc_sender->track()); + CHECK(sender_track_ref); + } + sender_state = blink::RtpSenderState( + main_task_runner_, signaling_task_runner_, webrtc_sender.get(), + std::move(sender_track_ref), webrtc_sender->stream_ids()); + } + // Create the receiver state. + base::Optional<blink::RtpReceiverState> receiver_state; + auto webrtc_receiver = webrtc_transceiver->receiver(); + if (webrtc_receiver) { + DCHECK(webrtc_receiver->track()); + auto receiver_track_ref = + track_adapter_map->GetOrCreateRemoteTrackAdapter( + webrtc_receiver->track().get()); + DCHECK(receiver_track_ref); + std::vector<std::string> receiver_stream_ids; + for (auto& stream : webrtc_receiver->streams()) { + receiver_stream_ids.push_back(stream->id()); + } + receiver_state = blink::RtpReceiverState( + main_task_runner_, signaling_task_runner_, webrtc_receiver.get(), + std::move(receiver_track_ref), std::move(receiver_stream_ids)); + } + // Create the transceiver state. + transceiver_states_.push_back(blink::RtpTransceiverState( + main_task_runner_, signaling_task_runner_, webrtc_transceiver.get(), + std::move(sender_state), std::move(receiver_state), + blink::ToBaseOptional(webrtc_transceiver->mid()), + webrtc_transceiver->stopped(), webrtc_transceiver->direction(), + blink::ToBaseOptional(webrtc_transceiver->current_direction()), + blink::ToBaseOptional(webrtc_transceiver->fired_direction()))); + } + is_initialized_ = true; +} + +blink::WebRTCSctpTransportSnapshot +TransceiverStateSurfacer::SctpTransportSnapshot() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK(is_initialized_); + return sctp_transport_snapshot_; +} + +std::vector<blink::RtpTransceiverState> +TransceiverStateSurfacer::ObtainStates() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK(is_initialized_); + for (auto& transceiver_state : transceiver_states_) + transceiver_state.Initialize(); + states_obtained_ = true; + return std::move(transceiver_states_); +} + +SurfaceSenderStateOnly::SurfaceSenderStateOnly( + rtc::scoped_refptr<webrtc::RtpSenderInterface> sender) + : sender_(std::move(sender)) { + DCHECK(sender_); +} + +SurfaceSenderStateOnly::~SurfaceSenderStateOnly() {} + +cricket::MediaType SurfaceSenderStateOnly::media_type() const { + return sender_->media_type(); +} + +absl::optional<std::string> SurfaceSenderStateOnly::mid() const { + return absl::nullopt; +} + +rtc::scoped_refptr<webrtc::RtpSenderInterface> SurfaceSenderStateOnly::sender() + const { + return sender_; +} + +rtc::scoped_refptr<webrtc::RtpReceiverInterface> +SurfaceSenderStateOnly::receiver() const { + return nullptr; +} + +bool SurfaceSenderStateOnly::stopped() const { + return false; +} + +webrtc::RtpTransceiverDirection SurfaceSenderStateOnly::direction() const { + return webrtc::RtpTransceiverDirection::kSendOnly; +} + +void SurfaceSenderStateOnly::SetDirection( + webrtc::RtpTransceiverDirection new_direction) { + NOTIMPLEMENTED(); +} + +absl::optional<webrtc::RtpTransceiverDirection> +SurfaceSenderStateOnly::current_direction() const { + return absl::nullopt; +} + +void SurfaceSenderStateOnly::Stop() { + NOTIMPLEMENTED(); +} + +SurfaceReceiverStateOnly::SurfaceReceiverStateOnly( + rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) + : receiver_(std::move(receiver)) { + DCHECK(receiver_); +} + +SurfaceReceiverStateOnly::~SurfaceReceiverStateOnly() {} + +cricket::MediaType SurfaceReceiverStateOnly::media_type() const { + return receiver_->media_type(); +} + +absl::optional<std::string> SurfaceReceiverStateOnly::mid() const { + return absl::nullopt; +} + +rtc::scoped_refptr<webrtc::RtpSenderInterface> +SurfaceReceiverStateOnly::sender() const { + return nullptr; +} + +rtc::scoped_refptr<webrtc::RtpReceiverInterface> +SurfaceReceiverStateOnly::receiver() const { + return receiver_; +} + +bool SurfaceReceiverStateOnly::stopped() const { + return false; +} + +webrtc::RtpTransceiverDirection SurfaceReceiverStateOnly::direction() const { + return webrtc::RtpTransceiverDirection::kRecvOnly; +} + +void SurfaceReceiverStateOnly::SetDirection( + webrtc::RtpTransceiverDirection new_direction) { + NOTIMPLEMENTED(); +} + +absl::optional<webrtc::RtpTransceiverDirection> +SurfaceReceiverStateOnly::current_direction() const { + return absl::nullopt; +} + +void SurfaceReceiverStateOnly::Stop() { + NOTIMPLEMENTED(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc new file mode 100644 index 00000000000..9d9ca8ea404 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer_test.cc @@ -0,0 +1,388 @@ +// 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 "third_party/blink/public/web/modules/peerconnection/transceiver_state_surfacer.h" + +#include <memory> +#include <tuple> + +#include "base/bind.h" +#include "base/memory/scoped_refptr.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" +#include "third_party/blink/public/platform/modules/peerconnection/webrtc_util.h" +#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" +#include "third_party/blink/public/platform/web_media_stream_source.h" +#include "third_party/blink/public/platform/web_media_stream_track.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_dependency_factory.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_impl.h" +#include "third_party/blink/public/web/web_heap.h" + +using testing::AnyNumber; +using testing::Return; + +namespace blink { + +// To avoid name collision on jumbo builds. +namespace transceiver_state_surfacer_test { + +class MockSctpTransport : public webrtc::SctpTransportInterface { + public: + MOCK_CONST_METHOD0(dtls_transport, + rtc::scoped_refptr<webrtc::DtlsTransportInterface>()); + MOCK_CONST_METHOD0(Information, webrtc::SctpTransportInformation()); + MOCK_METHOD1(RegisterObserver, void(webrtc::SctpTransportObserverInterface*)); + MOCK_METHOD0(UnregisterObserver, void()); +}; + +class TransceiverStateSurfacerTest : public ::testing::Test { + public: + void SetUp() override { + dependency_factory_.reset(new blink::MockPeerConnectionDependencyFactory()); + main_task_runner_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting(); + track_adapter_map_ = new blink::WebRtcMediaStreamTrackAdapterMap( + dependency_factory_.get(), main_task_runner_); + surfacer_.reset(new TransceiverStateSurfacer(main_task_runner_, + signaling_task_runner())); + peer_connection_ = dependency_factory_->CreatePeerConnection( + webrtc::PeerConnectionInterface::RTCConfiguration(), nullptr, nullptr); + EXPECT_CALL( + *(static_cast<blink::MockPeerConnectionImpl*>(peer_connection_.get())), + GetSctpTransport()) + .Times(AnyNumber()); + } + + void TearDown() override { + // Make sure posted tasks get a chance to execute or else the stuff is + // teared down while things are in flight. + base::RunLoop().RunUntilIdle(); + blink::WebHeap::CollectAllGarbageForTesting(); + } + + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const { + return dependency_factory_->GetWebRtcSignalingTaskRunner(); + } + + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + CreateLocalTrackAndAdapter(const std::string& id) { + return track_adapter_map_->GetOrCreateLocalTrackAdapter( + CreateBlinkLocalTrack(id)); + } + + rtc::scoped_refptr<blink::FakeRtpTransceiver> CreateWebRtcTransceiver( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> local_track, + const std::string& local_stream_id, + const std::string& remote_track_id, + const std::string& remote_stream_id, + rtc::scoped_refptr<webrtc::DtlsTransportInterface> transport) { + rtc::scoped_refptr<blink::FakeRtpTransceiver> transceiver = + new rtc::RefCountedObject<blink::FakeRtpTransceiver>( + local_track->kind() == webrtc::MediaStreamTrackInterface::kAudioKind + ? cricket::MEDIA_TYPE_AUDIO + : cricket::MEDIA_TYPE_VIDEO, + CreateWebRtcSender(local_track, local_stream_id), + CreateWebRtcReceiver(remote_track_id, remote_stream_id), + base::nullopt, false, webrtc::RtpTransceiverDirection::kSendRecv, + base::nullopt); + if (transport.get()) { + transceiver->SetTransport(transport); + } + return transceiver; + } + + rtc::scoped_refptr<blink::FakeRtpSender> CreateWebRtcSender( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + const std::string& stream_id) { + return new rtc::RefCountedObject<blink::FakeRtpSender>( + std::move(track), std::vector<std::string>({stream_id})); + } + + rtc::scoped_refptr<blink::FakeRtpReceiver> CreateWebRtcReceiver( + const std::string& track_id, + const std::string& stream_id) { + rtc::scoped_refptr<webrtc::AudioTrackInterface> remote_track = + blink::MockWebRtcAudioTrack::Create(track_id).get(); + rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream( + new rtc::RefCountedObject<blink::MockMediaStream>(stream_id)); + return new rtc::RefCountedObject<blink::FakeRtpReceiver>( + remote_track.get(), + std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>( + {remote_stream})); + } + + // Initializes the surfacer on the signaling thread and signals the waitable + // event when done. The WaitableEvent's Wait() blocks the main thread until + // initialization occurs. + std::unique_ptr<base::WaitableEvent> AsyncInitializeSurfacerWithWaitableEvent( + std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> + transceivers) { + std::unique_ptr<base::WaitableEvent> waitable_event(new base::WaitableEvent( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED)); + signaling_task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + &TransceiverStateSurfacerTest:: + AsyncInitializeSurfacerWithWaitableEventOnSignalingThread, + base::Unretained(this), std::move(transceivers), + waitable_event.get())); + return waitable_event; + } + + // Initializes the surfacer on the signaling thread and posts back to the main + // thread to execute the callback when done. The RunLoop quits after the + // callback is executed. Use the RunLoop's Run() method to allow the posted + // task (such as the callback) to be executed while waiting. The caller must + // let the loop Run() before destroying it. + std::unique_ptr<base::RunLoop> AsyncInitializeSurfacerWithCallback( + std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> + transceivers, + base::OnceCallback<void()> callback) { + std::unique_ptr<base::RunLoop> run_loop(new base::RunLoop()); + signaling_task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&TransceiverStateSurfacerTest:: + AsyncInitializeSurfacerWithCallbackOnSignalingThread, + base::Unretained(this), std::move(transceivers), + std::move(callback), run_loop.get())); + return run_loop; + } + + void ObtainStatesAndExpectInitialized( + rtc::scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver) { + // Inspect SCTP transport + auto sctp_snapshot = surfacer_->SctpTransportSnapshot(); + EXPECT_EQ(peer_connection_->GetSctpTransport(), sctp_snapshot.transport); + if (peer_connection_->GetSctpTransport()) { + EXPECT_EQ(peer_connection_->GetSctpTransport()->dtls_transport(), + sctp_snapshot.sctp_transport_state.dtls_transport()); + } + // Inspect transceivers + auto transceiver_states = surfacer_->ObtainStates(); + EXPECT_EQ(1u, transceiver_states.size()); + auto& transceiver_state = transceiver_states[0]; + EXPECT_EQ(transceiver_state.webrtc_transceiver().get(), + webrtc_transceiver.get()); + // Inspect sender states. + const auto& sender_state = transceiver_state.sender_state(); + EXPECT_TRUE(sender_state); + EXPECT_TRUE(sender_state->is_initialized()); + const auto& webrtc_sender = webrtc_transceiver->sender(); + EXPECT_EQ(sender_state->webrtc_sender().get(), webrtc_sender.get()); + EXPECT_TRUE(sender_state->track_ref()->is_initialized()); + EXPECT_EQ(sender_state->track_ref()->webrtc_track(), + webrtc_sender->track().get()); + EXPECT_EQ(sender_state->stream_ids(), webrtc_sender->stream_ids()); + EXPECT_EQ(sender_state->webrtc_dtls_transport(), + webrtc_sender->dtls_transport()); + if (webrtc_sender->dtls_transport()) { + EXPECT_EQ(webrtc_sender->dtls_transport()->Information().state(), + sender_state->webrtc_dtls_transport_information().state()); + } else { + EXPECT_EQ(webrtc::DtlsTransportState::kNew, + sender_state->webrtc_dtls_transport_information().state()); + } + // Inspect receiver states. + const auto& receiver_state = transceiver_state.receiver_state(); + EXPECT_TRUE(receiver_state); + EXPECT_TRUE(receiver_state->is_initialized()); + const auto& webrtc_receiver = webrtc_transceiver->receiver(); + EXPECT_EQ(receiver_state->webrtc_receiver().get(), webrtc_receiver.get()); + EXPECT_TRUE(receiver_state->track_ref()->is_initialized()); + EXPECT_EQ(receiver_state->track_ref()->webrtc_track(), + webrtc_receiver->track().get()); + std::vector<std::string> receiver_stream_ids; + for (const auto& stream : webrtc_receiver->streams()) { + receiver_stream_ids.push_back(stream->id()); + } + EXPECT_EQ(receiver_state->stream_ids(), receiver_stream_ids); + EXPECT_EQ(receiver_state->webrtc_dtls_transport(), + webrtc_receiver->dtls_transport()); + if (webrtc_receiver->dtls_transport()) { + EXPECT_EQ(webrtc_receiver->dtls_transport()->Information().state(), + receiver_state->webrtc_dtls_transport_information().state()); + } else { + EXPECT_EQ(webrtc::DtlsTransportState::kNew, + receiver_state->webrtc_dtls_transport_information().state()); + } + // Inspect transceiver states. + EXPECT_TRUE(blink::OptionalEquals(transceiver_state.mid(), + webrtc_transceiver->mid())); + EXPECT_EQ(transceiver_state.stopped(), webrtc_transceiver->stopped()); + EXPECT_TRUE(transceiver_state.direction() == + webrtc_transceiver->direction()); + EXPECT_TRUE(blink::OptionalEquals(transceiver_state.current_direction(), + webrtc_transceiver->current_direction())); + } + + private: + blink::WebMediaStreamTrack CreateBlinkLocalTrack(const std::string& id) { + blink::WebMediaStreamSource web_source; + web_source.Initialize( + blink::WebString::FromUTF8(id), blink::WebMediaStreamSource::kTypeAudio, + blink::WebString::FromUTF8("local_audio_track"), false); + blink::MediaStreamAudioSource* audio_source = + new blink::MediaStreamAudioSource( + blink::scheduler::GetSingleThreadTaskRunnerForTesting(), true); + // Takes ownership of |audio_source|. + web_source.SetPlatformSource(base::WrapUnique(audio_source)); + + blink::WebMediaStreamTrack web_track; + web_track.Initialize(web_source.Id(), web_source); + audio_source->ConnectToTrack(web_track); + return web_track; + } + + void AsyncInitializeSurfacerWithWaitableEventOnSignalingThread( + std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> + transceivers, + base::WaitableEvent* waitable_event) { + DCHECK(signaling_task_runner()->BelongsToCurrentThread()); + surfacer_->Initialize(peer_connection_, track_adapter_map_, + std::move(transceivers)); + waitable_event->Signal(); + } + + void AsyncInitializeSurfacerWithCallbackOnSignalingThread( + std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> + transceivers, + base::OnceCallback<void()> callback, + base::RunLoop* run_loop) { + DCHECK(signaling_task_runner()->BelongsToCurrentThread()); + surfacer_->Initialize(peer_connection_, track_adapter_map_, + std::move(transceivers)); + main_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&TransceiverStateSurfacerTest:: + AsyncInitializeSurfacerWithCallbackOnMainThread, + base::Unretained(this), std::move(callback), run_loop)); + } + + void AsyncInitializeSurfacerWithCallbackOnMainThread( + base::OnceCallback<void()> callback, + base::RunLoop* run_loop) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK(surfacer_->is_initialized()); + std::move(callback).Run(); + run_loop->Quit(); + } + + protected: + scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_; + std::unique_ptr<blink::MockPeerConnectionDependencyFactory> + dependency_factory_; + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map_; + std::unique_ptr<TransceiverStateSurfacer> surfacer_; +}; + +TEST_F(TransceiverStateSurfacerTest, SurfaceTransceiverBlockingly) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto webrtc_transceiver = CreateWebRtcTransceiver( + local_track_adapter->webrtc_track(), "local_stream", "remote_track", + "remote_stream", nullptr); + auto waitable_event = + AsyncInitializeSurfacerWithWaitableEvent({webrtc_transceiver}); + waitable_event->Wait(); + ObtainStatesAndExpectInitialized(webrtc_transceiver); +} + +TEST_F(TransceiverStateSurfacerTest, SurfaceTransceiverInCallback) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto webrtc_transceiver = CreateWebRtcTransceiver( + local_track_adapter->webrtc_track(), "local_stream", "remote_track", + "remote_stream", nullptr); + auto run_loop = AsyncInitializeSurfacerWithCallback( + {webrtc_transceiver}, + base::BindOnce( + &TransceiverStateSurfacerTest::ObtainStatesAndExpectInitialized, + base::Unretained(this), webrtc_transceiver)); + run_loop->Run(); +} + +TEST_F(TransceiverStateSurfacerTest, SurfaceTransceiverWithTransport) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto webrtc_transceiver = CreateWebRtcTransceiver( + local_track_adapter->webrtc_track(), "local_stream", "remote_track", + "remote_stream", new rtc::RefCountedObject<blink::FakeDtlsTransport>()); + auto run_loop = AsyncInitializeSurfacerWithCallback( + {webrtc_transceiver}, + base::BindOnce( + &TransceiverStateSurfacerTest::ObtainStatesAndExpectInitialized, + base::Unretained(this), webrtc_transceiver)); + run_loop->Run(); +} + +TEST_F(TransceiverStateSurfacerTest, SurfaceSenderStateOnly) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto webrtc_sender = + CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream"); + auto waitable_event = AsyncInitializeSurfacerWithWaitableEvent( + {new SurfaceSenderStateOnly(webrtc_sender)}); + waitable_event->Wait(); + auto transceiver_states = surfacer_->ObtainStates(); + EXPECT_EQ(1u, transceiver_states.size()); + auto& transceiver_state = transceiver_states[0]; + EXPECT_TRUE(transceiver_state.sender_state()); + EXPECT_TRUE(transceiver_state.sender_state()->is_initialized()); + EXPECT_FALSE(transceiver_state.receiver_state()); + // Expect transceiver members be be missing for optional members and have + // sensible values for non-optional members. + EXPECT_FALSE(transceiver_state.mid()); + EXPECT_FALSE(transceiver_state.stopped()); + EXPECT_EQ(transceiver_state.direction(), + webrtc::RtpTransceiverDirection::kSendOnly); + EXPECT_FALSE(transceiver_state.current_direction()); +} + +TEST_F(TransceiverStateSurfacerTest, SurfaceReceiverStateOnly) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto webrtc_receiver = CreateWebRtcReceiver("remote_track", "remote_stream"); + auto waitable_event = AsyncInitializeSurfacerWithWaitableEvent( + {new SurfaceReceiverStateOnly(webrtc_receiver)}); + waitable_event->Wait(); + auto transceiver_states = surfacer_->ObtainStates(); + EXPECT_EQ(1u, transceiver_states.size()); + auto& transceiver_state = transceiver_states[0]; + EXPECT_FALSE(transceiver_state.sender_state()); + EXPECT_TRUE(transceiver_state.receiver_state()); + EXPECT_TRUE(transceiver_state.receiver_state()->is_initialized()); + // Expect transceiver members be be missing for optional members and have + // sensible values for non-optional members. + EXPECT_FALSE(transceiver_state.mid()); + EXPECT_FALSE(transceiver_state.stopped()); + EXPECT_EQ(transceiver_state.direction(), + webrtc::RtpTransceiverDirection::kRecvOnly); + EXPECT_FALSE(transceiver_state.current_direction()); +} + +TEST_F(TransceiverStateSurfacerTest, SurfaceTransceiverWithSctpTransport) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto webrtc_transceiver = CreateWebRtcTransceiver( + local_track_adapter->webrtc_track(), "local_stream", "remote_track", + "remote_stream", nullptr); + rtc::scoped_refptr<MockSctpTransport> mock_sctp_transport = + new rtc::RefCountedObject<MockSctpTransport>(); + webrtc::SctpTransportInformation sctp_transport_info( + webrtc::SctpTransportState::kNew); + EXPECT_CALL( + *(static_cast<blink::MockPeerConnectionImpl*>(peer_connection_.get())), + GetSctpTransport()) + .WillRepeatedly(Return(mock_sctp_transport)); + EXPECT_CALL(*mock_sctp_transport.get(), Information()) + .WillRepeatedly(Return(sctp_transport_info)); + EXPECT_CALL(*mock_sctp_transport.get(), dtls_transport()).Times(AnyNumber()); + auto waitable_event = + AsyncInitializeSurfacerWithWaitableEvent({webrtc_transceiver}); + waitable_event->Wait(); + EXPECT_TRUE(surfacer_->SctpTransportSnapshot().transport); + ObtainStatesAndExpectInitialized(webrtc_transceiver); +} + +} // namespace transceiver_state_surfacer_test +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc new file mode 100644 index 00000000000..9165ecccfa7 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc @@ -0,0 +1,338 @@ +// Copyright (c) 2017 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 "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter.h" + +#include "base/bind.h" +#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h" +#include "third_party/blink/public/web/modules/mediastream/processed_local_audio_source.h" +#include "third_party/blink/public/web/modules/peerconnection/media_stream_video_webrtc_sink.h" +#include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h" + +namespace blink { + +// static +scoped_refptr<WebRtcMediaStreamTrackAdapter> +WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter( + blink::PeerConnectionDependencyFactory* factory, + const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, + const blink::WebMediaStreamTrack& web_track) { + DCHECK(factory); + DCHECK(main_thread->BelongsToCurrentThread()); + DCHECK(!web_track.IsNull()); + scoped_refptr<WebRtcMediaStreamTrackAdapter> local_track_adapter( + new WebRtcMediaStreamTrackAdapter(factory, main_thread)); + if (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio) { + local_track_adapter->InitializeLocalAudioTrack(web_track); + } else { + DCHECK_EQ(web_track.Source().GetType(), + blink::WebMediaStreamSource::kTypeVideo); + local_track_adapter->InitializeLocalVideoTrack(web_track); + } + return local_track_adapter; +} + +// static +scoped_refptr<WebRtcMediaStreamTrackAdapter> +WebRtcMediaStreamTrackAdapter::CreateRemoteTrackAdapter( + blink::PeerConnectionDependencyFactory* factory, + const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, + const scoped_refptr<webrtc::MediaStreamTrackInterface>& webrtc_track) { + DCHECK(factory); + DCHECK(!main_thread->BelongsToCurrentThread()); + DCHECK(webrtc_track); + scoped_refptr<WebRtcMediaStreamTrackAdapter> remote_track_adapter( + new WebRtcMediaStreamTrackAdapter(factory, main_thread)); + if (webrtc_track->kind() == webrtc::MediaStreamTrackInterface::kAudioKind) { + remote_track_adapter->InitializeRemoteAudioTrack(base::WrapRefCounted( + static_cast<webrtc::AudioTrackInterface*>(webrtc_track.get()))); + } else { + DCHECK_EQ(webrtc_track->kind(), + webrtc::MediaStreamTrackInterface::kVideoKind); + remote_track_adapter->InitializeRemoteVideoTrack(base::WrapRefCounted( + static_cast<webrtc::VideoTrackInterface*>(webrtc_track.get()))); + } + return remote_track_adapter; +} + +WebRtcMediaStreamTrackAdapter::WebRtcMediaStreamTrackAdapter( + blink::PeerConnectionDependencyFactory* factory, + const scoped_refptr<base::SingleThreadTaskRunner>& main_thread) + : factory_(factory), + main_thread_(main_thread), + remote_track_can_complete_initialization_( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED), + is_initialized_(false), + is_disposed_(false) { + DCHECK(factory_); + DCHECK(main_thread_); +} + +WebRtcMediaStreamTrackAdapter::~WebRtcMediaStreamTrackAdapter() { + DCHECK(!remote_track_can_complete_initialization_.IsSignaled()); + DCHECK(is_disposed_); + // Ensured by destructor traits. + DCHECK(main_thread_->BelongsToCurrentThread()); +} + +// static +void WebRtcMediaStreamTrackAdapterTraits::Destruct( + const WebRtcMediaStreamTrackAdapter* adapter) { + if (!adapter->main_thread_->BelongsToCurrentThread()) { + adapter->main_thread_->PostTask( + FROM_HERE, + base::BindOnce(&WebRtcMediaStreamTrackAdapterTraits::Destruct, + base::Unretained(adapter))); + return; + } + delete adapter; +} + +void WebRtcMediaStreamTrackAdapter::Dispose() { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(is_initialized_); + if (is_disposed_) + return; + remote_track_can_complete_initialization_.Reset(); + is_disposed_ = true; + if (web_track_.Source().GetType() == + blink::WebMediaStreamSource::kTypeAudio) { + if (local_track_audio_sink_) + DisposeLocalAudioTrack(); + else + DisposeRemoteAudioTrack(); + } else { + DCHECK_EQ(web_track_.Source().GetType(), + blink::WebMediaStreamSource::kTypeVideo); + if (local_track_video_sink_) + DisposeLocalVideoTrack(); + else + DisposeRemoteVideoTrack(); + } +} + +bool WebRtcMediaStreamTrackAdapter::is_initialized() const { + return is_initialized_; +} + +void WebRtcMediaStreamTrackAdapter::InitializeOnMainThread() { + DCHECK(main_thread_->BelongsToCurrentThread()); + if (is_initialized_) + return; + // TODO(hbos): Only ever initialize explicitly, + // remove EnsureTrackIsInitialized(). https://crbug.com/857458 + EnsureTrackIsInitialized(); +} + +const blink::WebMediaStreamTrack& WebRtcMediaStreamTrackAdapter::web_track() { + DCHECK(main_thread_->BelongsToCurrentThread()); + EnsureTrackIsInitialized(); + DCHECK(!web_track_.IsNull()); + return web_track_; +} + +webrtc::MediaStreamTrackInterface* +WebRtcMediaStreamTrackAdapter::webrtc_track() { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(webrtc_track_); + EnsureTrackIsInitialized(); + return webrtc_track_.get(); +} + +bool WebRtcMediaStreamTrackAdapter::IsEqual( + const blink::WebMediaStreamTrack& web_track) { + DCHECK(main_thread_->BelongsToCurrentThread()); + EnsureTrackIsInitialized(); + return web_track_.GetPlatformTrack() == web_track.GetPlatformTrack(); +} + +void WebRtcMediaStreamTrackAdapter::InitializeLocalAudioTrack( + const blink::WebMediaStreamTrack& web_track) { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(!is_initialized_); + DCHECK(!web_track.IsNull()); + DCHECK_EQ(web_track.Source().GetType(), + blink::WebMediaStreamSource::kTypeAudio); + web_track_ = web_track; + blink::MediaStreamAudioTrack* native_track = + blink::MediaStreamAudioTrack::From(web_track_); + DCHECK(native_track); + + // Non-WebRtc remote sources and local sources do not provide an instance of + // the webrtc::AudioSourceInterface, and also do not need references to the + // audio level calculator or audio processor passed to the sink. + webrtc::AudioSourceInterface* source_interface = nullptr; + local_track_audio_sink_.reset(new blink::WebRtcAudioSink( + web_track_.Id().Utf8(), source_interface, + factory_->GetWebRtcSignalingTaskRunner(), main_thread_)); + + if (auto* media_stream_source = blink::ProcessedLocalAudioSource::From( + blink::MediaStreamAudioSource::From(web_track_.Source()))) { + local_track_audio_sink_->SetLevel(media_stream_source->audio_level()); + // The sink only grabs stats from the audio processor. Stats are only + // available if audio processing is turned on. Therefore, only provide the + // sink a reference to the processor if audio processing is turned on. + if (media_stream_source->HasAudioProcessing()) { + local_track_audio_sink_->SetAudioProcessor( + media_stream_source->GetAudioProcessor()); + } + } + native_track->AddSink(local_track_audio_sink_.get()); + webrtc_track_ = local_track_audio_sink_->webrtc_audio_track(); + DCHECK(webrtc_track_); + is_initialized_ = true; +} + +void WebRtcMediaStreamTrackAdapter::InitializeLocalVideoTrack( + const blink::WebMediaStreamTrack& web_track) { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(!is_initialized_); + DCHECK(!web_track.IsNull()); + DCHECK_EQ(web_track.Source().GetType(), + blink::WebMediaStreamSource::kTypeVideo); + web_track_ = web_track; + local_track_video_sink_.reset(new blink::MediaStreamVideoWebRtcSink( + web_track_, factory_, main_thread_)); + webrtc_track_ = local_track_video_sink_->webrtc_video_track(); + DCHECK(webrtc_track_); + is_initialized_ = true; +} + +void WebRtcMediaStreamTrackAdapter::InitializeRemoteAudioTrack( + const scoped_refptr<webrtc::AudioTrackInterface>& webrtc_audio_track) { + DCHECK(!main_thread_->BelongsToCurrentThread()); + DCHECK(!is_initialized_); + DCHECK(!remote_track_can_complete_initialization_.IsSignaled()); + DCHECK(webrtc_audio_track); + DCHECK_EQ(webrtc_audio_track->kind(), + webrtc::MediaStreamTrackInterface::kAudioKind); + remote_audio_track_adapter_ = + base::MakeRefCounted<blink::RemoteAudioTrackAdapter>( + main_thread_, webrtc_audio_track.get()); + webrtc_track_ = webrtc_audio_track; + // Set the initial volume to zero. When the track is put in an audio tag for + // playout, its volume is set to that of the tag. Without this, we could end + // up playing out audio that's not attached to any tag, see: + // http://crbug.com/810848 + webrtc_audio_track->GetSource()->SetVolume(0); + remote_track_can_complete_initialization_.Signal(); + main_thread_->PostTask( + FROM_HERE, + base::BindOnce(&WebRtcMediaStreamTrackAdapter:: + FinalizeRemoteTrackInitializationOnMainThread, + this)); +} + +void WebRtcMediaStreamTrackAdapter::InitializeRemoteVideoTrack( + const scoped_refptr<webrtc::VideoTrackInterface>& webrtc_video_track) { + DCHECK(!main_thread_->BelongsToCurrentThread()); + DCHECK(webrtc_video_track); + DCHECK_EQ(webrtc_video_track->kind(), + webrtc::MediaStreamTrackInterface::kVideoKind); + remote_video_track_adapter_ = + base::MakeRefCounted<blink::RemoteVideoTrackAdapter>( + main_thread_, webrtc_video_track.get()); + webrtc_track_ = webrtc_video_track; + remote_track_can_complete_initialization_.Signal(); + main_thread_->PostTask( + FROM_HERE, + base::BindOnce(&WebRtcMediaStreamTrackAdapter:: + FinalizeRemoteTrackInitializationOnMainThread, + this)); +} + +void WebRtcMediaStreamTrackAdapter:: + FinalizeRemoteTrackInitializationOnMainThread() { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(remote_audio_track_adapter_ || remote_video_track_adapter_); + if (is_initialized_) + return; + + if (remote_audio_track_adapter_) { + remote_audio_track_adapter_->Initialize(); + web_track_ = *remote_audio_track_adapter_->web_track(); + } else { + remote_video_track_adapter_->Initialize(); + web_track_ = *remote_video_track_adapter_->web_track(); + } + is_initialized_ = true; +} + +void WebRtcMediaStreamTrackAdapter::EnsureTrackIsInitialized() { + DCHECK(main_thread_->BelongsToCurrentThread()); + if (is_initialized_) + return; + + // Remote tracks may not be fully initialized yet, since they are partly + // initialized on the signaling thread. + remote_track_can_complete_initialization_.Wait(); + FinalizeRemoteTrackInitializationOnMainThread(); +} + +void WebRtcMediaStreamTrackAdapter::DisposeLocalAudioTrack() { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(local_track_audio_sink_); + DCHECK_EQ(web_track_.Source().GetType(), + blink::WebMediaStreamSource::kTypeAudio); + blink::MediaStreamAudioTrack* audio_track = + blink::MediaStreamAudioTrack::From(web_track_); + DCHECK(audio_track); + audio_track->RemoveSink(local_track_audio_sink_.get()); + local_track_audio_sink_.reset(); + webrtc_track_ = nullptr; + web_track_.Reset(); +} + +void WebRtcMediaStreamTrackAdapter::DisposeLocalVideoTrack() { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(local_track_video_sink_); + DCHECK_EQ(web_track_.Source().GetType(), + blink::WebMediaStreamSource::kTypeVideo); + local_track_video_sink_.reset(); + webrtc_track_ = nullptr; + web_track_.Reset(); +} + +void WebRtcMediaStreamTrackAdapter::DisposeRemoteAudioTrack() { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(remote_audio_track_adapter_); + DCHECK_EQ(web_track_.Source().GetType(), + blink::WebMediaStreamSource::kTypeAudio); + factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce(&WebRtcMediaStreamTrackAdapter:: + UnregisterRemoteAudioTrackAdapterOnSignalingThread, + this)); +} + +void WebRtcMediaStreamTrackAdapter::DisposeRemoteVideoTrack() { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(remote_video_track_adapter_); + DCHECK_EQ(web_track_.Source().GetType(), + blink::WebMediaStreamSource::kTypeVideo); + FinalizeRemoteTrackDisposingOnMainThread(); +} + +void WebRtcMediaStreamTrackAdapter:: + UnregisterRemoteAudioTrackAdapterOnSignalingThread() { + DCHECK(!main_thread_->BelongsToCurrentThread()); + DCHECK(remote_audio_track_adapter_); + remote_audio_track_adapter_->Unregister(); + main_thread_->PostTask( + FROM_HERE, base::BindOnce(&WebRtcMediaStreamTrackAdapter:: + FinalizeRemoteTrackDisposingOnMainThread, + this)); +} + +void WebRtcMediaStreamTrackAdapter::FinalizeRemoteTrackDisposingOnMainThread() { + DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(is_disposed_); + remote_audio_track_adapter_ = nullptr; + remote_video_track_adapter_ = nullptr; + webrtc_track_ = nullptr; + web_track_.Reset(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.cc new file mode 100644 index 00000000000..d4b697db6c5 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.cc @@ -0,0 +1,215 @@ +// Copyright (c) 2017 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 "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h" + +#include <utility> + +#include "base/bind.h" +#include "base/single_thread_task_runner.h" +#include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h" + +namespace blink { + +WebRtcMediaStreamTrackAdapterMap::AdapterRef::AdapterRef( + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> map, + Type type, + scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> adapter) + : map_(std::move(map)), type_(type), adapter_(std::move(adapter)) { + DCHECK(map_); + DCHECK(adapter_); +} + +WebRtcMediaStreamTrackAdapterMap::AdapterRef::~AdapterRef() { + DCHECK(map_->main_thread_->BelongsToCurrentThread()); + scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> removed_adapter; + { + base::AutoLock scoped_lock(map_->lock_); + // The adapter is stored in the track adapter map and we have |adapter_|, + // so there must be at least two references to the adapter. + DCHECK(!adapter_->HasOneRef()); + // Using a raw pointer instead of |adapter_| allows the reference count to + // go down to one if this is the last |AdapterRef|. + blink::WebRtcMediaStreamTrackAdapter* adapter = adapter_.get(); + adapter_ = nullptr; + if (adapter->HasOneRef()) { + removed_adapter = adapter; + // "GetOrCreate..." ensures the adapter is initialized and the secondary + // key is set before the last |AdapterRef| is destroyed. We can use either + // the primary or secondary key for removal. + DCHECK(adapter->is_initialized()); + if (type_ == Type::kLocal) { + map_->local_track_adapters_.EraseByPrimary( + adapter->web_track().UniqueId()); + } else { + map_->remote_track_adapters_.EraseByPrimary(adapter->webrtc_track()); + } + } + } + // Dispose the adapter if it was removed. This is performed after releasing + // the lock so that it is safe for any disposal mechanism to do synchronous + // invokes to the signaling thread without any risk of deadlock. + if (removed_adapter) { + removed_adapter->Dispose(); + } +} + +std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> +WebRtcMediaStreamTrackAdapterMap::AdapterRef::Copy() const { + base::AutoLock scoped_lock(map_->lock_); + return base::WrapUnique(new AdapterRef(map_, type_, adapter_)); +} + +void WebRtcMediaStreamTrackAdapterMap::AdapterRef::InitializeOnMainThread() { + adapter_->InitializeOnMainThread(); + if (type_ == WebRtcMediaStreamTrackAdapterMap::AdapterRef::Type::kRemote) { + base::AutoLock scoped_lock(map_->lock_); + if (!map_->remote_track_adapters_.FindBySecondary(web_track().UniqueId())) { + map_->remote_track_adapters_.SetSecondaryKey(webrtc_track(), + web_track().UniqueId()); + } + } +} + +WebRtcMediaStreamTrackAdapterMap::WebRtcMediaStreamTrackAdapterMap( + blink::PeerConnectionDependencyFactory* const factory, + scoped_refptr<base::SingleThreadTaskRunner> main_thread) + : factory_(factory), main_thread_(std::move(main_thread)) { + DCHECK(factory_); + DCHECK(main_thread_); +} + +WebRtcMediaStreamTrackAdapterMap::~WebRtcMediaStreamTrackAdapterMap() { + DCHECK(local_track_adapters_.empty()); + DCHECK(remote_track_adapters_.empty()); +} + +std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> +WebRtcMediaStreamTrackAdapterMap::GetLocalTrackAdapter( + const blink::WebMediaStreamTrack& web_track) { + base::AutoLock scoped_lock(lock_); + scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr = + local_track_adapters_.FindByPrimary(web_track.UniqueId()); + if (!adapter_ptr) + return nullptr; + return base::WrapUnique( + new AdapterRef(this, AdapterRef::Type::kLocal, *adapter_ptr)); +} + +std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> +WebRtcMediaStreamTrackAdapterMap::GetLocalTrackAdapter( + webrtc::MediaStreamTrackInterface* webrtc_track) { + base::AutoLock scoped_lock(lock_); + scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr = + local_track_adapters_.FindBySecondary(webrtc_track); + if (!adapter_ptr) + return nullptr; + return base::WrapUnique( + new AdapterRef(this, AdapterRef::Type::kLocal, *adapter_ptr)); +} + +std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> +WebRtcMediaStreamTrackAdapterMap::GetOrCreateLocalTrackAdapter( + const blink::WebMediaStreamTrack& web_track) { + DCHECK(!web_track.IsNull()); + DCHECK(main_thread_->BelongsToCurrentThread()); + base::AutoLock scoped_lock(lock_); + scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr = + local_track_adapters_.FindByPrimary(web_track.UniqueId()); + if (adapter_ptr) { + return base::WrapUnique( + new AdapterRef(this, AdapterRef::Type::kLocal, *adapter_ptr)); + } + scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> new_adapter; + { + // Do not hold |lock_| while creating the adapter in case that operation + // synchronizes with the signaling thread. If we do and the signaling thread + // is blocked waiting for |lock_| we end up in a deadlock. + base::AutoUnlock scoped_unlock(lock_); + new_adapter = blink::WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter( + factory_, main_thread_, web_track); + } + DCHECK(new_adapter->is_initialized()); + local_track_adapters_.Insert(web_track.UniqueId(), new_adapter); + local_track_adapters_.SetSecondaryKey(web_track.UniqueId(), + new_adapter->webrtc_track()); + return base::WrapUnique( + new AdapterRef(this, AdapterRef::Type::kLocal, new_adapter)); +} + +size_t WebRtcMediaStreamTrackAdapterMap::GetLocalTrackCount() const { + base::AutoLock scoped_lock(lock_); + return local_track_adapters_.PrimarySize(); +} + +std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> +WebRtcMediaStreamTrackAdapterMap::GetRemoteTrackAdapter( + const blink::WebMediaStreamTrack& web_track) { + base::AutoLock scoped_lock(lock_); + scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr = + remote_track_adapters_.FindBySecondary(web_track.UniqueId()); + if (!adapter_ptr) + return nullptr; + DCHECK((*adapter_ptr)->is_initialized()); + return base::WrapUnique( + new AdapterRef(this, AdapterRef::Type::kRemote, *adapter_ptr)); +} + +std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> +WebRtcMediaStreamTrackAdapterMap::GetRemoteTrackAdapter( + webrtc::MediaStreamTrackInterface* webrtc_track) { + base::AutoLock scoped_lock(lock_); + scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr = + remote_track_adapters_.FindByPrimary(webrtc_track); + if (!adapter_ptr) + return nullptr; + return base::WrapUnique( + new AdapterRef(this, AdapterRef::Type::kRemote, *adapter_ptr)); +} + +std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> +WebRtcMediaStreamTrackAdapterMap::GetOrCreateRemoteTrackAdapter( + scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track) { + DCHECK(webrtc_track); + DCHECK(!main_thread_->BelongsToCurrentThread()); + base::AutoLock scoped_lock(lock_); + scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr = + remote_track_adapters_.FindByPrimary(webrtc_track.get()); + if (adapter_ptr) { + return base::WrapUnique( + new AdapterRef(this, AdapterRef::Type::kRemote, *adapter_ptr)); + } + scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> new_adapter; + { + // Do not hold |lock_| while creating the adapter in case that operation + // synchronizes with the main thread. If we do and the main thread is + // blocked waiting for |lock_| we end up in a deadlock. + base::AutoUnlock scoped_unlock(lock_); + new_adapter = + blink::WebRtcMediaStreamTrackAdapter::CreateRemoteTrackAdapter( + factory_, main_thread_, webrtc_track); + } + remote_track_adapters_.Insert(webrtc_track.get(), new_adapter); + // The new adapter is initialized in a post to the main thread. As soon as it + // is initialized we map its |webrtc_track| to the |remote_track_adapters_| + // entry as its secondary key. This ensures that there is at least one + // |AdapterRef| alive until after the adapter is initialized and its secondary + // key is set. + auto adapter_ref = base::WrapUnique( + new AdapterRef(this, AdapterRef::Type::kRemote, new_adapter)); + main_thread_->PostTask( + FROM_HERE, + base::BindOnce( + &WebRtcMediaStreamTrackAdapterMap::AdapterRef::InitializeOnMainThread, + std::move(adapter_ref))); + return base::WrapUnique( + new AdapterRef(this, AdapterRef::Type::kRemote, new_adapter)); +} + +size_t WebRtcMediaStreamTrackAdapterMap::GetRemoteTrackCount() const { + base::AutoLock scoped_lock(lock_); + return remote_track_adapters_.PrimarySize(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map_test.cc new file mode 100644 index 00000000000..34a97f0e690 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map_test.cc @@ -0,0 +1,357 @@ +// Copyright (c) 2017 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 "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h" + +#include <memory> + +#include "base/bind.h" +#include "base/memory/scoped_refptr.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/test/bind_test_util.h" +#include "base/test/test_timeouts.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" +#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" +#include "third_party/blink/public/platform/web_media_stream_source.h" +#include "third_party/blink/public/platform/web_media_stream_track.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_dependency_factory.h" +#include "third_party/blink/public/web/web_heap.h" +#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" + +namespace blink { + +class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test { + public: + void SetUp() override { + dependency_factory_.reset(new blink::MockPeerConnectionDependencyFactory()); + main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting(); + map_ = new blink::WebRtcMediaStreamTrackAdapterMap( + dependency_factory_.get(), main_thread_); + } + + void TearDown() override { blink::WebHeap::CollectAllGarbageForTesting(); } + + scoped_refptr<base::SingleThreadTaskRunner> signaling_thread() const { + return dependency_factory_->GetWebRtcSignalingTaskRunner(); + } + + blink::WebMediaStreamTrack CreateLocalTrack(const std::string& id) { + blink::WebMediaStreamSource web_source; + web_source.Initialize( + blink::WebString::FromUTF8(id), blink::WebMediaStreamSource::kTypeAudio, + blink::WebString::FromUTF8("local_audio_track"), false); + blink::MediaStreamAudioSource* audio_source = + new blink::MediaStreamAudioSource( + blink::scheduler::GetSingleThreadTaskRunnerForTesting(), true); + // Takes ownership of |audio_source|. + web_source.SetPlatformSource(base::WrapUnique(audio_source)); + + blink::WebMediaStreamTrack web_track; + web_track.Initialize(web_source.Id(), web_source); + audio_source->ConnectToTrack(web_track); + return web_track; + } + + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + GetOrCreateRemoteTrackAdapter(webrtc::MediaStreamTrackInterface* webrtc_track, + bool wait_for_initialization = true) { + DCHECK(main_thread_->BelongsToCurrentThread()); + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + adapter; + signaling_thread()->PostTask( + FROM_HERE, + base::BindOnce(&WebRtcMediaStreamTrackAdapterMapTest:: + GetOrCreateRemoteTrackAdapterOnSignalingThread, + base::Unretained(this), base::Unretained(webrtc_track), + &adapter)); + RunMessageLoopsUntilIdle(wait_for_initialization); + DCHECK(adapter); + if (wait_for_initialization) { + DCHECK(adapter->is_initialized()); + } else { + DCHECK(!adapter->is_initialized()); + } + return adapter; + } + + void GetOrCreateRemoteTrackAdapterOnSignalingThread( + webrtc::MediaStreamTrackInterface* webrtc_track, + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>* + adapter) { + DCHECK(signaling_thread()->BelongsToCurrentThread()); + *adapter = map_->GetOrCreateRemoteTrackAdapter(webrtc_track); + } + + // Runs message loops on the webrtc signaling thread and the main thread until + // idle. + void RunMessageLoopsUntilIdle(bool run_loop_on_main_thread = true) { + DCHECK(main_thread_->BelongsToCurrentThread()); + base::WaitableEvent waitable_event( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + signaling_thread()->PostTask( + FROM_HERE, base::BindOnce(&WebRtcMediaStreamTrackAdapterMapTest:: + RunMessageLoopUntilIdleOnSignalingThread, + base::Unretained(this), &waitable_event)); + waitable_event.Wait(); + if (run_loop_on_main_thread) + base::RunLoop().RunUntilIdle(); + } + + void RunMessageLoopUntilIdleOnSignalingThread( + base::WaitableEvent* waitable_event) { + DCHECK(signaling_thread()->BelongsToCurrentThread()); + base::RunLoop().RunUntilIdle(); + waitable_event->Signal(); + } + + protected: + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; + + std::unique_ptr<blink::MockPeerConnectionDependencyFactory> + dependency_factory_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_; + scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> map_; +}; + +TEST_F(WebRtcMediaStreamTrackAdapterMapTest, AddAndRemoveLocalTrackAdapter) { + blink::WebMediaStreamTrack web_track = CreateLocalTrack("local_track"); + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + adapter_ref = map_->GetOrCreateLocalTrackAdapter(web_track); + EXPECT_TRUE(adapter_ref->is_initialized()); + EXPECT_EQ(adapter_ref->GetAdapterForTesting(), + map_->GetLocalTrackAdapter(web_track)->GetAdapterForTesting()); + EXPECT_EQ(1u, map_->GetLocalTrackCount()); + + // "GetOrCreate" for already existing track. + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + adapter_ref2 = map_->GetOrCreateLocalTrackAdapter(web_track); + EXPECT_EQ(adapter_ref->GetAdapterForTesting(), + adapter_ref2->GetAdapterForTesting()); + EXPECT_EQ(1u, map_->GetLocalTrackCount()); + + adapter_ref2.reset(); // Not the last reference. + EXPECT_TRUE(adapter_ref->GetAdapterForTesting()->is_initialized()); + EXPECT_EQ(1u, map_->GetLocalTrackCount()); + + // Destroying all references to the adapter should remove it from the map and + // dispose it. + adapter_ref.reset(); + EXPECT_EQ(0u, map_->GetLocalTrackCount()); + EXPECT_EQ(nullptr, map_->GetLocalTrackAdapter(web_track)); + // Allow the disposing of track to occur. + RunMessageLoopsUntilIdle(); +} + +TEST_F(WebRtcMediaStreamTrackAdapterMapTest, AddAndRemoveRemoteTrackAdapter) { + scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track = + blink::MockWebRtcAudioTrack::Create("remote_track"); + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + adapter_ref = GetOrCreateRemoteTrackAdapter(webrtc_track.get()); + EXPECT_TRUE(adapter_ref->is_initialized()); + EXPECT_EQ( + adapter_ref->GetAdapterForTesting(), + map_->GetRemoteTrackAdapter(webrtc_track.get())->GetAdapterForTesting()); + EXPECT_EQ(1u, map_->GetRemoteTrackCount()); + + // "GetOrCreate" for already existing track. + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + adapter_ref2 = GetOrCreateRemoteTrackAdapter(webrtc_track.get()); + EXPECT_EQ(adapter_ref->GetAdapterForTesting(), + adapter_ref2->GetAdapterForTesting()); + EXPECT_EQ(1u, map_->GetRemoteTrackCount()); + + adapter_ref2.reset(); // Not the last reference. + EXPECT_TRUE(adapter_ref->GetAdapterForTesting()->is_initialized()); + EXPECT_EQ(1u, map_->GetRemoteTrackCount()); + + // Destroying all references to the adapter should remove it from the map and + // dispose it. + adapter_ref.reset(); + EXPECT_EQ(0u, map_->GetRemoteTrackCount()); + EXPECT_EQ(nullptr, map_->GetRemoteTrackAdapter(webrtc_track.get())); + // Allow the disposing of track to occur. + RunMessageLoopsUntilIdle(); +} + +TEST_F(WebRtcMediaStreamTrackAdapterMapTest, + InitializeRemoteTrackAdapterExplicitly) { + scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track = + blink::MockWebRtcAudioTrack::Create("remote_track"); + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + adapter_ref = GetOrCreateRemoteTrackAdapter(webrtc_track.get(), false); + EXPECT_FALSE(adapter_ref->is_initialized()); + adapter_ref->InitializeOnMainThread(); + EXPECT_TRUE(adapter_ref->is_initialized()); + + EXPECT_EQ(1u, map_->GetRemoteTrackCount()); + // Ensure the implicit initialization's posted task is run after it is already + // initialized. + RunMessageLoopsUntilIdle(); + // Destroying all references to the adapter should remove it from the map and + // dispose it. + adapter_ref.reset(); + EXPECT_EQ(0u, map_->GetRemoteTrackCount()); + EXPECT_EQ(nullptr, map_->GetRemoteTrackAdapter(webrtc_track.get())); + // Allow the disposing of track to occur. + RunMessageLoopsUntilIdle(); +} + +TEST_F(WebRtcMediaStreamTrackAdapterMapTest, + LocalAndRemoteTrackAdaptersWithSameID) { + // Local and remote tracks should be able to use the same id without conflict. + const char* id = "id"; + + blink::WebMediaStreamTrack local_web_track = CreateLocalTrack(id); + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + local_adapter = map_->GetOrCreateLocalTrackAdapter(local_web_track); + EXPECT_TRUE(local_adapter->is_initialized()); + EXPECT_EQ( + local_adapter->GetAdapterForTesting(), + map_->GetLocalTrackAdapter(local_web_track)->GetAdapterForTesting()); + EXPECT_EQ(1u, map_->GetLocalTrackCount()); + + scoped_refptr<blink::MockWebRtcAudioTrack> remote_webrtc_track = + blink::MockWebRtcAudioTrack::Create(id); + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> + remote_adapter = GetOrCreateRemoteTrackAdapter(remote_webrtc_track.get()); + EXPECT_TRUE(remote_adapter->is_initialized()); + EXPECT_EQ(remote_adapter->GetAdapterForTesting(), + map_->GetRemoteTrackAdapter(remote_webrtc_track.get()) + ->GetAdapterForTesting()); + EXPECT_NE(local_adapter->GetAdapterForTesting(), + remote_adapter->GetAdapterForTesting()); + EXPECT_EQ(1u, map_->GetRemoteTrackCount()); + + // Destroying all references to the adapters should remove them from the map. + local_adapter.reset(); + remote_adapter.reset(); + EXPECT_EQ(0u, map_->GetLocalTrackCount()); + EXPECT_EQ(0u, map_->GetRemoteTrackCount()); + EXPECT_EQ(nullptr, map_->GetLocalTrackAdapter(local_web_track)); + EXPECT_EQ(nullptr, map_->GetRemoteTrackAdapter(remote_webrtc_track.get())); + // Allow the disposing of tracks to occur. + RunMessageLoopsUntilIdle(); +} + +TEST_F(WebRtcMediaStreamTrackAdapterMapTest, GetMissingLocalTrackAdapter) { + blink::WebMediaStreamTrack local_web_track = CreateLocalTrack("missing"); + EXPECT_EQ(nullptr, map_->GetLocalTrackAdapter(local_web_track)); +} + +TEST_F(WebRtcMediaStreamTrackAdapterMapTest, GetMissingRemoteTrackAdapter) { + scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track = + blink::MockWebRtcAudioTrack::Create("missing"); + EXPECT_EQ(nullptr, map_->GetRemoteTrackAdapter(webrtc_track.get())); +} + +// Continuously calls GetOrCreateLocalTrackAdapter() on the main thread and +// GetOrCreateRemoteTrackAdapter() on the signaling thread hoping to hit +// deadlocks if the operations were to synchronize with the other thread while +// holding the lock. +// +// Note that this deadlock has been notoriously difficult to reproduce. This +// test is added as an attempt to guard against this type of regression, but do +// not trust that if this test passes there is no risk of deadlock. +class WebRtcMediaStreamTrackAdapterMapStressTest + : public WebRtcMediaStreamTrackAdapterMapTest { + public: + WebRtcMediaStreamTrackAdapterMapStressTest() + : WebRtcMediaStreamTrackAdapterMapTest(), + increased_run_timeout_( + TestTimeouts::action_max_timeout(), + base::MakeExpectedNotRunClosure(FROM_HERE, + "RunLoop::Run() timed out.")) {} + + void RunStressTest(size_t iterations) { + base::RunLoop run_loop; + remaining_iterations_ = iterations; + PostSignalingThreadLoop(); + MainThreadLoop(&run_loop); + run_loop.Run(); + // The run loop ensures all operations have began executing, but does not + // guarantee that all of them are complete, i.e. that track adapters have + // been fully initialized and subequently disposed. For that we need to run + // until idle or else we may tear down the test prematurely. + RunMessageLoopsUntilIdle(); + } + + void MainThreadLoop(base::RunLoop* run_loop) { + for (size_t i = 0u; i < 5u; ++i) { + map_->GetOrCreateLocalTrackAdapter(CreateLocalTrack("local_track_id")); + } + if (--remaining_iterations_ > 0) { + PostSignalingThreadLoop(); + PostMainThreadLoop(run_loop); + } else { + // We are now done, but there may still be operations pending to execute + // on signaling thread so we perform Quit() in a post to the signaling + // thread. This ensures that Quit() is called after all operations have + // began executing (but does not guarantee that all operations have + // completed). + signaling_thread()->PostTask( + FROM_HERE, + base::BindOnce(&WebRtcMediaStreamTrackAdapterMapStressTest:: + QuitRunLoopOnSignalingThread, + base::Unretained(this), base::Unretained(run_loop))); + } + } + + void PostMainThreadLoop(base::RunLoop* run_loop) { + main_thread_->PostTask( + FROM_HERE, + base::BindOnce( + &WebRtcMediaStreamTrackAdapterMapStressTest::MainThreadLoop, + base::Unretained(this), base::Unretained(run_loop))); + } + + void SignalingThreadLoop() { + std::vector< + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>> + track_refs; + for (size_t i = 0u; i < 5u; ++i) { + track_refs.push_back(map_->GetOrCreateRemoteTrackAdapter( + blink::MockWebRtcAudioTrack::Create("remote_track_id"))); + } + main_thread_->PostTask( + FROM_HERE, + base::BindOnce(&WebRtcMediaStreamTrackAdapterMapStressTest:: + DestroyAdapterRefsOnMainThread, + base::Unretained(this), std::move(track_refs))); + } + + void PostSignalingThreadLoop() { + signaling_thread()->PostTask( + FROM_HERE, + base::BindOnce( + &WebRtcMediaStreamTrackAdapterMapStressTest::SignalingThreadLoop, + base::Unretained(this))); + } + + void DestroyAdapterRefsOnMainThread( + std::vector< + std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>> + track_refs) {} + + void QuitRunLoopOnSignalingThread(base::RunLoop* run_loop) { + run_loop->Quit(); + } + + private: + // TODO(https://crbug.com/1002761): Fix this test to run in < action_timeout() + // on slower bots (e.g. Debug, ASAN, etc). + const base::RunLoop::ScopedRunTimeoutForTest increased_run_timeout_; + + size_t remaining_iterations_; +}; + +TEST_F(WebRtcMediaStreamTrackAdapterMapStressTest, StressTest) { + const size_t kNumStressTestIterations = 1000u; + RunStressTest(kNumStressTestIterations); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc new file mode 100644 index 00000000000..54e53ffea49 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc @@ -0,0 +1,271 @@ +// Copyright (c) 2017 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 "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter.h" + +#include <memory> + +#include "base/bind.h" +#include "base/memory/scoped_refptr.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h" +#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" +#include "third_party/blink/public/platform/web_media_stream_source.h" +#include "third_party/blink/public/platform/web_media_stream_track.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" +#include "third_party/blink/public/web/modules/mediastream/mock_media_stream_video_source.h" +#include "third_party/blink/public/web/modules/peerconnection/mock_peer_connection_dependency_factory.h" +#include "third_party/blink/public/web/web_heap.h" +#include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" + +namespace blink { + +class WebRtcMediaStreamTrackAdapterTest : public ::testing::Test { + public: + void SetUp() override { + dependency_factory_.reset(new blink::MockPeerConnectionDependencyFactory()); + main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting(); + } + + void TearDown() override { + if (track_adapter_) { + EXPECT_TRUE(track_adapter_->is_initialized()); + track_adapter_->Dispose(); + track_adapter_ = nullptr; + RunMessageLoopsUntilIdle(); + } + blink::WebHeap::CollectAllGarbageForTesting(); + } + + blink::WebMediaStreamTrack CreateLocalAudioTrack() { + blink::WebMediaStreamSource web_source; + web_source.Initialize(blink::WebString::FromUTF8("local_audio_id"), + blink::WebMediaStreamSource::kTypeAudio, + blink::WebString::FromUTF8("local_audio_track"), + false); + blink::MediaStreamAudioSource* audio_source = + new blink::MediaStreamAudioSource( + blink::scheduler::GetSingleThreadTaskRunnerForTesting(), true); + // Takes ownership of |audio_source|. + web_source.SetPlatformSource(base::WrapUnique(audio_source)); + + blink::WebMediaStreamTrack web_track; + web_track.Initialize(web_source.Id(), web_source); + audio_source->ConnectToTrack(web_track); + return web_track; + } + + blink::WebMediaStreamTrack CreateLocalVideoTrack() { + blink::WebMediaStreamSource web_source; + web_source.Initialize(blink::WebString::FromUTF8("local_video_id"), + blink::WebMediaStreamSource::kTypeVideo, + blink::WebString::FromUTF8("local_video_track"), + false); + blink::MockMediaStreamVideoSource* video_source = + new blink::MockMediaStreamVideoSource(); + // Takes ownership of |video_source|. + web_source.SetPlatformSource(base::WrapUnique(video_source)); + + return blink::MediaStreamVideoTrack::CreateVideoTrack( + video_source, blink::MediaStreamVideoSource::ConstraintsCallback(), + true); + } + + void CreateRemoteTrackAdapter( + webrtc::MediaStreamTrackInterface* webrtc_track) { + track_adapter_ = + blink::WebRtcMediaStreamTrackAdapter::CreateRemoteTrackAdapter( + dependency_factory_.get(), main_thread_, webrtc_track); + } + + void HoldOntoAdapterReference( + base::WaitableEvent* waitable_event, + scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> adapter) { + waitable_event->Wait(); + } + + // Runs message loops on the webrtc signaling thread and optionally the main + // thread until idle. + void RunMessageLoopsUntilIdle(bool run_loop_on_main_thread = true) { + base::WaitableEvent waitable_event( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + dependency_factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&WebRtcMediaStreamTrackAdapterTest:: + RunMessageLoopUntilIdleOnSignalingThread, + base::Unretained(this), &waitable_event)); + waitable_event.Wait(); + if (run_loop_on_main_thread) + base::RunLoop().RunUntilIdle(); + } + + void RunMessageLoopUntilIdleOnSignalingThread( + base::WaitableEvent* waitable_event) { + DCHECK(dependency_factory_->GetWebRtcSignalingTaskRunner() + ->BelongsToCurrentThread()); + base::RunLoop().RunUntilIdle(); + waitable_event->Signal(); + } + + protected: + ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; + + std::unique_ptr<blink::MockPeerConnectionDependencyFactory> + dependency_factory_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_; + scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> track_adapter_; +}; + +TEST_F(WebRtcMediaStreamTrackAdapterTest, LocalAudioTrack) { + track_adapter_ = + blink::WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter( + dependency_factory_.get(), main_thread_, CreateLocalAudioTrack()); + EXPECT_TRUE(track_adapter_->is_initialized()); + EXPECT_TRUE(!track_adapter_->web_track().IsNull()); + EXPECT_EQ(track_adapter_->web_track().Source().GetType(), + blink::WebMediaStreamSource::kTypeAudio); + EXPECT_TRUE(track_adapter_->webrtc_track()); + EXPECT_EQ(track_adapter_->webrtc_track()->kind(), + webrtc::MediaStreamTrackInterface::kAudioKind); + EXPECT_EQ(track_adapter_->webrtc_track()->id().c_str(), + track_adapter_->web_track().Id()); + EXPECT_TRUE(track_adapter_->GetLocalTrackAudioSinkForTesting()); + EXPECT_EQ( + track_adapter_->GetLocalTrackAudioSinkForTesting()->webrtc_audio_track(), + track_adapter_->webrtc_track()); +} + +// Flaky, see https://crbug.com/982200. +TEST_F(WebRtcMediaStreamTrackAdapterTest, DISABLED_LocalVideoTrack) { + track_adapter_ = + blink::WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter( + dependency_factory_.get(), main_thread_, CreateLocalVideoTrack()); + EXPECT_TRUE(track_adapter_->is_initialized()); + EXPECT_TRUE(!track_adapter_->web_track().IsNull()); + EXPECT_EQ(track_adapter_->web_track().Source().GetType(), + blink::WebMediaStreamSource::kTypeVideo); + EXPECT_TRUE(track_adapter_->webrtc_track()); + EXPECT_EQ(track_adapter_->webrtc_track()->kind(), + webrtc::MediaStreamTrackInterface::kVideoKind); + EXPECT_EQ(track_adapter_->webrtc_track()->id().c_str(), + track_adapter_->web_track().Id()); + EXPECT_TRUE(track_adapter_->GetLocalTrackVideoSinkForTesting()); + EXPECT_EQ( + track_adapter_->GetLocalTrackVideoSinkForTesting()->webrtc_video_track(), + track_adapter_->webrtc_track()); +} + +TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteAudioTrack) { + scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track = + blink::MockWebRtcAudioTrack::Create("remote_audio_track"); + dependency_factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + &WebRtcMediaStreamTrackAdapterTest::CreateRemoteTrackAdapter, + base::Unretained(this), base::Unretained(webrtc_track.get()))); + // The adapter is initialized implicitly in a PostTask, allow it to run. + RunMessageLoopsUntilIdle(); + DCHECK(track_adapter_); + EXPECT_TRUE(track_adapter_->is_initialized()); + EXPECT_TRUE(!track_adapter_->web_track().IsNull()); + EXPECT_EQ(track_adapter_->web_track().Source().GetType(), + blink::WebMediaStreamSource::kTypeAudio); + EXPECT_TRUE(track_adapter_->webrtc_track()); + EXPECT_EQ(track_adapter_->webrtc_track()->kind(), + webrtc::MediaStreamTrackInterface::kAudioKind); + EXPECT_EQ(track_adapter_->webrtc_track()->id().c_str(), + track_adapter_->web_track().Id()); + EXPECT_TRUE(track_adapter_->GetRemoteAudioTrackAdapterForTesting()); + EXPECT_TRUE( + track_adapter_->GetRemoteAudioTrackAdapterForTesting()->initialized()); +} + +TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteVideoTrack) { + scoped_refptr<blink::MockWebRtcVideoTrack> webrtc_track = + blink::MockWebRtcVideoTrack::Create("remote_video_track"); + dependency_factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + &WebRtcMediaStreamTrackAdapterTest::CreateRemoteTrackAdapter, + base::Unretained(this), base::Unretained(webrtc_track.get()))); + // The adapter is initialized implicitly in a PostTask, allow it to run. + RunMessageLoopsUntilIdle(); + DCHECK(track_adapter_); + EXPECT_TRUE(track_adapter_->is_initialized()); + EXPECT_TRUE(!track_adapter_->web_track().IsNull()); + EXPECT_EQ(track_adapter_->web_track().Source().GetType(), + blink::WebMediaStreamSource::kTypeVideo); + EXPECT_TRUE(track_adapter_->webrtc_track()); + EXPECT_EQ(track_adapter_->webrtc_track()->kind(), + webrtc::MediaStreamTrackInterface::kVideoKind); + EXPECT_EQ(track_adapter_->webrtc_track()->id().c_str(), + track_adapter_->web_track().Id()); + EXPECT_TRUE(track_adapter_->GetRemoteVideoTrackAdapterForTesting()); + EXPECT_TRUE( + track_adapter_->GetRemoteVideoTrackAdapterForTesting()->initialized()); +} + +TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteTrackExplicitlyInitialized) { + scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track = + blink::MockWebRtcAudioTrack::Create("remote_audio_track"); + dependency_factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + &WebRtcMediaStreamTrackAdapterTest::CreateRemoteTrackAdapter, + base::Unretained(this), base::Unretained(webrtc_track.get()))); + // Wait for the CreateRemoteTrackAdapter() call, but don't run the main thread + // loop that would have implicitly initialized the adapter. + RunMessageLoopsUntilIdle(false); + DCHECK(track_adapter_); + EXPECT_FALSE(track_adapter_->is_initialized()); + // Explicitly initialize before the main thread loop has a chance to run. + track_adapter_->InitializeOnMainThread(); + EXPECT_TRUE(track_adapter_->is_initialized()); + EXPECT_TRUE(!track_adapter_->web_track().IsNull()); + EXPECT_EQ(track_adapter_->web_track().Source().GetType(), + blink::WebMediaStreamSource::kTypeAudio); + EXPECT_TRUE(track_adapter_->webrtc_track()); + EXPECT_EQ(track_adapter_->webrtc_track()->kind(), + webrtc::MediaStreamTrackInterface::kAudioKind); + EXPECT_EQ(track_adapter_->webrtc_track()->id().c_str(), + track_adapter_->web_track().Id()); + EXPECT_TRUE(track_adapter_->GetRemoteAudioTrackAdapterForTesting()); + EXPECT_TRUE( + track_adapter_->GetRemoteAudioTrackAdapterForTesting()->initialized()); +} + +TEST_F(WebRtcMediaStreamTrackAdapterTest, LastReferenceOnSignalingThread) { + scoped_refptr<blink::MockWebRtcAudioTrack> webrtc_track = + blink::MockWebRtcAudioTrack::Create("remote_audio_track"); + dependency_factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + &WebRtcMediaStreamTrackAdapterTest::CreateRemoteTrackAdapter, + base::Unretained(this), base::Unretained(webrtc_track.get()))); + // The adapter is initialized implicitly in a PostTask, allow it to run. + RunMessageLoopsUntilIdle(); + DCHECK(track_adapter_); + EXPECT_TRUE(track_adapter_->is_initialized()); + + base::WaitableEvent waitable_event( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + dependency_factory_->GetWebRtcSignalingTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce( + &WebRtcMediaStreamTrackAdapterTest::HoldOntoAdapterReference, + base::Unretained(this), base::Unretained(&waitable_event), + track_adapter_)); + // Clear last reference on main thread. + track_adapter_->Dispose(); + track_adapter_ = nullptr; + waitable_event.Signal(); + RunMessageLoopsUntilIdle(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_stats_report_obtainer.cc b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_stats_report_obtainer.cc new file mode 100644 index 00000000000..f27836d2f8d --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_stats_report_obtainer.cc @@ -0,0 +1,36 @@ +// Copyright (c) 2017 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 "third_party/blink/public/web/modules/peerconnection/webrtc_stats_report_obtainer.h" + +#include "base/bind.h" +#include "base/callback.h" + +namespace blink { + +WebRTCStatsReportObtainer::WebRTCStatsReportObtainer() {} + +WebRTCStatsReportObtainer::~WebRTCStatsReportObtainer() {} + +blink::WebRTCStatsReportCallback +WebRTCStatsReportObtainer::GetStatsCallbackWrapper() { + return base::BindOnce(&WebRTCStatsReportObtainer::OnStatsDelivered, this); +} + +blink::WebRTCStatsReport* WebRTCStatsReportObtainer::report() const { + return report_.get(); +} + +blink::WebRTCStatsReport* WebRTCStatsReportObtainer::WaitForReport() { + run_loop_.Run(); + return report_.get(); +} + +void WebRTCStatsReportObtainer::OnStatsDelivered( + std::unique_ptr<blink::WebRTCStatsReport> report) { + report_ = std::move(report); + run_loop_.Quit(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc b/chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc index c61535bbb64..e03c047d0eb 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc +++ b/chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc @@ -6,7 +6,7 @@ #include <utility> -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -25,8 +25,8 @@ using mojom::blink::PermissionName; void ConnectToPermissionService( ExecutionContext* execution_context, mojo::PendingReceiver<mojom::blink::PermissionService> receiver) { - if (auto* interface_provider = execution_context->GetInterfaceProvider()) - interface_provider->GetInterface(std::move(receiver)); + execution_context->GetBrowserInterfaceBroker().GetInterface( + std::move(receiver)); } String PermissionStatusToString(mojom::blink::PermissionStatus status) { diff --git a/chromium/third_party/blink/renderer/modules/permissions/permissions.cc b/chromium/third_party/blink/renderer/modules/permissions/permissions.cc index 535c3d8d3be..b4e475b5f96 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/permissions.cc +++ b/chromium/third_party/blink/renderer/modules/permissions/permissions.cc @@ -249,7 +249,7 @@ ScriptPromise Permissions::revoke(ScriptState* script_state, ScriptPromise Permissions::requestAll( ScriptState* script_state, - const Vector<ScriptValue>& raw_permissions, + const HeapVector<ScriptValue>& raw_permissions, ExceptionState& exception_state) { Vector<PermissionDescriptorPtr> internal_permissions; Vector<int> caller_index_to_internal_index; diff --git a/chromium/third_party/blink/renderer/modules/permissions/permissions.h b/chromium/third_party/blink/renderer/modules/permissions/permissions.h index d17ffd938fe..66260d025e7 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/permissions.h +++ b/chromium/third_party/blink/renderer/modules/permissions/permissions.h @@ -26,7 +26,7 @@ class Permissions final : public ScriptWrappable { ScriptPromise request(ScriptState*, const ScriptValue&, ExceptionState&); ScriptPromise revoke(ScriptState*, const ScriptValue&, ExceptionState&); ScriptPromise requestAll(ScriptState*, - const Vector<ScriptValue>&, + const HeapVector<ScriptValue>&, ExceptionState&); private: diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc index b5490ca7819..1c8433f0fc0 100644 --- a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc +++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.cc @@ -9,9 +9,9 @@ #include "base/bind_helpers.h" #include "mojo/public/cpp/bindings/pending_remote.h" -#include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/public/common/manifest/web_display_mode.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" +#include "third_party/blink/public/mojom/manifest/display_mode.mojom-shared.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/dom/events/event.h" @@ -320,7 +320,7 @@ bool PictureInPictureControllerImpl::IsEnterAutoPictureInPictureAllowed() Fullscreen::FullscreenElementFrom(*GetSupplementable()) || (GetSupplementable()->View() && GetSupplementable()->View()->DisplayMode() != - WebDisplayMode::kWebDisplayModeBrowser && + blink::mojom::DisplayMode::kBrowser && GetSupplementable()->IsInWebAppScope()))) { return false; } @@ -423,7 +423,7 @@ bool PictureInPictureControllerImpl::EnsureService() { scoped_refptr<base::SingleThreadTaskRunner> task_runner = GetSupplementable()->GetFrame()->GetTaskRunner( TaskType::kMediaElementEvent); - GetSupplementable()->GetFrame()->GetInterfaceProvider().GetInterface( + GetSupplementable()->GetBrowserInterfaceBroker().GetInterface( picture_in_picture_service_.BindNewPipeAndPassReceiver(task_runner)); return true; } diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc index 169a91021a4..0d44effa064 100644 --- a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc +++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_test.cc @@ -9,6 +9,7 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/picture_in_picture/picture_in_picture.mojom-blink.h" #include "third_party/blink/public/platform/web_media_stream.h" #include "third_party/blink/public/platform/web_media_stream_track.h" @@ -116,16 +117,9 @@ class PictureInPictureControllerFrameClient explicit PictureInPictureControllerFrameClient( std::unique_ptr<WebMediaPlayer> player) - : test::MediaStubLocalFrameClient(std::move(player)), - interface_provider_(new service_manager::InterfaceProvider()) {} - - service_manager::InterfaceProvider* GetInterfaceProvider() override { - return interface_provider_.get(); - } + : test::MediaStubLocalFrameClient(std::move(player)) {} private: - std::unique_ptr<service_manager::InterfaceProvider> interface_provider_; - DISALLOW_COPY_AND_ASSIGN(PictureInPictureControllerFrameClient); }; @@ -158,9 +152,7 @@ class PictureInPictureControllerTest : public PageTestBase { nullptr, PictureInPictureControllerFrameClient::Create( std::make_unique<PictureInPictureControllerPlayer>())); - service_manager::InterfaceProvider::TestApi test_api( - GetFrame().Client()->GetInterfaceProvider()); - test_api.SetBinderForName( + GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting( mojom::blink::PictureInPictureService::Name_, WTF::BindRepeating(&MockPictureInPictureService::Bind, WTF::Unretained(&mock_service_))); @@ -184,6 +176,11 @@ class PictureInPictureControllerTest : public PageTestBase { test::RunPendingTasks(); } + void TearDown() override { + GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting( + mojom::blink::PictureInPictureService::Name_, {}); + } + HTMLVideoElement* Video() const { return video_.Get(); } MockPictureInPictureService& Service() { return mock_service_; } diff --git a/chromium/third_party/blink/renderer/modules/presentation/mock_presentation_service.h b/chromium/third_party/blink/renderer/modules/presentation/mock_presentation_service.h index cc570dac530..236a2c22b9b 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/mock_presentation_service.h +++ b/chromium/third_party/blink/renderer/modules/presentation/mock_presentation_service.h @@ -7,7 +7,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h" +#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink-forward.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.h index 64ed0b16312..022e6c45a98 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.h @@ -20,7 +20,7 @@ namespace blink { // TODO(crbug.com/749327): Consider removing this class and have // PresentationAvailabilityState use PresentationAvailabilityProperty directly. class MODULES_EXPORT PresentationAvailabilityCallbacks - : public GarbageCollectedFinalized<PresentationAvailabilityCallbacks> { + : public GarbageCollected<PresentationAvailabilityCallbacks> { public: PresentationAvailabilityCallbacks(PresentationAvailabilityProperty*, const WTF::Vector<KURL>&); diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_observer.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_observer.h index efd42039f73..5ac1e43c427 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_observer.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_observer.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_AVAILABILITY_OBSERVER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_AVAILABILITY_OBSERVER_H_ -#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h" +#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/wtf/vector.h" diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.h index e1ee2bf50c4..c85f91240f1 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.h @@ -28,8 +28,8 @@ class PresentationAvailabilityObserver; // TODO(crbug.com/780109): Improve encapsulation of PresentationAvailability and // this class by moving the multiple URL tracking logic to the former, and // consolidating this class's APIs to take repeating callbacks. -class MODULES_EXPORT PresentationAvailabilityState - : public GarbageCollectedFinalized<PresentationAvailabilityState> { +class MODULES_EXPORT PresentationAvailabilityState final + : public GarbageCollected<PresentationAvailabilityState> { public: explicit PresentationAvailabilityState(mojom::blink::PresentationService*); ~PresentationAvailabilityState(); @@ -60,8 +60,8 @@ class MODULES_EXPORT PresentationAvailabilityState // Tracks listeners of presentation displays availability for // |availability_urls|. Shared with PresentationRequest objects with the same // set of URLs. - class AvailabilityListener - : public GarbageCollectedFinalized<AvailabilityListener> { + class AvailabilityListener final + : public GarbageCollected<AvailabilityListener> { public: explicit AvailabilityListener(const Vector<KURL>& availability_urls); ~AvailabilityListener(); diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state_test.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state_test.cc index 719c3026d84..02dbf0b26bb 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state_test.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state_test.cc @@ -20,7 +20,7 @@ namespace blink { using mojom::blink::ScreenAvailability; class MockPresentationAvailabilityObserver - : public GarbageCollectedFinalized<MockPresentationAvailabilityObserver>, + : public GarbageCollected<MockPresentationAvailabilityObserver>, public PresentationAvailabilityObserver { USING_GARBAGE_COLLECTED_MIXIN(MockPresentationAvailabilityObserver); diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc index 3068367244a..fae2d02ddc2 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc @@ -100,7 +100,7 @@ void ThrowPresentationDisconnectedError(ExceptionState& exception_state) { } // namespace class PresentationConnection::Message final - : public GarbageCollectedFinalized<PresentationConnection::Message> { + : public GarbageCollected<PresentationConnection::Message> { public: Message(const String& text) : type(kMessageTypeText), text(text) {} @@ -119,7 +119,7 @@ class PresentationConnection::Message final }; class PresentationConnection::BlobLoader final - : public GarbageCollectedFinalized<PresentationConnection::BlobLoader>, + : public GarbageCollected<PresentationConnection::BlobLoader>, public FileReaderLoaderClient { public: BlobLoader(scoped_refptr<BlobDataHandle> blob_data_handle, diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h index ef6bb42e5b0..0dac738c3d5 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.h @@ -8,7 +8,7 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" -#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h" +#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc index 880e3228800..1c39732e27d 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/presentation/presentation_controller.h" #include <memory> +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -153,14 +154,11 @@ PresentationController::FindExistingConnection( mojo::Remote<mojom::blink::PresentationService>& PresentationController::GetPresentationService() { - if (!presentation_service_remote_ && GetFrame() && GetFrame()->Client()) { - auto* interface_provider = GetFrame()->Client()->GetInterfaceProvider(); - + if (!presentation_service_remote_ && GetFrame()) { scoped_refptr<base::SingleThreadTaskRunner> task_runner = GetFrame()->GetTaskRunner(TaskType::kPresentation); - interface_provider->GetInterface( + GetFrame()->GetBrowserInterfaceBroker().GetInterface( presentation_service_remote_.BindNewPipeAndPassReceiver(task_runner)); - presentation_service_remote_->SetController( presentation_controller_receiver_.BindNewPipeAndPassRemote( task_runner)); diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h index 635f6da2711..0518081b27f 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h @@ -30,7 +30,7 @@ class PresentationAvailabilityState; // Implements the PresentationController interface from the Presentation API // from which websites can implement the controlling side of a presentation. class MODULES_EXPORT PresentationController - : public GarbageCollectedFinalized<PresentationController>, + : public GarbageCollected<PresentationController>, public Supplement<LocalFrame>, public ContextLifecycleObserver, public mojom::blink::PresentationController { diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_error.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_error.cc index 7f9db6990b7..72083a57a62 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_error.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_error.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/presentation/presentation_error.h" +#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h" #include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_error.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_error.h index 46cb65f3f74..62f5fcbdbc9 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_error.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_error.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_ERROR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PRESENTATION_PRESENTATION_ERROR_H_ -#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink.h" +#include "third_party/blink/public/mojom/presentation/presentation.mojom-blink-forward.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc index 21d97512f07..df661cb69b8 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/presentation/presentation_receiver.h" #include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -27,16 +28,14 @@ PresentationReceiver::PresentationReceiver(LocalFrame* frame) : ContextLifecycleObserver(frame->GetDocument()), connection_list_(MakeGarbageCollected<PresentationConnectionList>( frame->GetDocument())) { - auto* interface_provider = GetFrame()->Client()->GetInterfaceProvider(); - interface_provider->GetInterface( + frame->GetBrowserInterfaceBroker().GetInterface( presentation_service_remote_.BindNewPipeAndPassReceiver()); - scoped_refptr<base::SingleThreadTaskRunner> task_runner = frame->GetTaskRunner(TaskType::kPresentation); // Set the mojo::Remote<T> that remote implementation of PresentationService - // will use to interact with the associated PresentationReceiver, in order to - // receive updates on new connections becoming available. + // will use to interact with the associated PresentationReceiver, in order + // to receive updates on new connections becoming available. presentation_service_remote_->SetReceiver( presentation_receiver_receiver_.BindNewPipeAndPassRemote(task_runner)); } diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_error.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_error.cc index c2edc0d050e..1ae288c8cf9 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_error.cc +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_error.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/push_messaging/push_error.h" +#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-blink.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_error.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_error.h index 045878dc81e..b48a8f41ea2 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_error.h +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_error.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_ERROR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PUSH_MESSAGING_PUSH_ERROR_H_ -#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-blink.h" +#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-blink-forward.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc index 28e48e6a7ef..3ba9a309263 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_message_data.cc @@ -83,7 +83,7 @@ ScriptValue PushMessageData::json(ScriptState* script_state, if (exception_state.HadException()) return ScriptValue(); - return ScriptValue(script_state, parsed); + return ScriptValue(script_state->GetIsolate(), parsed); } String PushMessageData::text() const { diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h index af26f9e596f..663392b016b 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h @@ -24,9 +24,8 @@ class ScriptState; // Registration. // // TODO(peter): Use the PushMessaging Mojo service directly from here. -class PushMessagingBridge final - : public GarbageCollectedFinalized<PushMessagingBridge>, - public Supplement<ServiceWorkerRegistration> { +class PushMessagingBridge final : public GarbageCollected<PushMessagingBridge>, + public Supplement<ServiceWorkerRegistration> { USING_GARBAGE_COLLECTED_MIXIN(PushMessagingBridge); public: diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc index a5a32209b7d..692dfc40d73 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.cc @@ -7,7 +7,8 @@ #include <string> #include <utility> -#include "third_party/blink/public/mojom/frame/document_interface_broker.mojom-blink.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h" #include "third_party/blink/public/mojom/push_messaging/push_messaging_status.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/web/web_local_frame.h" @@ -43,7 +44,7 @@ PushMessagingClient* PushMessagingClient::From(LocalFrame* frame) { mojom::blink::PushMessaging* PushMessagingClient::GetPushMessagingRemote() { if (!push_messaging_manager_) { - GetSupplementable()->GetDocumentInterfaceBroker().GetPushMessaging( + GetSupplementable()->GetBrowserInterfaceBroker().GetInterface( push_messaging_manager_.BindNewPipeAndPassReceiver( GetSupplementable()->GetTaskRunner(TaskType::kMiscPlatformAPI))); } diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.h index 606d91ead9c..dab40d00c38 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.h +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_client.h @@ -10,7 +10,7 @@ #include "base/macros.h" #include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink.h" +#include "third_party/blink/public/mojom/manifest/manifest.mojom-blink-forward.h" #include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-blink.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/modules/push_messaging/push_subscription_callbacks.h" @@ -26,9 +26,8 @@ class KURL; class PushSubscriptionOptions; class ServiceWorkerRegistration; -class PushMessagingClient final - : public GarbageCollectedFinalized<PushMessagingClient>, - public Supplement<LocalFrame> { +class PushMessagingClient final : public GarbageCollected<PushMessagingClient>, + public Supplement<LocalFrame> { USING_GARBAGE_COLLECTED_MIXIN(PushMessagingClient); public: diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.h index 64b942b4bb6..4ac49e828fd 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.h +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.h @@ -13,7 +13,7 @@ #include "base/single_thread_task_runner.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-blink.h" -#include "third_party/blink/public/mojom/push_messaging/push_messaging_status.mojom-blink.h" +#include "third_party/blink/public/mojom/push_messaging/push_messaging_status.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/push_messaging/push_subscription_callbacks.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h" #include "third_party/blink/renderer/platform/supplementable.h" @@ -28,7 +28,7 @@ enum class PushRegistrationStatus; class PushSubscriptionOptions; -class PushProvider final : public GarbageCollectedFinalized<PushProvider>, +class PushProvider final : public GarbageCollected<PushProvider>, public Supplement<ServiceWorkerRegistration> { USING_GARBAGE_COLLECTED_MIXIN(PushProvider); diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.h index 3c994990f27..8098e52b8ff 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.h +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.h @@ -8,7 +8,7 @@ #include <memory> #include "base/gtest_prod_util.h" #include "base/memory/scoped_refptr.h" -#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-blink.h" +#include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/core/dom/dom_time_stamp.h" diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h b/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h index 5cc313a0ec4..1c72a139be0 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h +++ b/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h @@ -16,7 +16,7 @@ class PushManager; class ServiceWorkerRegistration; class ServiceWorkerRegistrationPush final - : public GarbageCollectedFinalized<ServiceWorkerRegistrationPush>, + : public GarbageCollected<ServiceWorkerRegistrationPush>, public Supplement<ServiceWorkerRegistration> { USING_GARBAGE_COLLECTED_MIXIN(ServiceWorkerRegistrationPush); diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h b/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h index bcbb5c1abbb..1520f7575e2 100644 --- a/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h +++ b/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h @@ -20,7 +20,7 @@ class V8RemotePlaybackAvailabilityCallback; // Wraps either a base::OnceClosure or RemotePlaybackAvailabilityCallback object // to be kept in the RemotePlayback's |availability_callbacks_| map. class AvailabilityCallbackWrapper final - : public GarbageCollectedFinalized<AvailabilityCallbackWrapper>, + : public GarbageCollected<AvailabilityCallbackWrapper>, public NameClient { public: explicit AvailabilityCallbackWrapper(V8RemotePlaybackAvailabilityCallback*); diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc index 10cff33e4c6..85b33dca718 100644 --- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc +++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc @@ -369,7 +369,8 @@ void RemotePlayback::StateChanged( DispatchEvent(*Event::Create(event_type_names::kDisconnect)); if (media_element_->IsHTMLVideoElement()) { ToHTMLVideoElement(media_element_.Get()) - ->MediaRemotingStopped(WebLocalizedString::kMediaRemotingStopNoText); + ->MediaRemotingStopped( + WebMediaPlayerClient::kMediaRemotingStopNoText); } CleanupConnections(); presentation_id_ = ""; diff --git a/chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn b/chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn index e7365abba62..8612dd3de36 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn @@ -6,12 +6,12 @@ import("//third_party/blink/renderer/modules/modules.gni") blink_modules_sources("scheduler") { sources = [ - "scheduler.cc", - "scheduler.h", - "task.cc", - "task.h", - "task_queue.cc", - "task_queue.h", + "dom_scheduler.cc", + "dom_scheduler.h", + "dom_task.cc", + "dom_task.h", + "dom_task_queue.cc", + "dom_task_queue.h", "window_scheduler.cc", "window_scheduler.h", ] diff --git a/chromium/third_party/blink/renderer/modules/scheduler/README.md b/chromium/third_party/blink/renderer/modules/scheduler/README.md index bd4ac8cd279..a6f30bc2063 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/README.md +++ b/chromium/third_party/blink/renderer/modules/scheduler/README.md @@ -37,23 +37,23 @@ Tasks can be moved between task queues with `taskQueue.task(task)`. ### Code Overview and Blink Scheduler Integration -#### Scheduler +#### DOMScheduler -The `Scheduler` is per-document, and observes document lifecycle changes via -`ContextLifecycleObserver`. When the context is destroyed, the `Scheduler` stops +The `DOMScheduler` is per-document, and observes document lifecycle changes via +`ContextLifecycleObserver`. When the context is destroyed, the `DOMScheduler` stops running tasks. -The `Scheduler`'s primary function is to maintain TaskQueues. When the -`Scheduler` is created (when first accessed via `window.scheduler`), it creates -a set of *global* `TaskQueues`, one of each priority. Global here means +The `DOMScheduler`'s primary function is to maintain DOMTaskQueues. When the +`DOMScheduler` is created (when first accessed via `window.scheduler`), it creates +a set of *global* `DOMTaskQueues`, one of each priority. Global here means document-global, meaning all document script can access these via `window.scheduler`. This is opposed to *custom* task queues, which developers will be able to create via `new TaskQueue()` (WIP). -#### TaskQueues +#### DOMTaskQueues -Each `TaskQueue` wraps a `WebSchedulingTaskQueue`, which is the interface to the +Each `DOMTaskQueue` wraps a `WebSchedulingTaskQueue`, which is the interface to the Blink scheduler. The `WebSchedulingTaskQueue` is created through the document's `FrameScheduler`, @@ -61,24 +61,24 @@ and is created with a `WebSchedulingPriority`. The latter is used by the Blink scheduler to determine the priority of the underlying [base::sequence_manager::TaskQueue](https://cs.chromium.org/chromium/src/base/task/sequence_manager/task_queue.h). -The `TaskQueue` owns the `WebSchedulingTaskQueue`, and its lifetime is tied to -that of the `Document` associated with the `Scheduler`. +The `DOMTaskQueue` owns the `WebSchedulingTaskQueue`, and its lifetime is tied to +that of the `Document` associated with the `DOMScheduler`. -The `WebSchedulingTaskQueue` exposes a `TaskRunner`, which the `TaskQueue` uses +The `WebSchedulingTaskQueue` exposes a `TaskRunner`, which the `DOMTaskQueue` uses to post tasks to the Blink scheduler. -#### Tasks +#### DOMTasks -A `Task` is a wrapper for a callback, its arguments, its return value (for +A `DOMTask` is a wrapper for a callback, its arguments, its return value (for `task.result`), and a [`TaskHandle`](https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h?sq=package:chromium&g=0&l=22), -which allows the `Task` to be canceled with `task.cancel()`. +which allows the `DOMTask` to be canceled with `task.cancel()`. -The Blink scheduler handles the actual task scheduling. A `Task`'s callback is +The Blink scheduler handles the actual task scheduling. A `DOMTask`'s callback is scheduled to run by posting it a task to a `TaskRunner`—just as all tasks in Blink are. The `TaskRunner` is obtained through the `WebSchedulingTaskQueue`, -which is owned by the `TaskQueue` that the `Task` is posted to. +which is owned by the `DOMTaskQueue` that the `DOMTask` is posted to. TODO(shaseley): Add a diagram for the relation between all the different task queues. @@ -104,5 +104,5 @@ priority) of tasks. The API is modeled after setTimeout and setInterval with regards to detached documents. When a document is detached, any queued tasks will be prevented from -running, and future calls to postTask through a cached Scheduler or TaskQueue +running, and future calls to postTask through a cached DOMScheduler or DOMTaskQueue will be no-ops and return null. diff --git a/chromium/third_party/blink/renderer/modules/scheduler/scheduler.cc b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc index 5c7398ce025..d324ded33bf 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/scheduler.cc +++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc @@ -2,29 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/modules/scheduler/scheduler.h" +#include "third_party/blink/renderer/modules/scheduler/dom_scheduler.h" #include "base/memory/weak_ptr.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/modules/scheduler/dom_task_queue.h" #include "third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.h" -#include "third_party/blink/renderer/modules/scheduler/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_priority.h" namespace blink { -const char Scheduler::kSupplementName[] = "Scheduler"; +const char DOMScheduler::kSupplementName[] = "DOMScheduler"; -Scheduler* Scheduler::From(Document& document) { - Scheduler* scheduler = Supplement<Document>::From<Scheduler>(document); +DOMScheduler* DOMScheduler::From(Document& document) { + DOMScheduler* scheduler = Supplement<Document>::From<DOMScheduler>(document); if (!scheduler) { - scheduler = MakeGarbageCollected<Scheduler>(&document); + scheduler = MakeGarbageCollected<DOMScheduler>(&document); Supplement<Document>::ProvideTo(document, scheduler); } return scheduler; } -Scheduler::Scheduler(Document* document) : ContextLifecycleObserver(document) { +DOMScheduler::DOMScheduler(Document* document) + : ContextLifecycleObserver(document) { if (document->IsContextDestroyed()) return; DCHECK(document->GetScheduler()); @@ -32,11 +33,11 @@ Scheduler::Scheduler(Document* document) : ContextLifecycleObserver(document) { CreateGlobalTaskQueues(document); } -void Scheduler::ContextDestroyed(ExecutionContext* context) { +void DOMScheduler::ContextDestroyed(ExecutionContext* context) { global_task_queues_.clear(); } -void Scheduler::Trace(Visitor* visitor) { +void DOMScheduler::Trace(Visitor* visitor) { visitor->Trace(global_task_queues_); visitor->Trace(current_task_queue_); ScriptWrappable::Trace(visitor); @@ -44,7 +45,7 @@ void Scheduler::Trace(Visitor* visitor) { Supplement<Document>::Trace(visitor); } -TaskQueue* Scheduler::currentTaskQueue() { +DOMTaskQueue* DOMScheduler::currentTaskQueue() { // The |current_task_queue_| will only be set if the task currently running // was scheduled through window.scheduler. In other cases, e.g. setTimeout, // |current_task_queue_| will be nullptr, in which case we return the default @@ -54,41 +55,41 @@ TaskQueue* Scheduler::currentTaskQueue() { return GetTaskQueue(WebSchedulingPriority::kDefaultPriority); } -void Scheduler::OnTaskStarted(TaskQueue* task_queue, Task*) { +void DOMScheduler::OnTaskStarted(DOMTaskQueue* task_queue, DOMTask*) { // This is not reentrant; tasks are not nested. This allows us to set // |current_task_queue_| to nullptr when this task completes. DCHECK_EQ(current_task_queue_, nullptr); current_task_queue_ = task_queue; } -void Scheduler::OnTaskCompleted(TaskQueue* task_queue, Task*) { +void DOMScheduler::OnTaskCompleted(DOMTaskQueue* task_queue, DOMTask*) { DCHECK(current_task_queue_); DCHECK_EQ(current_task_queue_, task_queue); current_task_queue_ = nullptr; } -TaskQueue* Scheduler::getTaskQueue(AtomicString priority) { - return GetTaskQueue(TaskQueue::WebSchedulingPriorityFromString(priority)); +DOMTaskQueue* DOMScheduler::getTaskQueue(AtomicString priority) { + return GetTaskQueue(WebSchedulingPriorityFromString(priority)); } -TaskQueue* Scheduler::GetTaskQueue(WebSchedulingPriority priority) { +DOMTaskQueue* DOMScheduler::GetTaskQueue(WebSchedulingPriority priority) { if (global_task_queues_.IsEmpty()) return nullptr; return global_task_queues_[static_cast<int>(priority)]; } -Task* Scheduler::postTask(V8Function* callback_function, - SchedulerPostTaskOptions* options, - const Vector<ScriptValue>& args) { - TaskQueue* task_queue = getTaskQueue(AtomicString(options->priority())); +DOMTask* DOMScheduler::postTask(V8Function* callback_function, + SchedulerPostTaskOptions* options, + const HeapVector<ScriptValue>& args) { + DOMTaskQueue* task_queue = getTaskQueue(AtomicString(options->priority())); if (!task_queue) return nullptr; return task_queue->postTask(callback_function, options, args); } -void Scheduler::CreateGlobalTaskQueues(Document* document) { +void DOMScheduler::CreateGlobalTaskQueues(Document* document) { for (size_t i = 0; i < kWebSchedulingPriorityCount; i++) { - global_task_queues_.push_back(MakeGarbageCollected<TaskQueue>( + global_task_queues_.push_back(MakeGarbageCollected<DOMTaskQueue>( document, static_cast<WebSchedulingPriority>(i), this)); } } diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h new file mode 100644 index 00000000000..88f8d2bdff4 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h @@ -0,0 +1,82 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_DOM_SCHEDULER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_DOM_SCHEDULER_H_ + +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" +#include "third_party/blink/renderer/modules/modules_export.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/scheduler/public/web_scheduling_priority.h" +#include "third_party/blink/renderer/platform/supplementable.h" +#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" + +namespace blink { + +class DOMTask; +class DOMTaskQueue; +class ExecutionContext; +class SchedulerPostTaskOptions; +class ScriptValue; +class V8Function; + +class MODULES_EXPORT DOMScheduler : public ScriptWrappable, + public ContextLifecycleObserver, + public Supplement<Document> { + DEFINE_WRAPPERTYPEINFO(); + USING_GARBAGE_COLLECTED_MIXIN(DOMScheduler); + + public: + static const char kSupplementName[]; + + static DOMScheduler* From(Document&); + + explicit DOMScheduler(Document*); + + // Returns the DOMTaskQueue of the currently executing DOMTask. If the current + // task was not scheduled through the scheduler, this returns the default + // priority global task queue. + DOMTaskQueue* currentTaskQueue(); + + // Returns the DOMTaskQueue for the given |priority| or nullptr if the + // underlying context is destroyed, e.g. for detached documents. + DOMTaskQueue* getTaskQueue(AtomicString priority); + + // postTask creates and queues a DOMTask in the |global_task_queues_| entry + // corresponding to the priority in the SchedulerPostTaskOptions, and returns + // the DOMTask. If the underlying context is destroyed, e.g. for detached + // documents, this returns nullptr. + DOMTask* postTask(V8Function*, + SchedulerPostTaskOptions*, + const HeapVector<ScriptValue>& args); + + // Callbacks invoked by DOMTasks when they run. + void OnTaskStarted(DOMTaskQueue*, DOMTask*); + void OnTaskCompleted(DOMTaskQueue*, DOMTask*); + + void ContextDestroyed(ExecutionContext*) override; + + void Trace(Visitor*) override; + + private: + static constexpr size_t kWebSchedulingPriorityCount = + static_cast<size_t>(WebSchedulingPriority::kLastPriority) + 1; + + void CreateGlobalTaskQueues(Document*); + DOMTaskQueue* GetTaskQueue(WebSchedulingPriority); + + // |global_task_queues_| is initialized with one entry per priority, indexed + // by priority. This will be empty when the document is detached. + HeapVector<Member<DOMTaskQueue>, kWebSchedulingPriorityCount> + global_task_queues_; + // The DOMTaskQueue associated with the currently running DOMTask, or nullptr + // if the current task was not scheduled through this DOMScheduler. + Member<DOMTaskQueue> current_task_queue_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_DOM_SCHEDULER_H_ diff --git a/chromium/third_party/blink/renderer/modules/scheduler/task.cc b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc index f55ed74cbc9..038b65c2944 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/task.cc +++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/modules/scheduler/task.h" +#include "third_party/blink/renderer/modules/scheduler/dom_task.h" #include <utility> @@ -10,18 +10,18 @@ #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_function.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" -#include "third_party/blink/renderer/modules/scheduler/scheduler.h" -#include "third_party/blink/renderer/modules/scheduler/task_queue.h" +#include "third_party/blink/renderer/modules/scheduler/dom_scheduler.h" +#include "third_party/blink/renderer/modules/scheduler/dom_task_queue.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" namespace blink { -Task::Task(TaskQueue* task_queue, - ExecutionContext* context, - V8Function* callback, - const Vector<ScriptValue>& args, - base::TimeDelta delay) +DOMTask::DOMTask(DOMTaskQueue* task_queue, + ExecutionContext* context, + V8Function* callback, + const HeapVector<ScriptValue>& args, + base::TimeDelta delay) : ContextLifecycleObserver(context), status_(Status::kPending), task_queue_(task_queue), @@ -36,9 +36,10 @@ Task::Task(TaskQueue* task_queue, Schedule(delay_); } -void Task::Trace(Visitor* visitor) { +void DOMTask::Trace(Visitor* visitor) { visitor->Trace(task_queue_); visitor->Trace(callback_); + visitor->Trace(arguments_); visitor->Trace(result_value_); visitor->Trace(result_promise_); visitor->Trace(exception_); @@ -46,40 +47,40 @@ void Task::Trace(Visitor* visitor) { ContextLifecycleObserver::Trace(visitor); } -void Task::ContextDestroyed(ExecutionContext* context) { +void DOMTask::ContextDestroyed(ExecutionContext* context) { if (status_ != Status::kPending) return; CancelPendingTask(); } -AtomicString Task::priority() const { +AtomicString DOMTask::priority() const { DCHECK(task_queue_); return task_queue_->priority(); } -AtomicString Task::status() const { +AtomicString DOMTask::status() const { return TaskStatusToString(status_); } -void Task::cancel(ScriptState* script_state) { +void DOMTask::cancel(ScriptState* script_state) { if (status_ != Status::kPending) return; CancelPendingTask(); SetTaskStatus(Status::kCanceled); - ResolveOrRejectPromiseIfNeeded(script_state); + LazilyResolveOrRejectPromiseIfReady(script_state); } -ScriptPromise Task::result(ScriptState* script_state) { +ScriptPromise DOMTask::result(ScriptState* script_state) { if (!result_promise_) { result_promise_ = MakeGarbageCollected<TaskResultPromise>( ExecutionContext::From(script_state), this, TaskResultPromise::kFinished); - ResolveOrRejectPromiseIfNeeded(script_state); + LazilyResolveOrRejectPromiseIfReady(script_state); } return result_promise_->Promise(script_state->World()); } -void Task::MoveTo(TaskQueue* task_queue) { +void DOMTask::MoveTo(DOMTaskQueue* task_queue) { if (status_ != Status::kPending || task_queue == task_queue_) return; @@ -98,31 +99,31 @@ void Task::MoveTo(TaskQueue* task_queue) { Schedule(delay); } -void Task::Schedule(base::TimeDelta delay) { +void DOMTask::Schedule(base::TimeDelta delay) { DCHECK_EQ(status_, Status::kPending); DCHECK(!task_handle_.IsActive()); DCHECK_GE(delay, base::TimeDelta()); task_handle_ = PostDelayedCancellableTask( *task_queue_->GetTaskRunner(), FROM_HERE, - WTF::Bind(&Task::Invoke, WrapPersistent(this)), delay_); + WTF::Bind(&DOMTask::Invoke, WrapPersistent(this)), delay_); } -void Task::CancelPendingTask() { +void DOMTask::CancelPendingTask() { DCHECK_EQ(status_, Status::kPending); DCHECK(task_handle_.IsActive()); task_handle_.Cancel(); } -void Task::Invoke() { +void DOMTask::Invoke() { DCHECK_EQ(status_, Status::kPending); DCHECK(callback_); DCHECK(GetExecutionContext()); DCHECK(!GetExecutionContext()->IsContextDestroyed()); ScriptState* script_state = - callback_->CallbackRelevantScriptStateOrReportError("Task", "Invoke"); + callback_->CallbackRelevantScriptStateOrReportError("DOMTask", "Invoke"); if (!script_state || !script_state->ContextIsValid()) return; @@ -131,11 +132,11 @@ void Task::Invoke() { InvokeInternal(script_state); SetTaskStatus(Status::kCompleted); task_queue_->GetScheduler()->OnTaskCompleted(task_queue_, this); - ResolveOrRejectPromiseIfNeeded(script_state); + LazilyResolveOrRejectPromiseIfReady(script_state); callback_.Release(); } -void Task::InvokeInternal(ScriptState* script_state) { +void DOMTask::InvokeInternal(ScriptState* script_state) { ScriptState::Scope scope(script_state); v8::TryCatch try_catch(script_state->GetIsolate()); try_catch.SetVerbose(true); @@ -150,9 +151,7 @@ void Task::InvokeInternal(ScriptState* script_state) { result_value_.Set(script_state->GetIsolate(), result.V8Value()); } -void Task::ResolveOrRejectPromiseIfNeeded(ScriptState* script_state) { - // Lazily resolove or reject the Promise - we don't do anything unless the - // result property has been accessed. +void DOMTask::LazilyResolveOrRejectPromiseIfReady(ScriptState* script_state) { if (!result_promise_) return; @@ -182,15 +181,15 @@ void Task::ResolveOrRejectPromiseIfNeeded(ScriptState* script_state) { } } -void Task::SetTaskStatus(Status status) { +void DOMTask::SetTaskStatus(Status status) { DCHECK(IsValidStatusChange(status_, status)) - << "Cannot transition from Task::Status " << TaskStatusToString(status_) - << " to " << TaskStatusToString(status); + << "Cannot transition from DOMTask::Status " + << TaskStatusToString(status_) << " to " << TaskStatusToString(status); status_ = status; } // static -AtomicString Task::TaskStatusToString(Status status) { +AtomicString DOMTask::TaskStatusToString(Status status) { DEFINE_STATIC_LOCAL(const AtomicString, pending, ("pending")); DEFINE_STATIC_LOCAL(const AtomicString, running, ("running")); DEFINE_STATIC_LOCAL(const AtomicString, canceled, ("canceled")); @@ -212,7 +211,7 @@ AtomicString Task::TaskStatusToString(Status status) { } // static -bool Task::IsValidStatusChange(Status from, Status to) { +bool DOMTask::IsValidStatusChange(Status from, Status to) { // Note: Self transitions are not valid. switch (from) { case Status::kPending: { diff --git a/chromium/third_party/blink/renderer/modules/scheduler/task.h b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.h index 53e4e1c73f9..0fc2c709c6e 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/task.h +++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_TASK_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_TASK_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_DOM_TASK_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_DOM_TASK_H_ #include "base/time/time.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" @@ -18,22 +18,23 @@ namespace blink { +class DOMTaskQueue; class ScriptState; class ScriptValue; -class TaskQueue; class V8Function; -class MODULES_EXPORT Task : public ScriptWrappable, ContextLifecycleObserver { +class MODULES_EXPORT DOMTask : public ScriptWrappable, + ContextLifecycleObserver { DEFINE_WRAPPERTYPEINFO(); - USING_GARBAGE_COLLECTED_MIXIN(Task); + USING_GARBAGE_COLLECTED_MIXIN(DOMTask); public: - // Creating a task also causes the Task to be scheduled. - Task(TaskQueue*, - ExecutionContext*, - V8Function*, - const Vector<ScriptValue>& args, - base::TimeDelta delay); + // Creating a task also causes the DOMTask to be scheduled. + DOMTask(DOMTaskQueue*, + ExecutionContext*, + V8Function*, + const HeapVector<ScriptValue>& args, + base::TimeDelta delay); // Task IDL Interface. AtomicString priority() const; @@ -41,9 +42,9 @@ class MODULES_EXPORT Task : public ScriptWrappable, ContextLifecycleObserver { void cancel(ScriptState*); ScriptPromise result(ScriptState*); - // Move this Task to a different TaskQueue. If the task is already enqueued in - // the given task queue, this method has no effect. - void MoveTo(TaskQueue*); + // Move this DOMTask to a different DOMTaskQueue. If the task is already + // enqueued in the given task queue, this method has no effect. + void MoveTo(DOMTaskQueue*); void ContextDestroyed(ExecutionContext*) override; @@ -71,20 +72,26 @@ class MODULES_EXPORT Task : public ScriptWrappable, ContextLifecycleObserver { // otherwise it's queued after |delay|. void Schedule(base::TimeDelta delay); - // Callback for running the Task. + // Entry point for running this DOMTask's |callback_|. void Invoke(); + // Internal step of Invoke that handles invoking the callback, including + // catching any errors and retrieving the result. void InvokeInternal(ScriptState*); - void ResolveOrRejectPromiseIfNeeded(ScriptState*); + // Resolve |result_promise_| if both (a) the task has finished running (with + // or without an error) or has been canceled, and (b) task.result has been + // accessed and returned to userland. If invoked when either of these + // conditions are not met, this is a no-op. + void LazilyResolveOrRejectPromiseIfReady(ScriptState*); static bool IsValidStatusChange(Status from, Status to); static AtomicString TaskStatusToString(Status); Status status_; TaskHandle task_handle_; - Member<TaskQueue> task_queue_; + Member<DOMTaskQueue> task_queue_; Member<V8Function> callback_; - Vector<ScriptValue> arguments_; + HeapVector<ScriptValue> arguments_; const base::TimeDelta delay_; // Only set if |delay_| > 0 since Now() can be somewhat expensive. This // optimizes the case where there is no delay, which we expect to be the @@ -92,7 +99,10 @@ class MODULES_EXPORT Task : public ScriptWrappable, ContextLifecycleObserver { const base::TimeTicks queue_time_; using TaskResultPromise = - ScriptPromiseProperty<Member<Task>, ScriptValue, ScriptValue>; + ScriptPromiseProperty<Member<DOMTask>, ScriptValue, ScriptValue>; + // Lazily initialized when the task.result property is accessed to avoid the + // overhead of unnecessarily creating promises for every task if they aren't + // going to be used. Member<TaskResultPromise> result_promise_; TraceWrapperV8Reference<v8::Value> result_value_; @@ -101,4 +111,4 @@ class MODULES_EXPORT Task : public ScriptWrappable, ContextLifecycleObserver { } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_TASK_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_DOM_TASK_H_ diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_task_queue.cc b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_queue.cc new file mode 100644 index 00000000000..003733ed9ba --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_queue.cc @@ -0,0 +1,80 @@ +// 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. + +#include "third_party/blink/renderer/modules/scheduler/dom_task_queue.h" + +#include "base/location.h" +#include "base/logging.h" +#include "base/single_thread_task_runner.h" +#include "base/time/time.h" +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_function.h" +#include "third_party/blink/renderer/modules/scheduler/dom_scheduler.h" +#include "third_party/blink/renderer/modules/scheduler/dom_task.h" +#include "third_party/blink/renderer/modules/scheduler/task_queue_post_task_options.h" +#include "third_party/blink/renderer/platform/bindings/exception_code.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/persistent.h" +#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" +#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" +#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" + +namespace blink { + +DOMTaskQueue::DOMTaskQueue(Document* document, + WebSchedulingPriority priority, + DOMScheduler* scheduler) + : ContextLifecycleObserver(document), + priority_(priority), + web_scheduling_task_queue_(document->GetScheduler() + ->ToFrameScheduler() + ->CreateWebSchedulingTaskQueue(priority)), + task_runner_(web_scheduling_task_queue_->GetTaskRunner()), + scheduler_(scheduler) { + DCHECK(!document->IsContextDestroyed()); +} + +void DOMTaskQueue::Trace(Visitor* visitor) { + visitor->Trace(scheduler_); + ScriptWrappable::Trace(visitor); + ContextLifecycleObserver::Trace(visitor); +} + +void DOMTaskQueue::ContextDestroyed(ExecutionContext* context) { + web_scheduling_task_queue_.reset(nullptr); +} + +AtomicString DOMTaskQueue::priority() const { + return WebSchedulingPriorityToString(priority_); +} + +DOMTask* DOMTaskQueue::postTask(V8Function* function, + TaskQueuePostTaskOptions* options, + const HeapVector<ScriptValue>& args) { + if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed()) + return nullptr; + + // TODO(shaseley): We need to figure out the behavior we want for delay. For + // now, we use behavior that is very similar to setTimeout: negative delays + // are treated as 0, and we use the Blink scheduler's delayed task behavior. + // We don't, however, adjust the timeout based on nested calls (yet) or clamp + // the value to a minimal delay. + base::TimeDelta delay = base::TimeDelta::FromMilliseconds( + options->delay() > 0 ? options->delay() : 0); + + // For global task queues, we don't need to track the task objects separately; + // tracking is handled by the |web_scheduling_task_queue_|. + return MakeGarbageCollected<DOMTask>(this, GetExecutionContext(), function, + args, delay); +} + +void DOMTaskQueue::take(DOMTask* task) { + if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed()) + return; + task->MoveTo(this); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_task_queue.h b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_queue.h new file mode 100644 index 00000000000..417fa14f733 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_queue.h @@ -0,0 +1,86 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_DOM_TASK_QUEUE_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_DOM_TASK_QUEUE_H_ + +#include <memory> + +#include "base/memory/scoped_refptr.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" +#include "third_party/blink/renderer/modules/modules_export.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/scheduler/public/web_scheduling_priority.h" +#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" + +namespace base { +class SingleThreadTaskRunner; +} // namespace base + +namespace blink { + +class DOMScheduler; +class DOMTask; +class Document; +class ExecutionContext; +class ScriptValue; +class TaskQueuePostTaskOptions; +class V8Function; +class WebSchedulingTaskQueue; + +namespace scheduler { +class WebSchedulingTaskQueue; +} // namespace scheduler + +class MODULES_EXPORT DOMTaskQueue : public ScriptWrappable, + ContextLifecycleObserver { + DEFINE_WRAPPERTYPEINFO(); + USING_GARBAGE_COLLECTED_MIXIN(DOMTaskQueue); + + public: + DOMTaskQueue(Document*, WebSchedulingPriority, DOMScheduler*); + + // Returns the priority of the DOMTaskQueue. + AtomicString priority() const; + + // postTask creates and queues a DOMTask in this DOMTaskQueue and returns the + // DOMTask. If the underlying context is destroyed, e.g. for detached + // documents, this returns nullptr. + DOMTask* postTask(V8Function*, + TaskQueuePostTaskOptions*, + const HeapVector<ScriptValue>& args); + + // Move the task from its current DOMTaskQueue to this one. For pending + // non-delayed tasks, the task is enqueued at the end of this DOMTaskQueue. + // For delayed tasks, the delay is adjusted before reposting it. + void take(DOMTask*); + + const scoped_refptr<base::SingleThreadTaskRunner>& GetTaskRunner() { + return task_runner_; + } + + DOMScheduler* GetScheduler() { return scheduler_.Get(); } + + void ContextDestroyed(ExecutionContext*) override; + + void Trace(Visitor*) override; + + private: + void RunTaskCallback(DOMTask*); + void ScheduleTask(DOMTask*, base::TimeDelta delay); + + const WebSchedulingPriority priority_; + // This is destroyed when the Context is destroyed, and we rely on this + // happening before the underlying FrameScheduler is destroyed. + std::unique_ptr<WebSchedulingTaskQueue> web_scheduling_task_queue_; + const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + Member<DOMScheduler> scheduler_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_DOM_TASK_QUEUE_H_ diff --git a/chromium/third_party/blink/renderer/modules/scheduler/scheduler.h b/chromium/third_party/blink/renderer/modules/scheduler/scheduler.h deleted file mode 100644 index ad55aef669b..00000000000 --- a/chromium/third_party/blink/renderer/modules/scheduler/scheduler.h +++ /dev/null @@ -1,85 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_SCHEDULER_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_SCHEDULER_H_ - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" -#include "third_party/blink/renderer/modules/modules_export.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/scheduler/public/web_scheduling_priority.h" -#include "third_party/blink/renderer/platform/supplementable.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" - -namespace blink { - -class ExecutionContext; -class SchedulerPostTaskOptions; -class ScriptValue; -class Task; -class TaskQueue; -class V8Function; - -// TODO(shaseley): Rename this class along with TaskQueue and Task to better -// differentiate these classes from the various other scheduler, task queue, and -// task classes in the codebase. -class MODULES_EXPORT Scheduler : public ScriptWrappable, - public ContextLifecycleObserver, - public Supplement<Document> { - DEFINE_WRAPPERTYPEINFO(); - USING_GARBAGE_COLLECTED_MIXIN(Scheduler); - - public: - static const char kSupplementName[]; - - static Scheduler* From(Document&); - - explicit Scheduler(Document*); - - // Returns the TaskQueue of the currently executing Task. If the current task - // was not scheduled through the scheduler, this returns the default priority - // global task queue. - TaskQueue* currentTaskQueue(); - - // Returns the TaskQueue for the given |priority| or nullptr if the underlying - // context is destroyed, e.g. for detached documents. - TaskQueue* getTaskQueue(AtomicString priority); - - // postTask creates and queues a Task in the |global_task_queues_| entry - // corresponding to the priority in the SchedulerPostTaskOptions, and returns - // the Task. If the underlying context is destroyed, e.g. for detached - // documents, this returns nullptr. - Task* postTask(V8Function*, - SchedulerPostTaskOptions*, - const Vector<ScriptValue>& args); - - // Callbacks invoked by TaskQueues when they run scheduled tasks. - void OnTaskStarted(TaskQueue*, Task*); - void OnTaskCompleted(TaskQueue*, Task*); - - void ContextDestroyed(ExecutionContext*) override; - - void Trace(Visitor*) override; - - private: - static constexpr size_t kWebSchedulingPriorityCount = - static_cast<size_t>(WebSchedulingPriority::kLastPriority) + 1; - - void CreateGlobalTaskQueues(Document*); - TaskQueue* GetTaskQueue(WebSchedulingPriority); - - // |global_task_queues_| is initialized with one entry per priority, indexed - // by priority. This will be empty when the document is detached. - HeapVector<Member<TaskQueue>, kWebSchedulingPriorityCount> - global_task_queues_; - // The TaskQueue associated with the currently running Task, or nullptr if the - // current task was not scheduled through this Scheduler. - Member<TaskQueue> current_task_queue_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_SCHEDULER_H_ diff --git a/chromium/third_party/blink/renderer/modules/scheduler/scheduler.idl b/chromium/third_party/blink/renderer/modules/scheduler/scheduler.idl index 9a4311cf32c..cf184c192ec 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/scheduler.idl +++ b/chromium/third_party/blink/renderer/modules/scheduler/scheduler.idl @@ -4,7 +4,10 @@ // Experimental Scheduling API Proposal: // https://docs.google.com/document/d/1xU7HyNsEsbXhTgt0ZnXDbeSXm5-m5FzkLJAT6LTizEI/edit# -[RuntimeEnabled=WebScheduler] interface Scheduler { +[ + ImplementedAs=DOMScheduler, + RuntimeEnabled=WebScheduler +] interface Scheduler { readonly attribute TaskQueue currentTaskQueue; TaskQueue getTaskQueue(TaskQueuePriority priority); Task postTask(Function callback, optional SchedulerPostTaskOptions options, any... arguments); diff --git a/chromium/third_party/blink/renderer/modules/scheduler/task.idl b/chromium/third_party/blink/renderer/modules/scheduler/task.idl index 87baeb41d3b..80e1ccf7f32 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/task.idl +++ b/chromium/third_party/blink/renderer/modules/scheduler/task.idl @@ -6,7 +6,10 @@ // https://docs.google.com/document/d/1xU7HyNsEsbXhTgt0ZnXDbeSXm5-m5FzkLJAT6LTizEI/edit# enum TaskStatus { "pending", "running", "canceled", "completed" }; -[RuntimeEnabled=WebScheduler] interface Task { +[ + ImplementedAs=DOMTask, + RuntimeEnabled=WebScheduler +] interface Task { readonly attribute TaskStatus status; readonly attribute TaskQueuePriority priority; [CallWith=ScriptState] readonly attribute Promise<any> result; diff --git a/chromium/third_party/blink/renderer/modules/scheduler/task_queue.cc b/chromium/third_party/blink/renderer/modules/scheduler/task_queue.cc deleted file mode 100644 index aa2f3d88d48..00000000000 --- a/chromium/third_party/blink/renderer/modules/scheduler/task_queue.cc +++ /dev/null @@ -1,150 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/scheduler/task_queue.h" - -#include "base/location.h" -#include "base/logging.h" -#include "base/single_thread_task_runner.h" -#include "base/time/time.h" -#include "third_party/blink/renderer/bindings/core/v8/script_value.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_function.h" -#include "third_party/blink/renderer/modules/scheduler/scheduler.h" -#include "third_party/blink/renderer/modules/scheduler/task.h" -#include "third_party/blink/renderer/modules/scheduler/task_queue_post_task_options.h" -#include "third_party/blink/renderer/platform/bindings/exception_code.h" -#include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/heap/persistent.h" -#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" -#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" -#include "third_party/blink/renderer/platform/scheduler/public/web_scheduling_task_queue.h" -#include "third_party/blink/renderer/platform/wtf/functional.h" -#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" - -namespace blink { - -namespace { - -const AtomicString& ImmediatePriorityKeyword() { - DEFINE_STATIC_LOCAL(const AtomicString, immediate_priority, ("immediate")); - return immediate_priority; -} - -const AtomicString& HighPriorityKeyword() { - DEFINE_STATIC_LOCAL(const AtomicString, high_priority, ("high")); - return high_priority; -} - -const AtomicString& DefaultPriorityKeyword() { - DEFINE_STATIC_LOCAL(const AtomicString, default_priority, ("default")); - return default_priority; -} - -const AtomicString& LowPriorityKeyword() { - DEFINE_STATIC_LOCAL(const AtomicString, low_priority, ("low")); - return low_priority; -} - -const AtomicString& IdlePriorityKeyword() { - DEFINE_STATIC_LOCAL(const AtomicString, idle_priority, ("idle")); - return idle_priority; -} - -} // namespace - -TaskQueue::TaskQueue(Document* document, - WebSchedulingPriority priority, - Scheduler* scheduler) - : ContextLifecycleObserver(document), - priority_(priority), - web_scheduling_task_queue_(document->GetScheduler() - ->ToFrameScheduler() - ->CreateWebSchedulingTaskQueue(priority)), - task_runner_(web_scheduling_task_queue_->GetTaskRunner()), - scheduler_(scheduler) { - DCHECK(!document->IsContextDestroyed()); -} - -void TaskQueue::Trace(Visitor* visitor) { - visitor->Trace(scheduler_); - ScriptWrappable::Trace(visitor); - ContextLifecycleObserver::Trace(visitor); -} - -void TaskQueue::ContextDestroyed(ExecutionContext* context) { - web_scheduling_task_queue_.reset(nullptr); - task_runner_.reset(); -} - -AtomicString TaskQueue::priority() const { - return WebSchedulingPriorityToString(priority_); -} - -Task* TaskQueue::postTask(V8Function* function, - TaskQueuePostTaskOptions* options, - const Vector<ScriptValue>& args) { - // |task_runner_| will be nullptr when the context is destroyed, which - // prevents us from scheduling tasks for detached documents. - if (!task_runner_) - return nullptr; - - // TODO(shaseley): We need to figure out the behavior we want for delay. For - // now, we use behavior that is very similar to setTimeout: negative delays - // are treated as 0, and we use the Blink scheduler's delayed task behavior. - // We don't, however, adjust the timeout based on nested calls (yet) or clamp - // the value to a minimal delay. - base::TimeDelta delay = base::TimeDelta::FromMilliseconds( - options->delay() > 0 ? options->delay() : 0); - - // For global task queues, we don't need to track the task objects separately; - // tracking is handled by the |web_scheduling_task_queue_|. - return MakeGarbageCollected<Task>(this, GetExecutionContext(), function, args, - delay); -} - -void TaskQueue::take(Task* task) { - if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed()) - return; - task->MoveTo(this); -} - -// static -AtomicString TaskQueue::WebSchedulingPriorityToString( - WebSchedulingPriority priority) { - switch (priority) { - case WebSchedulingPriority::kImmediatePriority: - return ImmediatePriorityKeyword(); - case WebSchedulingPriority::kHighPriority: - return HighPriorityKeyword(); - case WebSchedulingPriority::kDefaultPriority: - return DefaultPriorityKeyword(); - case WebSchedulingPriority::kLowPriority: - return LowPriorityKeyword(); - case WebSchedulingPriority::kIdlePriority: - return IdlePriorityKeyword(); - } - - NOTREACHED(); - return g_empty_atom; -} - -// static -WebSchedulingPriority TaskQueue::WebSchedulingPriorityFromString( - AtomicString priority) { - if (priority == ImmediatePriorityKeyword()) - return WebSchedulingPriority::kImmediatePriority; - if (priority == HighPriorityKeyword()) - return WebSchedulingPriority::kHighPriority; - if (priority == DefaultPriorityKeyword()) - return WebSchedulingPriority::kDefaultPriority; - if (priority == LowPriorityKeyword()) - return WebSchedulingPriority::kLowPriority; - if (priority == IdlePriorityKeyword()) - return WebSchedulingPriority::kIdlePriority; - - NOTREACHED(); - return WebSchedulingPriority::kDefaultPriority; -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/scheduler/task_queue.h b/chromium/third_party/blink/renderer/modules/scheduler/task_queue.h deleted file mode 100644 index 7d8ac56e98e..00000000000 --- a/chromium/third_party/blink/renderer/modules/scheduler/task_queue.h +++ /dev/null @@ -1,83 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_TASK_QUEUE_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_TASK_QUEUE_H_ - -#include <memory> - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" -#include "third_party/blink/renderer/modules/modules_export.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/scheduler/public/web_scheduling_priority.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace base { -class SingleThreadTaskRunner; -} // namespace base - -namespace blink { - -class Document; -class ExecutionContext; -class Scheduler; -class ScriptValue; -class Task; -class TaskQueuePostTaskOptions; -class V8Function; -class WebSchedulingTaskQueue; - -namespace scheduler { -class WebSchedulingTaskQueue; -} // namespace scheduler - -class MODULES_EXPORT TaskQueue : public ScriptWrappable, - ContextLifecycleObserver { - DEFINE_WRAPPERTYPEINFO(); - USING_GARBAGE_COLLECTED_MIXIN(TaskQueue); - - public: - TaskQueue(Document*, WebSchedulingPriority, Scheduler*); - - // Returns the priority of the TaskQueue. - AtomicString priority() const; - - // postTask creates and queues a Task in this TaskQueue and returns the Task. - // If the underlying context is destroyed, e.g. for detached documents, this - // returns nullptr. - Task* postTask(V8Function*, - TaskQueuePostTaskOptions*, - const Vector<ScriptValue>& args); - - // Move the task from its current TaskQueue to this one. For pending - // non-delayed tasks, the task is enqueued at the end of this TaskQueue. For - // delayed tasks, the delay is adjusted before reposting it. - void take(Task*); - - base::SingleThreadTaskRunner* GetTaskRunner() { return task_runner_.get(); } - Scheduler* GetScheduler() { return scheduler_.Get(); } - - void ContextDestroyed(ExecutionContext*) override; - - void Trace(Visitor*) override; - - static AtomicString WebSchedulingPriorityToString(WebSchedulingPriority); - static WebSchedulingPriority WebSchedulingPriorityFromString(AtomicString); - - private: - void RunTaskCallback(Task*); - void ScheduleTask(Task*, base::TimeDelta delay); - - const WebSchedulingPriority priority_; - std::unique_ptr<WebSchedulingTaskQueue> web_scheduling_task_queue_; - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - Member<Scheduler> scheduler_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_TASK_QUEUE_H_ diff --git a/chromium/third_party/blink/renderer/modules/scheduler/task_queue.idl b/chromium/third_party/blink/renderer/modules/scheduler/task_queue.idl index 04e9b8b1cab..8c6e06dc034 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/task_queue.idl +++ b/chromium/third_party/blink/renderer/modules/scheduler/task_queue.idl @@ -12,7 +12,10 @@ enum TaskQueuePriority { "idle" }; -[RuntimeEnabled=WebScheduler] interface TaskQueue { +[ + ImplementedAs=DOMTaskQueue, + RuntimeEnabled=WebScheduler +] interface TaskQueue { readonly attribute TaskQueuePriority priority; Task postTask(Function callback, optional TaskQueuePostTaskOptions options, any... arguments); void take(Task task); diff --git a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.cc b/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.cc index b2c8e5cb7e4..e333a04fb54 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.cc +++ b/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.cc @@ -5,13 +5,13 @@ #include "third_party/blink/renderer/modules/scheduler/window_scheduler.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" -#include "third_party/blink/renderer/modules/scheduler/scheduler.h" +#include "third_party/blink/renderer/modules/scheduler/dom_scheduler.h" namespace blink { -Scheduler* WindowScheduler::scheduler(LocalDOMWindow& window) { +DOMScheduler* WindowScheduler::scheduler(LocalDOMWindow& window) { if (Document* document = window.document()) { - return Scheduler::From(*document); + return DOMScheduler::From(*document); } return nullptr; } diff --git a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.h b/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.h index bb82156906f..e8739bcfc70 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.h +++ b/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.h @@ -10,14 +10,14 @@ namespace blink { +class DOMScheduler; class LocalDOMWindow; -class Scheduler; class MODULES_EXPORT WindowScheduler { STATIC_ONLY(WindowScheduler); public: - static Scheduler* scheduler(LocalDOMWindow&); + static DOMScheduler* scheduler(LocalDOMWindow&); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.cc b/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.cc index 273d1edafc3..cdf517b9ff9 100644 --- a/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.cc +++ b/chromium/third_party/blink/renderer/modules/screen_enumeration/navigator_screen_manager.cc @@ -19,7 +19,7 @@ namespace { template <typename T> class NavigatorScreenManagerImpl final - : public GarbageCollectedFinalized<NavigatorScreenManagerImpl<T>>, + : public GarbageCollected<NavigatorScreenManagerImpl<T>>, public Supplement<T> { USING_GARBAGE_COLLECTED_MIXIN(NavigatorScreenManagerImpl<T>); diff --git a/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.cc b/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.cc index bb8085ff685..28e86de680d 100644 --- a/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.cc +++ b/chromium/third_party/blink/renderer/modules/screen_enumeration/screen_manager.cc @@ -6,6 +6,7 @@ #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/platform/bindings/exception_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/heap/heap.h" diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/DEPS b/chromium/third_party/blink/renderer/modules/screen_orientation/DEPS index 46ea48e4bcc..a8e4bf80211 100644 --- a/chromium/third_party/blink/renderer/modules/screen_orientation/DEPS +++ b/chromium/third_party/blink/renderer/modules/screen_orientation/DEPS @@ -1,6 +1,7 @@ include_rules = [ "+mojo/public/cpp/bindings/associated_interface_ptr.h", "+services/device/public/mojom/screen_orientation.mojom-blink.h", + "+services/device/public/mojom/screen_orientation.mojom-blink-forward.h", "-third_party/blink/renderer/modules", "+third_party/blink/renderer/modules/event_target_modules.h", "+third_party/blink/renderer/modules/modules_export.h", diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/lock_orientation_callback.cc b/chromium/third_party/blink/renderer/modules/screen_orientation/lock_orientation_callback.cc index e358e93cb64..314ed4e449d 100644 --- a/chromium/third_party/blink/renderer/modules/screen_orientation/lock_orientation_callback.cc +++ b/chromium/third_party/blink/renderer/modules/screen_orientation/lock_orientation_callback.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/screen_orientation/lock_orientation_callback.h" +#include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc index eecfa9c21bc..e2a7884ff63 100644 --- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc +++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller_impl.cc @@ -87,13 +87,14 @@ void ScreenOrientationControllerImpl::UpdateOrientation() { DCHECK(orientation_); DCHECK(GetPage()); ChromeClient& chrome_client = GetPage()->GetChromeClient(); - WebScreenInfo screen_info = chrome_client.GetScreenInfo(); + WebScreenInfo screen_info = chrome_client.GetScreenInfo(*GetFrame()); WebScreenOrientationType orientation_type = screen_info.orientation_type; if (orientation_type == kWebScreenOrientationUndefined) { // The embedder could not provide us with an orientation, deduce it // ourselves. - orientation_type = ComputeOrientation(chrome_client.GetScreenInfo().rect, - screen_info.orientation_angle); + orientation_type = + ComputeOrientation(chrome_client.GetScreenInfo(*GetFrame()).rect, + screen_info.orientation_angle); } DCHECK(orientation_type != kWebScreenOrientationUndefined); @@ -122,7 +123,7 @@ void ScreenOrientationControllerImpl::PageVisibilityChanged() { // The orientation type and angle are tied in a way that if the angle has // changed, the type must have changed. uint16_t current_angle = - GetPage()->GetChromeClient().GetScreenInfo().orientation_angle; + GetPage()->GetChromeClient().GetScreenInfo(*GetFrame()).orientation_angle; // FIXME: sendOrientationChangeEvent() currently send an event all the // children of the frame, so it should only be called on the frame on diff --git a/chromium/third_party/blink/renderer/modules/sensor/DEPS b/chromium/third_party/blink/renderer/modules/sensor/DEPS index a91f7e91ce6..ceb8fb25803 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/DEPS +++ b/chromium/third_party/blink/renderer/modules/sensor/DEPS @@ -2,6 +2,7 @@ include_rules = [ "+mojo/public/cpp/bindings", "+services/device/public/cpp/generic_sensor", "+services/device/public/mojom/sensor.mojom-blink.h", + "+services/device/public/mojom/sensor.mojom-blink-forward.h", "+services/device/public/mojom/sensor_provider.mojom-blink.h", "-third_party/blink/renderer/modules", "+third_party/blink/renderer/modules/event_modules.h", @@ -9,3 +10,10 @@ include_rules = [ "+third_party/blink/renderer/modules/modules_export.h", "+third_party/blink/renderer/modules/sensor", ] + +specific_include_rules = { + "sensor_test_utils\.(cc|h)|.+test\.cc": [ + "+base/run_loop.h", + "+services/device/public/cpp/test/fake_sensor_and_provider.h", + ], +} diff --git a/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.cc index 17b391a5817..d13b52dff27 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h" + using device::mojom::blink::SensorType; namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc index e9f332e53cc..0b1aad22976 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/sensor/accelerometer.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h" + using device::mojom::blink::SensorType; namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.cc index 58e3961a5a7..a35c7f3b4a5 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/sensor/ambient_light_sensor.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -11,6 +12,26 @@ using device::mojom::blink::SensorType; namespace blink { +namespace { + +// Even though the underlying value has changed, for ALS we provide readouts to +// JS to the nearest 50 Lux. +constexpr int kAlsRoundingThreshold = 50; + +// Decrease precision of ALS readouts. +// Round off to the nearest kAlsRoundingThreshold. +double RoundIlluminance(double value) { + return kAlsRoundingThreshold * std::round(value / kAlsRoundingThreshold); +} + +// Value will have to vary by at least half the rounding threshold before it has +// an effect on the output. +bool IsSignificantlyDifferent(double als_old, double als_new) { + return std::fabs(als_old - als_new) >= kAlsRoundingThreshold / 2; +} + +} // namespace + // static AmbientLightSensor* AmbientLightSensor::Create( ExecutionContext* execution_context, @@ -38,11 +59,22 @@ AmbientLightSensor::AmbientLightSensor(ExecutionContext* execution_context, double AmbientLightSensor::illuminance(bool& is_null) const { INIT_IS_NULL_AND_RETURN(is_null, 0.0); - return GetReading().als.value; + DCHECK(latest_reading_.has_value()); + return RoundIlluminance(*latest_reading_); } -void AmbientLightSensor::Trace(blink::Visitor* visitor) { - Sensor::Trace(visitor); +// When the reading we get does not differ significantly from our current +// value, we discard this reading and do not emit any events. This is a privacy +// measure to avoid giving readings that are too specific. +void AmbientLightSensor::OnSensorReadingChanged() { + const double new_reading = GetReading().als.value; + if (latest_reading_.has_value() && + !IsSignificantlyDifferent(*latest_reading_, new_reading)) { + return; + } + + latest_reading_ = new_reading; + Sensor::OnSensorReadingChanged(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.h b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.h index 34b3f1e0ec0..5d69f2fb5c3 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.h +++ b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor.h @@ -5,11 +5,14 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_AMBIENT_LIGHT_SENSOR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_AMBIENT_LIGHT_SENSOR_H_ +#include "base/gtest_prod_util.h" +#include "base/optional.h" +#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/sensor/sensor.h" namespace blink { -class AmbientLightSensor final : public Sensor { +class MODULES_EXPORT AmbientLightSensor final : public Sensor { DEFINE_WRAPPERTYPEINFO(); public: @@ -22,7 +25,12 @@ class AmbientLightSensor final : public Sensor { double illuminance(bool& is_null) const; - void Trace(blink::Visitor*) override; + void OnSensorReadingChanged() override; + + private: + base::Optional<double> latest_reading_; + + FRIEND_TEST_ALL_PREFIXES(AmbientLightSensorTest, IlluminanceRounding); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc new file mode 100644 index 00000000000..dff6922d122 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/sensor/ambient_light_sensor_test.cc @@ -0,0 +1,152 @@ +// 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. + +#include "third_party/blink/renderer/modules/sensor/ambient_light_sensor.h" + +#include "base/optional.h" +#include "base/run_loop.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/event_type_names.h" +#include "third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h" +#include "third_party/blink/renderer/modules/sensor/sensor_test_utils.h" + +namespace blink { + +namespace { + +class MockSensorProxyObserver + : public GarbageCollected<MockSensorProxyObserver>, + public SensorProxy::Observer { + USING_GARBAGE_COLLECTED_MIXIN(MockSensorProxyObserver); + + public: + virtual ~MockSensorProxyObserver() = default; + + // Synchronously waits for OnSensorReadingChanged() to be called. + void WaitForOnSensorReadingChanged() { + run_loop_.emplace(); + run_loop_->Run(); + } + + void OnSensorReadingChanged() override { + DCHECK(run_loop_.has_value() && run_loop_->running()); + run_loop_->Quit(); + } + + private: + base::Optional<base::RunLoop> run_loop_; +}; + +} // namespace + +TEST(AmbientLightSensorTest, IlluminanceInStoppedSensor) { + SensorTestContext context; + NonThrowableExceptionState exception_state; + + auto* sensor = AmbientLightSensor::Create(context.GetExecutionContext(), + exception_state); + + bool illuminance_is_null; + sensor->illuminance(illuminance_is_null); + EXPECT_TRUE(illuminance_is_null); + EXPECT_FALSE(sensor->hasReading()); +} + +TEST(AmbientLightSensorTest, IlluminanceInSensorWithoutReading) { + SensorTestContext context; + NonThrowableExceptionState exception_state; + + auto* sensor = AmbientLightSensor::Create(context.GetExecutionContext(), + exception_state); + sensor->start(); + SensorTestUtils::WaitForEvent(sensor, event_type_names::kActivate); + + bool illuminance_is_null; + sensor->illuminance(illuminance_is_null); + EXPECT_TRUE(illuminance_is_null); + EXPECT_FALSE(sensor->hasReading()); +} + +TEST(AmbientLightSensorTest, IlluminanceRounding) { + SensorTestContext context; + NonThrowableExceptionState exception_state; + + auto* sensor = AmbientLightSensor::Create(context.GetExecutionContext(), + exception_state); + sensor->start(); + SensorTestUtils::WaitForEvent(sensor, event_type_names::kActivate); + EXPECT_FALSE(sensor->hasReading()); + + // At this point, we have received an 'activate' event, so the sensor is + // initialized and it is connected to a SensorProxy that we can retrieve + // here. We then attach a new SensorProxy::Observer that we use to + // synchronously wait for OnSensorReadingChanged() to be called. Even though + // the order that each observer is notified is arbitrary, we know that by the + // time we get to the next call here all observers will have been called. + auto* sensor_proxy = + SensorProviderProxy::From(To<Document>(context.GetExecutionContext())) + ->GetSensorProxy(device::mojom::blink::SensorType::AMBIENT_LIGHT); + ASSERT_NE(sensor_proxy, nullptr); + auto* mock_observer = MakeGarbageCollected<MockSensorProxyObserver>(); + sensor_proxy->AddObserver(mock_observer); + + bool illuminance_is_null; + + auto* event_counter = MakeGarbageCollected<SensorTestUtils::EventCounter>(); + sensor->addEventListener(event_type_names::kReading, event_counter); + + // Go from no reading to 24. This will cause a new "reading" event to be + // emitted, and the rounding will cause illuminance() to return 0. + context.sensor_provider()->UpdateAmbientLightSensorData(24); + mock_observer->WaitForOnSensorReadingChanged(); + SensorTestUtils::WaitForEvent(sensor, event_type_names::kReading); + EXPECT_EQ(24, sensor->latest_reading_); + EXPECT_EQ(0, sensor->illuminance(illuminance_is_null)); + EXPECT_FALSE(illuminance_is_null); + + // Go from 24 to 35. The difference is not significant enough, so we will not + // emit any "reading" event or store the new raw reading, as if the new + // reading had never existed. + context.sensor_provider()->UpdateAmbientLightSensorData(35); + mock_observer->WaitForOnSensorReadingChanged(); + EXPECT_EQ(24, sensor->latest_reading_); + EXPECT_EQ(0, sensor->illuminance(illuminance_is_null)); + EXPECT_FALSE(illuminance_is_null); + + // Go from 24 to 49. The difference is significant enough, so we will emit a + // new "reading" event, update our raw reading and return a rounded value of + // 50 in illuminance(). + context.sensor_provider()->UpdateAmbientLightSensorData(49); + mock_observer->WaitForOnSensorReadingChanged(); + SensorTestUtils::WaitForEvent(sensor, event_type_names::kReading); + EXPECT_EQ(49, sensor->latest_reading_); + EXPECT_EQ(50, sensor->illuminance(illuminance_is_null)); + EXPECT_FALSE(illuminance_is_null); + + // Go from 49 to 35. The difference is not significant enough, so we will not + // emit any "reading" event or store the new raw reading, as if the new + // reading had never existed. + context.sensor_provider()->UpdateAmbientLightSensorData(35); + mock_observer->WaitForOnSensorReadingChanged(); + EXPECT_EQ(49, sensor->latest_reading_); + EXPECT_EQ(50, sensor->illuminance(illuminance_is_null)); + EXPECT_FALSE(illuminance_is_null); + + // Go from 49 to 24. The difference is significant enough, so we will emit a + // new "reading" event, update our raw reading and return a rounded value of + // 0 in illuminance(). + context.sensor_provider()->UpdateAmbientLightSensorData(24); + mock_observer->WaitForOnSensorReadingChanged(); + SensorTestUtils::WaitForEvent(sensor, event_type_names::kReading); + EXPECT_EQ(24, sensor->latest_reading_); + EXPECT_EQ(0, sensor->illuminance(illuminance_is_null)); + EXPECT_FALSE(illuminance_is_null); + + // Make sure there were no stray "reading" events besides those we expected + // above. + EXPECT_EQ(3U, event_counter->event_count()); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc index b03a5f8ab72..793edcd148e 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/sensor/gyroscope.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h" + using device::mojom::blink::SensorType; namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.cc index 26283bb9426..2ce628894ca 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h" + using device::mojom::blink::SensorType; namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc index c1d8838231a..0eb58a59c0a 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/sensor/magnetometer.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h" + using device::mojom::blink::SensorType; namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc index ef206c04ee3..87d9a9190b4 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h" + using device::mojom::blink::SensorType; namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor.cc index 57e0e572cc7..a233936449d 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor.cc @@ -352,12 +352,13 @@ void Sensor::NotifyActivated() { state_ = SensorState::kActivated; if (hasReading()) { - // If reading has already arrived, send initial 'reading' notification - // right away. + // If reading has already arrived, process the reading values (a subclass + // may do some filtering, for example) and then send an initial "reading" + // event right away. DCHECK(!pending_reading_notification_.IsActive()); pending_reading_notification_ = PostCancellableTask( *GetExecutionContext()->GetTaskRunner(TaskType::kSensor), FROM_HERE, - WTF::Bind(&Sensor::NotifyReading, WrapWeakPersistent(this))); + WTF::Bind(&Sensor::OnSensorReadingChanged, WrapWeakPersistent(this))); } DispatchEvent(*Event::Create(event_type_names::kActivate)); diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor.h b/chromium/third_party/blink/renderer/modules/sensor/sensor.h index bc43314d8ec..14fc0de5560 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor.h +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor.h @@ -12,6 +12,7 @@ #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/frame/platform_event_controller.h" #include "third_party/blink/renderer/modules/event_target_modules.h" +#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/sensor/sensor_options.h" #include "third_party/blink/renderer/modules/sensor/sensor_proxy.h" #include "third_party/blink/renderer/modules/sensor/spatial_sensor_options.h" @@ -26,10 +27,10 @@ class DOMException; class ExceptionState; class ExecutionContext; -class Sensor : public EventTargetWithInlineData, - public ActiveScriptWrappable<Sensor>, - public ContextLifecycleObserver, - public SensorProxy::Observer { +class MODULES_EXPORT Sensor : public EventTargetWithInlineData, + public ActiveScriptWrappable<Sensor>, + public ContextLifecycleObserver, + public SensorProxy::Observer { USING_GARBAGE_COLLECTED_MIXIN(Sensor); DEFINE_WRAPPERTYPEINFO(); diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc index 665a1b796ed..aba986057d5 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h" #include "third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.h" #include "third_party/blink/renderer/platform/mojo/mojo_helper.h" @@ -19,9 +19,9 @@ void SensorProviderProxy::InitializeIfNeeded() { if (IsInitialized()) return; - GetSupplementable()->GetInterfaceProvider()->GetInterface( - mojo::MakeRequest(&sensor_provider_)); - sensor_provider_.set_connection_error_handler( + GetSupplementable()->GetBrowserInterfaceBroker().GetInterface( + sensor_provider_.BindNewPipeAndPassReceiver()); + sensor_provider_.set_disconnect_handler( WTF::Bind(&SensorProviderProxy::OnSensorProviderConnectionError, WrapWeakPersistent(this))); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h index 4825cb21356..458e133730d 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_provider_proxy.h @@ -6,9 +6,11 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_SENSOR_PROVIDER_PROXY_H_ #include "base/macros.h" -#include "services/device/public/mojom/sensor.mojom-blink.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "services/device/public/mojom/sensor.mojom-blink-forward.h" #include "services/device/public/mojom/sensor_provider.mojom-blink.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/supplementable.h" @@ -18,8 +20,8 @@ class SensorProxy; // This class wraps 'SensorProvider' mojo interface and it manages // 'SensorProxy' instances. -class SensorProviderProxy final - : public GarbageCollectedFinalized<SensorProviderProxy>, +class MODULES_EXPORT SensorProviderProxy final + : public GarbageCollected<SensorProviderProxy>, public Supplement<Document> { USING_GARBAGE_COLLECTED_MIXIN(SensorProviderProxy); @@ -56,7 +58,7 @@ class SensorProviderProxy final void OnSensorProviderConnectionError(); SensorsSet sensor_proxies_; - device::mojom::blink::SensorProviderPtr sensor_provider_; + mojo::Remote<device::mojom::blink::SensorProvider> sensor_provider_; bool inspector_mode_; DISALLOW_COPY_AND_ASSIGN(SensorProviderProxy); diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc index e32c2c7df62..bdf81b05d7f 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc @@ -17,12 +17,10 @@ namespace blink { -using namespace device::mojom::blink; - const char SensorProxy::kDefaultErrorDescription[] = "Could not connect to a sensor"; -SensorProxy::SensorProxy(SensorType sensor_type, +SensorProxy::SensorProxy(device::mojom::blink::SensorType sensor_type, SensorProviderProxy* provider, Page* page) : PageVisibilityObserver(page), @@ -65,14 +63,14 @@ void SensorProxy::ReportError(DOMExceptionCode code, const String& message) { namespace { -uint16_t GetScreenOrientationAngleForPage(Page* page) { +uint16_t GetScreenOrientationAngle(LocalFrame& frame) { if (WebTestSupport::IsRunningWebTest()) { // Simulate that the device is turned 90 degrees on the right. // 'orientation_angle' must be 270 as per // https://w3c.github.io/screen-orientation/#dfn-update-the-orientation-information. return 270; } - return page->GetChromeClient().GetScreenInfo().orientation_angle; + return frame.GetChromeClient().GetScreenInfo(frame).orientation_angle; } } // namespace @@ -83,7 +81,9 @@ const device::SensorReading& SensorProxy::GetReading(bool remapped) const { if (remapped_reading_.timestamp() != reading_.timestamp()) { remapped_reading_ = reading_; SensorReadingRemapper::RemapToScreenCoords( - type_, GetScreenOrientationAngleForPage(GetPage()), + type_, + GetScreenOrientationAngle( + *provider_->GetSupplementable()->GetFrame()), &remapped_reading_); } return remapped_reading_; @@ -130,7 +130,7 @@ bool SensorProxy::ShouldSuspendUpdates() const { return !focused_frame_origin->CanAccess(this_origin); } -SensorProvider* SensorProxy::sensor_provider() const { +device::mojom::blink::SensorProvider* SensorProxy::sensor_provider() const { return provider_->sensor_provider(); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.h index 7357953a898..f25fc82384b 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.h +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.h @@ -8,10 +8,11 @@ #include "base/macros.h" #include "services/device/public/cpp/generic_sensor/sensor_reading.h" #include "services/device/public/cpp/generic_sensor/sensor_reading_shared_buffer_reader.h" -#include "services/device/public/mojom/sensor.mojom-blink.h" +#include "services/device/public/mojom/sensor.mojom-blink-forward.h" #include "services/device/public/mojom/sensor_provider.mojom-blink.h" #include "third_party/blink/renderer/core/page/focus_changed_observer.h" #include "third_party/blink/renderer/core/page/page_visibility_observer.h" +#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/exception_code.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -21,9 +22,9 @@ class SensorProviderProxy; // This class wraps 'Sensor' mojo interface and used by multiple // JS sensor instances of the same type (within a single frame). -class SensorProxy : public GarbageCollectedFinalized<SensorProxy>, - public PageVisibilityObserver, - public FocusChangedObserver { +class MODULES_EXPORT SensorProxy : public GarbageCollected<SensorProxy>, + public PageVisibilityObserver, + public FocusChangedObserver { USING_GARBAGE_COLLECTED_MIXIN(SensorProxy); public: diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc index 06d6d591890..9f574c42d57 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.cc @@ -11,11 +11,11 @@ #include "third_party/blink/renderer/modules/sensor/sensor_reading_remapper.h" #include "third_party/blink/renderer/platform/mojo/mojo_helper.h" -namespace blink { +using device::mojom::blink::SensorCreationResult; -using namespace device::mojom::blink; +namespace blink { -SensorProxyImpl::SensorProxyImpl(SensorType sensor_type, +SensorProxyImpl::SensorProxyImpl(device::mojom::blink::SensorType sensor_type, SensorProviderProxy* provider, Page* page) : SensorProxy(sensor_type, provider, page), @@ -50,7 +50,7 @@ void SensorProxyImpl::Initialize() { } void SensorProxyImpl::AddConfiguration( - SensorConfigurationPtr configuration, + device::mojom::blink::SensorConfigurationPtr configuration, base::OnceCallback<void(bool)> callback) { DCHECK(IsInitialized()); AddActiveFrequency(configuration->frequency); @@ -59,7 +59,7 @@ void SensorProxyImpl::AddConfiguration( } void SensorProxyImpl::RemoveConfiguration( - SensorConfigurationPtr configuration) { + device::mojom::blink::SensorConfigurationPtr configuration) { DCHECK(IsInitialized()); RemoveActiveFrequency(configuration->frequency); sensor_remote_->RemoveConfiguration(std::move(configuration)); @@ -122,7 +122,7 @@ void SensorProxyImpl::RaiseError() { } void SensorProxyImpl::SensorReadingChanged() { - DCHECK_EQ(ReportingMode::ON_CHANGE, mode_); + DCHECK_EQ(device::mojom::blink::ReportingMode::ON_CHANGE, mode_); if (ShouldProcessReadings()) UpdateSensorReading(); } @@ -154,8 +154,9 @@ void SensorProxyImpl::HandleSensorError(SensorCreationResult error) { } } -void SensorProxyImpl::OnSensorCreated(SensorCreationResult result, - SensorInitParamsPtr params) { +void SensorProxyImpl::OnSensorCreated( + SensorCreationResult result, + device::mojom::blink::SensorInitParamsPtr params) { DCHECK_EQ(kInitializing, state_); if (!params) { DCHECK_NE(SensorCreationResult::SUCCESS, result); @@ -175,7 +176,7 @@ void SensorProxyImpl::OnSensorCreated(SensorCreationResult result, DCHECK_GT(default_frequency_, 0.0); sensor_remote_.Bind(std::move(params->sensor)); - client_receiver_.Bind(std::move(params->client_request)); + client_receiver_.Bind(std::move(params->client_receiver)); shared_buffer_reader_ = device::SensorReadingSharedBufferReader::Create( std::move(params->memory), params->buffer_offset); @@ -216,7 +217,7 @@ bool SensorProxyImpl::ShouldProcessReadings() const { } void SensorProxyImpl::UpdatePollingStatus() { - if (mode_ != ReportingMode::CONTINUOUS) + if (mode_ != device::mojom::blink::ReportingMode::CONTINUOUS) return; if (ShouldProcessReadings()) { diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc index 8a2de5b2290..2eb8cfdf1ab 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.cc @@ -14,10 +14,8 @@ namespace blink { -using namespace device::mojom::blink; - SensorProxyInspectorImpl::SensorProxyInspectorImpl( - SensorType sensor_type, + device::mojom::blink::SensorType sensor_type, SensorProviderProxy* provider, Page* page) : SensorProxy(sensor_type, provider, page) {} @@ -41,14 +39,14 @@ void SensorProxyInspectorImpl::Initialize() { } void SensorProxyInspectorImpl::AddConfiguration( - SensorConfigurationPtr configuration, + device::mojom::blink::SensorConfigurationPtr configuration, base::OnceCallback<void(bool)> callback) { DCHECK(IsInitialized()); std::move(callback).Run(true); } void SensorProxyInspectorImpl::RemoveConfiguration( - SensorConfigurationPtr configuration) { + device::mojom::blink::SensorConfigurationPtr configuration) { DCHECK(IsInitialized()); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_reading_remapper.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_reading_remapper.h index b912c58288a..8bcc8ddf92b 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_reading_remapper.h +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_reading_remapper.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_SENSOR_READING_REMAPPER_H_ #include "services/device/public/cpp/generic_sensor/sensor_reading.h" -#include "services/device/public/mojom/sensor.mojom-blink.h" +#include "services/device/public/mojom/sensor.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.cc new file mode 100644 index 00000000000..76b03b67e6f --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.cc @@ -0,0 +1,83 @@ +// 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. + +#include <utility> + +#include "base/callback.h" +#include "base/run_loop.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/events/event_target.h" +#include "third_party/blink/renderer/core/dom/events/native_event_listener.h" +#include "third_party/blink/renderer/core/page/focus_controller.h" +#include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/modules/sensor/sensor_test_utils.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +namespace { + +// An event listener that invokes |invocation_callback| when it is called. +class SyncEventListener final : public NativeEventListener { + public: + SyncEventListener(base::OnceClosure invocation_callback) + : invocation_callback_(std::move(invocation_callback)) {} + + void Invoke(ExecutionContext*, Event*) override { + DCHECK(invocation_callback_); + std::move(invocation_callback_).Run(); + } + + private: + base::OnceClosure invocation_callback_; +}; + +} // namespace + +// SensorTestContext + +SensorTestContext::SensorTestContext() { + // Sensor's constructor has a check for this that could be removed in the + // future. + testing_scope_.GetDocument().SetSecureContextStateForTesting( + SecureContextState::kSecure); + // Necessary for SensorProxy::ShouldSuspendUpdates() to work correctly. + testing_scope_.GetPage().GetFocusController().SetFocused(true); + + testing_scope_.GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting( + device::mojom::blink::SensorProvider::Name_, + WTF::BindRepeating(&SensorTestContext::BindSensorProviderRequest, + WTF::Unretained(this))); +} + +SensorTestContext::~SensorTestContext() { + testing_scope_.GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting( + device::mojom::blink::SensorProvider::Name_, {}); +} + +ExecutionContext* SensorTestContext::GetExecutionContext() const { + return testing_scope_.GetExecutionContext(); +} + +void SensorTestContext::BindSensorProviderRequest( + mojo::ScopedMessagePipeHandle handle) { + sensor_provider_.Bind( + device::mojom::SensorProviderRequest(std::move(handle))); +} + +// SensorTestUtils + +// static +void SensorTestUtils::WaitForEvent(EventTarget* event_target, + const WTF::AtomicString& event_type) { + base::RunLoop run_loop; + auto* event_listener = + MakeGarbageCollected<SyncEventListener>(run_loop.QuitClosure()); + event_target->addEventListener(event_type, event_listener); + run_loop.Run(); + event_target->removeEventListener(event_type, event_listener); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.h new file mode 100644 index 00000000000..1f43d08a1b6 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.h @@ -0,0 +1,67 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_SENSOR_TEST_UTILS_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_SENSOR_TEST_UTILS_H_ + +#include "services/device/public/cpp/test/fake_sensor_and_provider.h" +#include "services/device/public/mojom/sensor_provider.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" +#include "third_party/blink/renderer/core/dom/events/native_event_listener.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/blink/renderer/platform/wtf/forward.h" + +namespace blink { + +class EventTarget; +class ExecutionContext; + +class SensorTestContext final { + STACK_ALLOCATED(); + + public: + SensorTestContext(); + + ~SensorTestContext(); + + ExecutionContext* GetExecutionContext() const; + + device::FakeSensorProvider* sensor_provider() { return &sensor_provider_; } + + private: + void BindSensorProviderRequest(mojo::ScopedMessagePipeHandle handle); + + device::FakeSensorProvider sensor_provider_; + V8TestingScope testing_scope_; +}; + +class SensorTestUtils final { + public: + // An event listener that can be used to count the number of times a + // particular event has been fired. + // + // Usage: + // auto* event_counter = + // MakeGarbageCollected<SensorTestUtils::EventCounter>(); + // my_event_target->addEventListener(..., event_counter); + // [...] + // EXPECT_EQ(42U, event_counter->event_count()); + class EventCounter : public NativeEventListener { + public: + void Invoke(ExecutionContext*, Event*) override { event_count_++; } + + size_t event_count() const { return event_count_; } + + private: + size_t event_count_ = 0; + }; + + // Synchronously waits for |event_type| to be delivered to |event_target|. + static void WaitForEvent(EventTarget* event_target, + const WTF::AtomicString& event_type); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SENSOR_SENSOR_TEST_UTILS_H_ diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.cc b/chromium/third_party/blink/renderer/modules/serial/serial.cc index 6c31da03a82..b9654d2cdae 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial.cc +++ b/chromium/third_party/blink/renderer/modules/serial/serial.cc @@ -8,7 +8,8 @@ #include <utility> #include "base/unguessable_token.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -23,6 +24,7 @@ namespace blink { namespace { +const char kContextGone[] = "Script context has shut down."; const char kFeaturePolicyBlocked[] = "Access to the feature \"serial\" is disallowed by feature policy."; const char kNoPortSelected[] = "No port selected by the user."; @@ -52,21 +54,20 @@ void Serial::ContextDestroyed(ExecutionContext*) { entry.value->ContextDestroyed(); } -ScriptPromise Serial::getPorts(ScriptState* script_state) { +ScriptPromise Serial::getPorts(ScriptState* script_state, + ExceptionState& exception_state) { auto* context = GetExecutionContext(); if (!context) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotSupportedError)); + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + kContextGone); + return ScriptPromise(); } if (!context->GetSecurityContext().IsFeatureEnabled( mojom::FeaturePolicyFeature::kSerial, ReportOptions::kReportOnFailure)) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kSecurityError, - kFeaturePolicyBlocked)); + exception_state.ThrowSecurityError(kFeaturePolicyBlocked); + return ScriptPromise(); } auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); @@ -80,29 +81,26 @@ ScriptPromise Serial::getPorts(ScriptState* script_state) { } ScriptPromise Serial::requestPort(ScriptState* script_state, - const SerialPortRequestOptions* options) { + const SerialPortRequestOptions* options, + ExceptionState& exception_state) { auto* frame = GetFrame(); if (!frame || !frame->GetDocument()) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotSupportedError)); + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + kContextGone); + return ScriptPromise(); } if (!frame->GetDocument()->IsFeatureEnabled( mojom::FeaturePolicyFeature::kSerial, ReportOptions::kReportOnFailure)) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kSecurityError, - kFeaturePolicyBlocked)); + exception_state.ThrowSecurityError(kFeaturePolicyBlocked); + return ScriptPromise(); } if (!LocalFrame::HasTransientUserActivation(frame)) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>( - DOMExceptionCode::kSecurityError, - "Must be handling a user gesture to show a permission request.")); + exception_state.ThrowSecurityError( + "Must be handling a user gesture to show a permission request."); + return ScriptPromise(); } auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); @@ -139,7 +137,7 @@ void Serial::EnsureServiceConnection() { auto task_runner = GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI); - GetExecutionContext()->GetInterfaceProvider()->GetInterface( + GetExecutionContext()->GetBrowserInterfaceBroker().GetInterface( service_.BindNewPipeAndPassReceiver(task_runner)); service_.set_disconnect_handler( WTF::Bind(&Serial::OnServiceConnectionError, WrapWeakPersistent(this))); diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.h b/chromium/third_party/blink/renderer/modules/serial/serial.h index 33290cc0b48..cba9edd27e9 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial.h +++ b/chromium/third_party/blink/renderer/modules/serial/serial.h @@ -41,8 +41,10 @@ class Serial final : public EventTargetWithInlineData, // Web-exposed interfaces DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect) DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect) - ScriptPromise getPorts(ScriptState*); - ScriptPromise requestPort(ScriptState*, const SerialPortRequestOptions*); + ScriptPromise getPorts(ScriptState*, ExceptionState&); + ScriptPromise requestPort(ScriptState*, + const SerialPortRequestOptions*, + ExceptionState&); void GetPort( const base::UnguessableToken& token, diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.idl b/chromium/third_party/blink/renderer/modules/serial/serial.idl index ff9f6568f63..48d7960a578 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial.idl +++ b/chromium/third_party/blink/renderer/modules/serial/serial.idl @@ -11,9 +11,9 @@ attribute EventHandler onconnect; attribute EventHandler ondisconnect; - [CallWith=ScriptState, MeasureAs=SerialGetPorts] + [CallWith=ScriptState, RaisesException, MeasureAs=SerialGetPorts] Promise<sequence<SerialPort>> getPorts(); - [CallWith=ScriptState, MeasureAs=SerialRequestPort, Exposed=Window] + [CallWith=ScriptState, RaisesException, MeasureAs=SerialRequestPort, Exposed=Window] Promise<SerialPort> requestPort(optional SerialPortRequestOptions options); }; diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port.cc b/chromium/third_party/blink/renderer/modules/serial/serial_port.cc index a0c6a1543c7..b03503cd8d4 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial_port.cc +++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/serial/serial_port.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/streams/readable_stream.h" @@ -73,6 +75,57 @@ DOMException* DOMExceptionFromReceiveError(SerialReceiveError error) { } } +// A ScriptFunction that calls ContinueClose() on the provided SerialPort. +class ContinueCloseFunction : public ScriptFunction { + public: + static v8::Local<v8::Function> Create(ScriptState* script_state, + SerialPort* port) { + auto* self = + MakeGarbageCollected<ContinueCloseFunction>(script_state, port); + return self->BindToV8Function(); + } + + ContinueCloseFunction(ScriptState* script_state, SerialPort* port) + : ScriptFunction(script_state), port_(port) {} + + ScriptValue Call(ScriptValue) override { + return port_->ContinueClose(GetScriptState()).GetScriptValue(); + } + + void Trace(Visitor* visitor) override { + visitor->Trace(port_); + ScriptFunction::Trace(visitor); + } + + private: + Member<SerialPort> port_; +}; + +// A ScriptFunction that calls AbortClose() on the provided SerialPort. +class AbortCloseFunction : public ScriptFunction { + public: + static v8::Local<v8::Function> Create(ScriptState* script_state, + SerialPort* port) { + auto* self = MakeGarbageCollected<AbortCloseFunction>(script_state, port); + return self->BindToV8Function(); + } + + AbortCloseFunction(ScriptState* script_state, SerialPort* port) + : ScriptFunction(script_state), port_(port) {} + + ScriptValue Call(ScriptValue) override { + port_->AbortClose(); + return ScriptValue(); + } + + void Trace(Visitor* visitor) override { + visitor->Trace(port_); + ScriptFunction::Trace(visitor); + } + + private: + Member<SerialPort> port_; +}; } // namespace SerialPort::SerialPort(Serial* parent, mojom::blink::SerialPortInfoPtr info) @@ -81,28 +134,27 @@ SerialPort::SerialPort(Serial* parent, mojom::blink::SerialPortInfoPtr info) SerialPort::~SerialPort() = default; ScriptPromise SerialPort::open(ScriptState* script_state, - const SerialOptions* options) { + const SerialOptions* options, + ExceptionState& exception_state) { if (open_resolver_) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, - "A call to open() is already in progress.")); + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "A call to open() is already in progress."); + return ScriptPromise(); } if (port_) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError, - "The port is already open.")); + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "The port is already open."); + return ScriptPromise(); } auto mojo_options = device::mojom::blink::SerialConnectionOptions::New(); if (options->baudrate() == 0) { - return ScriptPromise::Reject( - script_state, V8ThrowException::CreateTypeError( - script_state->GetIsolate(), - "Requested baud rate must be greater than zero.")); + exception_state.ThrowTypeError( + "Requested baud rate must be greater than zero."); + return ScriptPromise(); } mojo_options->bitrate = options->baudrate(); @@ -114,10 +166,9 @@ ScriptPromise SerialPort::open(ScriptState* script_state, mojo_options->data_bits = device::mojom::blink::SerialDataBits::EIGHT; break; default: - return ScriptPromise::Reject( - script_state, V8ThrowException::CreateTypeError( - script_state->GetIsolate(), - "Requested number of data bits must be 7 or 8.")); + exception_state.ThrowTypeError( + "Requested number of data bits must be 7 or 8."); + return ScriptPromise(); } if (options->parity() == "none") { @@ -138,30 +189,24 @@ ScriptPromise SerialPort::open(ScriptState* script_state, mojo_options->stop_bits = device::mojom::blink::SerialStopBits::TWO; break; default: - return ScriptPromise::Reject( - script_state, V8ThrowException::CreateTypeError( - script_state->GetIsolate(), - "Requested number of stop bits must be 1 or 2.")); + exception_state.ThrowTypeError( + "Requested number of stop bits must be 1 or 2."); + return ScriptPromise(); } if (options->buffersize() == 0) { - return ScriptPromise::Reject( - script_state, - V8ThrowException::CreateTypeError( - script_state->GetIsolate(), - String::Format( - "Requested buffer size (%d bytes) must be greater than zero.", - options->buffersize()))); + exception_state.ThrowTypeError(String::Format( + "Requested buffer size (%d bytes) must be greater than zero.", + options->buffersize())); + return ScriptPromise(); } if (options->buffersize() > kMaxBufferSize) { - return ScriptPromise::Reject( - script_state, - V8ThrowException::CreateTypeError( - script_state->GetIsolate(), - String::Format("Requested buffer size (%d bytes) is greater than " - "the maximum allowed (%d bytes).", - options->buffersize(), kMaxBufferSize))); + exception_state.ThrowTypeError( + String::Format("Requested buffer size (%d bytes) is greater than " + "the maximum allowed (%d bytes).", + options->buffersize(), kMaxBufferSize)); + return ScriptPromise(); } buffer_size_ = options->buffersize(); @@ -172,25 +217,21 @@ ScriptPromise SerialPort::open(ScriptState* script_state, mojo::ScopedDataPipeConsumerHandle readable_pipe; mojo::ScopedDataPipeProducerHandle readable_pipe_producer; if (!CreateDataPipe(&readable_pipe_producer, &readable_pipe)) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kQuotaExceededError, - kResourcesExhaustedReadBuffer)); + exception_state.ThrowDOMException(DOMExceptionCode::kQuotaExceededError, + kResourcesExhaustedReadBuffer); + return ScriptPromise(); } // Pipe handle pair for the WritableStream. mojo::ScopedDataPipeProducerHandle writable_pipe; mojo::ScopedDataPipeConsumerHandle writable_pipe_consumer; if (!CreateDataPipe(&writable_pipe, &writable_pipe_consumer)) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kQuotaExceededError, - kResourcesExhaustedWriteBuffer)); + exception_state.ThrowDOMException(DOMExceptionCode::kQuotaExceededError, + kResourcesExhaustedWriteBuffer); + return ScriptPromise(); } - device::mojom::blink::SerialPortClientPtr client_ptr; - auto client_request = mojo::MakeRequest(&client_ptr); - + mojo::PendingRemote<device::mojom::blink::SerialPortClient> client; parent_->GetPort(info_->token, port_.BindNewPipeAndPassReceiver()); port_.set_disconnect_handler( WTF::Bind(&SerialPort::OnConnectionError, WrapWeakPersistent(this))); @@ -198,10 +239,10 @@ ScriptPromise SerialPort::open(ScriptState* script_state, open_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state); auto callback = WTF::Bind(&SerialPort::OnOpen, WrapPersistent(this), std::move(readable_pipe), std::move(writable_pipe), - std::move(client_request)); + client.InitWithNewPipeAndPassReceiver()); port_->Open(std::move(mojo_options), std::move(writable_pipe_consumer), - std::move(readable_pipe_producer), std::move(client_ptr), + std::move(readable_pipe_producer), std::move(client), std::move(callback)); return open_resolver_->Promise(); } @@ -211,7 +252,7 @@ ReadableStream* SerialPort::readable(ScriptState* script_state, if (readable_) return readable_; - if (!port_ || open_resolver_) + if (!port_ || open_resolver_ || closing_) return nullptr; mojo::ScopedDataPipeConsumerHandle readable_pipe; @@ -232,7 +273,7 @@ WritableStream* SerialPort::writable(ScriptState* script_state, if (writable_) return writable_; - if (!port_ || open_resolver_) + if (!port_ || open_resolver_ || closing_) return nullptr; mojo::ScopedDataPipeProducerHandle writable_pipe; @@ -248,11 +289,12 @@ WritableStream* SerialPort::writable(ScriptState* script_state, return writable_; } -ScriptPromise SerialPort::getSignals(ScriptState* script_state) { +ScriptPromise SerialPort::getSignals(ScriptState* script_state, + ExceptionState& exception_state) { if (!port_) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, kPortClosed)); + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kPortClosed); + return ScriptPromise(); } auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); @@ -264,11 +306,12 @@ ScriptPromise SerialPort::getSignals(ScriptState* script_state) { } ScriptPromise SerialPort::setSignals(ScriptState* script_state, - const SerialOutputSignals* signals) { + const SerialOutputSignals* signals, + ExceptionState& exception_state) { if (!port_) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, kPortClosed)); + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kPortClosed); + return ScriptPromise(); } auto mojo_signals = device::mojom::blink::SerialHostControlSignals::New(); @@ -294,24 +337,65 @@ ScriptPromise SerialPort::setSignals(ScriptState* script_state, return resolver->Promise(); } -void SerialPort::close() { - if (underlying_source_) { - // The ReadableStream will report "done" when the data pipe is closed. - underlying_source_->ExpectClose(); - underlying_source_ = nullptr; - readable_ = nullptr; +ScriptPromise SerialPort::close(ScriptState* script_state, + ExceptionState& exception_state) { + if (!port_) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "The port is already closed."); + return ScriptPromise(); } - if (underlying_sink_) { - // TODO(crbug.com/893334): Rather than triggering an error on the - // WritableStream this should imply a call to abort() and fail if the stream - // is locked. - underlying_sink_->SignalErrorOnClose(DOMExceptionFromSendError( - device::mojom::SerialSendError::DISCONNECTED)); - underlying_sink_ = nullptr; - writable_ = nullptr; + + if (closing_) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "A call to close() is already in progress."); + return ScriptPromise(); } - port_.reset(); - client_receiver_.reset(); + + closing_ = true; + + HeapVector<ScriptPromise> promises; + if (readable_) { + promises.push_back(readable_->cancel(script_state, exception_state)); + if (exception_state.HadException()) { + closing_ = false; + return ScriptPromise(); + } + } + if (writable_) { + auto* reason = MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, kPortClosed); + promises.push_back(writable_->abort(script_state, + ScriptValue::From(script_state, reason), + exception_state)); + if (exception_state.HadException()) { + closing_ = false; + return ScriptPromise(); + } + } + + return ScriptPromise::All(script_state, promises) + .Then(ContinueCloseFunction::Create(script_state, this), + AbortCloseFunction::Create(script_state, this)); +} + +ScriptPromise SerialPort::ContinueClose(ScriptState* script_state) { + DCHECK(closing_); + DCHECK(!readable_); + DCHECK(!writable_); + DCHECK(!close_resolver_); + + if (!port_) + return ScriptPromise::CastUndefined(script_state); + + close_resolver_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + port_->Close(WTF::Bind(&SerialPort::OnClose, WrapPersistent(this))); + return close_resolver_->Promise(); +} + +void SerialPort::AbortClose() { + DCHECK(closing_); + closing_ = false; } void SerialPort::UnderlyingSourceClosed() { @@ -337,6 +421,7 @@ void SerialPort::Trace(Visitor* visitor) { visitor->Trace(underlying_sink_); visitor->Trace(open_resolver_); visitor->Trace(signal_resolvers_); + visitor->Trace(close_resolver_); ScriptWrappable::Trace(visitor); } @@ -375,6 +460,7 @@ bool SerialPort::CreateDataPipe(mojo::ScopedDataPipeProducerHandle* producer, } void SerialPort::OnConnectionError() { + closing_ = false; port_.reset(); client_receiver_.reset(); @@ -387,6 +473,8 @@ void SerialPort::OnConnectionError() { underlying_source_ = nullptr; SerialPortUnderlyingSink* underlying_sink = underlying_sink_; underlying_sink_ = nullptr; + ScriptPromiseResolver* close_resolver = close_resolver_; + close_resolver_ = nullptr; if (open_resolver) { open_resolver->Reject(MakeGarbageCollected<DOMException>( @@ -404,12 +492,15 @@ void SerialPort::OnConnectionError() { underlying_sink->SignalErrorOnClose( DOMExceptionFromSendError(SerialSendError::DISCONNECTED)); } + if (close_resolver) + close_resolver->Resolve(); } void SerialPort::OnOpen( mojo::ScopedDataPipeConsumerHandle readable_pipe, mojo::ScopedDataPipeProducerHandle writable_pipe, - device::mojom::blink::SerialPortClientRequest client_request, + mojo::PendingReceiver<device::mojom::blink::SerialPortClient> + client_receiver, bool success) { ScriptState* script_state = open_resolver_->GetScriptState(); if (!script_state->ContextIsValid()) @@ -426,7 +517,7 @@ void SerialPort::OnOpen( ScriptState::Scope scope(script_state); InitializeReadableStream(script_state, std::move(readable_pipe)); InitializeWritableStream(script_state, std::move(writable_pipe)); - client_receiver_.Bind(std::move(client_request)); + client_receiver_.Bind(std::move(client_receiver)); open_resolver_->Resolve(); open_resolver_ = nullptr; } @@ -438,8 +529,12 @@ void SerialPort::InitializeReadableStream( DCHECK(!readable_); underlying_source_ = MakeGarbageCollected<SerialPortUnderlyingSource>( script_state, this, std::move(readable_pipe)); + // Ideally the stream would report the number of bytes that can be read from + // the underlying Mojo data pipe. As an approximation the high water mark is + // set to 0 so that data remains in the pipe rather than being queued in the + // stream and thus adding an extra layer of buffering. readable_ = ReadableStream::CreateWithCountQueueingStrategy( - script_state, underlying_source_, 0); + script_state, underlying_source_, /*high_water_mark=*/0); } void SerialPort::InitializeWritableStream( @@ -449,8 +544,13 @@ void SerialPort::InitializeWritableStream( DCHECK(!writable_); underlying_sink_ = MakeGarbageCollected<SerialPortUnderlyingSink>( this, std::move(writable_pipe)); + // Ideally the stream would report the number of bytes that could be written + // to the underlying Mojo data pipe. As an approximation the high water mark + // is set to 1 so that the stream appears ready but producers observing + // backpressure won't queue additional chunks in the stream and thus add an + // extra layer of buffering. writable_ = WritableStream::CreateWithCountQueueingStrategy( - script_state, underlying_sink_, 0); + script_state, underlying_sink_, /*high_water_mark=*/1); } void SerialPort::OnGetSignals( @@ -486,4 +586,15 @@ void SerialPort::OnSetSignals(ScriptPromiseResolver* resolver, bool success) { resolver->Resolve(); } +void SerialPort::OnClose() { + DCHECK(close_resolver_); + closing_ = false; + port_.reset(); + client_receiver_.reset(); + + ScriptPromiseResolver* close_resolver = close_resolver_; + close_resolver_ = nullptr; + close_resolver->Resolve(); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port.h b/chromium/third_party/blink/renderer/modules/serial/serial_port.h index f4b84df9600..c2a8626509a 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial_port.h +++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.h @@ -5,9 +5,10 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_PORT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SERIAL_SERIAL_PORT_H_ +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/device/public/mojom/serial.mojom-blink.h" +#include "services/device/public/mojom/serial.mojom-blink-forward.h" #include "third_party/blink/public/mojom/serial/serial.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -40,17 +41,23 @@ class SerialPort final : public ScriptWrappable, ~SerialPort() override; // Web-exposed functions - ScriptPromise open(ScriptState*, const SerialOptions* options); + ScriptPromise open(ScriptState*, + const SerialOptions* options, + ExceptionState&); ReadableStream* readable(ScriptState*, ExceptionState&); WritableStream* writable(ScriptState*, ExceptionState&); - ScriptPromise getSignals(ScriptState*); - ScriptPromise setSignals(ScriptState*, const SerialOutputSignals*); - void close(); + ScriptPromise getSignals(ScriptState*, ExceptionState&); + ScriptPromise setSignals(ScriptState*, + const SerialOutputSignals*, + ExceptionState&); + ScriptPromise close(ScriptState*, ExceptionState&); const base::UnguessableToken& token() const { return info_->token; } void UnderlyingSourceClosed(); void UnderlyingSinkClosed(); + ScriptPromise ContinueClose(ScriptState*); + void AbortClose(); void ContextDestroyed(); void Trace(Visitor*) override; @@ -66,7 +73,7 @@ class SerialPort final : public ScriptWrappable, void OnConnectionError(); void OnOpen(mojo::ScopedDataPipeConsumerHandle, mojo::ScopedDataPipeProducerHandle, - device::mojom::blink::SerialPortClientRequest, + mojo::PendingReceiver<device::mojom::blink::SerialPortClient>, bool success); void InitializeReadableStream(ScriptState*, mojo::ScopedDataPipeConsumerHandle); @@ -75,6 +82,7 @@ class SerialPort final : public ScriptWrappable, void OnGetSignals(ScriptPromiseResolver*, device::mojom::blink::SerialPortControlSignalsPtr); void OnSetSignals(ScriptPromiseResolver*, bool success); + void OnClose(); mojom::blink::SerialPortInfoPtr info_; Member<Serial> parent_; @@ -88,11 +96,17 @@ class SerialPort final : public ScriptWrappable, Member<WritableStream> writable_; Member<SerialPortUnderlyingSink> underlying_sink_; + // Indicates that the port is being closed and so the streams should not be + // reopened on demand. + bool closing_ = false; + // Resolver for the Promise returned by open(). Member<ScriptPromiseResolver> open_resolver_; // Resolvers for the Promises returned by getSignals() and setSignals() to // reject them on Mojo connection failure. HeapHashSet<Member<ScriptPromiseResolver>> signal_resolvers_; + // Resolver for the Promise returned by ClosePort(). + Member<ScriptPromiseResolver> close_resolver_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port.idl b/chromium/third_party/blink/renderer/modules/serial/serial_port.idl index fb126830669..24f88bfe635 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial_port.idl +++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.idl @@ -13,12 +13,12 @@ [CallWith=ScriptState, RaisesException] readonly attribute WritableStream writable; - [CallWith=ScriptState, MeasureAs=SerialPortOpen] + [CallWith=ScriptState, RaisesException, MeasureAs=SerialPortOpen] Promise<void> open(SerialOptions options); - [CallWith=ScriptState] + [CallWith=ScriptState, RaisesException] Promise<SerialInputSignals> getSignals(); - [CallWith=ScriptState] + [CallWith=ScriptState, RaisesException] Promise<void> setSignals(SerialOutputSignals signals); - [MeasureAs=SerialPortClose] - void close(); + [RaisesException, CallWith=ScriptState, MeasureAs=SerialPortClose] + Promise<void> close(); }; diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc index a2867d7c937..0c10f770169 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc +++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.cc @@ -69,11 +69,11 @@ ScriptPromise SerialPortUnderlyingSink::close(ScriptState* script_state) { watcher_.Cancel(); data_pipe_.reset(); + serial_port_->UnderlyingSinkClosed(); if (pending_exception_) { DOMException* exception = pending_exception_; pending_exception_ = nullptr; - serial_port_->UnderlyingSinkClosed(); return ScriptPromise::RejectWithDOMException(script_state, exception); } diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc index 8ba9a20a54f..0cf7af14900 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc +++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.cc @@ -4,7 +4,6 @@ #include "third_party/blink/renderer/modules/serial/serial_port_underlying_source.h" -#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/streams/readable_stream_default_controller_interface.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" @@ -28,22 +27,25 @@ SerialPortUnderlyingSource::SerialPortUnderlyingSource( } ScriptPromise SerialPortUnderlyingSource::pull(ScriptState* script_state) { - // Only one pending call to pull() is allowed by the spec. - DCHECK(!pending_pull_); - // pull() shouldn't be called if an error has been signaled to the controller. + // pull() signals that the stream wants more data. By resolving immediately + // we allow the stream to be canceled before that data is received. pull() + // will not be called again until a chunk is enqueued or if an error has been + // signaled to the controller. DCHECK(data_pipe_); - if (ReadData()) - return ScriptPromise::CastUndefined(script_state); + if (!ReadData()) + ArmWatcher(); - return ArmWatcher(script_state); + return ScriptPromise::CastUndefined(script_state); } ScriptPromise SerialPortUnderlyingSource::Cancel(ScriptState* script_state, ScriptValue reason) { - // TODO(crbug.com/989653): cancel() should trigger a purge of the serial - // read buffer. + // TODO(crbug.com/989653): Rather than calling Close(), cancel() should + // trigger a purge of the serial read buffer and wait for the pipe to close to + // indicate the purge has been completed. Close(); + ExpectPipeClose(); return ScriptPromise::CastUndefined(script_state); } @@ -70,19 +72,7 @@ void SerialPortUnderlyingSource::SignalErrorOnClose(DOMException* exception) { serial_port_->UnderlyingSourceClosed(); } -void SerialPortUnderlyingSource::ExpectClose() { - if (data_pipe_) { - // Pipe is still open. Wait for PipeClosed() to be called. - expect_close_ = true; - return; - } - - Controller()->Close(); - serial_port_->UnderlyingSourceClosed(); -} - void SerialPortUnderlyingSource::Trace(Visitor* visitor) { - visitor->Trace(pending_pull_); visitor->Trace(pending_exception_); visitor->Trace(serial_port_); UnderlyingSourceBase::Trace(visitor); @@ -113,15 +103,12 @@ bool SerialPortUnderlyingSource::ReadData() { } } -ScriptPromise SerialPortUnderlyingSource::ArmWatcher( - ScriptState* script_state) { +void SerialPortUnderlyingSource::ArmWatcher() { MojoResult ready_result; mojo::HandleSignalsState ready_state; MojoResult result = watcher_.Arm(&ready_result, &ready_state); - if (result == MOJO_RESULT_OK) { - pending_pull_ = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - return pending_pull_->Promise(); - } + if (result == MOJO_RESULT_OK) + return; DCHECK_EQ(ready_result, MOJO_RESULT_OK); if (ready_state.readable()) { @@ -130,24 +117,15 @@ ScriptPromise SerialPortUnderlyingSource::ArmWatcher( } else if (ready_state.peer_closed()) { PipeClosed(); } - - return ScriptPromise::CastUndefined(script_state); } void SerialPortUnderlyingSource::OnHandleReady( MojoResult result, const mojo::HandleSignalsState& state) { - DCHECK(pending_pull_); - switch (result) { case MOJO_RESULT_OK: { bool read_result = ReadData(); DCHECK(read_result); - // If the pipe was closed |pending_pull_| will have been resolved. - if (pending_pull_) { - pending_pull_->Resolve(); - pending_pull_ = nullptr; - } break; } case MOJO_RESULT_SHOULD_WAIT: @@ -159,6 +137,17 @@ void SerialPortUnderlyingSource::OnHandleReady( } } +void SerialPortUnderlyingSource::ExpectPipeClose() { + if (data_pipe_) { + // The pipe is still open. Wait for PipeClosed() to be called. + expect_close_ = true; + return; + } + + Controller()->Close(); + serial_port_->UnderlyingSourceClosed(); +} + void SerialPortUnderlyingSource::PipeClosed() { if (pending_exception_) { Controller()->Error(pending_exception_); @@ -174,10 +163,6 @@ void SerialPortUnderlyingSource::PipeClosed() { void SerialPortUnderlyingSource::Close() { watcher_.Cancel(); data_pipe_.reset(); - if (pending_pull_) { - pending_pull_->Resolve(); - pending_pull_ = nullptr; - } } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.h b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.h index c4a803af0ec..1d6116aa6d0 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.h +++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_source.h @@ -12,7 +12,6 @@ namespace blink { class DOMException; -class ScriptPromiseResolver; class SerialPort; class SerialPortUnderlyingSource : public UnderlyingSourceBase { @@ -28,7 +27,6 @@ class SerialPortUnderlyingSource : public UnderlyingSourceBase { void SignalErrorImmediately(DOMException*); void SignalErrorOnClose(DOMException*); - void ExpectClose(); void Trace(Visitor*) override; @@ -37,15 +35,15 @@ class SerialPortUnderlyingSource : public UnderlyingSourceBase { // |Controller()| or the pipe was closed, and false otherwise. bool ReadData(); - ScriptPromise ArmWatcher(ScriptState*); + void ArmWatcher(); void OnHandleReady(MojoResult, const mojo::HandleSignalsState&); + void ExpectPipeClose(); void PipeClosed(); void Close(); mojo::ScopedDataPipeConsumerHandle data_pipe_; mojo::SimpleWatcher watcher_; Member<SerialPort> serial_port_; - Member<ScriptPromiseResolver> pending_pull_; Member<DOMException> pending_exception_; bool expect_close_ = false; }; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/client.idl b/chromium/third_party/blink/renderer/modules/service_worker/client.idl index f11f4d44fc9..640ef5c6395 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/client.idl +++ b/chromium/third_party/blink/renderer/modules/service_worker/client.idl @@ -22,5 +22,5 @@ enum ClientLifecycleState { // FIXME: frameType is non-standard, see https://crbug.com/697110 [CallWith=ScriptState] readonly attribute ContextFrameType frameType; - [RuntimeEnabled=ServiceWorkerFilterFrozen] readonly attribute ClientLifecycleState lifecycleState; + [RuntimeEnabled=ServiceWorkerClientLifecycleState] readonly attribute ClientLifecycleState lifecycleState; }; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/client_query_options.idl b/chromium/third_party/blink/renderer/modules/service_worker/client_query_options.idl index c30fdc809bb..f8d2306379f 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/client_query_options.idl +++ b/chromium/third_party/blink/renderer/modules/service_worker/client_query_options.idl @@ -20,6 +20,5 @@ enum ClientLifecycleStateQuery { // https://w3c.github.io/ServiceWorker/#dictdef-clientqueryoptions dictionary ClientQueryOptions { boolean includeUncontrolled = false; - [RuntimeEnabled=ServiceWorkerFilterFrozen] ClientLifecycleStateQuery lifecycleState = "active"; ClientType type = "window"; }; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc index 78d1139b5e3..cf4f35ebd16 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.cc @@ -20,6 +20,7 @@ #include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" +#include "third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h" #include "third_party/blink/renderer/platform/network/network_utils.h" diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc index 6bc45178eff..7de6a92c87b 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc @@ -125,9 +125,8 @@ bool IsClientRequest(network::mojom::RequestContextFrameType frame_type, // Notifies the result of FetchDataLoader to |callback_|, the other endpoint // for which is passed to the browser process via // blink.mojom.ServiceWorkerFetchResponseCallback.OnResponseStream(). -class FetchLoaderClient final - : public GarbageCollectedFinalized<FetchLoaderClient>, - public FetchDataLoader::Client { +class FetchLoaderClient final : public GarbageCollected<FetchLoaderClient>, + public FetchDataLoader::Client { USING_GARBAGE_COLLECTED_MIXIN(FetchLoaderClient); public: @@ -217,7 +216,7 @@ void FetchRespondWithObserver::OnResponseRejected( response->status_text = ""; response->error = error; To<ServiceWorkerGlobalScope>(GetExecutionContext()) - ->RespondToFetchEvent(event_id_, std::move(response), + ->RespondToFetchEvent(event_id_, request_url_, std::move(response), event_dispatch_time_, base::TimeTicks::Now()); } @@ -324,8 +323,8 @@ void FetchRespondWithObserver::OnResponseFulfilled( // Handle the blob response body. fetch_api_response->blob = blob_data_handle; service_worker_global_scope->RespondToFetchEvent( - event_id_, std::move(fetch_api_response), event_dispatch_time_, - base::TimeTicks::Now()); + event_id_, request_url_, std::move(fetch_api_response), + event_dispatch_time_, base::TimeTicks::Now()); return; } @@ -350,19 +349,20 @@ void FetchRespondWithObserver::OnResponseFulfilled( } service_worker_global_scope->RespondToFetchEventWithResponseStream( - event_id_, std::move(fetch_api_response), std::move(stream_handle), - event_dispatch_time_, base::TimeTicks::Now()); + event_id_, request_url_, std::move(fetch_api_response), + std::move(stream_handle), event_dispatch_time_, base::TimeTicks::Now()); return; } service_worker_global_scope->RespondToFetchEvent( - event_id_, std::move(fetch_api_response), event_dispatch_time_, - base::TimeTicks::Now()); + event_id_, request_url_, std::move(fetch_api_response), + event_dispatch_time_, base::TimeTicks::Now()); } void FetchRespondWithObserver::OnNoResponse() { DCHECK(GetExecutionContext()); To<ServiceWorkerGlobalScope>(GetExecutionContext()) - ->RespondToFetchEventWithNoResponse(event_id_, event_dispatch_time_, + ->RespondToFetchEventWithNoResponse(event_id_, request_url_, + event_dispatch_time_, base::TimeTicks::Now()); } diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h index abd45b54e55..e18cf9dc8c0 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_FETCH_RESPOND_WITH_OBSERVER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_FETCH_RESPOND_WITH_OBSERVER_H_ -#include "services/network/public/mojom/fetch_api.mojom-blink.h" +#include "services/network/public/mojom/fetch_api.mojom-blink-forward.h" #include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/service_worker/respond_with_observer.h" diff --git a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc index 6bf52b2494e..9732b7eba96 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/service_worker/respond_with_observer.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" diff --git a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h index 3e15f3af490..63e8cee54f1 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_RESPOND_WITH_OBSERVER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_RESPOND_WITH_OBSERVER_H_ -#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink-forward.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/modules/modules_export.h" @@ -25,7 +25,7 @@ class WaitUntilObserver; // each event should implement the procedure of the three behaviors by // overriding onResponseFulfilled, onResponseRejected and onNoResponse. class MODULES_EXPORT RespondWithObserver - : public GarbageCollectedFinalized<RespondWithObserver>, + : public GarbageCollected<RespondWithObserver>, public ContextClient { USING_GARBAGE_COLLECTED_MIXIN(RespondWithObserver); diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc index 66703e150f1..0163be1110b 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc @@ -56,7 +56,7 @@ const AtomicString& ServiceWorker::InterfaceName() const { void ServiceWorker::postMessage(ScriptState* script_state, const ScriptValue& message, - Vector<ScriptValue>& transfer, + HeapVector<ScriptValue>& transfer, ExceptionState& exception_state) { PostMessageOptions* options = PostMessageOptions::Create(); if (!transfer.IsEmpty()) @@ -116,10 +116,8 @@ String ServiceWorker::scriptURL() const { String ServiceWorker::state() const { switch (state_) { - case mojom::blink::ServiceWorkerState::kUnknown: - // The web platform should never see this internal state - NOTREACHED(); - return "unknown"; + case mojom::blink::ServiceWorkerState::kParsed: + return "parsed"; case mojom::blink::ServiceWorkerState::kInstalling: return "installing"; case mojom::blink::ServiceWorkerState::kInstalled: diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.h index 13e6d1d1649..4d6385ef29c 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.h @@ -55,7 +55,7 @@ class MODULES_EXPORT ServiceWorker final DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(ServiceWorker); USING_PRE_FINALIZER(ServiceWorker, Dispose); - + public: static ServiceWorker* From(ExecutionContext*, mojom::blink::ServiceWorkerObjectInfoPtr); @@ -80,7 +80,7 @@ class MODULES_EXPORT ServiceWorker final void postMessage(ScriptState*, const ScriptValue& message, - Vector<ScriptValue>& transfer, + HeapVector<ScriptValue>& transfer, ExceptionState&); void postMessage(ScriptState*, const ScriptValue& message, diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc index 8a8e121d8af..297f47b118b 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.cc @@ -86,7 +86,7 @@ String ServiceWorkerClient::lifecycleState() const { void ServiceWorkerClient::postMessage(ScriptState* script_state, const ScriptValue& message, - Vector<ScriptValue>& transfer, + HeapVector<ScriptValue>& transfer, ExceptionState& exception_state) { PostMessageOptions* options = PostMessageOptions::Create(); if (!transfer.IsEmpty()) diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h index 0a148390ccf..b44ef1ca091 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_client.h @@ -36,7 +36,7 @@ class MODULES_EXPORT ServiceWorkerClient : public ScriptWrappable { String lifecycleState() const; void postMessage(ScriptState*, const ScriptValue& message, - Vector<ScriptValue>& transfer, + HeapVector<ScriptValue>& transfer, ExceptionState&); void postMessage(ScriptState*, const ScriptValue& message, diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc index 406718e2126..9c4ee806a60 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc @@ -39,18 +39,6 @@ mojom::ServiceWorkerClientType GetClientType(const String& type) { return mojom::ServiceWorkerClientType::kWindow; } -mojom::ServiceWorkerClientLifecycleStateQuery GetLifecycleStateQueryType( - const String& type) { - if (type == "active") - return mojom::ServiceWorkerClientLifecycleStateQuery::kActive; - if (type == "frozen") - return mojom::ServiceWorkerClientLifecycleStateQuery::kFrozen; - if (type == "all") - return mojom::ServiceWorkerClientLifecycleStateQuery::kAll; - NOTREACHED(); - return mojom::ServiceWorkerClientLifecycleStateQuery::kActive; -} - void DidGetClient(ScriptPromiseResolver* resolver, mojom::blink::ServiceWorkerClientInfoPtr info) { if (!resolver->GetExecutionContext() || @@ -149,8 +137,7 @@ ScriptPromise ServiceWorkerClients::matchAll( auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); global_scope->GetServiceWorkerHost()->GetClients( mojom::blink::ServiceWorkerClientQueryOptions::New( - options->includeUncontrolled(), GetClientType(options->type()), - GetLifecycleStateQueryType(options->lifecycleState())), + options->includeUncontrolled(), GetClientType(options->type())), WTF::Bind(&DidGetClients, WrapPersistent(resolver))); return resolver->Promise(); } diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h index 168f1ddf22a..f2ff5ac9e15 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h @@ -33,7 +33,7 @@ #include <memory> -#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom-blink.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom-blink-forward.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_provider_client.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc index 4fff53a2573..a89c3e20a2f 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc @@ -46,6 +46,7 @@ struct StubScriptFunction { size_t CallCount() { return call_count_; } ScriptValue Arg() { return arg_; } + void Trace(blink::Visitor* visitor) { visitor->Trace(arg_); } private: size_t call_count_; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.h index 27f011d1985..60d2bc1d96f 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_error.h @@ -31,7 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_ERROR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_ERROR_H_ -#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_error_type.mojom-blink-forward.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "v8/include/v8.h" diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc index d3137079f20..395ec6c1746 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc @@ -61,7 +61,6 @@ #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h" #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h" -#include "third_party/blink/renderer/core/workers/installed_scripts_manager.h" #include "third_party/blink/renderer/core/workers/worker_classic_script_loader.h" #include "third_party/blink/renderer/core/workers/worker_clients.h" #include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h" @@ -181,16 +180,18 @@ static std::string MojoEnumToString(T mojo_enum) { ServiceWorkerGlobalScope* ServiceWorkerGlobalScope::Create( ServiceWorkerThread* thread, std::unique_ptr<GlobalScopeCreationParams> creation_params, + std::unique_ptr<ServiceWorkerInstalledScriptsManager> + installed_scripts_manager, mojo::PendingRemote<mojom::blink::CacheStorage> cache_storage_remote, base::TimeTicks time_origin) { DCHECK_EQ(creation_params->off_main_thread_fetch_option, OffMainThreadWorkerScriptFetchOption::kEnabled); +#if DCHECK_IS_ON() // If the script is being loaded via script streaming, the script is not yet // loaded. - if (thread->GetInstalledScriptsManager() && - thread->GetInstalledScriptsManager()->IsScriptInstalled( - creation_params->script_url)) { + if (installed_scripts_manager && installed_scripts_manager->IsScriptInstalled( + creation_params->script_url)) { // CSP headers, referrer policy, and origin trial tokens will be provided by // the InstalledScriptsManager in EvaluateClassicScript(). DCHECK(creation_params->outside_content_security_policy_headers.IsEmpty()); @@ -198,18 +199,22 @@ ServiceWorkerGlobalScope* ServiceWorkerGlobalScope::Create( creation_params->referrer_policy); DCHECK(creation_params->origin_trial_tokens->IsEmpty()); } +#endif // DCHECK_IS_ON() return MakeGarbageCollected<ServiceWorkerGlobalScope>( - std::move(creation_params), thread, std::move(cache_storage_remote), - time_origin); + std::move(creation_params), thread, std::move(installed_scripts_manager), + std::move(cache_storage_remote), time_origin); } ServiceWorkerGlobalScope::ServiceWorkerGlobalScope( std::unique_ptr<GlobalScopeCreationParams> creation_params, ServiceWorkerThread* thread, + std::unique_ptr<ServiceWorkerInstalledScriptsManager> + installed_scripts_manager, mojo::PendingRemote<mojom::blink::CacheStorage> cache_storage_remote, base::TimeTicks time_origin) : WorkerGlobalScope(std::move(creation_params), thread, time_origin), + installed_scripts_manager_(std::move(installed_scripts_manager)), cache_storage_remote_(std::move(cache_storage_remote)) { // Create the idle timer. At this point the timer is not started. It will be // started by DidEvaluateScript(). @@ -233,6 +238,12 @@ void ServiceWorkerGlobalScope::FetchAndRunClassicScript( const v8_inspector::V8StackTraceId& stack_id) { DCHECK(!IsContextPaused()); + if (installed_scripts_manager_) { + // This service worker is installed. Load and run the installed script. + LoadAndRunInstalledClassicScript(script_url, stack_id); + return; + } + // Step 9. "Switching on job's worker type, run these substeps with the // following options:" // "classic: Fetch a classic worker script given job's serialized script url, @@ -279,75 +290,17 @@ void ServiceWorkerGlobalScope::FetchAndRunModuleScript( WorkerResourceTimingNotifier& outside_resource_timing_notifier, network::mojom::CredentialsMode credentials_mode) { DCHECK(IsContextThread()); + + // Start fetching scripts regardless of whether this service worker is + // installed. For the installed case, the scripts will be read from the + // service worker script storage during module script fetch (see + // InstalledServiceWorkerModuleScriptFetcher). FetchModuleScript(module_url_record, outside_settings_object, outside_resource_timing_notifier, mojom::RequestContextType::SERVICE_WORKER, credentials_mode, ModuleScriptCustomFetchType::kWorkerConstructor, MakeGarbageCollected<ServiceWorkerModuleTreeClient>( - Modulator::From(ScriptController()->GetScriptState()))); -} - -void ServiceWorkerGlobalScope::RunInstalledClassicScript( - const KURL& script_url, - const v8_inspector::V8StackTraceId& stack_id) { - DCHECK(IsContextThread()); - - InstalledScriptsManager* installed_scripts_manager = - GetThread()->GetInstalledScriptsManager(); - DCHECK(installed_scripts_manager); - DCHECK(installed_scripts_manager->IsScriptInstalled(script_url)); - - // GetScriptData blocks until the script is received from the browser. - std::unique_ptr<InstalledScriptsManager::ScriptData> script_data = - installed_scripts_manager->GetScriptData(script_url); - if (!script_data) { - ReportingProxy().DidFailToLoadClassicScript(); - // This will eventually initiate worker thread termination. See - // ServiceWorkerGlobalScopeProxy::DidCloseWorkerGlobalScope() for details. - close(); - return; - } - ReportingProxy().DidLoadClassicScript(); - - auto referrer_policy = network::mojom::ReferrerPolicy::kDefault; - if (!script_data->GetReferrerPolicy().IsNull()) { - SecurityPolicy::ReferrerPolicyFromHeaderValue( - script_data->GetReferrerPolicy(), - kDoNotSupportReferrerPolicyLegacyKeywords, &referrer_policy); - } - - // Construct a ContentSecurityPolicy object to convert - // ContentSecurityPolicyResponseHeaders to CSPHeaderAndType. - // TODO(nhiroki): Find an efficient way to do this. - auto* content_security_policy = MakeGarbageCollected<ContentSecurityPolicy>(); - content_security_policy->DidReceiveHeaders( - script_data->GetContentSecurityPolicyResponseHeaders()); - - RunClassicScript( - script_url, referrer_policy, script_data->GetResponseAddressSpace(), - content_security_policy->Headers(), - script_data->CreateOriginTrialTokens().get(), - script_data->TakeSourceText(), script_data->TakeMetaData(), stack_id); -} - -void ServiceWorkerGlobalScope::RunInstalledModuleScript( - const KURL& module_url_record, - const FetchClientSettingsObjectSnapshot& outside_settings_object, - network::mojom::CredentialsMode credentials_mode) { - DCHECK(IsContextThread()); - // Currently we don't plumb performance timing for toplevel service worker - // script fetch. https://crbug.com/954005 - auto* outside_resource_timing_notifier = - MakeGarbageCollected<NullWorkerResourceTimingNotifier>(); - - // The installed scripts will be read from the service worker script storage - // during module script fetch. - FetchModuleScript(module_url_record, outside_settings_object, - *outside_resource_timing_notifier, - mojom::RequestContextType::SERVICE_WORKER, credentials_mode, - ModuleScriptCustomFetchType::kInstalledServiceWorker, - MakeGarbageCollected<ServiceWorkerModuleTreeClient>( - Modulator::From(ScriptController()->GetScriptState()))); + ScriptController()->GetScriptState())); } void ServiceWorkerGlobalScope::Dispose() { @@ -359,6 +312,11 @@ void ServiceWorkerGlobalScope::Dispose() { WorkerGlobalScope::Dispose(); } +InstalledScriptsManager* +ServiceWorkerGlobalScope::GetInstalledScriptsManager() { + return installed_scripts_manager_.get(); +} + void ServiceWorkerGlobalScope::CountWorkerScript(size_t script_size, size_t cached_metadata_size) { DCHECK_EQ(GetScriptType(), mojom::ScriptType::kClassic); @@ -536,6 +494,47 @@ void ServiceWorkerGlobalScope::Initialize( DCHECK_EQ(appcache_id, mojom::blink::kAppCacheNoCacheId); } +void ServiceWorkerGlobalScope::LoadAndRunInstalledClassicScript( + const KURL& script_url, + const v8_inspector::V8StackTraceId& stack_id) { + DCHECK(IsContextThread()); + + DCHECK(installed_scripts_manager_); + DCHECK(installed_scripts_manager_->IsScriptInstalled(script_url)); + + // GetScriptData blocks until the script is received from the browser. + std::unique_ptr<InstalledScriptsManager::ScriptData> script_data = + installed_scripts_manager_->GetScriptData(script_url); + if (!script_data) { + ReportingProxy().DidFailToFetchClassicScript(); + // This will eventually initiate worker thread termination. See + // ServiceWorkerGlobalScopeProxy::DidCloseWorkerGlobalScope() for details. + close(); + return; + } + ReportingProxy().DidLoadClassicScript(); + + auto referrer_policy = network::mojom::ReferrerPolicy::kDefault; + if (!script_data->GetReferrerPolicy().IsNull()) { + SecurityPolicy::ReferrerPolicyFromHeaderValue( + script_data->GetReferrerPolicy(), + kDoNotSupportReferrerPolicyLegacyKeywords, &referrer_policy); + } + + // Construct a ContentSecurityPolicy object to convert + // ContentSecurityPolicyResponseHeaders to CSPHeaderAndType. + // TODO(nhiroki): Find an efficient way to do this. + auto* content_security_policy = MakeGarbageCollected<ContentSecurityPolicy>(); + content_security_policy->DidReceiveHeaders( + script_data->GetContentSecurityPolicyResponseHeaders()); + + RunClassicScript( + script_url, referrer_policy, script_data->GetResponseAddressSpace(), + content_security_policy->Headers(), + script_data->CreateOriginTrialTokens().get(), + script_data->TakeSourceText(), script_data->TakeMetaData(), stack_id); +} + // https://w3c.github.io/ServiceWorker/#run-service-worker-algorithm void ServiceWorkerGlobalScope::RunClassicScript( const KURL& response_url, @@ -576,6 +575,10 @@ ServiceWorkerRegistration* ServiceWorkerGlobalScope::registration() { return registration_; } +::blink::ServiceWorker* ServiceWorkerGlobalScope::serviceWorker() { + return service_worker_; +} + ScriptPromise ServiceWorkerGlobalScope::skipWaiting(ScriptState* script_state) { ExecutionContext* execution_context = ExecutionContext::From(script_state); // FIXME: short-term fix, see details at: @@ -695,6 +698,33 @@ bool ServiceWorkerGlobalScope::AddEventListenerInternal( options); } +bool ServiceWorkerGlobalScope::FetchClassicImportedScript( + const KURL& script_url, + KURL* out_response_url, + String* out_source_code, + std::unique_ptr<Vector<uint8_t>>* out_cached_meta_data) { + // InstalledScriptsManager is used only for starting installed service + // workers. + if (installed_scripts_manager_) { + // All imported scripts must be installed. This is already checked in + // ServiceWorkerGlobalScope::importScripts(). + DCHECK(installed_scripts_manager_->IsScriptInstalled(script_url)); + std::unique_ptr<InstalledScriptsManager::ScriptData> script_data = + installed_scripts_manager_->GetScriptData(script_url); + if (!script_data) + return false; + *out_response_url = script_url; + *out_source_code = script_data->TakeSourceText(); + *out_cached_meta_data = script_data->TakeMetaData(); + // TODO(shimazu): Add appropriate probes for inspector. + return true; + } + // This is a new service worker. Proceed with importing scripts and installing + // them. + return WorkerGlobalScope::FetchClassicImportedScript( + script_url, out_response_url, out_source_code, out_cached_meta_data); +} + const AtomicString& ServiceWorkerGlobalScope::InterfaceName() const { return event_target_names::kServiceWorkerGlobalScope; } @@ -726,25 +756,30 @@ void ServiceWorkerGlobalScope::DispatchExtendableEventWithRespondWith( void ServiceWorkerGlobalScope::Trace(blink::Visitor* visitor) { visitor->Trace(clients_); visitor->Trace(registration_); + visitor->Trace(service_worker_); visitor->Trace(service_worker_objects_); visitor->Trace(pending_preload_fetch_events_); WorkerGlobalScope::Trace(visitor); } +bool ServiceWorkerGlobalScope::HasRelatedFetchEvent( + const KURL& request_url) const { + auto it = unresponded_fetch_event_counts_.find(request_url); + return it != unresponded_fetch_event_counts_.end(); +} + void ServiceWorkerGlobalScope::importScripts( const HeapVector<StringOrTrustedScriptURL>& urls, ExceptionState& exception_state) { - InstalledScriptsManager* installed_scripts_manager = - GetThread()->GetInstalledScriptsManager(); for (const StringOrTrustedScriptURL& stringOrUrl : urls) { String string_url = stringOrUrl.IsString() ? stringOrUrl.GetAsString() : stringOrUrl.GetAsTrustedScriptURL()->toString(); KURL completed_url = CompleteURL(string_url); - if (installed_scripts_manager && - !installed_scripts_manager->IsScriptInstalled(completed_url)) { - DCHECK(installed_scripts_manager->IsScriptInstalled(Url())); + if (installed_scripts_manager_ && + !installed_scripts_manager_->IsScriptInstalled(completed_url)) { + DCHECK(installed_scripts_manager_->IsScriptInstalled(Url())); exception_state.ThrowDOMException( DOMExceptionCode::kNetworkError, "Failed to import '" + completed_url.ElidedString() + @@ -903,6 +938,7 @@ void ServiceWorkerGlobalScope::DidHandleExtendableMessageEvent( void ServiceWorkerGlobalScope::RespondToFetchEventWithNoResponse( int fetch_event_id, + const KURL& request_url, base::TimeTicks event_dispatch_time, base::TimeTicks respond_with_settled_time) { DCHECK(IsContextThread()); @@ -920,11 +956,14 @@ void ServiceWorkerGlobalScope::RespondToFetchEventWithNoResponse( timing->dispatch_event_time = event_dispatch_time; timing->respond_with_settled_time = respond_with_settled_time; + NoteRespondedToFetchEvent(request_url); + response_callback->OnFallback(std::move(timing)); } void ServiceWorkerGlobalScope::RespondToFetchEvent( int fetch_event_id, + const KURL& request_url, mojom::blink::FetchAPIResponsePtr response, base::TimeTicks event_dispatch_time, base::TimeTicks respond_with_settled_time) { @@ -943,11 +982,14 @@ void ServiceWorkerGlobalScope::RespondToFetchEvent( timing->dispatch_event_time = event_dispatch_time; timing->respond_with_settled_time = respond_with_settled_time; + NoteRespondedToFetchEvent(request_url); + response_callback->OnResponse(std::move(response), std::move(timing)); } void ServiceWorkerGlobalScope::RespondToFetchEventWithResponseStream( int fetch_event_id, + const KURL& request_url, mojom::blink::FetchAPIResponsePtr response, mojom::blink::ServiceWorkerStreamHandlePtr body_as_stream, base::TimeTicks event_dispatch_time, @@ -967,6 +1009,8 @@ void ServiceWorkerGlobalScope::RespondToFetchEventWithResponseStream( timing->dispatch_event_time = event_dispatch_time; timing->respond_with_settled_time = respond_with_settled_time; + NoteRespondedToFetchEvent(request_url); + response_callback->OnResponseStream( std::move(response), std::move(body_as_stream), std::move(timing)); } @@ -1235,23 +1279,6 @@ ServiceWorkerGlobalScope::GetServiceWorkerHost() { return service_worker_host_.get(); } -int ServiceWorkerGlobalScope::WillStartTask() { - DCHECK(IsContextThread()); - DCHECK(timeout_timer_); - return timeout_timer_->StartEvent(base::DoNothing()); -} - -void ServiceWorkerGlobalScope::DidEndTask(int task_id) { - DCHECK(IsContextThread()); - DCHECK(timeout_timer_); - // Check if the task is still alive, since the timeout timer might have - // already timed it out (which calls the abort callback passed to StartEvent() - // but that does nothing, since we just check HasEvent() here instead of - // maintaining our own set of started events). - if (timeout_timer_->HasEvent(task_id)) - timeout_timer_->EndEvent(task_id); -} - void ServiceWorkerGlobalScope::OnIdleTimeout() { DCHECK(IsContextThread()); // RequestedTermination() returns true if ServiceWorkerTimeoutTimer agrees @@ -1379,6 +1406,8 @@ void ServiceWorkerGlobalScope::DispatchFetchEventInternal( pending_preload_fetch_events_.insert(event_id, fetch_event); } + NoteNewFetchEvent(request->url()); + DispatchExtendableEventWithRespondWith(fetch_event, wait_until_observer, respond_with_observer); } @@ -1386,11 +1415,8 @@ void ServiceWorkerGlobalScope::DispatchFetchEventInternal( void ServiceWorkerGlobalScope::SetFetchHandlerExistence( FetchHandlerExistence fetch_handler_existence) { DCHECK(IsContextThread()); - if (fetch_handler_existence == FetchHandlerExistence::EXISTS && - base::FeatureList::IsEnabled( - features::kServiceWorkerIsolateInForeground)) { + if (fetch_handler_existence == FetchHandlerExistence::EXISTS) GetThread()->GetIsolate()->IsolateInForegroundNotification(); - } } void ServiceWorkerGlobalScope::DispatchFetchEventForSubresource( @@ -1426,8 +1452,10 @@ void ServiceWorkerGlobalScope::InitializeGlobalScope( mojo::PendingAssociatedRemote<mojom::blink::ServiceWorkerHost> service_worker_host, mojom::blink::ServiceWorkerRegistrationObjectInfoPtr registration_info, + mojom::blink::ServiceWorkerObjectInfoPtr service_worker_info, mojom::blink::FetchHandlerExistence fetch_hander_existence) { DCHECK(IsContextThread()); + DCHECK(!global_scope_initialized_); DCHECK(service_worker_host.is_valid()); DCHECK(!service_worker_host_); @@ -1442,9 +1470,34 @@ void ServiceWorkerGlobalScope::InitializeGlobalScope( registration_ = MakeGarbageCollected<ServiceWorkerRegistration>( GetExecutionContext(), std::move(registration_info)); + // Set ServiceWorkerGlobalScope#serviceWorker. + DCHECK_NE(service_worker_info->version_id, + mojom::blink::kInvalidServiceWorkerVersionId); + DCHECK(service_worker_info->host_remote.is_valid()); + DCHECK(service_worker_info->receiver.is_valid()); + service_worker_ = ::blink::ServiceWorker::From( + GetExecutionContext(), std::move(service_worker_info)); + SetFetchHandlerExistence(fetch_hander_existence); - ReadyToRunWorkerScript(); + global_scope_initialized_ = true; + if (!pause_evaluation_) + ReadyToRunWorkerScript(); +} + +void ServiceWorkerGlobalScope::PauseEvaluation() { + DCHECK(IsContextThread()); + DCHECK(!global_scope_initialized_); + DCHECK(!pause_evaluation_); + pause_evaluation_ = true; +} + +void ServiceWorkerGlobalScope::ResumeEvaluation() { + DCHECK(IsContextThread()); + DCHECK(pause_evaluation_); + pause_evaluation_ = false; + if (global_scope_initialized_) + ReadyToRunWorkerScript(); } void ServiceWorkerGlobalScope::DispatchInstallEvent( @@ -1628,24 +1681,6 @@ void ServiceWorkerGlobalScope::DispatchExtendableMessageEvent( DispatchExtendableMessageEventInternal(event_id, std::move(event)); } -void ServiceWorkerGlobalScope::DispatchExtendableMessageEventWithCustomTimeout( - mojom::blink::ExtendableMessageEventPtr event, - base::TimeDelta timeout, - DispatchExtendableMessageEventCallback callback) { - DCHECK(IsContextThread()); - int event_id = timeout_timer_->StartEventWithCustomTimeout( - CreateAbortCallback(&message_event_callbacks_), timeout); - message_event_callbacks_.Set(event_id, std::move(callback)); - TRACE_EVENT_WITH_FLOW0( - "ServiceWorker", - "ServiceWorkerGlobalScope::" - "DispatchExtendableMessageEventWithCustomTimeout", - TRACE_ID_WITH_SCOPE(kServiceWorkerGlobalScopeTraceScope, - TRACE_ID_LOCAL(event_id)), - TRACE_EVENT_FLAG_FLOW_OUT); - DispatchExtendableMessageEventInternal(event_id, std::move(event)); -} - void ServiceWorkerGlobalScope::DispatchFetchEventForMainResource( mojom::blink::DispatchFetchEventParamsPtr params, mojo::PendingRemote<mojom::blink::ServiceWorkerFetchResponseCallback> @@ -1893,6 +1928,20 @@ void ServiceWorkerGlobalScope::DispatchPaymentRequestEvent( PaymentRequestRespondWithObserver* respond_with_observer = PaymentRequestRespondWithObserver::Create(this, event_id, wait_until_observer); + + // Update respond_with_observer to check for required information specified in + // the event_data during response validation. + if (event_data->payment_options) { + respond_with_observer->set_should_have_payer_name( + event_data->payment_options->request_payer_name); + respond_with_observer->set_should_have_payer_email( + event_data->payment_options->request_payer_email); + respond_with_observer->set_should_have_payer_phone( + event_data->payment_options->request_payer_phone); + respond_with_observer->set_should_have_shipping_info( + event_data->payment_options->request_shipping); + } + mojo::PendingRemote<payments::mojom::blink::PaymentHandlerHost> payment_handler_host = std::move(event_data->payment_handler_host); Event* event = PaymentRequestEvent::Create( @@ -1907,8 +1956,7 @@ void ServiceWorkerGlobalScope::DispatchPaymentRequestEvent( } void ServiceWorkerGlobalScope::DispatchCookieChangeEvent( - const WebCanonicalCookie& cookie, - ::network::mojom::CookieChangeCause change_cause, + network::mojom::blink::CookieChangeInfoPtr change, DispatchCookieChangeEventCallback callback) { DCHECK(IsContextThread()); int event_id = timeout_timer_->StartEvent( @@ -1925,7 +1973,8 @@ void ServiceWorkerGlobalScope::DispatchCookieChangeEvent( HeapVector<Member<CookieListItem>> changed; HeapVector<Member<CookieListItem>> deleted; - CookieChangeEvent::ToEventInfo(cookie, change_cause, changed, deleted); + CookieChangeEvent::ToEventInfo(change->cookie, change->cause, changed, + deleted); Event* event = ExtendableCookieChangeEvent::Create( event_type_names::kCookiechange, std::move(changed), std::move(deleted), observer); @@ -1982,4 +2031,22 @@ void ServiceWorkerGlobalScope::AddMessageToConsole( /* column_number= */ 0))); } +void ServiceWorkerGlobalScope::NoteNewFetchEvent(const KURL& request_url) { + auto it = unresponded_fetch_event_counts_.find(request_url); + if (it == unresponded_fetch_event_counts_.end()) { + unresponded_fetch_event_counts_.insert(request_url, 1); + } else { + it->value += 1; + } +} + +void ServiceWorkerGlobalScope::NoteRespondedToFetchEvent( + const KURL& request_url) { + auto it = unresponded_fetch_event_counts_.find(request_url); + DCHECK_GE(it->value, 1); + it->value -= 1; + if (it->value == 0) + unresponded_fetch_event_counts_.erase(it); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h index daeae831872..a31bb47b710 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h @@ -38,16 +38,18 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" +#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink-forward.h" #include "third_party/blink/public/mojom/service_worker/controller_service_worker.mojom-blink.h" #include "third_party/blink/public/mojom/service_worker/service_worker.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h" #include "third_party/blink/renderer/core/workers/worker_global_scope.h" #include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/forward.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" namespace blink { @@ -59,6 +61,7 @@ class ScriptPromise; class ScriptState; class ServiceWorker; class ServiceWorkerClients; +class ServiceWorkerInstalledScriptsManager; class ServiceWorkerRegistration; class ServiceWorkerThread; class StringOrTrustedScriptURL; @@ -83,13 +86,16 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final static ServiceWorkerGlobalScope* Create( ServiceWorkerThread*, std::unique_ptr<GlobalScopeCreationParams>, + std::unique_ptr<ServiceWorkerInstalledScriptsManager>, mojo::PendingRemote<mojom::blink::CacheStorage>, base::TimeTicks time_origin); - ServiceWorkerGlobalScope(std::unique_ptr<GlobalScopeCreationParams>, - ServiceWorkerThread*, - mojo::PendingRemote<mojom::blink::CacheStorage>, - base::TimeTicks time_origin); + ServiceWorkerGlobalScope( + std::unique_ptr<GlobalScopeCreationParams>, + ServiceWorkerThread*, + std::unique_ptr<ServiceWorkerInstalledScriptsManager>, + mojo::PendingRemote<mojom::blink::CacheStorage>, + base::TimeTicks time_origin); ~ServiceWorkerGlobalScope() override; // ExecutionContext overrides: @@ -103,33 +109,20 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final const Vector<CSPHeaderAndType>& response_csp_headers, const Vector<String>* response_origin_trial_tokens, int64_t appcache_id) override; - // Fetches and runs the top-level classic worker script for the 'new' or - // 'update' service worker cases. + // Fetches and runs the top-level classic worker script. void FetchAndRunClassicScript( const KURL& script_url, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, const v8_inspector::V8StackTraceId& stack_id) override; - // Fetches and runs the top-level module worker script for the 'new' or - // 'update' service worker cases. + // Fetches and runs the top-level module worker script. void FetchAndRunModuleScript( const KURL& module_url_record, const FetchClientSettingsObjectSnapshot& outside_settings_object, WorkerResourceTimingNotifier& outside_resource_timing_notifier, network::mojom::CredentialsMode) override; void Dispose() override; - - // Runs the installed top-level classic worker script for the 'installed' - // service worker case. - void RunInstalledClassicScript(const KURL& script_url, - const v8_inspector::V8StackTraceId& stack_id); - - // Runs the installed top-level module worker script for the 'installed' - // service worker case. - void RunInstalledModuleScript( - const KURL& module_url_record, - const FetchClientSettingsObjectSnapshot& outside_settings_object, - network::mojom::CredentialsMode); + InstalledScriptsManager* GetInstalledScriptsManager() override; // Counts an evaluated script and its size. Called for the main worker script. void CountWorkerScript(size_t script_size, size_t cached_metadata_size); @@ -144,6 +137,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final // ServiceWorkerGlobalScope.idl ServiceWorkerClients* clients(); ServiceWorkerRegistration* registration(); + ::blink::ServiceWorker* serviceWorker(); ScriptPromise fetch(ScriptState*, const RequestInfo&, @@ -166,6 +160,12 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final int64_t encoded_data_length, int64_t encoded_body_length, int64_t decoded_body_length); + // Pauses the toplevel script evaluation until ResumeEvaluation is called. + // Must be called before InitializeGlobalScope(). + void PauseEvaluation(); + // Resumes the toplevel script evaluation. Must be called only after + // PauseEvaluation() is called. + void ResumeEvaluation(); // Creates a ServiceWorkerTimeoutTimer::StayAwakeToken to ensure that the idle // timer won't be triggered while any of these are alive. @@ -215,10 +215,12 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final // native fetch. void RespondToFetchEventWithNoResponse( int fetch_event_id, + const KURL& request_url, base::TimeTicks event_dispatch_time, base::TimeTicks respond_with_settled_time); // Responds to the fetch event with |response|. void RespondToFetchEvent(int fetch_event_id, + const KURL& request_url, mojom::blink::FetchAPIResponsePtr, base::TimeTicks event_dispatch_time, base::TimeTicks respond_with_settled_time); @@ -226,6 +228,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final // |body_as_stream|. void RespondToFetchEventWithResponseStream( int fetch_event_id, + const KURL& request_url, mojom::blink::FetchAPIResponsePtr, mojom::blink::ServiceWorkerStreamHandlePtr, base::TimeTicks event_dispatch_time, @@ -277,15 +280,6 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final mojom::blink::ServiceWorkerHost* GetServiceWorkerHost(); - // Called when a task is going to be scheduled on the service worker. - // The service worker shouldn't request to be terminated until the task is - // finished. Returns an id for the task. The caller must call DidEndTask() - // with the returned id to notify that the task is finished. - int WillStartTask(); - // Called when a task is finished. |task_id| must be a return value of - // WillStartTask(). - void DidEndTask(int task_id); - DEFINE_ATTRIBUTE_EVENT_LISTENER(install, kInstall) DEFINE_ATTRIBUTE_EVENT_LISTENER(activate, kActivate) DEFINE_ATTRIBUTE_EVENT_LISTENER(fetch, kFetch) @@ -293,6 +287,10 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final void Trace(blink::Visitor*) override; + // Returns true if a FetchEvent exists with the given request URL and + // is still waiting for a Response. + bool HasRelatedFetchEvent(const KURL& request_url) const; + protected: // EventTarget bool AddEventListenerInternal( @@ -300,6 +298,13 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final EventListener*, const AddEventListenerOptionsResolved*) override; + // WorkerGlobalScope + bool FetchClassicImportedScript( + const KURL& script_url, + KURL* out_response_url, + String* out_source_code, + std::unique_ptr<Vector<uint8_t>>* out_cached_meta_data) override; + private: void importScripts(const HeapVector<StringOrTrustedScriptURL>& urls, ExceptionState&) override; @@ -313,6 +318,11 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final void DidFetchClassicScript(WorkerClassicScriptLoader* classic_script_loader, const v8_inspector::V8StackTraceId& stack_id); + // Loads and runs the installed top-level classic worker script. + void LoadAndRunInstalledClassicScript( + const KURL& script_url, + const v8_inspector::V8StackTraceId& stack_id); + // https://w3c.github.io/ServiceWorker/#run-service-worker-algorithm void RunClassicScript(const KURL& response_url, network::mojom::ReferrerPolicy response_referrer_policy, @@ -371,6 +381,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final mojo::PendingAssociatedRemote<mojom::blink::ServiceWorkerHost> service_worker_host, mojom::blink::ServiceWorkerRegistrationObjectInfoPtr registration_info, + mojom::blink::ServiceWorkerObjectInfoPtr service_worker_info, mojom::blink::FetchHandlerExistence fetch_hander_existence) override; void DispatchInstallEvent(DispatchInstallEventCallback callback) override; void DispatchActivateEvent(DispatchActivateEventCallback callback) override; @@ -389,10 +400,6 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final void DispatchExtendableMessageEvent( mojom::blink::ExtendableMessageEventPtr event, DispatchExtendableMessageEventCallback callback) override; - void DispatchExtendableMessageEventWithCustomTimeout( - mojom::blink::ExtendableMessageEventPtr event, - base::TimeDelta timeout, - DispatchExtendableMessageEventCallback callback) override; void DispatchFetchEventForMainResource( mojom::blink::DispatchFetchEventParamsPtr params, mojo::PendingRemote<mojom::blink::ServiceWorkerFetchResponseCallback> @@ -440,8 +447,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final response_callback, DispatchPaymentRequestEventCallback callback) override; void DispatchCookieChangeEvent( - const WebCanonicalCookie& cookie, - ::network::mojom::blink::CookieChangeCause cause, + network::mojom::blink::CookieChangeInfoPtr change, DispatchCookieChangeEventCallback callback) override; void DispatchContentDeleteEvent( const String& id, @@ -451,8 +457,13 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final void AddMessageToConsole(mojom::blink::ConsoleMessageLevel, const String& message) override; + void NoteNewFetchEvent(const KURL& request_url); + void NoteRespondedToFetchEvent(const KURL& request_url); + Member<ServiceWorkerClients> clients_; Member<ServiceWorkerRegistration> registration_; + Member<::blink::ServiceWorker> service_worker_; + // Map from service worker version id to JavaScript ServiceWorker object in // current execution context. HeapHashMap<int64_t, @@ -469,6 +480,10 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final uint64_t cache_storage_installed_script_total_size_ = 0; uint64_t cache_storage_installed_script_metadata_total_size_ = 0; + // Non-null only when this service worker is already installed. + std::unique_ptr<ServiceWorkerInstalledScriptsManager> + installed_scripts_manager_; + // May be provided in the constructor as an optimization so InterfaceProvider // doesn't need to be used. Taken at the initial call to // ServiceWorkerGlobalScope#caches. @@ -532,10 +547,23 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final HeapHashMap<int, Member<FetchEvent>> pending_preload_fetch_events_; + // Track outstanding FetchEvent objects still waiting for a response by + // request URL. This information can be used as a hint that cache_storage + // or fetch requests to the same URL is likely to be used to satisfy a + // FetchEvent. This in turn can allow us to use more aggressive + // optimizations in these cases. + HashMap<KURL, int> unresponded_fetch_event_counts_; + // Timer triggered when the service worker considers it should be stopped or // an event should be aborted. std::unique_ptr<ServiceWorkerTimeoutTimer> timeout_timer_; + // InitializeGlobalScope() pauses the top level script evaluation when this + // flag is true. + bool pause_evaluation_ = false; + // ResumeEvaluation() evaluates the top level script when this flag is true. + bool global_scope_initialized_ = false; + // Connected by the ServiceWorkerProviderHost in the browser process and by // the controllees. |controller_bindings_| should be destroyed before // |timeout_timer_| since the pipe needs to be disconnected before callbacks diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.idl b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.idl index 88ad7c0cb5d..e76abe6f525 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.idl +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.idl @@ -37,6 +37,7 @@ readonly attribute Clients clients; readonly attribute ServiceWorkerRegistration registration; + readonly attribute ServiceWorker serviceWorker; [CallWith=ScriptState] Promise<void> skipWaiting(); diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc index 5e14386cff6..5ead861c27b 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc @@ -165,14 +165,6 @@ void ServiceWorkerGlobalScopeProxy::DidLoadClassicScript() { Client().WorkerScriptLoadedOnWorkerThread(); } -void ServiceWorkerGlobalScopeProxy::DidFailToLoadClassicScript() { - DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_); - // Tell ServiceWorkerContextClient about the failure. The generic - // WorkerContextFailedToStart() wouldn't make sense because - // WorkerContextStarted() was already called. - Client().FailedToLoadClassicScript(); -} - void ServiceWorkerGlobalScopeProxy::DidFetchScript() { DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_); Client().WorkerScriptLoadedOnWorkerThread(); @@ -180,7 +172,7 @@ void ServiceWorkerGlobalScopeProxy::DidFetchScript() { void ServiceWorkerGlobalScopeProxy::DidFailToFetchClassicScript() { DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_); - Client().FailedToLoadClassicScript(); + Client().FailedToFetchClassicScript(); } void ServiceWorkerGlobalScopeProxy::DidFailToFetchModuleScript() { @@ -324,6 +316,14 @@ bool ServiceWorkerGlobalScopeProxy::IsWindowInteractionAllowed() { return WorkerGlobalScope()->IsWindowInteractionAllowed(); } +void ServiceWorkerGlobalScopeProxy::PauseEvaluation() { + WorkerGlobalScope()->PauseEvaluation(); +} + +void ServiceWorkerGlobalScopeProxy::ResumeEvaluation() { + WorkerGlobalScope()->ResumeEvaluation(); +} + WebServiceWorkerContextClient& ServiceWorkerGlobalScopeProxy::Client() const { DCHECK(client_); return *client_; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h index e39df8ad6c1..981994b3fa3 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h @@ -91,6 +91,8 @@ class ServiceWorkerGlobalScopeProxy final : public WebServiceWorkerContextProxy, int64_t encoded_body_length, int64_t decoded_body_length) override; bool IsWindowInteractionAllowed() override; + void PauseEvaluation() override; + void ResumeEvaluation() override; // WorkerReportingProxy overrides: void CountFeature(WebFeature) override; @@ -105,7 +107,6 @@ class ServiceWorkerGlobalScopeProxy final : public WebServiceWorkerContextProxy, void WillInitializeWorkerContext() override; void DidCreateWorkerGlobalScope(WorkerOrWorkletGlobalScope*) override; void DidLoadClassicScript() override; - void DidFailToLoadClassicScript() override; void DidFetchScript() override; void DidFailToFetchClassicScript() override; void DidFailToFetchModuleScript() override; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc index c265bf8da3e..e4c2615fb09 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc @@ -9,7 +9,10 @@ #include "base/barrier_closure.h" #include "base/threading/thread_checker.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" +#include "third_party/blink/public/web/web_embedded_worker.h" #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_thread.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h" @@ -245,18 +248,33 @@ std::unique_ptr<TracedValue> UrlToTracedValue(const KURL& url) { } // namespace ServiceWorkerInstalledScriptsManager::ServiceWorkerInstalledScriptsManager( - const Vector<KURL>& installed_urls, - mojo::PendingReceiver<mojom::blink::ServiceWorkerInstalledScriptsManager> - manager_receiver, - mojo::PendingRemote<mojom::blink::ServiceWorkerInstalledScriptsManagerHost> - manager_host, + std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams> + installed_scripts_manager_params, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) - : script_container_(base::MakeRefCounted<ThreadSafeScriptContainer>()), - manager_host_(std::move(manager_host)) { - // We're on the main thread now, but |installed_urls_| will be accessed on the - // worker thread later, so make a deep copy of |url| as key. - for (const KURL& url : installed_urls) - installed_urls_.insert(url.Copy()); + : script_container_(base::MakeRefCounted<ThreadSafeScriptContainer>()) { + DCHECK(installed_scripts_manager_params); + + DCHECK(installed_scripts_manager_params->manager_receiver); + auto manager_receiver = + mojo::PendingReceiver<mojom::blink::ServiceWorkerInstalledScriptsManager>( + std::move(installed_scripts_manager_params->manager_receiver)); + + DCHECK(installed_scripts_manager_params->manager_host_remote); + manager_host_ = mojo::SharedRemote< + mojom::blink::ServiceWorkerInstalledScriptsManagerHost>( + mojo::PendingRemote< + mojom::blink::ServiceWorkerInstalledScriptsManagerHost>( + std::move(installed_scripts_manager_params->manager_host_remote), + mojom::blink::ServiceWorkerInstalledScriptsManagerHost::Version_)); + + // Don't touch |installed_urls_| after this point. We're on the initiator + // thread now, but |installed_urls_| will be accessed on the + // worker thread later, so they should keep isolated from the current thread. + for (const WebURL& url : + installed_scripts_manager_params->installed_scripts_urls) { + installed_urls_.insert(KURL(url).Copy()); + } + PostCrossThreadTask( *io_task_runner, FROM_HERE, CrossThreadBindOnce(&Internal::Create, script_container_, diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h index 91f9aeac710..3c7f8803746 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h @@ -5,8 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_INSTALLED_SCRIPTS_MANAGER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_SERVICE_WORKER_INSTALLED_SCRIPTS_MANAGER_H_ -#include "mojo/public/cpp/bindings/pending_receiver.h" -#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/shared_remote.h" #include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom-blink.h" #include "third_party/blink/renderer/core/workers/installed_scripts_manager.h" @@ -19,17 +17,16 @@ namespace blink { +struct WebServiceWorkerInstalledScriptsManagerParams; + // ServiceWorkerInstalledScriptsManager provides the main script and imported // scripts of an installed service worker. The scripts are streamed from the // browser process in parallel with worker thread initialization. -class MODULES_EXPORT ServiceWorkerInstalledScriptsManager +class MODULES_EXPORT ServiceWorkerInstalledScriptsManager final : public InstalledScriptsManager { public: ServiceWorkerInstalledScriptsManager( - const Vector<KURL>& installed_urls, - mojo::PendingReceiver<mojom::blink::ServiceWorkerInstalledScriptsManager>, - mojo::PendingRemote< - mojom::blink::ServiceWorkerInstalledScriptsManagerHost>, + std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); virtual ~ServiceWorkerInstalledScriptsManager() = default; @@ -43,7 +40,10 @@ class MODULES_EXPORT ServiceWorkerInstalledScriptsManager std::unique_ptr<ThreadSafeScriptContainer::RawScriptData> GetRawScriptData( const KURL& script_url); + // Constructed on the initiator thread, and accessed only on the worker + // thread. HashSet<KURL> installed_urls_; + scoped_refptr<ThreadSafeScriptContainer> script_container_; mojo::SharedRemote<mojom::blink::ServiceWorkerInstalledScriptsManagerHost> manager_host_; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc index 8f78882ba54..2e6ef8e49ee 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc @@ -11,6 +11,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/web/web_embedded_worker.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" @@ -140,11 +141,14 @@ class ServiceWorkerInstalledScriptsManagerTest : public testing::Test { void CreateInstalledScriptsManager( mojom::blink::ServiceWorkerInstalledScriptsInfoPtr installed_scripts_info) { + auto installed_scripts_manager_params = + std::make_unique<WebServiceWorkerInstalledScriptsManagerParams>( + std::move(installed_scripts_info->installed_urls), + installed_scripts_info->manager_receiver.PassPipe(), + installed_scripts_info->manager_host_remote.PassPipe()); installed_scripts_manager_ = std::make_unique<ServiceWorkerInstalledScriptsManager>( - std::move(installed_scripts_info->installed_urls), - std::move(installed_scripts_info->manager_receiver), - std::move(installed_scripts_info->manager_host_remote), + std::move(installed_scripts_manager_params), io_thread_->GetTaskRunner()); } diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.cc index 04d76da1954..6136ce36971 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.cc @@ -12,8 +12,8 @@ namespace blink { ServiceWorkerModuleTreeClient::ServiceWorkerModuleTreeClient( - Modulator* modulator) - : modulator_(modulator) {} + ScriptState* script_state) + : script_state_(script_state) {} // This client is used for both new and installed scripts. In the new scripts // case, this is a partial implementation of the custom "perform the fetch" hook @@ -23,9 +23,8 @@ ServiceWorkerModuleTreeClient::ServiceWorkerModuleTreeClient( // script resource. void ServiceWorkerModuleTreeClient::NotifyModuleTreeLoadFinished( ModuleScript* module_script) { - auto* execution_context = - ExecutionContext::From(modulator_->GetScriptState()); - auto* worker_global_scope = To<WorkerGlobalScope>(execution_context); + auto* worker_global_scope = + To<WorkerGlobalScope>(ExecutionContext::From(script_state_)); blink::WorkerReportingProxy& worker_reporting_proxy = worker_global_scope->ReportingProxy(); @@ -48,7 +47,7 @@ void ServiceWorkerModuleTreeClient::NotifyModuleTreeLoadFinished( } void ServiceWorkerModuleTreeClient::Trace(blink::Visitor* visitor) { - visitor->Trace(modulator_); + visitor->Trace(script_state_); ModuleTreeClient::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.h index e6cae49b147..94e2ec67e37 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_module_tree_client.h @@ -12,12 +12,13 @@ namespace blink { class ModuleScript; +class ScriptState; // This is an implementation of ModuleTreeClient for service workers that lives // on the worker context's thread. class ServiceWorkerModuleTreeClient final : public ModuleTreeClient { public: - explicit ServiceWorkerModuleTreeClient(Modulator*); + explicit ServiceWorkerModuleTreeClient(ScriptState*); // Implements ModuleTreeClient. void NotifyModuleTreeLoadFinished(ModuleScript*) final; @@ -25,7 +26,7 @@ class ServiceWorkerModuleTreeClient final : public ModuleTreeClient { void Trace(blink::Visitor*) override; private: - Member<Modulator> modulator_; + Member<ScriptState> script_state_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc index c33064b4337..c8f8a946500 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc @@ -32,16 +32,12 @@ #include <memory> -#include "third_party/blink/renderer/core/inspector/thread_debugger.h" #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h" #include "third_party/blink/renderer/core/workers/worker_backing_thread.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h" -#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" -#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" -#include "v8/include/v8-inspector.h" namespace blink { @@ -68,68 +64,16 @@ void ServiceWorkerThread::ClearWorkerBackingThread() { worker_backing_thread_ = nullptr; } -InstalledScriptsManager* ServiceWorkerThread::GetInstalledScriptsManager() { - return installed_scripts_manager_.get(); -} - void ServiceWorkerThread::TerminateForTesting() { global_scope_proxy_->TerminateWorkerContext(); WorkerThread::TerminateForTesting(); } -void ServiceWorkerThread::RunInstalledClassicScript( - const KURL& script_url, - const v8_inspector::V8StackTraceId& stack_id) { - // Use TaskType::kDOMManipulation for consistency with - // WorkerThread::EvaluateClassicScript(). - PostCrossThreadTask( - *GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE, - CrossThreadBindOnce( - &ServiceWorkerThread::RunInstalledClassicScriptOnWorkerThread, - CrossThreadUnretained(this), script_url, stack_id)); -} - -void ServiceWorkerThread::RunInstalledModuleScript( - const KURL& module_url_record, - std::unique_ptr<CrossThreadFetchClientSettingsObjectData> - outside_settings_object_data, - network::mojom::CredentialsMode credentials_mode) { - PostCrossThreadTask( - *GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE, - CrossThreadBindOnce( - &ServiceWorkerThread::RunInstalledModuleScriptOnWorkerThread, - CrossThreadUnretained(this), module_url_record, - WTF::Passed(std::move(outside_settings_object_data)), - credentials_mode)); -} - -void ServiceWorkerThread::RunInstalledClassicScriptOnWorkerThread( - const KURL& script_url, - const v8_inspector::V8StackTraceId& stack_id) { - DCHECK(IsCurrentThread()); - To<ServiceWorkerGlobalScope>(GlobalScope()) - ->RunInstalledClassicScript(script_url, stack_id); -} - -void ServiceWorkerThread::RunInstalledModuleScriptOnWorkerThread( - const KURL& module_url_record, - std::unique_ptr<CrossThreadFetchClientSettingsObjectData> - outside_settings_object, - network::mojom::CredentialsMode credentials_mode) { - DCHECK(IsCurrentThread()); - To<ServiceWorkerGlobalScope>(GlobalScope()) - ->RunInstalledModuleScript( - module_url_record, - *MakeGarbageCollected<FetchClientSettingsObjectSnapshot>( - std::move(outside_settings_object)), - credentials_mode); -} - WorkerOrWorkletGlobalScope* ServiceWorkerThread::CreateWorkerGlobalScope( std::unique_ptr<GlobalScopeCreationParams> creation_params) { - return ServiceWorkerGlobalScope::Create(this, std::move(creation_params), - std::move(cache_storage_remote_), - time_origin_); + return ServiceWorkerGlobalScope::Create( + this, std::move(creation_params), std::move(installed_scripts_manager_), + std::move(cache_storage_remote_), time_origin_); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h index 528e594a45b..9c5919c632e 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h @@ -32,7 +32,7 @@ #include <memory> #include "mojo/public/cpp/bindings/pending_remote.h" -#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h" +#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink-forward.h" #include "third_party/blink/renderer/core/workers/worker_thread.h" #include "third_party/blink/renderer/modules/modules_export.h" @@ -60,17 +60,8 @@ class MODULES_EXPORT ServiceWorkerThread final : public WorkerThread { return *worker_backing_thread_; } void ClearWorkerBackingThread() override; - InstalledScriptsManager* GetInstalledScriptsManager() override; void TerminateForTesting() override; - void RunInstalledClassicScript(const KURL& script_url, - const v8_inspector::V8StackTraceId& stack_id); - void RunInstalledModuleScript( - const KURL& module_url_record, - std::unique_ptr<CrossThreadFetchClientSettingsObjectData> - outside_settings_object_data, - network::mojom::CredentialsMode); - private: WorkerOrWorkletGlobalScope* CreateWorkerGlobalScope( std::unique_ptr<GlobalScopeCreationParams>) override; @@ -79,17 +70,10 @@ class MODULES_EXPORT ServiceWorkerThread final : public WorkerThread { return WebThreadType::kServiceWorkerThread; } - void RunInstalledClassicScriptOnWorkerThread( - const KURL& script_url, - const v8_inspector::V8StackTraceId& stack_id); - void RunInstalledModuleScriptOnWorkerThread( - const KURL& module_url_record, - std::unique_ptr<CrossThreadFetchClientSettingsObjectData> - outside_settings_object, - network::mojom::CredentialsMode); - std::unique_ptr<ServiceWorkerGlobalScopeProxy> global_scope_proxy_; std::unique_ptr<WorkerBackingThread> worker_backing_thread_; + + // Ownership of these members is moved out in CreateWorkerGlobalScope(). std::unique_ptr<ServiceWorkerInstalledScriptsManager> installed_scripts_manager_; mojo::PendingRemote<mojom::blink::CacheStorage> cache_storage_remote_; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer.cc index cd504d0d3ce..fb160277bc8 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer.cc @@ -9,6 +9,7 @@ #include "base/stl_util.h" #include "base/time/default_tick_clock.h" #include "base/time/time.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom-blink.h" #include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer.h index 257a1df5e48..3cad5e70a8a 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_timeout_timer.h @@ -11,7 +11,7 @@ #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "base/timer/timer.h" -#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom-blink.h" +#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/wtf/deque.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" diff --git a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h index 162abc3de8b..13a009afcd4 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h @@ -20,7 +20,7 @@ class ScriptValue; // Created for each ExtendableEvent instance. class MODULES_EXPORT WaitUntilObserver final - : public GarbageCollectedFinalized<WaitUntilObserver>, + : public GarbageCollected<WaitUntilObserver>, public ContextClient { USING_GARBAGE_COLLECTED_MIXIN(WaitUntilObserver); diff --git a/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc index 5841f33ba20..0b8b5fc56a4 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc @@ -18,7 +18,6 @@ #include "third_party/blink/public/common/messaging/message_port_channel.h" #include "third_party/blink/public/mojom/service_worker/controller_service_worker_mode.mojom-blink.h" #include "third_party/blink/public/mojom/service_worker/service_worker.mojom-blink.h" -#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom-blink.h" #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_content_settings_client.h" @@ -28,12 +27,11 @@ #include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h" #include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h" #include "third_party/blink/public/web/web_embedded_worker_start_data.h" -#include "third_party/blink/public/web/web_settings.h" -#include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h" -#include "third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_error.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h" +#include "third_party/blink/renderer/platform/testing/testing_platform_support.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/testing/url_test_helpers.h" @@ -127,7 +125,6 @@ class MockServiceWorkerContextClient final MOCK_METHOD2(WorkerReadyForInspectionOnInitiatorThread, void(mojo::ScopedMessagePipeHandle, mojo::ScopedMessagePipeHandle)); - MOCK_METHOD0(WorkerContextFailedToStartOnInitiatorThread, void()); void WorkerContextStarted(WebServiceWorkerContextProxy* proxy, scoped_refptr<base::SequencedTaskRunner>) override { @@ -142,6 +139,13 @@ class MockServiceWorkerContextClient final mojo::PendingAssociatedRemote<mojom::blink::ServiceWorkerRegistrationObject> registration_object; + mojo::PendingAssociatedRemote<mojom::blink::ServiceWorkerObjectHost> + service_worker_object_host; + auto service_worker_object_host_receiver = + service_worker_object_host.InitWithNewEndpointAndPassReceiver(); + mojo::PendingAssociatedRemote<mojom::blink::ServiceWorkerObject> + service_worker_object; + // Simulates calling blink.mojom.ServiceWorker.InitializeGlobalScope() to // unblock the service worker script evaluation. mojo::Remote<mojom::blink::ServiceWorker> service_worker; @@ -155,18 +159,22 @@ class MockServiceWorkerContextClient final std::move(registration_object_host), registration_object.InitWithNewEndpointAndPassReceiver(), nullptr, nullptr, nullptr), + mojom::blink::ServiceWorkerObjectInfo::New( + 1 /* service_worker_version_id */, + mojom::blink::ServiceWorkerState::kParsed, + KURL("https://example.com"), std::move(service_worker_object_host), + service_worker_object.InitWithNewEndpointAndPassReceiver()), mojom::blink::FetchHandlerExistence::EXISTS); // To make the other side callable. mojo::AssociateWithDisconnectedPipe(host_receiver.PassHandle()); mojo::AssociateWithDisconnectedPipe( registration_object_host_receiver.PassHandle()); + mojo::AssociateWithDisconnectedPipe( + service_worker_object_host_receiver.PassHandle()); } - void FailedToLoadClassicScript() override { - // off-main-script fetch: - // In production code, calling FailedToLoadClassicScript results in - // terminating the worker. + void FailedToFetchClassicScript() override { classic_script_load_failure_event_.Signal(); } @@ -194,130 +202,108 @@ class MockServiceWorkerContextClient final base::WaitableEvent classic_script_load_failure_event_; }; -class MockServiceWorkerInstalledScriptsManager - : public ServiceWorkerInstalledScriptsManager { - public: - MockServiceWorkerInstalledScriptsManager() - : ServiceWorkerInstalledScriptsManager( - Vector<KURL>() /* installed_urls */, - mojo::PendingReceiver< - mojom::blink::ServiceWorkerInstalledScriptsManager>( - mojo::MessagePipe().handle1), - mojo::PendingRemote< - mojom::blink::ServiceWorkerInstalledScriptsManagerHost>( - mojo::MessagePipe().handle0, - mojom::blink::ServiceWorkerInstalledScriptsManagerHost:: - Version_), - // Pass a temporary task runner to ensure - // ServiceWorkerInstalledScriptsManager construction succeeds. - Platform::Current() - ->CreateThread(ThreadCreationParams(WebThreadType::kTestThread) - .SetThreadNameForTest("io thread")) - ->GetTaskRunner()) {} - MOCK_CONST_METHOD1(IsScriptInstalled, bool(const KURL& script_url)); - MOCK_METHOD1(GetRawScriptData, - std::unique_ptr<ThreadSafeScriptContainer::RawScriptData>( - const KURL& script_url)); -}; - class WebEmbeddedWorkerImplTest : public testing::Test { protected: void SetUp() override { - auto installed_scripts_manager = - std::make_unique<MockServiceWorkerInstalledScriptsManager>(); - mock_installed_scripts_manager_ = installed_scripts_manager.get(); mock_client_ = std::make_unique<MockServiceWorkerContextClient>(); - worker_ = WebEmbeddedWorkerImpl::CreateForTesting( - mock_client_.get(), std::move(installed_scripts_manager)); + worker_ = std::make_unique<WebEmbeddedWorkerImpl>(mock_client_.get()); - WebURL script_url = - url_test_helpers::ToKURL("https://www.example.com/sw.js"); - WebURLResponse response(script_url); + script_url_ = url_test_helpers::ToKURL("https://www.example.com/sw.js"); + WebURLResponse response(script_url_); response.SetMimeType("text/javascript"); response.SetHttpStatusCode(200); - Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(script_url, - response, ""); + url_test_helpers::RegisterMockedURLLoadWithCustomResponse(script_url_, "", + response); + } - start_data_.script_url = script_url; - start_data_.user_agent = WebString("dummy user agent"); - start_data_.script_type = mojom::ScriptType::kClassic; - start_data_.wait_for_debugger_mode = + std::unique_ptr<WebEmbeddedWorkerStartData> CreateStartData() { + WebFetchClientSettingsObject outside_settings_object( + network::mojom::ReferrerPolicy::kDefault, + /*outgoing_referrer=*/WebURL(script_url_), + blink::mojom::InsecureRequestsPolicy::kDoNotUpgrade); + auto start_data = std::make_unique<WebEmbeddedWorkerStartData>( + std::move(outside_settings_object)); + start_data->script_url = script_url_; + start_data->user_agent = WebString("dummy user agent"); + start_data->script_type = mojom::ScriptType::kClassic; + start_data->wait_for_debugger_mode = WebEmbeddedWorkerStartData::kDontWaitForDebugger; - start_data_.v8_cache_options = WebSettings::V8CacheOptions::kDefault; + return start_data; } void TearDown() override { - Platform::Current() - ->GetURLLoaderMockFactory() - ->UnregisterAllURLsAndClearMemoryCache(); + // Drain queued tasks posted from the worker thread in order to avoid tasks + // bound with unretained objects from running after tear down. Worker + // termination may post such tasks (see https://crbug,com/1007616). + // TODO(nhiroki): Stop using synchronous WaitableEvent, and instead use + // QuitClosure to wait until all the tasks run before test completion. + test::RunPendingTasks(); + + url_test_helpers::UnregisterAllURLsAndClearMemoryCache(); } - WebEmbeddedWorkerStartData start_data_; + WebURL script_url_; std::unique_ptr<MockServiceWorkerContextClient> mock_client_; - MockServiceWorkerInstalledScriptsManager* mock_installed_scripts_manager_; std::unique_ptr<WebEmbeddedWorkerImpl> worker_; }; } // namespace TEST_F(WebEmbeddedWorkerImplTest, TerminateSoonAfterStart) { - worker_->StartWorkerContext(start_data_, Thread::Current()->GetTaskRunner()); + worker_->StartWorkerContext( + CreateStartData(), + /*installed_scripts_manager_params=*/nullptr, + /*content_settings_proxy=*/mojo::ScopedMessagePipeHandle(), + /*cache_storage_remote=*/mojo::ScopedMessagePipeHandle(), + /*interface_provider_info=*/mojo::ScopedMessagePipeHandle(), + /*browser_interface_broker=*/mojo::ScopedMessagePipeHandle(), + Thread::Current()->GetTaskRunner()); testing::Mock::VerifyAndClearExpectations(mock_client_.get()); + // Terminate the worker immediately after start. worker_->TerminateWorkerContext(); - // The worker thread was started. Wait for shutdown tasks to finish. worker_->WaitForShutdownForTesting(); } TEST_F(WebEmbeddedWorkerImplTest, TerminateWhileWaitingForDebugger) { - start_data_.wait_for_debugger_mode = + std::unique_ptr<WebEmbeddedWorkerStartData> start_data = CreateStartData(); + start_data->wait_for_debugger_mode = WebEmbeddedWorkerStartData::kWaitForDebugger; - worker_->StartWorkerContext(start_data_, Thread::Current()->GetTaskRunner()); + worker_->StartWorkerContext( + std::move(start_data), + /*installed_scripts_manager_params=*/nullptr, + /*content_settings_proxy=*/mojo::ScopedMessagePipeHandle(), + /*cache_storage_remote=*/mojo::ScopedMessagePipeHandle(), + /*interface_provider_info=*/mojo::ScopedMessagePipeHandle(), + /*browser_interface_broker=*/mojo::ScopedMessagePipeHandle(), + Thread::Current()->GetTaskRunner()); testing::Mock::VerifyAndClearExpectations(mock_client_.get()); + // Terminate the worker while waiting for the debugger. worker_->TerminateWorkerContext(); worker_->WaitForShutdownForTesting(); } -TEST_F(WebEmbeddedWorkerImplTest, TerminateWhileLoadingScript) { - // Load the shadow page. - EXPECT_CALL(*mock_installed_scripts_manager_, - IsScriptInstalled(KURL(start_data_.script_url))) - .Times(testing::AtLeast(1)) - .WillRepeatedly(testing::Return(false)); - worker_->StartWorkerContext(start_data_, Thread::Current()->GetTaskRunner()); - testing::Mock::VerifyAndClearExpectations(mock_client_.get()); - testing::Mock::VerifyAndClearExpectations(mock_installed_scripts_manager_); - - // Terminate before finishing the script load. - worker_->TerminateWorkerContext(); - // The worker thread was started. Wait for shutdown tasks to finish. - worker_->WaitForShutdownForTesting(); -} - TEST_F(WebEmbeddedWorkerImplTest, ScriptNotFound) { - // Load the shadow page. WebURL script_url = url_test_helpers::ToKURL(kNotFoundScriptURL); - WebURLResponse response; - response.SetMimeType("text/javascript"); - response.SetHttpStatusCode(404); - ResourceError error = ResourceError::Failure(script_url); - Platform::Current()->GetURLLoaderMockFactory()->RegisterErrorURL( - script_url, response, error); - start_data_.script_url = script_url; - EXPECT_CALL(*mock_installed_scripts_manager_, - IsScriptInstalled(KURL(start_data_.script_url))) - .Times(testing::AtLeast(1)) - .WillRepeatedly(testing::Return(false)); + url_test_helpers::RegisterMockedErrorURLLoad(script_url); + std::unique_ptr<WebEmbeddedWorkerStartData> start_data = CreateStartData(); + start_data->script_url = script_url; + // Start worker and load the script. - worker_->StartWorkerContext(start_data_, Thread::Current()->GetTaskRunner()); + worker_->StartWorkerContext( + std::move(start_data), + /*installed_scripts_manager_params=*/nullptr, + /*content_settings_proxy=*/mojo::ScopedMessagePipeHandle(), + /*cache_storage_remote=*/mojo::ScopedMessagePipeHandle(), + /*interface_provider_info=*/mojo::ScopedMessagePipeHandle(), + /*browser_interface_broker=*/mojo::ScopedMessagePipeHandle(), + Thread::Current()->GetTaskRunner()); testing::Mock::VerifyAndClearExpectations(mock_client_.get()); - testing::Mock::VerifyAndClearExpectations(mock_installed_scripts_manager_); mock_client_->WaitUntilFailedToLoadClassicScript(); - // The worker thread was started. Ask to shutdown and wait for shutdown - // tasks to finish. + // Terminate the worker for cleanup. worker_->TerminateWorkerContext(); worker_->WaitForShutdownForTesting(); } diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/DEPS b/chromium/third_party/blink/renderer/modules/shapedetection/DEPS index c1b5ad37a4f..7b205447533 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/DEPS +++ b/chromium/third_party/blink/renderer/modules/shapedetection/DEPS @@ -2,6 +2,7 @@ include_rules = [ "+services/shape_detection/public/mojom", "+services/service_manager/public/cpp", "+skia/public/mojom/bitmap.mojom-blink.h", + "+skia/public/mojom/bitmap.mojom-blink-forward.h", "-third_party/blink/renderer/modules", "+third_party/blink/renderer/modules/canvas/canvas2d", "+third_party/blink/renderer/modules/imagecapture/point_2d.h", diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc index 27c599799ad..46ad05e8bad 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc +++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc @@ -87,9 +87,9 @@ BarcodeDetector::BarcodeDetector(ExecutionContext* context, auto task_runner = context->GetTaskRunner(TaskType::kMiscPlatformAPI); BarcodeDetectorStatics::From(context)->CreateBarcodeDetection( - mojo::MakeRequest(&service_, task_runner), + service_.BindNewPipeAndPassReceiver(task_runner), std::move(barcode_detector_options)); - service_.set_connection_error_handler( + service_.set_disconnect_handler( WTF::Bind(&BarcodeDetector::OnConnectionError, WrapWeakPersistent(this))); } diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h index 775a513cf22..98a324a2e88 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h +++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_BARCODE_DETECTOR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_BARCODE_DETECTOR_H_ +#include "mojo/public/cpp/bindings/remote.h" #include "services/shape_detection/public/mojom/barcodedetection.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -44,7 +45,7 @@ class MODULES_EXPORT BarcodeDetector final : public ShapeDetector { void OnConnectionError(); - shape_detection::mojom::blink::BarcodeDetectionPtr service_; + mojo::Remote<shape_detection::mojom::blink::BarcodeDetection> service_; HeapHashSet<Member<ScriptPromiseResolver>> detect_requests_; }; diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc index a2f366142c5..4ec76fed03b 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc +++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" @@ -34,10 +34,11 @@ BarcodeDetectorStatics::BarcodeDetectorStatics(ExecutionContext& document) BarcodeDetectorStatics::~BarcodeDetectorStatics() = default; void BarcodeDetectorStatics::CreateBarcodeDetection( - shape_detection::mojom::blink::BarcodeDetectionRequest request, + mojo::PendingReceiver<shape_detection::mojom::blink::BarcodeDetection> + receiver, shape_detection::mojom::blink::BarcodeDetectorOptionsPtr options) { EnsureServiceConnection(); - service_->CreateBarcodeDetection(std::move(request), std::move(options)); + service_->CreateBarcodeDetection(std::move(receiver), std::move(options)); } ScriptPromise BarcodeDetectorStatics::EnumerateSupportedFormats( @@ -65,9 +66,9 @@ void BarcodeDetectorStatics::EnsureServiceConnection() { // See https://bit.ly/2S0zRAS for task types. auto task_runner = context->GetTaskRunner(TaskType::kMiscPlatformAPI); - auto request = mojo::MakeRequest(&service_, task_runner); - context->GetInterfaceProvider()->GetInterface(std::move(request)); - service_.set_connection_error_handler(WTF::Bind( + context->GetBrowserInterfaceBroker().GetInterface( + service_.BindNewPipeAndPassReceiver(task_runner)); + service_.set_disconnect_handler(WTF::Bind( &BarcodeDetectorStatics::OnConnectionError, WrapWeakPersistent(this))); } diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h index 0689a11fcb8..fc94f081c17 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h +++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector_statics.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_BARCODE_DETECTOR_STATICS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_BARCODE_DETECTOR_STATICS_H_ +#include "mojo/public/cpp/bindings/remote.h" #include "services/shape_detection/public/mojom/barcodedetection_provider.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -20,7 +21,7 @@ class ScriptPromiseResolver; // This class owns the BarcodeDetectionProvider connection used to create the // BarcodeDetector instances for this ExecutionContext. class BarcodeDetectorStatics final - : public GarbageCollectedFinalized<BarcodeDetectorStatics>, + : public GarbageCollected<BarcodeDetectorStatics>, public Supplement<ExecutionContext> { USING_GARBAGE_COLLECTED_MIXIN(BarcodeDetectorStatics); @@ -33,7 +34,7 @@ class BarcodeDetectorStatics final ~BarcodeDetectorStatics(); void CreateBarcodeDetection( - shape_detection::mojom::blink::BarcodeDetectionRequest, + mojo::PendingReceiver<shape_detection::mojom::blink::BarcodeDetection>, shape_detection::mojom::blink::BarcodeDetectorOptionsPtr); ScriptPromise EnumerateSupportedFormats(ScriptState*); @@ -46,7 +47,8 @@ class BarcodeDetectorStatics final const Vector<shape_detection::mojom::blink::BarcodeFormat>&); void OnConnectionError(); - shape_detection::mojom::blink::BarcodeDetectionProviderPtr service_; + mojo::Remote<shape_detection::mojom::blink::BarcodeDetectionProvider> + service_; // Holds Promises returned by EnumerateSupportedFormats() so that they can be // resolve in the case of a Mojo connection error. diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc index a0a130d890c..6577edc0000 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc +++ b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc @@ -6,8 +6,8 @@ #include <utility> -#include "services/service_manager/public/cpp/interface_provider.h" #include "services/shape_detection/public/mojom/facedetection_provider.mojom-blink.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -37,17 +37,17 @@ FaceDetector::FaceDetector(ExecutionContext* context, face_detector_options->max_detected_faces = options->maxDetectedFaces(); face_detector_options->fast_mode = options->fastMode(); - shape_detection::mojom::blink::FaceDetectionProviderPtr provider; + mojo::Remote<shape_detection::mojom::blink::FaceDetectionProvider> provider; // See https://bit.ly/2S0zRAS for task types. auto task_runner = context->GetTaskRunner(TaskType::kMiscPlatformAPI); - auto request = mojo::MakeRequest(&provider, task_runner); - if (auto* interface_provider = context->GetInterfaceProvider()) { - interface_provider->GetInterface(std::move(request)); - } - provider->CreateFaceDetection(mojo::MakeRequest(&face_service_, task_runner), - std::move(face_detector_options)); + context->GetBrowserInterfaceBroker().GetInterface( + provider.BindNewPipeAndPassReceiver(task_runner)); + + provider->CreateFaceDetection( + face_service_.BindNewPipeAndPassReceiver(task_runner), + std::move(face_detector_options)); - face_service_.set_connection_error_handler(WTF::Bind( + face_service_.set_disconnect_handler(WTF::Bind( &FaceDetector::OnFaceServiceConnectionError, WrapWeakPersistent(this))); } diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h index 86537084d01..7c5bb6b07f3 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h +++ b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_FACE_DETECTOR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_FACE_DETECTOR_H_ +#include "mojo/public/cpp/bindings/remote.h" #include "services/shape_detection/public/mojom/facedetection.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -36,7 +37,7 @@ class MODULES_EXPORT FaceDetector final : public ShapeDetector { Vector<shape_detection::mojom::blink::FaceDetectionResultPtr>); void OnFaceServiceConnectionError(); - shape_detection::mojom::blink::FaceDetectionPtr face_service_; + mojo::Remote<shape_detection::mojom::blink::FaceDetection> face_service_; HeapHashSet<Member<ScriptPromiseResolver>> face_service_requests_; }; diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/shape_detection_type_converter.h b/chromium/third_party/blink/renderer/modules/shapedetection/shape_detection_type_converter.h index 9fa35082f54..91fc95f6c6d 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/shape_detection_type_converter.h +++ b/chromium/third_party/blink/renderer/modules/shapedetection/shape_detection_type_converter.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_SHAPE_DETECTION_TYPE_CONVERTER_H_ #include "mojo/public/cpp/bindings/type_converter.h" -#include "services/shape_detection/public/mojom/facedetection.mojom-blink.h" +#include "services/shape_detection/public/mojom/facedetection.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace mojo { diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.h b/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.h index bb7e075111b..f1ed766b476 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.h +++ b/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_SHAPE_DETECTOR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_SHAPE_DETECTOR_H_ -#include "skia/public/mojom/bitmap.mojom-blink.h" +#include "skia/public/mojom/bitmap.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/frame/window_or_worker_global_scope.h" diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc index 0db9dc33c66..8c01af260ce 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc +++ b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc @@ -6,7 +6,7 @@ #include <utility> -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/geometry/dom_rect.h" @@ -25,12 +25,10 @@ TextDetector* TextDetector::Create(ExecutionContext* context) { TextDetector::TextDetector(ExecutionContext* context) : ShapeDetector() { // See https://bit.ly/2S0zRAS for task types. auto task_runner = context->GetTaskRunner(TaskType::kMiscPlatformAPI); - auto request = mojo::MakeRequest(&text_service_, task_runner); - if (auto* interface_provider = context->GetInterfaceProvider()) { - interface_provider->GetInterface(std::move(request)); - } + context->GetBrowserInterfaceBroker().GetInterface( + text_service_.BindNewPipeAndPassReceiver(task_runner)); - text_service_.set_connection_error_handler(WTF::Bind( + text_service_.set_disconnect_handler(WTF::Bind( &TextDetector::OnTextServiceConnectionError, WrapWeakPersistent(this))); } diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h index 89136af5626..48e06aff0f3 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h +++ b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_TEXT_DETECTOR_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SHAPEDETECTION_TEXT_DETECTOR_H_ +#include "mojo/public/cpp/bindings/remote.h" #include "services/shape_detection/public/mojom/textdetection.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -35,7 +36,7 @@ class MODULES_EXPORT TextDetector final : public ShapeDetector { Vector<shape_detection::mojom::blink::TextDetectionResultPtr>); void OnTextServiceConnectionError(); - shape_detection::mojom::blink::TextDetectionPtr text_service_; + mojo::Remote<shape_detection::mojom::blink::TextDetection> text_service_; HeapHashSet<Member<ScriptPromiseResolver>> text_service_requests_; }; diff --git a/chromium/third_party/blink/renderer/modules/sms/sms_receiver.cc b/chromium/third_party/blink/renderer/modules/sms/sms_receiver.cc index be89fae5847..127220a175a 100644 --- a/chromium/third_party/blink/renderer/modules/sms/sms_receiver.cc +++ b/chromium/third_party/blink/renderer/modules/sms/sms_receiver.cc @@ -6,7 +6,7 @@ #include "third_party/blink/renderer/modules/sms/sms_receiver.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/sms/sms_receiver.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -46,7 +46,7 @@ ScriptPromise SMSReceiver::receive(ScriptState* script_state, GetExecutionContext()->GetTaskRunner(TaskType::kInternalIPC); if (!service_) { - GetExecutionContext()->GetInterfaceProvider()->GetInterface( + GetExecutionContext()->GetBrowserInterfaceBroker().GetInterface( service_.BindNewPipeAndPassReceiver(task_runner)); service_.set_disconnect_handler(WTF::Bind( &SMSReceiver::OnSMSReceiverConnectionError, WrapWeakPersistent(this))); diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc index 9b6db1d2104..ea507a2a1a4 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc @@ -27,6 +27,8 @@ #include <algorithm> #include "build/build_config.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/modules/speech/speech_recognition_controller.h" @@ -56,18 +58,15 @@ void SpeechRecognition::start(ExceptionState& exception_state) { // See https://bit.ly/2S0zRAS for task types. scoped_refptr<base::SingleThreadTaskRunner> task_runner = GetExecutionContext()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI); - mojom::blink::SpeechRecognitionSessionClientPtrInfo session_client; - binding_.Bind(mojo::MakeRequest(&session_client), - GetExecutionContext()->GetInterfaceInvalidator(), task_runner); - binding_.set_connection_error_handler(WTF::Bind( + mojo::PendingRemote<mojom::blink::SpeechRecognitionSessionClient> + session_client; + receiver_.Bind(session_client.InitWithNewPipeAndPassReceiver(), task_runner); + receiver_.set_disconnect_handler(WTF::Bind( &SpeechRecognition::OnConnectionError, WrapWeakPersistent(this))); - mojom::blink::SpeechRecognitionSessionRequest session_request = - MakeRequest(&session_, GetExecutionContext()->GetInterfaceInvalidator()); - - controller_->Start(std::move(session_request), std::move(session_client), - *grammars_, lang_, continuous_, interim_results_, - max_alternatives_); + controller_->Start(session_.BindNewPipeAndPassReceiver(), + std::move(session_client), *grammars_, lang_, continuous_, + interim_results_, max_alternatives_); started_ = true; } @@ -171,7 +170,7 @@ void SpeechRecognition::Ended() { started_ = false; stopping_ = false; session_.reset(); - binding_.Close(); + receiver_.reset(); DispatchEvent(*Event::Create(event_type_names::kEnd)); } @@ -185,6 +184,8 @@ ExecutionContext* SpeechRecognition::GetExecutionContext() const { void SpeechRecognition::ContextDestroyed(ExecutionContext*) { controller_ = nullptr; + receiver_.reset(); + session_.reset(); } bool SpeechRecognition::HasPendingActivity() const { @@ -218,7 +219,7 @@ SpeechRecognition::SpeechRecognition(LocalFrame* frame, controller_(SpeechRecognitionController::From(frame)), started_(false), stopping_(false), - binding_(this) {} + receiver_(this) {} SpeechRecognition::~SpeechRecognition() = default; diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h index fb936e1ec48..a849c046819 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h @@ -26,6 +26,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_H_ +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/speech/speech_recognizer.mojom-blink.h" #include "third_party/blink/public/platform/web_private_ptr.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" @@ -36,8 +38,6 @@ #include "third_party/blink/renderer/modules/speech/speech_grammar_list.h" #include "third_party/blink/renderer/modules/speech/speech_recognition_result.h" #include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/mojo/revocable_binding.h" -#include "third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -135,8 +135,8 @@ class MODULES_EXPORT SpeechRecognition final bool started_; bool stopping_; HeapVector<Member<SpeechRecognitionResult>> final_results_; - RevocableBinding<mojom::blink::SpeechRecognitionSessionClient> binding_; - RevocableInterfacePtr<mojom::blink::SpeechRecognitionSession> session_; + mojo::Receiver<mojom::blink::SpeechRecognitionSessionClient> receiver_; + mojo::Remote<mojom::blink::SpeechRecognitionSession> session_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc index bdeacd02c7d..e228072ef86 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.cc @@ -27,7 +27,7 @@ #include <memory> -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/modules/speech/speech_grammar_list.h" #include "third_party/blink/renderer/modules/speech/speech_recognition.h" @@ -50,8 +50,10 @@ SpeechRecognitionController* SpeechRecognitionController::Create( } void SpeechRecognitionController::Start( - mojom::blink::SpeechRecognitionSessionRequest session_request, - mojom::blink::SpeechRecognitionSessionClientPtrInfo session_client, + mojo::PendingReceiver<mojom::blink::SpeechRecognitionSession> + session_receiver, + mojo::PendingRemote<mojom::blink::SpeechRecognitionSessionClient> + session_client, const SpeechGrammarList& grammars, const String& lang, bool continuous, @@ -70,7 +72,7 @@ void SpeechRecognitionController::Start( msg_params->interim_results = interim_results; msg_params->origin = GetSupplementable()->GetDocument()->GetSecurityOrigin(); msg_params->client = std::move(session_client); - msg_params->session_request = std::move(session_request); + msg_params->session_receiver = std::move(session_receiver); GetSpeechRecognizer()->Start(std::move(msg_params)); } @@ -83,7 +85,7 @@ void ProvideSpeechRecognitionTo(LocalFrame& frame) { mojo::Remote<mojom::blink::SpeechRecognizer>& SpeechRecognitionController::GetSpeechRecognizer() { if (!speech_recognizer_) { - GetSupplementable()->GetInterfaceProvider().GetInterface( + GetSupplementable()->GetBrowserInterfaceBroker().GetInterface( speech_recognizer_.BindNewPipeAndPassReceiver()); } return speech_recognizer_; diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h index 0e8cd808298..1c3c658e95d 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_controller.h @@ -28,6 +28,8 @@ #include <memory> +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/speech/speech_recognizer.mojom-blink.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -38,7 +40,7 @@ namespace blink { class SpeechGrammarList; class SpeechRecognitionController final - : public GarbageCollectedFinalized<SpeechRecognitionController>, + : public GarbageCollected<SpeechRecognitionController>, public Supplement<LocalFrame> { USING_GARBAGE_COLLECTED_MIXIN(SpeechRecognitionController); @@ -48,8 +50,10 @@ class SpeechRecognitionController final explicit SpeechRecognitionController(LocalFrame& frame); virtual ~SpeechRecognitionController(); - void Start(mojom::blink::SpeechRecognitionSessionRequest session_request, - mojom::blink::SpeechRecognitionSessionClientPtrInfo session_client, + void Start(mojo::PendingReceiver<mojom::blink::SpeechRecognitionSession> + session_receiver, + mojo::PendingRemote<mojom::blink::SpeechRecognitionSessionClient> + session_client, const SpeechGrammarList& grammars, const String& lang, bool continuous, diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.cc index b6af5b34492..923f679cb9a 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.cc +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.cc @@ -25,6 +25,7 @@ #include "third_party/blink/renderer/modules/speech/speech_recognition_error_event.h" +#include "third_party/blink/public/mojom/speech/speech_recognition_error_code.mojom-blink.h" #include "third_party/blink/renderer/core/event_type_names.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.h index b2a4bfc59b4..a8f68f994f7 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.h +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_error_event.h @@ -26,7 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_ERROR_EVENT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_RECOGNITION_ERROR_EVENT_H_ -#include "third_party/blink/public/mojom/speech/speech_recognition_error_code.mojom-blink.h" +#include "third_party/blink/public/mojom/speech/speech_recognition_error_code.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/event_modules.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/speech/speech_recognition_error_event_init.h" diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h index 881c00103a0..576818ba299 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h +++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h @@ -28,7 +28,7 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/mojom/speech/speech_synthesis.mojom-blink.h" +#include "third_party/blink/public/mojom/speech/speech_synthesis.mojom-blink-forward.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/modules/event_target_modules.h" #include "third_party/blink/renderer/modules/modules_export.h" diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h index 095a437502a..763545898bf 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h +++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.h @@ -27,7 +27,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_SPEECH_SYNTHESIS_UTTERANCE_H_ #include "mojo/public/cpp/bindings/receiver.h" -#include "third_party/blink/public/mojom/speech/speech_synthesis.mojom-blink.h" +#include "third_party/blink/public/mojom/speech/speech_synthesis.mojom-blink-forward.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/modules/event_target_modules.h" #include "third_party/blink/renderer/modules/speech/speech_synthesis_voice.h" diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h index d8091d631e0..3e04a018e3e 100644 --- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h +++ b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h @@ -31,7 +31,7 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/dom_storage/session_storage_namespace.mojom-blink.h" -#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom-blink.h" +#include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom-blink-forward.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/storage/cached_storage_area.h" @@ -65,7 +65,7 @@ class WebViewClient; // The StorageNamespace for SessioStorage supplement the Page. |GetCachedArea| // is used to get the storage area for an origin. class MODULES_EXPORT StorageNamespace final - : public GarbageCollectedFinalized<StorageNamespace>, + : public GarbageCollected<StorageNamespace>, public Supplement<Page>, public CachedStorageArea::InspectorEventListener { USING_GARBAGE_COLLECTED_MIXIN(StorageNamespace); diff --git a/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h b/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h index 3dd94dd97d5..9d57e679df2 100644 --- a/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h +++ b/chromium/third_party/blink/renderer/modules/storage/testing/fake_area_source.h @@ -11,7 +11,7 @@ namespace blink { -class FakeAreaSource : public GarbageCollectedFinalized<FakeAreaSource>, +class FakeAreaSource : public GarbageCollected<FakeAreaSource>, public CachedStorageArea::Source { USING_GARBAGE_COLLECTED_MIXIN(FakeAreaSource); diff --git a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h index 4c2fad06174..c478a282200 100644 --- a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h +++ b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h @@ -46,7 +46,7 @@ enum NavigatorVibrationType { }; class MODULES_EXPORT NavigatorVibration final - : public GarbageCollectedFinalized<NavigatorVibration>, + : public GarbageCollected<NavigatorVibration>, public Supplement<Navigator>, public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(NavigatorVibration); diff --git a/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc b/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc index ca05aba2bd1..c42f2033249 100644 --- a/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc +++ b/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc @@ -19,7 +19,7 @@ #include "third_party/blink/renderer/modules/vibration/vibration_controller.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_or_unsigned_long_sequence.h" @@ -85,8 +85,8 @@ VibrationController::VibrationController(LocalFrame& frame) is_running_(false), is_calling_cancel_(false), is_calling_vibrate_(false) { - frame.GetInterfaceProvider().GetInterface( - mojo::MakeRequest(&vibration_manager_)); + frame.GetBrowserInterfaceBroker().GetInterface( + vibration_manager_.BindNewPipeAndPassReceiver()); } VibrationController::~VibrationController() = default; diff --git a/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h b/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h index 613f45e4a80..3e4153725b0 100644 --- a/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h +++ b/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h @@ -21,6 +21,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_VIBRATION_VIBRATION_CONTROLLER_H_ #include "base/macros.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/device/public/mojom/vibration_manager.mojom-blink.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/page/page_visibility_observer.h" @@ -36,7 +37,7 @@ class LocalFrame; class UnsignedLongOrUnsignedLongSequence; class MODULES_EXPORT VibrationController final - : public GarbageCollectedFinalized<VibrationController>, + : public GarbageCollected<VibrationController>, public ContextLifecycleObserver, public PageVisibilityObserver { USING_GARBAGE_COLLECTED_MIXIN(VibrationController); @@ -73,9 +74,9 @@ class MODULES_EXPORT VibrationController final // Inherited from PageVisibilityObserver. void PageVisibilityChanged() override; - // Ptr to VibrationManager mojo interface. This is reset in |contextDestroyed| - // and must not be called or recreated after it is reset. - device::mojom::blink::VibrationManagerPtr vibration_manager_; + // Remote to VibrationManager mojo interface. This is reset in + // |contextDestroyed| and must not be called or recreated after it is reset. + mojo::Remote<device::mojom::blink::VibrationManager> vibration_manager_; // Timer for calling |doVibrate| after a delay. It is safe to call // |startOneshot| when the timer is already running: it may affect the time diff --git a/chromium/third_party/blink/renderer/modules/vr/DEPS b/chromium/third_party/blink/renderer/modules/vr/DEPS index fb7ece351e6..4ba629d6702 100644 --- a/chromium/third_party/blink/renderer/modules/vr/DEPS +++ b/chromium/third_party/blink/renderer/modules/vr/DEPS @@ -1,6 +1,7 @@ include_rules = [ "+mojo/public/cpp/bindings/binding.h", "+device/vr/public/mojom/vr_service.mojom-blink.h", + "+device/vr/public/mojom/vr_service.mojom-blink-forward.h", "+gpu/command_buffer/client/gles2_interface.h", "+ui/gfx/geometry", "+services/metrics/public/cpp/ukm_builders.h" diff --git a/chromium/third_party/blink/renderer/modules/vr/navigator_vr.h b/chromium/third_party/blink/renderer/modules/vr/navigator_vr.h index 7f7922274f5..29f360281f7 100644 --- a/chromium/third_party/blink/renderer/modules/vr/navigator_vr.h +++ b/chromium/third_party/blink/renderer/modules/vr/navigator_vr.h @@ -21,7 +21,7 @@ class Document; class VRController; class MODULES_EXPORT NavigatorVR final - : public GarbageCollectedFinalized<NavigatorVR>, + : public GarbageCollected<NavigatorVR>, public Supplement<Navigator>, public LocalDOMWindow::EventListenerObserver, public FocusChangedObserver { diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_controller.cc b/chromium/third_party/blink/renderer/modules/vr/vr_controller.cc index 139896ffc8f..fb555e7d41f 100644 --- a/chromium/third_party/blink/renderer/modules/vr/vr_controller.cc +++ b/chromium/third_party/blink/renderer/modules/vr/vr_controller.cc @@ -7,7 +7,7 @@ #include "device/vr/public/mojom/vr_service.mojom-blink.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "services/metrics/public/cpp/ukm_builders.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -27,7 +27,7 @@ VRController::VRController(NavigatorVR* navigator_vr) // See https://bit.ly/2S0zRAS for task types. scoped_refptr<base::SingleThreadTaskRunner> task_runner = navigator_vr->GetDocument()->GetTaskRunner(TaskType::kMiscPlatformAPI); - navigator_vr->GetDocument()->GetFrame()->GetInterfaceProvider().GetInterface( + navigator_vr->GetDocument()->GetBrowserInterfaceBroker().GetInterface( service_.BindNewPipeAndPassReceiver(task_runner)); service_.set_disconnect_handler( WTF::Bind(&VRController::Dispose, WrapWeakPersistent(this))); diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_controller.h b/chromium/third_party/blink/renderer/modules/vr/vr_controller.h index 68888f53684..11403461fe3 100644 --- a/chromium/third_party/blink/renderer/modules/vr/vr_controller.h +++ b/chromium/third_party/blink/renderer/modules/vr/vr_controller.h @@ -8,7 +8,7 @@ #include <memory> #include "base/macros.h" -#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -22,7 +22,7 @@ namespace blink { class NavigatorVR; -class VRController final : public GarbageCollectedFinalized<VRController>, +class VRController final : public GarbageCollected<VRController>, public device::mojom::blink::VRServiceClient, public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(VRController); diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_display.cc b/chromium/third_party/blink/renderer/modules/vr/vr_display.cc index c6bc369fc5e..81b28bd5488 100644 --- a/chromium/third_party/blink/renderer/modules/vr/vr_display.cc +++ b/chromium/third_party/blink/renderer/modules/vr/vr_display.cc @@ -124,11 +124,19 @@ void SessionClientBinding::OnChanged( void SessionClientBinding::OnExitPresent() { display_->OnExitPresent(is_immersive_); } -void SessionClientBinding::OnBlur() { - display_->OnBlur(is_immersive_); -} -void SessionClientBinding::OnFocus() { - display_->OnFocus(is_immersive_); +void SessionClientBinding::OnVisibilityStateChanged( + device::mojom::blink::XRVisibilityState visibility_state) { + switch (visibility_state) { + case device::mojom::blink::XRVisibilityState::VISIBLE: + display_->OnFocus(is_immersive_); + break; + case device::mojom::blink::XRVisibilityState::VISIBLE_BLURRED: + display_->OnBlur(is_immersive_); + break; + case device::mojom::blink::XRVisibilityState::HIDDEN: + display_->OnBlur(is_immersive_); + break; + } } void SessionClientBinding::Trace(blink::Visitor* visitor) { visitor->Trace(display_); @@ -557,18 +565,18 @@ void VRDisplay::OnRequestImmersiveSessionReturned( // The presentation provider error handler can trigger if a device is // disconnected from the system. This can happen if, for example, an HMD is // unplugged. - vr_presentation_data_provider_.set_connection_error_handler( + vr_presentation_data_provider_.set_disconnect_handler( WTF::Bind(&VRDisplay::OnPresentationProviderConnectionError, WrapWeakPersistent(this))); vr_presentation_provider_.Bind( std::move(session->submit_frame_sink->provider)); - vr_presentation_provider_.set_connection_error_handler( + vr_presentation_provider_.set_disconnect_handler( WTF::Bind(&VRDisplay::OnPresentationProviderConnectionError, WrapWeakPersistent(this))); frame_transport_ = MakeGarbageCollected<XRFrameTransport>(); frame_transport_->BindSubmitFrameClient( - std::move(session->submit_frame_sink->client_request)); + std::move(session->submit_frame_sink->client_receiver)); frame_transport_->SetTransportOptions( std::move(session->submit_frame_sink->transport_options)); @@ -576,7 +584,7 @@ void VRDisplay::OnRequestImmersiveSessionReturned( immersive_client_binding_->Close(); immersive_client_binding_ = MakeGarbageCollected<SessionClientBinding>( this, SessionClientBinding::SessionBindingType::kImmersive, - std::move(session->client_request)); + std::move(session->client_receiver)); Update(std::move(session->display_info)); @@ -605,7 +613,7 @@ void VRDisplay::SetNonImmersiveSession( non_immersive_provider_.Bind(std::move(session->data_provider)); non_immersive_client_binding_ = MakeGarbageCollected<SessionClientBinding>( this, SessionClientBinding::SessionBindingType::kNonImmersive, - std::move(session->client_request)); + std::move(session->client_receiver)); } // Now that we're initialized, we need to ensure that the data is flowing diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_display.h b/chromium/third_party/blink/renderer/modules/vr/vr_display.h index b03e6b39360..c438fc4cb91 100644 --- a/chromium/third_party/blink/renderer/modules/vr/vr_display.h +++ b/chromium/third_party/blink/renderer/modules/vr/vr_display.h @@ -8,8 +8,9 @@ #include <memory> #include <utility> -#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/v8_frame_request_callback.h" @@ -45,9 +46,8 @@ class WebGLRenderingContextBase; // Wrapper class to allow the VRDisplay to distinguish between immersive and // non-immersive XRSession events. -class SessionClientBinding - : public GarbageCollectedFinalized<SessionClientBinding>, - public device::mojom::blink::XRSessionClient { +class SessionClientBinding : public GarbageCollected<SessionClientBinding>, + public device::mojom::blink::XRSessionClient { public: enum class SessionBindingType { kImmersive = 0, @@ -66,8 +66,8 @@ class SessionClientBinding private: void OnChanged(device::mojom::blink::VRDisplayInfoPtr) override; void OnExitPresent() override; - void OnBlur() override; - void OnFocus() override; + void OnVisibilityStateChanged( + device::mojom::blink::XRVisibilityState) override; // VRDisplay keeps all references to SessionClientBinding, so as soon as // VRDisplay is destroyed, so is the SessionClientBinding. @@ -262,7 +262,8 @@ class VRDisplay final : public EventTargetWithInlineData, bool did_log_requestPresent_ = false; bool non_immersive_session_initialized_ = false; - device::mojom::blink::XRFrameDataProviderPtr non_immersive_provider_; + mojo::Remote<device::mojom::blink::XRFrameDataProvider> + non_immersive_provider_; bool present_image_needs_copy_ = false; @@ -270,8 +271,10 @@ class VRDisplay final : public EventTargetWithInlineData, Member<SessionClientBinding> immersive_client_binding_; mojo::Receiver<device::mojom::blink::VRDisplayClient> display_client_receiver_{this}; - device::mojom::blink::XRFrameDataProviderPtr vr_presentation_data_provider_; - device::mojom::blink::XRPresentationProviderPtr vr_presentation_provider_; + mojo::Remote<device::mojom::blink::XRFrameDataProvider> + vr_presentation_data_provider_; + mojo::Remote<device::mojom::blink::XRPresentationProvider> + vr_presentation_provider_; HeapDeque<Member<ScriptPromiseResolver>> pending_present_resolvers_; }; diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.cc b/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.cc index 729055bb210..e0de2507520 100644 --- a/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.cc +++ b/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/vr/vr_eye_parameters.h" +#include "device/vr/public/mojom/vr_service.mojom-blink.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.h b/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.h index cde8e8b97ca..11068fa643c 100644 --- a/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.h +++ b/chromium/third_party/blink/renderer/modules/vr/vr_eye_parameters.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_VR_VR_EYE_PARAMETERS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_VR_VR_EYE_PARAMETERS_H_ -#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" #include "third_party/blink/renderer/modules/vr/vr_field_of_view.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.cc b/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.cc index d3e07747c32..b135694f997 100644 --- a/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.cc +++ b/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/vr/vr_frame_data.h" +#include "device/vr/public/mojom/vr_service.mojom-blink.h" #include "third_party/blink/renderer/modules/vr/vr_eye_parameters.h" #include "third_party/blink/renderer/modules/vr/vr_pose.h" diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.h b/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.h index b028cbd8d45..b25514aa7b3 100644 --- a/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.h +++ b/chromium/third_party/blink/renderer/modules/vr/vr_frame_data.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_VR_VR_FRAME_DATA_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_VR_VR_FRAME_DATA_H_ -#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_pose.cc b/chromium/third_party/blink/renderer/modules/vr/vr_pose.cc index d5bc8c4740f..50d3abaceca 100644 --- a/chromium/third_party/blink/renderer/modules/vr/vr_pose.cc +++ b/chromium/third_party/blink/renderer/modules/vr/vr_pose.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/vr/vr_pose.h" +#include "device/vr/public/mojom/vr_service.mojom-blink.h" + namespace blink { namespace { diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_pose.h b/chromium/third_party/blink/renderer/modules/vr/vr_pose.h index 626bf3305c2..0e94034c163 100644 --- a/chromium/third_party/blink/renderer/modules/vr/vr_pose.h +++ b/chromium/third_party/blink/renderer/modules/vr/vr_pose.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_VR_VR_POSE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_VR_VR_POSE_H_ -#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.cc b/chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.cc index 3b2169b7c5f..3f298212143 100644 --- a/chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.cc +++ b/chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "third_party/blink/renderer/modules/vr/vr_stage_parameters.h" +#include "device/vr/public/mojom/vr_service.mojom-blink.h" #include "third_party/blink/renderer/modules/xr/xr_utils.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" diff --git a/chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.h b/chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.h index 24e6432d01f..f2aca2a27f1 100644 --- a/chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.h +++ b/chromium/third_party/blink/renderer/modules/vr/vr_stage_parameters.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_VR_VR_STAGE_PARAMETERS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_VR_VR_STAGE_PARAMETERS_H_ -#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/BUILD.gn b/chromium/third_party/blink/renderer/modules/wake_lock/BUILD.gn index 5ac56b29436..d9feea597d9 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/wake_lock/BUILD.gn @@ -6,14 +6,20 @@ import("//third_party/blink/renderer/modules/modules.gni") blink_modules_sources("wake_lock") { sources = [ + "navigator_wake_lock.cc", + "navigator_wake_lock.h", "wake_lock.cc", "wake_lock.h", - "wake_lock_controller.cc", - "wake_lock_controller.h", + "wake_lock_event.cc", + "wake_lock_event.h", + "wake_lock_sentinel.cc", + "wake_lock_sentinel.h", "wake_lock_state_record.cc", "wake_lock_state_record.h", "wake_lock_type.cc", "wake_lock_type.h", + "worker_navigator_wake_lock.cc", + "worker_navigator_wake_lock.h", ] deps = [ "//mojo/public/cpp/bindings", diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/DEPS b/chromium/third_party/blink/renderer/modules/wake_lock/DEPS index 12b0536e1e6..271ccdbd562 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/DEPS +++ b/chromium/third_party/blink/renderer/modules/wake_lock/DEPS @@ -6,7 +6,7 @@ include_rules = [ ] specific_include_rules = { - "wake_lock_test_utils\.cc": [ + "wake_lock_test_utils\.cc|.+_test\.cc": [ "+base/run_loop.h", ], } diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/README.md b/chromium/third_party/blink/renderer/modules/wake_lock/README.md index f30e0a386f3..8c6e964062b 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/README.md +++ b/chromium/third_party/blink/renderer/modules/wake_lock/README.md @@ -101,9 +101,9 @@ This is an implementation detail, but the code handling wake locks in `VideoWake ```c++ mojo::Remote<mojom::blink::WakeLockService> wake_lock_service; -device::mojom::blink::WakeLockPtr wake_lock; +mojo::Remote<device::mojom::blink::WakeLock> wake_lock; execution_context->GetInterface(wake_lock_service.BindNewPipeAndPassReceiver()); -wake_lock_service->GetWakeLock(..., mojo::MakeRequest(&wake_lock)); +wake_lock_service->GetWakeLock(..., wake_lock.BindNewPipeAndPassReceiver()); wake_lock_->RequestWakeLock(); ``` diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc new file mode 100644 index 00000000000..e6f900b1bd3 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.cc @@ -0,0 +1,52 @@ +// 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. + +#include "third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h" + +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/frame/navigator.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock.h" + +namespace blink { + +NavigatorWakeLock::NavigatorWakeLock(Navigator& navigator) + : Supplement<Navigator>(navigator) {} + +WakeLock* NavigatorWakeLock::GetWakeLock() { + if (!wake_lock_) { + auto* frame = GetSupplementable()->GetFrame(); + if (frame) { + DCHECK(frame->GetDocument()); + wake_lock_ = MakeGarbageCollected<WakeLock>(*frame->GetDocument()); + } + } + return wake_lock_; +} + +// static +const char NavigatorWakeLock::kSupplementName[] = "NavigatorWakeLock"; + +// static +NavigatorWakeLock& NavigatorWakeLock::From(Navigator& navigator) { + NavigatorWakeLock* supplement = + Supplement<Navigator>::From<NavigatorWakeLock>(navigator); + if (!supplement) { + supplement = MakeGarbageCollected<NavigatorWakeLock>(navigator); + ProvideTo(navigator, supplement); + } + return *supplement; +} + +// static +WakeLock* NavigatorWakeLock::wakeLock(Navigator& navigator) { + return NavigatorWakeLock::From(navigator).GetWakeLock(); +} + +void NavigatorWakeLock::Trace(blink::Visitor* visitor) { + visitor->Trace(wake_lock_); + Supplement<Navigator>::Trace(visitor); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h new file mode 100644 index 00000000000..bdfd505cad1 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.h @@ -0,0 +1,39 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_NAVIGATOR_WAKE_LOCK_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_NAVIGATOR_WAKE_LOCK_H_ + +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/supplementable.h" + +namespace blink { + +class Navigator; +class WakeLock; + +class NavigatorWakeLock final : public GarbageCollected<NavigatorWakeLock>, + public Supplement<Navigator> { + USING_GARBAGE_COLLECTED_MIXIN(NavigatorWakeLock); + + public: + static const char kSupplementName[]; + + static NavigatorWakeLock& From(Navigator&); + + static WakeLock* wakeLock(Navigator&); + + explicit NavigatorWakeLock(Navigator&); + + void Trace(blink::Visitor*) override; + + private: + WakeLock* GetWakeLock(); + + Member<WakeLock> wake_lock_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_NAVIGATOR_WAKE_LOCK_H_ diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.idl b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.idl new file mode 100644 index 00000000000..36fc458d69d --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.idl @@ -0,0 +1,11 @@ +// 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. + +[ + ImplementedAs=NavigatorWakeLock, + RuntimeEnabled=WakeLock, + SecureContext +] partial interface Navigator { + [SameObject] readonly attribute WakeLock wakeLock; +}; diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc index b74d76454e1..4d6da59d01b 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.cc @@ -4,14 +4,15 @@ #include "third_party/blink/renderer/modules/wake_lock/wake_lock.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/web_feature.h" -#include "third_party/blink/renderer/modules/wake_lock/wake_lock_controller.h" -#include "third_party/blink/renderer/modules/wake_lock/wake_lock_request_options.h" +#include "third_party/blink/renderer/modules/permissions/permission_utils.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h" #include "third_party/blink/renderer/modules/wake_lock/wake_lock_type.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -19,28 +20,28 @@ namespace blink { -// static -ScriptPromise WakeLock::requestPermission(ScriptState* script_state, - const String& type) { - // https://w3c.github.io/wake-lock/#requestpermission-static-method - // 1. Let promise be a new promise. - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); +using mojom::blink::PermissionService; +using mojom::blink::PermissionStatus; - // 2. Return promise and run the following steps in parallel: - // 2.1. Let state be the result of running and waiting for the obtain - // permission steps with type. - // 2.2. Resolve promise with state. - auto* document = To<Document>(ExecutionContext::From(script_state)); - WakeLockController::From(document).RequestPermission(ToWakeLockType(type), - resolver); - return promise; -} +WakeLock::WakeLock(Document& document) + : ContextLifecycleObserver(&document), + PageVisibilityObserver(document.GetPage()), + state_records_{ + MakeGarbageCollected<WakeLockStateRecord>(&document, + WakeLockType::kScreen), + MakeGarbageCollected<WakeLockStateRecord>(&document, + WakeLockType::kSystem)} {} -// static -ScriptPromise WakeLock::request(ScriptState* script_state, - const String& type, - WakeLockRequestOptions* options) { +WakeLock::WakeLock(DedicatedWorkerGlobalScope& worker_scope) + : ContextLifecycleObserver(&worker_scope), + PageVisibilityObserver(nullptr), + state_records_{ + MakeGarbageCollected<WakeLockStateRecord>(&worker_scope, + WakeLockType::kScreen), + MakeGarbageCollected<WakeLockStateRecord>(&worker_scope, + WakeLockType::kSystem)} {} + +ScriptPromise WakeLock::request(ScriptState* script_state, const String& type) { // https://w3c.github.io/wake-lock/#request-static-method auto* context = ExecutionContext::From(script_state); DCHECK(context->IsDocument() || context->IsDedicatedWorkerGlobalScope()); @@ -111,21 +112,10 @@ ScriptPromise WakeLock::request(ScriptState* script_state, } } - // 5. If options' signal member is present, then run the following steps: - // 5.1. Let signal be options's signal member. - // 5.2. If signal’s aborted flag is set, then reject promise with an - // "AbortError" DOMException and return promise. - if (options->hasSignal() && options->signal()->aborted()) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError)); - } - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); WakeLockType wake_lock_type = ToWakeLockType(type); - WakeLockController& controller = WakeLockController::From(context); switch (wake_lock_type) { case WakeLockType::kScreen: @@ -139,20 +129,140 @@ ScriptPromise WakeLock::request(ScriptState* script_state, break; } - // 5.3. Otherwise, add to signal: - // 5.3.1. Run release a wake lock with promise and type. - if (options->hasSignal()) { - options->signal()->AddAlgorithm(WTF::Bind( - &WakeLockController::ReleaseWakeLock, WrapWeakPersistent(&controller), - wake_lock_type, WrapPersistent(resolver))); - } - // 6. Run the following steps in parallel, but abort when options' signal // member is present and its aborted flag is set: - controller.RequestWakeLock(wake_lock_type, resolver, options->signal()); + // 6.1. Let state be the result of awaiting obtain permission steps with + // type: + DoRequest(wake_lock_type, resolver); // 7. Return promise. return promise; } +void WakeLock::DoRequest(WakeLockType type, ScriptPromiseResolver* resolver) { + ObtainPermission( + type, WTF::Bind(&WakeLock::DidReceivePermissionResponse, + WrapPersistent(this), type, WrapPersistent(resolver))); +} + +void WakeLock::DidReceivePermissionResponse(WakeLockType type, + ScriptPromiseResolver* resolver, + PermissionStatus status) { + // https://w3c.github.io/wake-lock/#request-static-method + DCHECK(status == PermissionStatus::GRANTED || + status == PermissionStatus::DENIED); + DCHECK(resolver); + // 6.1.1. If state is "denied", then reject promise with a "NotAllowedError" + // DOMException, and abort these steps. + if (status != PermissionStatus::GRANTED) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNotAllowedError, + "Wake Lock permission request denied")); + return; + } + // https://github.com/w3c/wake-lock/issues/222: the page can become hidden + // between request() and WakeLockStateRecord::AcquireWakeLock(), in which case + // we need to abort early. + if (type == WakeLockType::kScreen && + !(GetPage() && GetPage()->IsPageVisible())) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kNotAllowedError, + "The requesting page is not visible")); + return; + } + // 6.2. Let success be the result of awaiting acquire a wake lock with promise + // and type: + // 6.2.1. If success is false then reject promise with a "NotAllowedError" + // DOMException, and abort these steps. + WakeLockStateRecord* state_record = state_records_[static_cast<size_t>(type)]; + DCHECK(state_record); + state_record->AcquireWakeLock(resolver); +} + +void WakeLock::ContextDestroyed(ExecutionContext*) { + // https://w3c.github.io/wake-lock/#handling-document-loss-of-full-activity + // 1. Let document be the responsible document of the current settings object. + // 2. Let screenRecord be the platform wake lock's state record associated + // with document and wake lock type "screen". + // 3. For each lockPromise in screenRecord.[[WakeLockStateRecord]]: + // 3.1. Run release a wake lock with lockPromise and "screen". + // 4. Let systemRecord be the platform wake lock's state record associated + // with document and wake lock type "system". + // 5. For each lockPromise in systemRecord.[[WakeLockStateRecord]]: + // 5.1. Run release a wake lock with lockPromise and "system". + for (WakeLockStateRecord* state_record : state_records_) { + if (state_record) + state_record->ClearWakeLocks(); + } +} + +void WakeLock::PageVisibilityChanged() { + // https://w3c.github.io/wake-lock/#handling-document-loss-of-visibility + // 1. Let document be the Document of the top-level browsing context. + // 2. If document's visibility state is "visible", abort these steps. + if (GetPage() && GetPage()->IsPageVisible()) + return; + // 3. Let screenRecord be the platform wake lock's state record associated + // with wake lock type "screen". + // 4. For each lockPromise in screenRecord.[[WakeLockStateRecord]]: + // 4.1. Run release a wake lock with lockPromise and "screen". + WakeLockStateRecord* state_record = + state_records_[static_cast<size_t>(WakeLockType::kScreen)]; + if (state_record) + state_record->ClearWakeLocks(); +} + +void WakeLock::ObtainPermission( + WakeLockType type, + base::OnceCallback<void(PermissionStatus)> callback) { + // https://w3c.github.io/wake-lock/#dfn-obtain-permission + // Note we actually implement a simplified version of the "obtain permission" + // algorithm that essentially just calls the "request permission to use" + // algorithm from the Permissions spec (i.e. we bypass all the steps covering + // calling the "query a permission" algorithm and handling its result). + // * Right now, we can do that because there is no way for Chromium's + // permission system to get to the "prompt" state given how + // WakeLockPermissionContext is currently implemented. + // * Even if WakeLockPermissionContext changes in the future, this Blink + // implementation is unlikely to change because + // WakeLockPermissionContext::RequestPermission() will take its + // |user_gesture| argument into account to actually implement a slightly + // altered version of "request permission to use", the behavior of which + // will match the definition of "obtain permission" in the Wake Lock spec. + DCHECK(type == WakeLockType::kScreen || type == WakeLockType::kSystem); + static_assert( + static_cast<mojom::blink::WakeLockType>(WakeLockType::kScreen) == + mojom::blink::WakeLockType::kScreen, + "WakeLockType and mojom::blink::WakeLockType must have identical values"); + static_assert( + static_cast<mojom::blink::WakeLockType>(WakeLockType::kSystem) == + mojom::blink::WakeLockType::kSystem, + "WakeLockType and mojom::blink::WakeLockType must have identical values"); + + auto* local_frame = GetExecutionContext()->IsDocument() + ? To<Document>(GetExecutionContext())->GetFrame() + : nullptr; + GetPermissionService()->RequestPermission( + CreateWakeLockPermissionDescriptor( + static_cast<mojom::blink::WakeLockType>(type)), + LocalFrame::HasTransientUserActivation(local_frame), std::move(callback)); +} + +PermissionService* WakeLock::GetPermissionService() { + if (!permission_service_) { + ConnectToPermissionService( + GetExecutionContext(), + permission_service_.BindNewPipeAndPassReceiver()); + } + return permission_service_.get(); +} + +void WakeLock::Trace(Visitor* visitor) { + for (WakeLockStateRecord* state_record : state_records_) + visitor->Trace(state_record); + PageVisibilityObserver::Trace(visitor); + ContextLifecycleObserver::Trace(visitor); + ScriptWrappable::Trace(visitor); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h index 4042b2bccbe..4484785512f 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.h @@ -5,8 +5,18 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_H_ +#include "base/callback.h" +#include "base/gtest_prod_util.h" +#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/page/page_visibility_observer.h" +#include "third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h" +#include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_type.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/heap/handle.h" namespace WTF { @@ -16,17 +26,60 @@ class String; namespace blink { +class ExecutionContext; class ScriptState; -class WakeLockRequestOptions; +class WakeLockStateRecord; -class WakeLock final : public ScriptWrappable { +class MODULES_EXPORT WakeLock final : public ScriptWrappable, + public ContextLifecycleObserver, + public PageVisibilityObserver { + USING_GARBAGE_COLLECTED_MIXIN(WakeLock); DEFINE_WRAPPERTYPEINFO(); public: - static ScriptPromise requestPermission(ScriptState*, const WTF::String& type); - static ScriptPromise request(ScriptState*, - const WTF::String& type, - WakeLockRequestOptions*); + explicit WakeLock(Document&); + explicit WakeLock(DedicatedWorkerGlobalScope&); + + ScriptPromise request(ScriptState*, const WTF::String& type); + + void Trace(blink::Visitor*) override; + + private: + // While this could be part of request() itself, having it as a separate + // function makes testing (which uses a custom ScriptPromiseResolver) a lot + // easier. + void DoRequest(WakeLockType, ScriptPromiseResolver*); + + void DidReceivePermissionResponse(WakeLockType, + ScriptPromiseResolver*, + mojom::blink::PermissionStatus); + + // ContextLifecycleObserver implementation + void ContextDestroyed(ExecutionContext*) override; + + // PageVisibilityObserver implementation + void PageVisibilityChanged() override; + + // Permission handling + void ObtainPermission( + WakeLockType, + base::OnceCallback<void(mojom::blink::PermissionStatus)> callback); + mojom::blink::PermissionService* GetPermissionService(); + + mojo::Remote<mojom::blink::PermissionService> permission_service_; + + // https://w3c.github.io/wake-lock/#concepts-and-state-record + // Each platform wake lock (one per wake lock type) has an associated state + // record per responsible document [...] internal slots. + Member<WakeLockStateRecord> state_records_[kWakeLockTypeCount]; + + FRIEND_TEST_ALL_PREFIXES(WakeLockSentinelTest, ContextDestruction); + FRIEND_TEST_ALL_PREFIXES(WakeLockTest, RequestWakeLockGranted); + FRIEND_TEST_ALL_PREFIXES(WakeLockTest, RequestWakeLockDenied); + FRIEND_TEST_ALL_PREFIXES(WakeLockTest, LossOfDocumentActivity); + FRIEND_TEST_ALL_PREFIXES(WakeLockTest, PageVisibilityHidden); + FRIEND_TEST_ALL_PREFIXES(WakeLockTest, + PageVisibilityHiddenBeforeLockAcquisition); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.idl b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.idl index 6fd074ad4cd..806981c25f9 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.idl +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock.idl @@ -13,6 +13,5 @@ enum WakeLockType { Exposed=(DedicatedWorker,Window), RuntimeEnabled=WakeLock ] interface WakeLock { - [CallWith=ScriptState, Exposed=Window] static Promise<PermissionState> requestPermission(WakeLockType type); - [CallWith=ScriptState] static Promise<void> request(WakeLockType type, optional WakeLockRequestOptions options); + [CallWith=ScriptState] Promise<WakeLockSentinel> request(WakeLockType type); }; diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.cc deleted file mode 100644 index 6c87877bd04..00000000000 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.cc +++ /dev/null @@ -1,234 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/wake_lock/wake_lock_controller.h" - -#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/core/dom/abort_signal.h" -#include "third_party/blink/renderer/core/dom/dom_exception.h" -#include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/modules/permissions/permission_utils.h" -#include "third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h" -#include "third_party/blink/renderer/platform/wtf/functional.h" - -namespace blink { - -using mojom::blink::PermissionService; -using mojom::blink::PermissionStatus; - -WakeLockController::WakeLockController(Document& document) - : Supplement<ExecutionContext>(document), - ContextLifecycleObserver(&document), - PageVisibilityObserver(document.GetPage()), - state_records_{ - MakeGarbageCollected<WakeLockStateRecord>(&document, - WakeLockType::kScreen), - MakeGarbageCollected<WakeLockStateRecord>(&document, - WakeLockType::kSystem)} {} - -WakeLockController::WakeLockController(DedicatedWorkerGlobalScope& worker_scope) - : Supplement<ExecutionContext>(worker_scope), - ContextLifecycleObserver(&worker_scope), - PageVisibilityObserver(nullptr), - state_records_{ - MakeGarbageCollected<WakeLockStateRecord>(&worker_scope, - WakeLockType::kScreen), - MakeGarbageCollected<WakeLockStateRecord>(&worker_scope, - WakeLockType::kSystem)} {} - -const char WakeLockController::kSupplementName[] = "WakeLockController"; - -// static -WakeLockController& WakeLockController::From( - ExecutionContext* execution_context) { - DCHECK(execution_context->IsDocument() || - execution_context->IsDedicatedWorkerGlobalScope()); - auto* controller = - Supplement<ExecutionContext>::From<WakeLockController>(execution_context); - if (!controller) { - if (execution_context->IsDocument()) { - controller = MakeGarbageCollected<WakeLockController>( - *To<Document>(execution_context)); - } else { - controller = MakeGarbageCollected<WakeLockController>( - *To<DedicatedWorkerGlobalScope>(execution_context)); - } - Supplement<ExecutionContext>::ProvideTo(*execution_context, controller); - } - return *controller; -} - -void WakeLockController::Trace(Visitor* visitor) { - for (WakeLockStateRecord* state_record : state_records_) - visitor->Trace(state_record); - PageVisibilityObserver::Trace(visitor); - ContextLifecycleObserver::Trace(visitor); - Supplement<ExecutionContext>::Trace(visitor); -} - -void WakeLockController::RequestWakeLock(WakeLockType type, - ScriptPromiseResolver* resolver, - AbortSignal* signal) { - // https://w3c.github.io/wake-lock/#request-static-method - // 6. [...] abort when options' signal member is present and its aborted flag - // is set: - DCHECK(resolver); - // We were called via WakeLock::request(), which should have handled the - // signal->aborted() case. - DCHECK(!signal || !signal->aborted()); - // 6.1. Let state be the result of awaiting obtain permission steps with - // type: - ObtainPermission( - type, WTF::Bind(&WakeLockController::DidReceivePermissionResponse, - WrapPersistent(this), type, WrapPersistent(resolver), - WrapPersistent(signal))); -} - -void WakeLockController::DidReceivePermissionResponse( - WakeLockType type, - ScriptPromiseResolver* resolver, - AbortSignal* signal, - PermissionStatus status) { - // https://w3c.github.io/wake-lock/#request-static-method - DCHECK(status == PermissionStatus::GRANTED || - status == PermissionStatus::DENIED); - DCHECK(resolver); - if (signal && signal->aborted()) - return; - // 6.1.1. If state is "denied", then reject promise with a "NotAllowedError" - // DOMException, and abort these steps. - if (status != PermissionStatus::GRANTED) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotAllowedError, - "Wake Lock permission request denied")); - return; - } - // https://github.com/w3c/wake-lock/issues/222: the page can become hidden - // between RequestWakeLock() and AcquireWakeLock(), in which case we need to - // abort early. - if (type == WakeLockType::kScreen && - !(GetPage() && GetPage()->IsPageVisible())) { - ReleaseWakeLock(type, resolver); - return; - } - // 6.2. Let success be the result of awaiting acquire a wake lock with promise - // and type: - // 6.2.1. If success is false then reject promise with a "NotAllowedError" - // DOMException, and abort these steps. - AcquireWakeLock(type, resolver); -} - -void WakeLockController::ReleaseWakeLock(WakeLockType type, - ScriptPromiseResolver* resolver) { - DCHECK_LE(type, WakeLockType::kMaxValue); - WakeLockStateRecord* state_record = state_records_[static_cast<size_t>(type)]; - DCHECK(state_record); - state_record->ReleaseWakeLock(resolver); -} - -void WakeLockController::RequestPermission(WakeLockType type, - ScriptPromiseResolver* resolver) { - // https://w3c.github.io/wake-lock/#requestpermission-static-method - // 2.1. Let state be the result of running and waiting for the obtain - // permission steps with type. - // 2.2. Resolve promise with state. - auto permission_callback = WTF::Bind( - [](ScriptPromiseResolver* resolver, PermissionStatus status) { - DCHECK(status == PermissionStatus::GRANTED || - status == PermissionStatus::DENIED); - DCHECK(resolver); - resolver->Resolve(PermissionStatusToString(status)); - }, - WrapPersistent(resolver)); - ObtainPermission(type, std::move(permission_callback)); -} - -void WakeLockController::ContextDestroyed(ExecutionContext*) { - // https://w3c.github.io/wake-lock/#handling-document-loss-of-full-activity - // 1. Let document be the responsible document of the current settings object. - // 2. Let screenRecord be the platform wake lock's state record associated - // with document and wake lock type "screen". - // 3. For each lockPromise in screenRecord.[[WakeLockStateRecord]]: - // 3.1. Run release a wake lock with lockPromise and "screen". - // 4. Let systemRecord be the platform wake lock's state record associated - // with document and wake lock type "system". - // 5. For each lockPromise in systemRecord.[[WakeLockStateRecord]]: - // 5.1. Run release a wake lock with lockPromise and "system". - for (WakeLockStateRecord* state_record : state_records_) { - if (state_record) - state_record->ClearWakeLocks(); - } -} - -void WakeLockController::PageVisibilityChanged() { - // https://w3c.github.io/wake-lock/#handling-document-loss-of-visibility - // 1. Let document be the Document of the top-level browsing context. - // 2. If document's visibility state is "visible", abort these steps. - if (GetPage() && GetPage()->IsPageVisible()) - return; - // 3. Let screenRecord be the platform wake lock's state record associated - // with wake lock type "screen". - // 4. For each lockPromise in screenRecord.[[WakeLockStateRecord]]: - // 4.1. Run release a wake lock with lockPromise and "screen". - WakeLockStateRecord* state_record = - state_records_[static_cast<size_t>(WakeLockType::kScreen)]; - if (state_record) - state_record->ClearWakeLocks(); -} - -void WakeLockController::AcquireWakeLock(WakeLockType type, - ScriptPromiseResolver* resolver) { - DCHECK_LE(type, WakeLockType::kMaxValue); - WakeLockStateRecord* state_record = state_records_[static_cast<size_t>(type)]; - DCHECK(state_record); - state_record->AcquireWakeLock(resolver); -} - -void WakeLockController::ObtainPermission( - WakeLockType type, - base::OnceCallback<void(PermissionStatus)> callback) { - // https:w3c.github.io/wake-lock/#dfn-obtain-permission - // Note we actually implement a simplified version of the "obtain permission" - // algorithm that essentially just calls the "request permission to use" - // algorithm from the Permissions spec (i.e. we bypass all the steps covering - // calling the "query a permission" algorithm and handling its result). - // * Right now, we can do that because there is no way for Chromium's - // permission system to get to the "prompt" state given how - // WakeLockPermissionContext is currently implemented. - // * Even if WakeLockPermissionContext changes in the future, this Blink - // implementation is unlikely to change because - // WakeLockPermissionContext::RequestPermission() will take its - // |user_gesture| argument into account to actually implement a slightly - // altered version of "request permission to use", the behavior of which - // will match the definition of "obtain permission" in the Wake Lock spec. - DCHECK(type == WakeLockType::kScreen || type == WakeLockType::kSystem); - static_assert( - static_cast<mojom::blink::WakeLockType>(WakeLockType::kScreen) == - mojom::blink::WakeLockType::kScreen, - "WakeLockType and mojom::blink::WakeLockType must have identical values"); - static_assert( - static_cast<mojom::blink::WakeLockType>(WakeLockType::kSystem) == - mojom::blink::WakeLockType::kSystem, - "WakeLockType and mojom::blink::WakeLockType must have identical values"); - - auto* local_frame = GetExecutionContext()->IsDocument() - ? To<Document>(GetExecutionContext())->GetFrame() - : nullptr; - - GetPermissionService()->RequestPermission( - CreateWakeLockPermissionDescriptor( - static_cast<mojom::blink::WakeLockType>(type)), - LocalFrame::HasTransientUserActivation(local_frame), std::move(callback)); -} - -PermissionService* WakeLockController::GetPermissionService() { - if (!permission_service_) { - ConnectToPermissionService( - GetExecutionContext(), - permission_service_.BindNewPipeAndPassReceiver()); - } - return permission_service_.get(); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.h deleted file mode 100644 index 4688fdd5a97..00000000000 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_controller.h +++ /dev/null @@ -1,88 +0,0 @@ -// 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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_CONTROLLER_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_CONTROLLER_H_ - -#include "base/callback.h" -#include "base/gtest_prod_util.h" -#include "mojo/public/cpp/bindings/remote.h" -#include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" -#include "third_party/blink/renderer/core/page/page_visibility_observer.h" -#include "third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h" -#include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/modules/wake_lock/wake_lock_type.h" -#include "third_party/blink/renderer/platform/heap/handle.h" - -namespace blink { - -class AbortSignal; -class ExecutionContext; -class ScriptPromiseResolver; -class WakeLockStateRecord; - -// WakeLockController is used to track per-Document wake lock state and react to -// Document changes appropriately. -class MODULES_EXPORT WakeLockController final - : public GarbageCollectedFinalized<WakeLockController>, - public Supplement<ExecutionContext>, - public ContextLifecycleObserver, - public PageVisibilityObserver { - USING_GARBAGE_COLLECTED_MIXIN(WakeLockController); - - public: - static const char kSupplementName[]; - - explicit WakeLockController(Document&); - explicit WakeLockController(DedicatedWorkerGlobalScope&); - - static WakeLockController& From(ExecutionContext*); - - void Trace(blink::Visitor*) override; - - void RequestWakeLock(WakeLockType type, - ScriptPromiseResolver* resolver, - AbortSignal* signal); - - void ReleaseWakeLock(WakeLockType type, ScriptPromiseResolver*); - - void RequestPermission(WakeLockType type, ScriptPromiseResolver*); - - private: - // ContextLifecycleObserver implementation - void ContextDestroyed(ExecutionContext*) override; - - // PageVisibilityObserver implementation - void PageVisibilityChanged() override; - - void AcquireWakeLock(WakeLockType type, ScriptPromiseResolver*); - - void DidReceivePermissionResponse(WakeLockType type, - ScriptPromiseResolver*, - AbortSignal*, - mojom::blink::PermissionStatus); - - // Permission handling - void ObtainPermission( - WakeLockType type, - base::OnceCallback<void(mojom::blink::PermissionStatus)> callback); - mojom::blink::PermissionService* GetPermissionService(); - - mojo::Remote<mojom::blink::PermissionService> permission_service_; - - // https://w3c.github.io/wake-lock/#concepts-and-state-record - // Each platform wake lock (one per wake lock type) has an associated state - // record per responsible document [...] internal slots. - Member<WakeLockStateRecord> state_records_[kWakeLockTypeCount]; - - FRIEND_TEST_ALL_PREFIXES(WakeLockControllerTest, AcquireScreenWakeLock); - FRIEND_TEST_ALL_PREFIXES(WakeLockControllerTest, AcquireSystemWakeLock); - FRIEND_TEST_ALL_PREFIXES(WakeLockControllerTest, AcquireMultipleLocks); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_CONTROLLER_H_ diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_controller_test.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_controller_test.cc deleted file mode 100644 index 32d40ff0145..00000000000 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_controller_test.cc +++ /dev/null @@ -1,488 +0,0 @@ -// 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. - -#include "third_party/blink/renderer/modules/wake_lock/wake_lock_controller.h" - -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" -#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/core/dom/abort_signal.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/dom_exception.h" -#include "third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h" -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" -#include "v8/include/v8.h" - -namespace blink { - -TEST(WakeLockControllerTest, RequestWakeLockGranted) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); - - auto* screen_resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise screen_promise = screen_resolver->Promise(); - - controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver, nullptr); - - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - MockPermissionService& permission_service = context.GetPermissionService(); - - permission_service.WaitForPermissionRequest(WakeLockType::kScreen); - screen_lock.WaitForRequest(); - - EXPECT_EQ(v8::Promise::kPending, - ScriptPromiseUtils::GetPromiseState(screen_promise)); - EXPECT_TRUE(screen_lock.is_acquired()); -} - -TEST(WakeLockControllerTest, RequestWakeLockDenied) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kSystem, mojom::blink::PermissionStatus::DENIED); - - auto* system_resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise system_promise = system_resolver->Promise(); - - controller.RequestWakeLock(WakeLockType::kSystem, system_resolver, nullptr); - - MockWakeLock& system_lock = - wake_lock_service.get_wake_lock(WakeLockType::kSystem); - MockPermissionService& permission_service = context.GetPermissionService(); - - permission_service.WaitForPermissionRequest(WakeLockType::kSystem); - context.WaitForPromiseRejection(system_promise); - - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(system_promise)); - EXPECT_FALSE(system_lock.is_acquired()); - - // System locks are not allowed by default, so the promise should have been - // rejected with a NotAllowedError DOMException. - DOMException* dom_exception = - ScriptPromiseUtils::GetPromiseResolutionAsDOMException(system_promise); - ASSERT_NE(dom_exception, nullptr); - EXPECT_EQ("NotAllowedError", dom_exception->name()); -} - -// Abort early in DidReceivePermissionResponse(). -TEST(WakeLockControllerTest, RequestWakeLockAbortEarly) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); - - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - auto* screen_resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise screen_promise = screen_resolver->Promise(); - - auto* abort_signal = MakeGarbageCollected<AbortSignal>(context.GetDocument()); - abort_signal->AddAlgorithm(WTF::Bind( - &WakeLockController::ReleaseWakeLock, WrapWeakPersistent(&controller), - WakeLockType::kScreen, WrapPersistent(screen_resolver))); - - controller.RequestWakeLock( - WakeLockType::kScreen, - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()), - abort_signal); - - MockPermissionService& permission_service = context.GetPermissionService(); - - permission_service.WaitForPermissionRequest(WakeLockType::kScreen); - abort_signal->SignalAbort(); - - context.WaitForPromiseRejection(screen_promise); - - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(screen_promise)); - EXPECT_FALSE(screen_lock.is_acquired()); - - DOMException* dom_exception = - ScriptPromiseUtils::GetPromiseResolutionAsDOMException(screen_promise); - ASSERT_NE(dom_exception, nullptr); - EXPECT_EQ("AbortError", dom_exception->name()); -} - -TEST(WakeLockControllerTest, AcquireScreenWakeLock) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - controller.AcquireWakeLock( - WakeLockType::kScreen, - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState())); - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - screen_lock.WaitForRequest(); - - EXPECT_TRUE(screen_lock.is_acquired()); -} - -TEST(WakeLockControllerTest, AcquireSystemWakeLock) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - controller.AcquireWakeLock( - WakeLockType::kSystem, - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState())); - MockWakeLock& system_lock = - wake_lock_service.get_wake_lock(WakeLockType::kSystem); - system_lock.WaitForRequest(); - - EXPECT_TRUE(system_lock.is_acquired()); -} - -TEST(WakeLockControllerTest, AcquireMultipleLocks) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - controller.AcquireWakeLock( - WakeLockType::kScreen, - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState())); - controller.AcquireWakeLock( - WakeLockType::kSystem, - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState())); - controller.AcquireWakeLock( - WakeLockType::kSystem, - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState())); - - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - screen_lock.WaitForRequest(); - MockWakeLock& system_lock = - wake_lock_service.get_wake_lock(WakeLockType::kSystem); - system_lock.WaitForRequest(); - - EXPECT_TRUE(screen_lock.is_acquired()); - EXPECT_TRUE(system_lock.is_acquired()); -} - -TEST(WakeLockControllerTest, ReleaseUnaquiredWakeLockRejectsPromise) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - - auto* resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise promise = resolver->Promise(); - - EXPECT_EQ(v8::Promise::kPending, - ScriptPromiseUtils::GetPromiseState(promise)); - controller.ReleaseWakeLock(WakeLockType::kScreen, resolver); - context.WaitForPromiseRejection(promise); - - // The promise is always rejected, even if it is not in [[ActiveLocks]]. - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(promise)); - EXPECT_FALSE(screen_lock.is_acquired()); -} - -TEST(WakeLockControllerTest, ReleaseWakeLock) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); - - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - - auto* resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise promise = resolver->Promise(); - - controller.RequestWakeLock(WakeLockType::kScreen, resolver, - /*signal=*/nullptr); - screen_lock.WaitForRequest(); - controller.ReleaseWakeLock(WakeLockType::kScreen, resolver); - context.WaitForPromiseRejection(promise); - screen_lock.WaitForCancelation(); - - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(promise)); - EXPECT_FALSE(screen_lock.is_acquired()); -} - -// This is actually part of WakeLock::request(), but it is easier to just test -// it here. -TEST(WakeLockControllerTest, AbortSignal) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); - - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - auto* screen_resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise screen_promise = screen_resolver->Promise(); - - auto* abort_signal = MakeGarbageCollected<AbortSignal>(context.GetDocument()); - abort_signal->AddAlgorithm(WTF::Bind( - &WakeLockController::ReleaseWakeLock, WrapWeakPersistent(&controller), - WakeLockType::kScreen, WrapPersistent(screen_resolver))); - - controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver, - /*signal=*/nullptr); - screen_lock.WaitForRequest(); - - abort_signal->SignalAbort(); - context.WaitForPromiseRejection(screen_promise); - screen_lock.WaitForCancelation(); - - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(screen_promise)); - EXPECT_FALSE(screen_lock.is_acquired()); -} - -// https://w3c.github.io/wake-lock/#handling-document-loss-of-full-activity -TEST(WakeLockControllerTest, LossOfDocumentActivity) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - MockWakeLock& system_lock = - wake_lock_service.get_wake_lock(WakeLockType::kSystem); - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kSystem, mojom::blink::PermissionStatus::GRANTED); - - // First, acquire a handful of locks of different types. - auto* screen_resolver1 = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise screen_promise1 = screen_resolver1->Promise(); - auto* screen_resolver2 = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise screen_promise2 = screen_resolver2->Promise(); - auto* system_resolver1 = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise system_promise1 = system_resolver1->Promise(); - controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver1, - /*signal=*/nullptr); - controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver2, - /*signal=*/nullptr); - screen_lock.WaitForRequest(); - controller.RequestWakeLock(WakeLockType::kSystem, system_resolver1, - /*signal=*/nullptr); - system_lock.WaitForRequest(); - - // Now shut down our Document and make sure all [[ActiveLocks]] slots have - // been cleared. We cannot check that the promises have been rejected because - // ScriptPromiseResolver::Reject() will bail out if we no longer have a valid - // execution context. - context.GetDocument()->Shutdown(); - screen_lock.WaitForCancelation(); - system_lock.WaitForCancelation(); - - EXPECT_FALSE(screen_lock.is_acquired()); - EXPECT_FALSE(system_lock.is_acquired()); -} - -// https://w3c.github.io/wake-lock/#handling-document-loss-of-visibility -TEST(WakeLockControllerTest, PageVisibilityHidden) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kSystem, mojom::blink::PermissionStatus::GRANTED); - - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - auto* screen_resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise screen_promise = screen_resolver->Promise(); - - MockWakeLock& system_lock = - wake_lock_service.get_wake_lock(WakeLockType::kSystem); - auto* system_resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise system_promise = system_resolver->Promise(); - - controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver, - /*signal=*/nullptr); - controller.RequestWakeLock(WakeLockType::kSystem, system_resolver, - /*signal=*/nullptr); - - screen_lock.WaitForRequest(); - system_lock.WaitForRequest(); - - context.GetDocument()->GetPage()->SetIsHidden(true, false); - - context.WaitForPromiseRejection(screen_promise); - screen_lock.WaitForCancelation(); - - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(screen_promise)); - DOMException* dom_exception = - ScriptPromiseUtils::GetPromiseResolutionAsDOMException(screen_promise); - ASSERT_NE(dom_exception, nullptr); - EXPECT_EQ("AbortError", dom_exception->name()); - EXPECT_FALSE(screen_lock.is_acquired()); - EXPECT_EQ(v8::Promise::kPending, - ScriptPromiseUtils::GetPromiseState(system_promise)); - EXPECT_TRUE(system_lock.is_acquired()); - - context.GetDocument()->GetPage()->SetIsHidden(false, false); - - auto* other_resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise other_promise = system_resolver->Promise(); - controller.RequestWakeLock(WakeLockType::kScreen, other_resolver, - /*signal=*/nullptr); - screen_lock.WaitForRequest(); - EXPECT_EQ(v8::Promise::kPending, - ScriptPromiseUtils::GetPromiseState(other_promise)); - EXPECT_TRUE(screen_lock.is_acquired()); -} - -// https://w3c.github.io/wake-lock/#handling-document-loss-of-visibility -TEST(WakeLockControllerTest, PageVisibilityHiddenBeforeLockAcquisition) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kSystem, mojom::blink::PermissionStatus::GRANTED); - - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - auto* screen_resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise screen_promise = screen_resolver->Promise(); - - MockWakeLock& system_lock = - wake_lock_service.get_wake_lock(WakeLockType::kSystem); - auto* system_resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise system_promise = system_resolver->Promise(); - - controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver, - /*signal=*/nullptr); - controller.RequestWakeLock(WakeLockType::kSystem, system_resolver, - /*signal=*/nullptr); - context.GetDocument()->GetPage()->SetIsHidden(true, false); - - context.WaitForPromiseRejection(screen_promise); - system_lock.WaitForRequest(); - - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(screen_promise)); - EXPECT_FALSE(screen_lock.is_acquired()); - EXPECT_EQ(v8::Promise::kPending, - ScriptPromiseUtils::GetPromiseState(system_promise)); - EXPECT_TRUE(system_lock.is_acquired()); -} - -// Check that hiding a page and signaling abort does not try to delete a -// screen lock twice. -TEST(WakeLockControllerTest, PageVisibilityAndAbortSignal) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); - - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - auto* screen_resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise screen_promise = screen_resolver->Promise(); - - auto* abort_signal = MakeGarbageCollected<AbortSignal>(context.GetDocument()); - abort_signal->AddAlgorithm(WTF::Bind( - &WakeLockController::ReleaseWakeLock, WrapWeakPersistent(&controller), - WakeLockType::kScreen, WrapPersistent(screen_resolver))); - - controller.RequestWakeLock(WakeLockType::kScreen, screen_resolver, - /*signal=*/nullptr); - screen_lock.WaitForRequest(); - - context.GetDocument()->GetPage()->SetIsHidden(true, false); - context.WaitForPromiseRejection(screen_promise); - screen_lock.WaitForCancelation(); - - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(screen_promise)); - EXPECT_FALSE(screen_lock.is_acquired()); - - abort_signal->SignalAbort(); - test::RunPendingTasks(); - - EXPECT_FALSE(screen_lock.is_acquired()); -} - -TEST(WakeLockControllerTest, RequestPermissionGranted) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kSystem, mojom::blink::PermissionStatus::GRANTED); - - auto* system_resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise system_promise = system_resolver->Promise(); - - controller.RequestPermission(WakeLockType::kSystem, system_resolver); - context.WaitForPromiseFulfillment(system_promise); - - EXPECT_EQ(v8::Promise::kFulfilled, - ScriptPromiseUtils::GetPromiseState(system_promise)); - EXPECT_EQ("granted", - ScriptPromiseUtils::GetPromiseResolutionAsString(system_promise)); -} - -TEST(WakeLockControllerTest, RequestPermissionDenied) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto& controller = WakeLockController::From(context.GetDocument()); - - context.GetPermissionService().SetPermissionResponse( - WakeLockType::kSystem, mojom::blink::PermissionStatus::DENIED); - - auto* system_resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise system_promise = system_resolver->Promise(); - - controller.RequestPermission(WakeLockType::kSystem, system_resolver); - context.WaitForPromiseFulfillment(system_promise); - - EXPECT_EQ(v8::Promise::kFulfilled, - ScriptPromiseUtils::GetPromiseState(system_promise)); - EXPECT_EQ("denied", - ScriptPromiseUtils::GetPromiseResolutionAsString(system_promise)); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_event.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_event.cc new file mode 100644 index 00000000000..866fbaeb109 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_event.cc @@ -0,0 +1,46 @@ +// 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. + +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_event.h" + +#include "base/logging.h" +#include "third_party/blink/renderer/modules/event_interface_modules_names.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_event_init.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h" +#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" + +namespace blink { + +// static +WakeLockEvent* WakeLockEvent::Create(const AtomicString& type, + const WakeLockEventInit* initializer) { + DCHECK(initializer->hasLock()); + return MakeGarbageCollected<WakeLockEvent>(type, initializer); +} + +WakeLockEvent::WakeLockEvent(const AtomicString& type, + const WakeLockEventInit* initializer) + : Event(type, initializer), lock_(initializer->lock()) { + DCHECK_NE(nullptr, lock_); +} + +WakeLockEvent::WakeLockEvent(const AtomicString& type, WakeLockSentinel* lock) + : Event(type, Bubbles::kNo, Cancelable::kNo), lock_(lock) {} + +WakeLockEvent::~WakeLockEvent() = default; + +WakeLockSentinel* WakeLockEvent::lock() const { + return lock_; +} + +const AtomicString& WakeLockEvent::InterfaceName() const { + return event_interface_names::kWakeLockEvent; +} + +void WakeLockEvent::Trace(blink::Visitor* visitor) { + visitor->Trace(lock_); + Event::Trace(visitor); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_event.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_event.h new file mode 100644 index 00000000000..228a4b13597 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_event.h @@ -0,0 +1,41 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_EVENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_EVENT_H_ + +#include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/wtf/forward.h" + +namespace blink { + +class WakeLockEventInit; +class WakeLockSentinel; + +class WakeLockEvent final : public Event { + DEFINE_WRAPPERTYPEINFO(); + + public: + static WakeLockEvent* Create(const AtomicString& type, + const WakeLockEventInit* initializer); + + WakeLockEvent(const AtomicString& type, const WakeLockEventInit* initializer); + WakeLockEvent(const AtomicString& type, WakeLockSentinel* lock); + ~WakeLockEvent() override; + + // Web-exposed APIs. + WakeLockSentinel* lock() const; + + // Event overrides. + const AtomicString& InterfaceName() const override; + void Trace(blink::Visitor* visitor) override; + + private: + const Member<WakeLockSentinel> lock_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_EVENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_event.idl b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_event.idl new file mode 100644 index 00000000000..9ad1cfb5b7e --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_event.idl @@ -0,0 +1,12 @@ +// 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. + +[ + SecureContext, + Exposed=(DedicatedWorker,Window), + Constructor(DOMString type, WakeLockEventInit init), + RuntimeEnabled=WakeLock +] interface WakeLockEvent : Event { + readonly attribute WakeLockSentinel lock; +}; diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request_options.idl b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_event_init.idl index 074fe3c7a10..40d203e5e49 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_request_options.idl +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_event_init.idl @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/wake-lock/#the-wakelockrequestoptions-dictionary -dictionary WakeLockRequestOptions { - AbortSignal signal; +dictionary WakeLockEventInit : EventInit { + required WakeLockSentinel lock; }; diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.cc new file mode 100644 index 00000000000..2738eb99a9e --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.cc @@ -0,0 +1,81 @@ +// 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. + +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h" + +#include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/modules/event_target_modules_names.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_event.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_event_init.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h" +#include "third_party/blink/renderer/platform/bindings/script_state.h" + +namespace blink { + +WakeLockSentinel::WakeLockSentinel(ScriptState* script_state, + WakeLockType type, + WakeLockStateRecord* manager) + : ContextLifecycleObserver(ExecutionContext::From(script_state)), + manager_(manager), + type_(type) {} + +WakeLockSentinel::~WakeLockSentinel() = default; + +ScriptPromise WakeLockSentinel::release(ScriptState* script_state) { + DoRelease(); + return ScriptPromise::CastUndefined(script_state); +} + +String WakeLockSentinel::type() const { + switch (type_) { + case WakeLockType::kScreen: + return "screen"; + case WakeLockType::kSystem: + return "system"; + } +} + +ExecutionContext* WakeLockSentinel::GetExecutionContext() const { + return ContextLifecycleObserver::GetExecutionContext(); +} + +const AtomicString& WakeLockSentinel::InterfaceName() const { + return event_target_names::kWakeLockSentinel; +} + +void WakeLockSentinel::Trace(blink::Visitor* visitor) { + visitor->Trace(manager_); + EventTargetWithInlineData::Trace(visitor); + ContextLifecycleObserver::Trace(visitor); +} + +bool WakeLockSentinel::HasPendingActivity() const { + return HasEventListeners(); +} + +void WakeLockSentinel::ContextDestroyed(ExecutionContext*) { + // Release all event listeners so that HasPendingActivity() does not return + // true forever once a listener has been added to the object. + RemoveAllEventListeners(); + DCHECK(!HasEventListeners()); +} + +void WakeLockSentinel::DoRelease() { + if (!manager_) + return; + + manager_->UnregisterSentinel(this); + manager_.Clear(); + + // This function may be called on ExecutionContext destruction. Events should + // not be dispatched in this case. + if (!GetExecutionContext() || GetExecutionContext()->IsContextDestroyed()) + return; + + DispatchEvent( + *MakeGarbageCollected<WakeLockEvent>(event_type_names::kRelease, this)); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h new file mode 100644 index 00000000000..30d954a1f50 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h @@ -0,0 +1,72 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_SENTINEL_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_SENTINEL_H_ + +#include "base/gtest_prod_util.h" +#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/core/dom/events/event_target.h" +#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" +#include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_type.h" +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +class ExecutionContext; +class ScriptState; +class WakeLockStateRecord; + +class MODULES_EXPORT WakeLockSentinel final + : public EventTargetWithInlineData, + public ActiveScriptWrappable<WakeLockSentinel>, + public ContextLifecycleObserver { + DEFINE_WRAPPERTYPEINFO(); + USING_GARBAGE_COLLECTED_MIXIN(WakeLockSentinel); + + public: + WakeLockSentinel(ScriptState* script_state, + WakeLockType type, + WakeLockStateRecord* manager); + ~WakeLockSentinel() override; + + // Web-exposed interfaces + DEFINE_ATTRIBUTE_EVENT_LISTENER(release, kRelease) + ScriptPromise release(ScriptState*); + String type() const; + + // EventTarget overrides. + ExecutionContext* GetExecutionContext() const override; + const AtomicString& InterfaceName() const override; + void Trace(blink::Visitor*) override; + + // ActiveScriptWrappable overrides. + bool HasPendingActivity() const override; + + // ContextLifecycleObserver overrides. + void ContextDestroyed(ExecutionContext*) override; + + private: + friend class WakeLockStateRecord; + + // This function, which only has any effect once, detaches this sentinel from + // its |manager_|, and fires a "release" event. + // It is implemented separately from release() itself so that |manager_| can + // call it without triggering the creation of a new ScriptPromise, as it is + // not relevant to |manager_| and this function may be called from a context + // where |script_state_|'s context is no longer valid. + void DoRelease(); + + Member<WakeLockStateRecord> manager_; + const WakeLockType type_; + + FRIEND_TEST_ALL_PREFIXES(WakeLockSentinelTest, MultipleReleaseCalls); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WAKE_LOCK_SENTINEL_H_ diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.idl b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.idl new file mode 100644 index 00000000000..f747650f99a --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.idl @@ -0,0 +1,16 @@ +// 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. + +[ + ActiveScriptWrappable, + Exposed=(DedicatedWorker,Window), + RuntimeEnabled=WakeLock, + SecureContext +] interface WakeLockSentinel : EventTarget { + attribute EventHandler onrelease; + + readonly attribute WakeLockType type; + + [CallWith=ScriptState] Promise<void> release(); +}; diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel_test.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel_test.cc new file mode 100644 index 00000000000..e086827f145 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel_test.cc @@ -0,0 +1,121 @@ +// 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. + +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h" + +#include "base/callback.h" +#include "base/run_loop.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/events/native_event_listener.h" +#include "third_party/blink/renderer/modules/event_target_modules_names.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h" +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "v8/include/v8.h" + +namespace blink { + +namespace { + +class SyncEventListener final : public NativeEventListener { + public: + SyncEventListener(base::OnceClosure invocation_callback) + : invocation_callback_(std::move(invocation_callback)) {} + void Invoke(ExecutionContext*, Event*) override { + DCHECK(invocation_callback_); + std::move(invocation_callback_).Run(); + } + + private: + base::OnceClosure invocation_callback_; +}; + +} // namespace + +TEST(WakeLockSentinelTest, SentinelType) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + + auto* sentinel = MakeGarbageCollected<WakeLockSentinel>( + context.GetScriptState(), WakeLockType::kScreen, /*manager=*/nullptr); + EXPECT_EQ("screen", sentinel->type()); + + sentinel = MakeGarbageCollected<WakeLockSentinel>( + context.GetScriptState(), WakeLockType::kSystem, /*manager=*/nullptr); + EXPECT_EQ("system", sentinel->type()); +} + +TEST(WakeLockSentinelTest, MultipleReleaseCalls) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + + auto* state_record = MakeGarbageCollected<WakeLockStateRecord>( + context.GetDocument(), WakeLockType::kScreen); + auto* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise promise = resolver->Promise(); + state_record->AcquireWakeLock(resolver); + context.WaitForPromiseFulfillment(promise); + auto* sentinel = + ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel(promise); + ASSERT_NE(nullptr, sentinel); + + base::RunLoop run_loop; + auto* event_listener = + MakeGarbageCollected<SyncEventListener>(run_loop.QuitClosure()); + sentinel->addEventListener(event_type_names::kRelease, event_listener); + sentinel->release(context.GetScriptState()); + run_loop.Run(); + sentinel->removeEventListener(event_type_names::kRelease, event_listener); + + EXPECT_EQ(nullptr, sentinel->manager_); + + event_listener = MakeGarbageCollected<SyncEventListener>(WTF::Bind([]() { + EXPECT_TRUE(false) << "This event handler should not be reached."; + })); + sentinel->addEventListener(event_type_names::kRelease, event_listener); + sentinel->release(context.GetScriptState()); +} + +TEST(WakeLockSentinelTest, ContextDestruction) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + + auto* screen_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise screen_promise = screen_resolver->Promise(); + + auto* wake_lock = MakeGarbageCollected<WakeLock>(*context.GetDocument()); + wake_lock->DoRequest(WakeLockType::kScreen, screen_resolver); + + WakeLockStateRecord* state_record = + wake_lock->state_records_[static_cast<size_t>(WakeLockType::kScreen)]; + ASSERT_TRUE(state_record); + + context.WaitForPromiseFulfillment(screen_promise); + auto* sentinel = ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel( + screen_promise); + ASSERT_TRUE(sentinel); + + auto* event_listener = + MakeGarbageCollected<SyncEventListener>(WTF::Bind([]() { + EXPECT_TRUE(false) << "This event handler should not be reached."; + })); + sentinel->addEventListener(event_type_names::kRelease, event_listener); + EXPECT_TRUE(sentinel->HasPendingActivity()); + + context.GetDocument()->Shutdown(); + + // If the method returns false the object can be GC'ed. + EXPECT_FALSE(sentinel->HasPendingActivity()); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.cc index 37d8ba05609..c5194fb2dea 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.cc +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.cc @@ -5,19 +5,19 @@ #include "third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h" #include "base/logging.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/wake_lock/wake_lock.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.h" #include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { WakeLockStateRecord::WakeLockStateRecord(ExecutionContext* execution_context, WakeLockType type) - : wake_lock_type_(ToMojomWakeLockType(type)), - execution_context_(execution_context) { + : wake_lock_type_(type), execution_context_(execution_context) { DCHECK_NE(execution_context, nullptr); } @@ -37,60 +37,39 @@ void WakeLockStateRecord::AcquireWakeLock(ScriptPromiseResolver* resolver) { // 4.3. Add lockPromise to record.[[WakeLockStateRecord]]. // 5. Return active. if (!wake_lock_) { - auto* interface_provider = execution_context_->GetInterfaceProvider(); - DCHECK(interface_provider); mojo::Remote<mojom::blink::WakeLockService> wake_lock_service; - interface_provider->GetInterface( + execution_context_->GetBrowserInterfaceBroker().GetInterface( wake_lock_service.BindNewPipeAndPassReceiver()); - wake_lock_service->GetWakeLock( - wake_lock_type_, device::mojom::blink::WakeLockReason::kOther, - "Blink Wake Lock", wake_lock_.BindNewPipeAndPassReceiver()); + wake_lock_service->GetWakeLock(ToMojomWakeLockType(wake_lock_type_), + device::mojom::blink::WakeLockReason::kOther, + "Blink Wake Lock", + wake_lock_.BindNewPipeAndPassReceiver()); wake_lock_.set_disconnect_handler( WTF::Bind(&WakeLockStateRecord::OnWakeLockConnectionError, WrapWeakPersistent(this))); wake_lock_->RequestWakeLock(); } - DCHECK(!active_locks_.Contains(resolver)); - active_locks_.insert(resolver); + auto* sentinel = MakeGarbageCollected<WakeLockSentinel>( + resolver->GetScriptState(), wake_lock_type_, this); + wake_lock_sentinels_.insert(sentinel); + resolver->Resolve(sentinel); } -void WakeLockStateRecord::ReleaseWakeLock(ScriptPromiseResolver* resolver) { - // https://w3c.github.io/wake-lock/#release-wake-lock-algorithm - // 1. Reject lockPromise with an "AbortError" DOMException. - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kAbortError, "Wake Lock released")); +void WakeLockStateRecord::UnregisterSentinel(WakeLockSentinel* sentinel) { + auto iterator = wake_lock_sentinels_.find(sentinel); + DCHECK(iterator != wake_lock_sentinels_.end()); + wake_lock_sentinels_.erase(iterator); - // 2. Let document be the responsible document of the current settings object. - // 3. Let record be the platform wake lock's state record associated with - // document and type. - // 4. If record.[[ActiveLocks]] does not contain lockPromise, abort these - // steps. - auto iterator = active_locks_.find(resolver); - if (iterator == active_locks_.end()) - return; - - // 5. Remove lockPromise from record.[[ActiveLocks]]. - active_locks_.erase(iterator); - - // 6. If the internal slot [[ActiveLocks]] of all the platform wake lock's - // state records are all empty, then run the following steps in parallel: - // 6.1. Ask the underlying operation system to release the wake lock of type - // type and let success be true if the operation succeeded, or else - // false. - if (active_locks_.IsEmpty() && wake_lock_.is_bound()) { + if (wake_lock_sentinels_.IsEmpty() && wake_lock_.is_bound()) { wake_lock_->CancelWakeLock(); wake_lock_.reset(); - - // 6.2. If success is true and type is "screen" run the following: - // 6.2.1. Reset the platform-specific inactivity timer after which the - // screen is actually turned off. } } void WakeLockStateRecord::ClearWakeLocks() { - while (!active_locks_.IsEmpty()) - ReleaseWakeLock(*active_locks_.begin()); + while (!wake_lock_sentinels_.IsEmpty()) + (*wake_lock_sentinels_.begin())->DoRelease(); } void WakeLockStateRecord::OnWakeLockConnectionError() { @@ -100,7 +79,7 @@ void WakeLockStateRecord::OnWakeLockConnectionError() { void WakeLockStateRecord::Trace(blink::Visitor* visitor) { visitor->Trace(execution_context_); - visitor->Trace(active_locks_); + visitor->Trace(wake_lock_sentinels_); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h index 5a8a9af7841..c40a504771c 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record.h @@ -7,7 +7,7 @@ #include "base/gtest_prod_util.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/device/public/mojom/wake_lock.mojom-blink.h" +#include "services/device/public/mojom/wake_lock.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/wake_lock/wake_lock_type.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -16,45 +16,41 @@ namespace blink { class ExecutionContext; class ScriptPromiseResolver; +class WakeLockSentinel; // https://w3c.github.io/wake-lock/#concepts-and-state-record // Per-document and per-wake lock type internal data. -class MODULES_EXPORT WakeLockStateRecord - : public GarbageCollectedFinalized<WakeLockStateRecord> { +class MODULES_EXPORT WakeLockStateRecord final + : public GarbageCollected<WakeLockStateRecord> { public: WakeLockStateRecord(ExecutionContext*, WakeLockType); void AcquireWakeLock(ScriptPromiseResolver*); - void ReleaseWakeLock(ScriptPromiseResolver*); void ClearWakeLocks(); + void UnregisterSentinel(WakeLockSentinel*); + void Trace(blink::Visitor* visitor); private: - using ActiveLocksType = HeapHashSet<Member<ScriptPromiseResolver>>; - - friend class WakeLockControllerTest; - // Handle connection errors from |wake_lock_|. void OnWakeLockConnectionError(); - // A list of Promises representing active wake locks associated with the - // responsible document. - ActiveLocksType active_locks_; + // A set with all WakeLockSentinel instances belonging to this + // Navigator/WorkerNavigator. + HeapHashSet<Member<WakeLockSentinel>> wake_lock_sentinels_; // An actual platform WakeLock. If bound, it means there is an active wake // lock for a given type. mojo::Remote<device::mojom::blink::WakeLock> wake_lock_; - device::mojom::blink::WakeLockType wake_lock_type_; + WakeLockType wake_lock_type_; // ExecutionContext from which we will connect to |wake_lock_service_|. Member<ExecutionContext> execution_context_; FRIEND_TEST_ALL_PREFIXES(WakeLockStateRecordTest, AcquireWakeLock); FRIEND_TEST_ALL_PREFIXES(WakeLockStateRecordTest, ReleaseAllWakeLocks); - FRIEND_TEST_ALL_PREFIXES(WakeLockStateRecordTest, ReleaseNonExistentWakeLock); FRIEND_TEST_ALL_PREFIXES(WakeLockStateRecordTest, ReleaseOneWakeLock); - FRIEND_TEST_ALL_PREFIXES(WakeLockStateRecordTest, ReleaseRejectsPromise); FRIEND_TEST_ALL_PREFIXES(WakeLockStateRecordTest, ClearWakeLocks); FRIEND_TEST_ALL_PREFIXES(WakeLockStateRecordTest, WakeLockConnectionError); }; diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record_test.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record_test.cc index 3fea7bcfc3a..ed2828c27eb 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record_test.cc +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_state_record_test.cc @@ -33,6 +33,7 @@ TEST(WakeLockStateRecordTest, AcquireWakeLock) { MockWakeLock& screen_lock = wake_lock_service.get_wake_lock(WakeLockType::kScreen); EXPECT_FALSE(screen_lock.is_acquired()); + EXPECT_FALSE(state_record->wake_lock_.is_bound()); auto* resolver1 = MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); @@ -45,12 +46,19 @@ TEST(WakeLockStateRecordTest, AcquireWakeLock) { state_record->AcquireWakeLock(resolver2); screen_lock.WaitForRequest(); - EXPECT_EQ(v8::Promise::kPending, - ScriptPromiseUtils::GetPromiseState(promise1)); - EXPECT_EQ(v8::Promise::kPending, - ScriptPromiseUtils::GetPromiseState(promise2)); + context.WaitForPromiseFulfillment(promise1); + context.WaitForPromiseFulfillment(promise2); + + auto* sentinel1 = + ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel(promise1); + auto* sentinel2 = + ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel(promise2); + + EXPECT_TRUE(state_record->wake_lock_sentinels_.Contains(sentinel1)); + EXPECT_TRUE(state_record->wake_lock_sentinels_.Contains(sentinel2)); + EXPECT_EQ(2U, state_record->wake_lock_sentinels_.size()); EXPECT_TRUE(screen_lock.is_acquired()); - EXPECT_EQ(2U, state_record->active_locks_.size()); + EXPECT_TRUE(state_record->wake_lock_.is_bound()); } TEST(WakeLockStateRecordTest, ReleaseAllWakeLocks) { @@ -67,61 +75,20 @@ TEST(WakeLockStateRecordTest, ReleaseAllWakeLocks) { state_record->AcquireWakeLock(resolver); screen_lock.WaitForRequest(); + context.WaitForPromiseFulfillment(promise); - EXPECT_EQ(v8::Promise::kPending, - ScriptPromiseUtils::GetPromiseState(promise)); - EXPECT_EQ(1U, state_record->active_locks_.size()); + EXPECT_EQ(1U, state_record->wake_lock_sentinels_.size()); EXPECT_TRUE(screen_lock.is_acquired()); - state_record->ReleaseWakeLock(resolver); - context.WaitForPromiseRejection(promise); - screen_lock.WaitForCancelation(); - - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(promise)); - DOMException* dom_exception = - ScriptPromiseUtils::GetPromiseResolutionAsDOMException(promise); - ASSERT_NE(nullptr, dom_exception); - EXPECT_EQ("AbortError", dom_exception->name()); - - EXPECT_EQ(0U, state_record->active_locks_.size()); - EXPECT_FALSE(screen_lock.is_acquired()); -} - -// Test that trying to remove an entry that does not exist is a no-op. This can -// happen, for example, when a page visibility change releases a screen lock -// and a call to AbortController.abort() causes an attempt to release the same -// lock again. -TEST(WakeLockStateRecordTest, ReleaseNonExistentWakeLock) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto* state_record = MakeStateRecord(context, WakeLockType::kScreen); + auto* sentinel = + ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel(promise); - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - - auto* resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise promise = resolver->Promise(); - - state_record->AcquireWakeLock(resolver); - screen_lock.WaitForRequest(); - state_record->ReleaseWakeLock(resolver); - context.WaitForPromiseRejection(promise); + state_record->UnregisterSentinel(sentinel); screen_lock.WaitForCancelation(); - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(promise)); - EXPECT_EQ(0U, state_record->active_locks_.size()); - EXPECT_FALSE(screen_lock.is_acquired()); - - state_record->ReleaseWakeLock(resolver); - test::RunPendingTasks(); - - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(promise)); - EXPECT_EQ(0U, state_record->active_locks_.size()); + EXPECT_EQ(0U, state_record->wake_lock_sentinels_.size()); EXPECT_FALSE(screen_lock.is_acquired()); + EXPECT_FALSE(state_record->wake_lock_.is_bound()); } TEST(WakeLockStateRecordTest, ReleaseOneWakeLock) { @@ -143,54 +110,24 @@ TEST(WakeLockStateRecordTest, ReleaseOneWakeLock) { state_record->AcquireWakeLock(resolver2); screen_lock.WaitForRequest(); - EXPECT_EQ(v8::Promise::kPending, - ScriptPromiseUtils::GetPromiseState(promise1)); - EXPECT_EQ(v8::Promise::kPending, - ScriptPromiseUtils::GetPromiseState(promise2)); - EXPECT_EQ(2U, state_record->active_locks_.size()); - EXPECT_TRUE(screen_lock.is_acquired()); - - state_record->ReleaseWakeLock(resolver1); - context.WaitForPromiseRejection(promise1); + context.WaitForPromiseFulfillment(promise1); + context.WaitForPromiseFulfillment(promise2); - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(promise1)); - EXPECT_EQ(v8::Promise::kPending, - ScriptPromiseUtils::GetPromiseState(promise2)); - DOMException* dom_exception = - ScriptPromiseUtils::GetPromiseResolutionAsDOMException(promise1); - ASSERT_NE(nullptr, dom_exception); - EXPECT_EQ("AbortError", dom_exception->name()); - - EXPECT_EQ(1U, state_record->active_locks_.size()); EXPECT_TRUE(screen_lock.is_acquired()); -} - -TEST(WakeLockStateRecordTest, ReleaseRejectsPromise) { - MockWakeLockService wake_lock_service; - WakeLockTestingContext context(&wake_lock_service); - auto* state_record = MakeStateRecord(context, WakeLockType::kScreen); - - MockWakeLock& screen_lock = - wake_lock_service.get_wake_lock(WakeLockType::kScreen); - - auto* resolver = - MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); - ScriptPromise promise = resolver->Promise(); - - EXPECT_EQ(v8::Promise::kPending, - ScriptPromiseUtils::GetPromiseState(promise)); + EXPECT_EQ(2U, state_record->wake_lock_sentinels_.size()); - state_record->ReleaseWakeLock(resolver); - context.WaitForPromiseRejection(promise); + auto* sentinel1 = + ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel(promise1); + EXPECT_TRUE(state_record->wake_lock_sentinels_.Contains(sentinel1)); - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(promise)); - EXPECT_EQ(0U, state_record->active_locks_.size()); - EXPECT_FALSE(screen_lock.is_acquired()); + state_record->UnregisterSentinel(sentinel1); + EXPECT_FALSE(state_record->wake_lock_sentinels_.Contains(sentinel1)); + EXPECT_TRUE(state_record->wake_lock_.is_bound()); + EXPECT_EQ(1U, state_record->wake_lock_sentinels_.size()); + EXPECT_TRUE(screen_lock.is_acquired()); } -TEST(WakeLockStateRecordTest, ClearEmptyActiveLocksList) { +TEST(WakeLockStateRecordTest, ClearEmptyWakeLockSentinelList) { MockWakeLockService wake_lock_service; WakeLockTestingContext context(&wake_lock_service); auto* state_record = MakeStateRecord(context, WakeLockType::kSystem); @@ -223,26 +160,15 @@ TEST(WakeLockStateRecordTest, ClearWakeLocks) { state_record->AcquireWakeLock(resolver1); state_record->AcquireWakeLock(resolver2); system_lock.WaitForRequest(); + context.WaitForPromiseFulfillment(promise1); + context.WaitForPromiseFulfillment(promise2); + + EXPECT_EQ(2U, state_record->wake_lock_sentinels_.size()); state_record->ClearWakeLocks(); - context.WaitForPromiseRejection(promise1); - context.WaitForPromiseRejection(promise2); system_lock.WaitForCancelation(); - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(promise1)); - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(promise2)); - DOMException* dom_exception = - ScriptPromiseUtils::GetPromiseResolutionAsDOMException(promise1); - ASSERT_NE(nullptr, dom_exception); - EXPECT_EQ("AbortError", dom_exception->name()); - dom_exception = - ScriptPromiseUtils::GetPromiseResolutionAsDOMException(promise2); - ASSERT_NE(nullptr, dom_exception); - EXPECT_EQ("AbortError", dom_exception->name()); - - EXPECT_EQ(0U, state_record->active_locks_.size()); + EXPECT_EQ(0U, state_record->wake_lock_sentinels_.size()); EXPECT_FALSE(system_lock.is_acquired()); } @@ -264,25 +190,17 @@ TEST(WakeLockStateRecordTest, WakeLockConnectionError) { state_record->AcquireWakeLock(resolver1); state_record->AcquireWakeLock(resolver2); system_lock.WaitForRequest(); + context.WaitForPromiseFulfillment(promise1); + context.WaitForPromiseFulfillment(promise2); + EXPECT_EQ(2U, state_record->wake_lock_sentinels_.size()); + + // Unbind and wait for the disconnection to reach |wake_lock_|'s + // disconnection handler. system_lock.Unbind(); - context.WaitForPromiseRejection(promise1); - context.WaitForPromiseRejection(promise2); - - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(promise1)); - EXPECT_EQ(v8::Promise::kRejected, - ScriptPromiseUtils::GetPromiseState(promise2)); - DOMException* dom_exception = - ScriptPromiseUtils::GetPromiseResolutionAsDOMException(promise1); - ASSERT_NE(nullptr, dom_exception); - EXPECT_EQ("AbortError", dom_exception->name()); - dom_exception = - ScriptPromiseUtils::GetPromiseResolutionAsDOMException(promise2); - ASSERT_NE(nullptr, dom_exception); - EXPECT_EQ("AbortError", dom_exception->name()); - - EXPECT_EQ(0U, state_record->active_locks_.size()); + state_record->wake_lock_.FlushForTesting(); + + EXPECT_EQ(0U, state_record->wake_lock_sentinels_.size()); EXPECT_FALSE(state_record->wake_lock_); EXPECT_FALSE(system_lock.is_acquired()); } diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test.cc new file mode 100644 index 00000000000..049f2e99b89 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test.cc @@ -0,0 +1,212 @@ +// 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. + +#include "third_party/blink/renderer/modules/wake_lock/wake_lock.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h" +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "v8/include/v8.h" + +namespace blink { + +TEST(WakeLockTest, RequestWakeLockGranted) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + + auto* screen_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise screen_promise = screen_resolver->Promise(); + + auto* wake_lock = MakeGarbageCollected<WakeLock>(*context.GetDocument()); + wake_lock->DoRequest(WakeLockType::kScreen, screen_resolver); + + MockWakeLock& screen_lock = + wake_lock_service.get_wake_lock(WakeLockType::kScreen); + MockPermissionService& permission_service = context.GetPermissionService(); + + permission_service.WaitForPermissionRequest(WakeLockType::kScreen); + screen_lock.WaitForRequest(); + context.WaitForPromiseFulfillment(screen_promise); + + EXPECT_NE(nullptr, ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel( + screen_promise)); + EXPECT_TRUE(screen_lock.is_acquired()); +} + +TEST(WakeLockTest, RequestWakeLockDenied) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kSystem, mojom::blink::PermissionStatus::DENIED); + + auto* system_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise system_promise = system_resolver->Promise(); + + auto* wake_lock = MakeGarbageCollected<WakeLock>(*context.GetDocument()); + wake_lock->DoRequest(WakeLockType::kSystem, system_resolver); + + MockWakeLock& system_lock = + wake_lock_service.get_wake_lock(WakeLockType::kSystem); + MockPermissionService& permission_service = context.GetPermissionService(); + + permission_service.WaitForPermissionRequest(WakeLockType::kSystem); + context.WaitForPromiseRejection(system_promise); + + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(system_promise)); + EXPECT_FALSE(system_lock.is_acquired()); + + // System locks are not allowed by default, so the promise should have been + // rejected with a NotAllowedError DOMException. + DOMException* dom_exception = + ScriptPromiseUtils::GetPromiseResolutionAsDOMException(system_promise); + ASSERT_NE(dom_exception, nullptr); + EXPECT_EQ("NotAllowedError", dom_exception->name()); +} + +// https://w3c.github.io/wake-lock/#handling-document-loss-of-full-activity +TEST(WakeLockTest, LossOfDocumentActivity) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + + MockWakeLock& screen_lock = + wake_lock_service.get_wake_lock(WakeLockType::kScreen); + MockWakeLock& system_lock = + wake_lock_service.get_wake_lock(WakeLockType::kSystem); + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kSystem, mojom::blink::PermissionStatus::GRANTED); + + // First, acquire a handful of locks of different types. + auto* screen_resolver1 = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + screen_resolver1->Promise(); + auto* screen_resolver2 = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + screen_resolver2->Promise(); + auto* system_resolver1 = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + system_resolver1->Promise(); + + auto* wake_lock = MakeGarbageCollected<WakeLock>(*context.GetDocument()); + wake_lock->DoRequest(WakeLockType::kScreen, screen_resolver1); + wake_lock->DoRequest(WakeLockType::kScreen, screen_resolver2); + screen_lock.WaitForRequest(); + wake_lock->DoRequest(WakeLockType::kSystem, system_resolver1); + system_lock.WaitForRequest(); + + // Now shut down our Document and make sure all [[ActiveLocks]] slots have + // been cleared. We cannot check that the promises have been rejected because + // ScriptPromiseResolver::Reject() will bail out if we no longer have a valid + // execution context. + context.GetDocument()->Shutdown(); + screen_lock.WaitForCancelation(); + system_lock.WaitForCancelation(); + + EXPECT_FALSE(screen_lock.is_acquired()); + EXPECT_FALSE(system_lock.is_acquired()); +} + +// https://w3c.github.io/wake-lock/#handling-document-loss-of-visibility +TEST(WakeLockTest, PageVisibilityHidden) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kSystem, mojom::blink::PermissionStatus::GRANTED); + + MockWakeLock& screen_lock = + wake_lock_service.get_wake_lock(WakeLockType::kScreen); + auto* screen_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise screen_promise = screen_resolver->Promise(); + + MockWakeLock& system_lock = + wake_lock_service.get_wake_lock(WakeLockType::kSystem); + auto* system_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise system_promise = system_resolver->Promise(); + + auto* wake_lock = MakeGarbageCollected<WakeLock>(*context.GetDocument()); + wake_lock->DoRequest(WakeLockType::kScreen, screen_resolver); + screen_lock.WaitForRequest(); + wake_lock->DoRequest(WakeLockType::kSystem, system_resolver); + system_lock.WaitForRequest(); + + context.WaitForPromiseFulfillment(screen_promise); + context.WaitForPromiseFulfillment(system_promise); + + context.GetDocument()->GetPage()->SetIsHidden(true, false); + + screen_lock.WaitForCancelation(); + + EXPECT_FALSE(screen_lock.is_acquired()); + EXPECT_TRUE(system_lock.is_acquired()); + + context.GetDocument()->GetPage()->SetIsHidden(false, false); + + auto* other_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise other_promise = other_resolver->Promise(); + wake_lock->DoRequest(WakeLockType::kScreen, other_resolver); + screen_lock.WaitForRequest(); + context.WaitForPromiseFulfillment(other_promise); + EXPECT_TRUE(screen_lock.is_acquired()); +} + +// https://w3c.github.io/wake-lock/#handling-document-loss-of-visibility +TEST(WakeLockTest, PageVisibilityHiddenBeforeLockAcquisition) { + MockWakeLockService wake_lock_service; + WakeLockTestingContext context(&wake_lock_service); + + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kScreen, mojom::blink::PermissionStatus::GRANTED); + context.GetPermissionService().SetPermissionResponse( + WakeLockType::kSystem, mojom::blink::PermissionStatus::GRANTED); + + MockWakeLock& screen_lock = + wake_lock_service.get_wake_lock(WakeLockType::kScreen); + auto* screen_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise screen_promise = screen_resolver->Promise(); + + MockWakeLock& system_lock = + wake_lock_service.get_wake_lock(WakeLockType::kSystem); + auto* system_resolver = + MakeGarbageCollected<ScriptPromiseResolver>(context.GetScriptState()); + ScriptPromise system_promise = system_resolver->Promise(); + + auto* wake_lock = MakeGarbageCollected<WakeLock>(*context.GetDocument()); + wake_lock->DoRequest(WakeLockType::kScreen, screen_resolver); + wake_lock->DoRequest(WakeLockType::kSystem, system_resolver); + context.GetDocument()->GetPage()->SetIsHidden(true, false); + + context.WaitForPromiseRejection(screen_promise); + system_lock.WaitForRequest(); + context.WaitForPromiseFulfillment(system_promise); + + EXPECT_EQ(v8::Promise::kRejected, + ScriptPromiseUtils::GetPromiseState(screen_promise)); + DOMException* dom_exception = + ScriptPromiseUtils::GetPromiseResolutionAsDOMException(screen_promise); + ASSERT_NE(dom_exception, nullptr); + EXPECT_EQ("NotAllowedError", dom_exception->name()); + + EXPECT_FALSE(screen_lock.is_acquired()); + EXPECT_TRUE(system_lock.is_acquired()); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc index 35274834c92..804169849a8 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc @@ -10,9 +10,10 @@ #include "base/macros.h" #include "base/run_loop.h" #include "mojo/public/cpp/bindings/pending_receiver.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_wake_lock_sentinel.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/modules/wake_lock/wake_lock_type.h" #include "third_party/blink/renderer/platform/bindings/v8_binding.h" @@ -247,18 +248,26 @@ void MockPermissionService::AddPermissionObserver( WakeLockTestingContext::WakeLockTestingContext( MockWakeLockService* mock_wake_lock_service) { - service_manager::InterfaceProvider::TestApi test_api( - GetDocument()->GetInterfaceProvider()); - test_api.SetBinderForName( + GetDocument()->GetBrowserInterfaceBroker().SetBinderForTesting( mojom::blink::WakeLockService::Name_, WTF::BindRepeating(&MockWakeLockService::BindRequest, WTF::Unretained(mock_wake_lock_service))); - test_api.SetBinderForName( + GetDocument()->GetBrowserInterfaceBroker().SetBinderForTesting( mojom::blink::PermissionService::Name_, WTF::BindRepeating(&MockPermissionService::BindRequest, WTF::Unretained(&permission_service_))); } +WakeLockTestingContext::~WakeLockTestingContext() { + // Remove the testing binder to avoid crashes between tests caused by + // our mocks rebinding an already-bound Binding. + // See https://crbug.com/1010116 for more information. + GetDocument()->GetBrowserInterfaceBroker().SetBinderForTesting( + mojom::blink::WakeLockService::Name_, {}); + GetDocument()->GetBrowserInterfaceBroker().SetBinderForTesting( + mojom::blink::PermissionService::Name_, {}); +} + Document* WakeLockTestingContext::GetDocument() { return &testing_scope_.GetDocument(); } @@ -309,25 +318,16 @@ v8::Promise::PromiseState ScriptPromiseUtils::GetPromiseState( } // static -String ScriptPromiseUtils::GetPromiseResolutionAsString( +DOMException* ScriptPromiseUtils::GetPromiseResolutionAsDOMException( const ScriptPromise& promise) { - auto v8_promise = promise.V8Value().As<v8::Promise>(); - if (v8_promise->State() == v8::Promise::kPending) { - return g_empty_string; - } - ScriptValue promise_result(promise.GetScriptValue().GetScriptState(), - v8_promise->Result()); - String value; - if (!promise_result.ToString(value)) { - return g_empty_string; - } - return value; + return V8DOMException::ToImplWithTypeCheck( + promise.GetIsolate(), promise.V8Value().As<v8::Promise>()->Result()); } // static -DOMException* ScriptPromiseUtils::GetPromiseResolutionAsDOMException( +WakeLockSentinel* ScriptPromiseUtils::GetPromiseResolutionAsWakeLockSentinel( const ScriptPromise& promise) { - return V8DOMException::ToImplWithTypeCheck( + return V8WakeLockSentinel::ToImplWithTypeCheck( promise.GetIsolate(), promise.V8Value().As<v8::Promise>()->Result()); } diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h index 03a76b5eea2..a2630eb8955 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.h @@ -11,7 +11,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h" -#include "services/device/public/mojom/wake_lock.mojom-blink.h" +#include "services/device/public/mojom/wake_lock.mojom-blink-forward.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" #include "third_party/blink/public/mojom/wake_lock/wake_lock.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" @@ -22,7 +22,9 @@ namespace blink { +class DOMException; class Document; +class WakeLockSentinel; // Mock WakeLock implementation that tracks whether it's bound or acquired, and // provides a few helper methods to synchronously wait for RequestWakeLock() @@ -141,7 +143,7 @@ class MockPermissionService final : public mojom::blink::PermissionService { // MockWakeLockService mock_service; // WakeLockTestingContext context(&mock_service); // mojo::Remote<mojom::blink::WakeLockService> service; -// context.GetDocument()->GetInterfaceProvider()->GetInterface( +// context.GetDocument()->GetBrowserInterfaceBroker().GetInterface( // service.BindNewPipeAndPassReceiver()); // service->GetWakeLock(...); // Will call mock_service.GetWakeLock(). // } @@ -150,6 +152,7 @@ class WakeLockTestingContext final { public: WakeLockTestingContext(MockWakeLockService* mock_wake_lock_service); + ~WakeLockTestingContext(); Document* GetDocument(); LocalFrame* Frame(); @@ -174,15 +177,16 @@ class ScriptPromiseUtils final { static v8::Promise::PromiseState GetPromiseState( const ScriptPromise& promise); - // Shorthand for getting a String out of a ScriptPromise. This assumes the - // promise has been resolved with a string. If anything wrong happens during - // the conversion, an empty string is returned. - static String GetPromiseResolutionAsString(const ScriptPromise&); - // Shorthand for getting a DOMException* out of a ScriptPromise. This assumes // the promise has been resolved with a DOMException. If the conversion fails, // nullptr is returned. static DOMException* GetPromiseResolutionAsDOMException(const ScriptPromise&); + + // Shorthand for getting a WakeLockSentinel* out of a ScriptPromise. This + // assumes the promise has been resolved with a WakeLockSentinel. If the + // conversion fails, nullptr is returned. + static WakeLockSentinel* GetPromiseResolutionAsWakeLockSentinel( + const ScriptPromise&); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.cc b/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.cc new file mode 100644 index 00000000000..094a3baedb1 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.cc @@ -0,0 +1,57 @@ +// 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. + +#include "third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.h" + +#include "third_party/blink/renderer/core/workers/worker_navigator.h" +#include "third_party/blink/renderer/modules/wake_lock/wake_lock.h" + +namespace blink { + +WorkerNavigatorWakeLock::WorkerNavigatorWakeLock(WorkerNavigator& navigator) + : Supplement<WorkerNavigator>(navigator) {} + +// static +const char WorkerNavigatorWakeLock::kSupplementName[] = + "WorkerNavigatorWakeLock"; + +// static +WorkerNavigatorWakeLock& WorkerNavigatorWakeLock::From( + WorkerNavigator& navigator) { + WorkerNavigatorWakeLock* supplement = + Supplement<WorkerNavigator>::From<WorkerNavigatorWakeLock>(navigator); + if (!supplement) { + supplement = MakeGarbageCollected<WorkerNavigatorWakeLock>(navigator); + ProvideTo(navigator, supplement); + } + return *supplement; +} + +// static +WakeLock* WorkerNavigatorWakeLock::wakeLock(ScriptState* script_state, + WorkerNavigator& navigator) { + return WorkerNavigatorWakeLock::From(navigator).GetWakeLock(script_state); +} + +WakeLock* WorkerNavigatorWakeLock::GetWakeLock(ScriptState* script_state) { + if (!wake_lock_) { + auto* execution_context = ExecutionContext::From(script_state); + DCHECK(execution_context); + + // TODO(https://crbug.com/839117): Remove this check once the Exposed + // attribute is fixed to only expose this property in dedicated workers. + if (execution_context->IsDedicatedWorkerGlobalScope()) { + wake_lock_ = MakeGarbageCollected<WakeLock>( + *To<DedicatedWorkerGlobalScope>(execution_context)); + } + } + return wake_lock_; +} + +void WorkerNavigatorWakeLock::Trace(blink::Visitor* visitor) { + visitor->Trace(wake_lock_); + Supplement<WorkerNavigator>::Trace(visitor); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.h b/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.h new file mode 100644 index 00000000000..bc01e30e4a5 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.h @@ -0,0 +1,41 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WORKER_NAVIGATOR_WAKE_LOCK_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WORKER_NAVIGATOR_WAKE_LOCK_H_ + +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/supplementable.h" + +namespace blink { + +class ScriptState; +class WakeLock; +class WorkerNavigator; + +class WorkerNavigatorWakeLock final + : public GarbageCollected<WorkerNavigatorWakeLock>, + public Supplement<WorkerNavigator> { + USING_GARBAGE_COLLECTED_MIXIN(WorkerNavigatorWakeLock); + + public: + static const char kSupplementName[]; + + static WorkerNavigatorWakeLock& From(WorkerNavigator&); + + static WakeLock* wakeLock(ScriptState*, WorkerNavigator&); + + explicit WorkerNavigatorWakeLock(WorkerNavigator&); + + void Trace(blink::Visitor*) override; + + private: + WakeLock* GetWakeLock(ScriptState*); + + Member<WakeLock> wake_lock_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WAKE_LOCK_WORKER_NAVIGATOR_WAKE_LOCK_H_ diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.idl b/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.idl new file mode 100644 index 00000000000..ddcc2c2d006 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.idl @@ -0,0 +1,11 @@ +// 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. + +[ + ImplementedAs=WorkerNavigatorWakeLock, + RuntimeEnabled=WakeLock, + SecureContext +] partial interface WorkerNavigator { + [CallWith=ScriptState, SameObject] readonly attribute WakeLock wakeLock; +}; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc index 839d8c83973..bd76a6a7dec 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc @@ -155,6 +155,20 @@ AudioContext::AudioContext(Document& document, } Initialize(); + + // Compute the base latency now and cache the value since it doesn't change + // once the context is constructed. We need the destination to be initialized + // so we have to compute it here. + // + // TODO(hongchan): Due to the incompatible constructor between + // AudioDestinationNode and RealtimeAudioDestinationNode, casting directly + // from |destination()| is impossible. This is a temporary workaround until + // the refactoring is completed. + RealtimeAudioDestinationHandler& destination_handler = + static_cast<RealtimeAudioDestinationHandler&>( + destination()->GetAudioDestinationHandler()); + base_latency_ = destination_handler.GetFramesPerBuffer() / + static_cast<double>(sampleRate()); } void AudioContext::Uninitialize() { @@ -359,15 +373,7 @@ double AudioContext::baseLatency() const { DCHECK(IsMainThread()); DCHECK(destination()); - // TODO(hongchan): Due to the incompatible constructor between - // AudioDestinationNode and RealtimeAudioDestinationNode, casting directly - // from |destination()| is impossible. This is a temporary workaround until - // the refactoring is completed. - RealtimeAudioDestinationHandler& destination_handler = - static_cast<RealtimeAudioDestinationHandler&>( - destination()->GetAudioDestinationHandler()); - return destination_handler.GetFramesPerBuffer() / - static_cast<double>(sampleRate()); + return base_latency_; } MediaElementAudioSourceNode* AudioContext::createMediaElementSource( diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h index e0d4cf1aef2..013eee56725 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h @@ -176,6 +176,9 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext { // Represents whether a context is suspended by explicit |context.suspend()|. bool suspended_by_user_ = false; + // baseLatency for this context + double base_latency_ = 0; + // AudioContextManager for reporting audibility. mojo::Remote<mojom::blink::AudioContextManager> audio_context_manager_; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc index 168593bce8c..15496ffdc8b 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc @@ -45,13 +45,13 @@ namespace blink { AudioHandler::AudioHandler(NodeType node_type, AudioNode& node, float sample_rate) - : is_initialized_(false), + : last_processing_time_(-1), + last_non_silent_time_(0), + is_initialized_(false), node_type_(kNodeTypeUnknown), node_(&node), context_(node.context()), deferred_task_handler_(&context_->GetDeferredTaskHandler()), - last_processing_time_(-1), - last_non_silent_time_(0), connection_ref_count_(0), is_disabled_(false), channel_count_(2) { diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.h index f9c9b0688f4..5f716c83d44 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.h @@ -180,7 +180,7 @@ class MODULES_EXPORT AudioHandler : public ThreadSafeRefCounted<AudioHandler> { // will only process once per rendering time quantum even if it's called // repeatedly. This handles the case of "fanout" where an output is connected // to multiple AudioNode inputs. Called from context's audio thread. - void ProcessIfNecessary(uint32_t frames_to_process); + virtual void ProcessIfNecessary(uint32_t frames_to_process); // Called when a new connection has been made to one of our inputs or the // connection number of channels has changed. This potentially gives us @@ -267,6 +267,14 @@ class MODULES_EXPORT AudioHandler : public ThreadSafeRefCounted<AudioHandler> { // Force all inputs to take any channel interpretation changes into account. void UpdateChannelsForInputs(); + // The last time (context time) that his handler ran its Process() method. + // For each render quantum, we only want to process just once to handle fanout + // of this handler. + double last_processing_time_; + + // The last time (context time) when this node did not have silent inputs. + double last_non_silent_time_; + private: void SetNodeType(NodeType); @@ -289,9 +297,6 @@ class MODULES_EXPORT AudioHandler : public ThreadSafeRefCounted<AudioHandler> { Vector<std::unique_ptr<AudioNodeInput>> inputs_; Vector<std::unique_ptr<AudioNodeOutput>> outputs_; - double last_processing_time_; - double last_non_silent_time_; - int connection_ref_count_; bool is_disabled_; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc index ae1686cc677..72e7eb137d9 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc @@ -153,7 +153,7 @@ AudioWorkletProcessor* AudioWorkletGlobalScope::CreateProcessor( std::make_unique<ProcessorCreationParams>( name, std::move(message_port_channel))); - ScriptValue options(script_state, + ScriptValue options(isolate, ToV8(node_options->Deserialize(isolate), script_state)); ScriptValue instance; @@ -310,9 +310,9 @@ bool AudioWorkletGlobalScope::Process( // wrapper of v8::Object instance. ScriptValue result; if (!definition->ProcessFunction() - ->Invoke(processor, ScriptValue(script_state, inputs), - ScriptValue(script_state, outputs), - ScriptValue(script_state, param_values)) + ->Invoke(processor, ScriptValue(isolate, inputs), + ScriptValue(isolate, outputs), + ScriptValue(isolate, param_values)) .To(&result)) { // process() method call failed for some reason or an exception was thrown // by the user supplied code. Disable the processor to exclude it from the diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_object_proxy.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_object_proxy.cc index d720ccf90ec..2607d5b4ec7 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_object_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_object_proxy.cc @@ -41,8 +41,12 @@ void AudioWorkletObjectProxy::DidEvaluateModuleScript(bool success) { if (processor_info_list->size() == 0) return; + // This method is called by a loading task which calls + // WorkletModuleTreeClient::NotifyModuleTreeLoadFinished and + // SynchronizeWorkletProcessorInfoList needs to run in FIFO order with other + // loading tasks. PostCrossThreadTask( - *GetParentExecutionContextTaskRunners()->Get(TaskType::kInternalMedia), + *GetParentExecutionContextTaskRunners()->Get(TaskType::kInternalLoading), FROM_HERE, CrossThreadBindOnce( &AudioWorkletMessagingProxy::SynchronizeWorkletProcessorInfoList, diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h index c5fa9ee8346..4ff7ca44d3a 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.h @@ -25,7 +25,7 @@ class V8BlinkAudioWorkletProcessorConstructor; // This is constructed and destroyed on a worker thread, and all methods also // must be called on the worker thread. class MODULES_EXPORT AudioWorkletProcessorDefinition final - : public GarbageCollectedFinalized<AudioWorkletProcessorDefinition>, + : public GarbageCollected<AudioWorkletProcessorDefinition>, public NameClient { public: static AudioWorkletProcessorDefinition* Create( diff --git a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc index 34adef56ced..a9ecf56688a 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.cc @@ -151,6 +151,8 @@ void BaseAudioContext::Clear() { void BaseAudioContext::Uninitialize() { DCHECK(IsMainThread()); + MutexLocker locker(GetTearDownMutex()); + if (!IsDestinationInitialized()) return; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h index d5aadf7e58e..d6e4fe5e25f 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/base_audio_context.h @@ -328,6 +328,8 @@ class MODULES_EXPORT BaseAudioContext void ReportDidCreate() final; void ReportWillBeDestroyed() final; + Mutex& GetTearDownMutex() const { return tear_down_mutex_; } + protected: enum ContextType { kRealtimeContext, kOfflineContext }; @@ -429,6 +431,12 @@ class MODULES_EXPORT BaseAudioContext // This cannot be nullptr once it is assigned from AudioWorkletThread until // the BaseAudioContext goes away. WorkerThread* audio_worklet_thread_ = nullptr; + + // Due to the multi-threading architecture of WebAudio, it is possible that + // object allocated by the main thread still can be accessed by the audio + // rendering thread while this context is torn down (GCed) by + // |Uninitialize()|. + mutable Mutex tear_down_mutex_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc index 2dc8395143d..ce19fe6675c 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc @@ -31,6 +31,7 @@ #include "third_party/blink/renderer/modules/webaudio/convolver_options.h" #include "third_party/blink/renderer/platform/audio/reverb.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/instrumentation/histogram.h" // Note about empirical tuning: // The maximum FFT size affects reverb performance and accuracy. @@ -136,6 +137,12 @@ void ConvolverHandler::SetBuffer(AudioBuffer* buffer, return; } + { + // Get some statistics on the size of the impulse response. + UMA_HISTOGRAM_LONG_TIMES("WebAudio.ConvolverNode.ImpulseResponseLength", + base::TimeDelta::FromSecondsD(buffer->duration())); + } + // Wrap the AudioBuffer by an AudioBus. It's an efficient pointer set and not // a memcpy(). This memory is simply used in the Reverb constructor and no // reference to it is kept for later use in that class. diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc index 69a58ba8816..b0cc2b94ef4 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.cc @@ -293,24 +293,32 @@ bool OfflineAudioDestinationHandler::RenderIfNotSuspended( return true; } - DCHECK_GE(NumberOfInputs(), 1u); - - // This will cause the node(s) connected to us to process, which in turn will - // pull on their input(s), all the way backwards through the rendering graph. - AudioBus* rendered_bus = Input(0).Pull(destination_bus, number_of_frames); + { + MutexTryLocker try_locker(Context()->GetTearDownMutex()); + if (try_locker.Locked()) { + DCHECK_GE(NumberOfInputs(), 1u); + + // This will cause the node(s) connected to us to process, which in turn + // will pull on their input(s), all the way backwards through the + // rendering graph. + AudioBus* rendered_bus = Input(0).Pull(destination_bus, number_of_frames); + + if (!rendered_bus) { + destination_bus->Zero(); + } else if (rendered_bus != destination_bus) { + // in-place processing was not possible - so copy + destination_bus->CopyFrom(*rendered_bus); + } + } else { + destination_bus->Zero(); + } - if (!rendered_bus) { - destination_bus->Zero(); - } else if (rendered_bus != destination_bus) { - // in-place processing was not possible - so copy - destination_bus->CopyFrom(*rendered_bus); + // Process nodes which need a little extra help because they are not + // connected to anything, but still need to process. + Context()->GetDeferredTaskHandler().ProcessAutomaticPullNodes( + number_of_frames); } - // Process nodes which need a little extra help because they are not connected - // to anything, but still need to process. - Context()->GetDeferredTaskHandler().ProcessAutomaticPullNodes( - number_of_frames); - // Let the context take care of any business at the end of each render // quantum. Context()->HandlePostRenderTasks(); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc index c0ac6bd2294..da282b553eb 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc @@ -37,8 +37,6 @@ namespace blink { -using namespace vector_math; - OscillatorHandler::OscillatorHandler(AudioNode& node, float sample_rate, const String& oscillator_type, @@ -218,15 +216,16 @@ bool OscillatorHandler::CalculateSampleAccuratePhaseIncrements( // Convert from cents to rate scalar. float k = 1.0 / 1200; - Vsmul(detune_values, 1, &k, detune_values, 1, frames_to_process); + vector_math::Vsmul(detune_values, 1, &k, detune_values, 1, + frames_to_process); for (unsigned i = 0; i < frames_to_process; ++i) { detune_values[i] = std::exp2(detune_values[i]); } if (has_frequency_changes) { // Multiply frequencies by detune scalings. - Vmul(detune_values, 1, phase_increments, 1, phase_increments, 1, - frames_to_process); + vector_math::Vmul(detune_values, 1, phase_increments, 1, phase_increments, + 1, frames_to_process); } } else { // Handle ordinary parameter changes if there are no scheduled @@ -240,8 +239,8 @@ bool OscillatorHandler::CalculateSampleAccuratePhaseIncrements( ClampFrequency(phase_increments, frames_to_process, Context()->sampleRate() / 2); // Convert from frequency to wavetable increment. - Vsmul(phase_increments, 1, &final_scale, phase_increments, 1, - frames_to_process); + vector_math::Vsmul(phase_increments, 1, &final_scale, phase_increments, 1, + frames_to_process); } return has_sample_accurate_values; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc index eeb96c0e0c1..5eb9ad6251c 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc @@ -99,6 +99,69 @@ PannerHandler::~PannerHandler() { Uninitialize(); } +// PannerNode needs a custom ProcessIfNecessary to get the process lock when +// computing PropagatesSilence() to protect processing from changes happening to +// the panning model. This is very similar to AudioNode::ProcessIfNecessary. +void PannerHandler::ProcessIfNecessary(uint32_t frames_to_process) { + DCHECK(Context()->IsAudioThread()); + + if (!IsInitialized()) + return; + + // Ensure that we only process once per rendering quantum. + // This handles the "fanout" problem where an output is connected to multiple + // inputs. The first time we're called during this time slice we process, but + // after that we don't want to re-process, instead our output(s) will already + // have the results cached in their bus; + double current_time = Context()->currentTime(); + if (last_processing_time_ != current_time) { + // important to first update this time because of feedback loops in the + // rendering graph. + last_processing_time_ = current_time; + + PullInputs(frames_to_process); + + bool silent_inputs = InputsAreSilent(); + + { + // Need to protect calls to PropagetesSilence (and Process) because the + // main threda may be changing the panning model that modifies the + // TailTime and LatencyTime methods called by PropagatesSilence. + MutexTryLocker try_locker(process_lock_); + if (try_locker.Locked()) { + if (silent_inputs && PropagatesSilence()) { + SilenceOutputs(); + // AudioParams still need to be processed so that the value can be + // updated if there are automations or so that the upstream nodes get + // pulled if any are connected to the AudioParam. + ProcessOnlyAudioParams(frames_to_process); + } else { + // Unsilence the outputs first because the processing of the node may + // cause the outputs to go silent and we want to propagate that hint + // to the downstream nodes. (For example, a Gain node with a gain of + // 0 will want to silence its output.) + UnsilenceOutputs(); + Process(frames_to_process); + } + } else { + // We must be in the middle of changing the properties of the panner. + // Just output silence. + AudioBus* destination = Output(0).Bus(); + destination->Zero(); + } + } + + if (!silent_inputs) { + // Update |last_non_silent_time| AFTER processing this block. + // Doing it before causes |PropagateSilence()| to be one render + // quantum longer than necessary. + last_non_silent_time_ = + (Context()->CurrentSampleFrame() + frames_to_process) / + static_cast<double>(Context()->sampleRate()); + } + } +} + void PannerHandler::Process(uint32_t frames_to_process) { AudioBus* destination = Output(0).Bus(); @@ -114,10 +177,9 @@ void PannerHandler::Process(uint32_t frames_to_process) { } // The audio thread can't block on this lock, so we call tryLock() instead. - MutexTryLocker try_locker(process_lock_); MutexTryLocker try_listener_locker(Listener()->ListenerLock()); - if (try_locker.Locked() && try_listener_locker.Locked()) { + if (try_listener_locker.Locked()) { if (!Context()->HasRealtimeConstraint() && panning_model_ == Panner::kPanningModelHRTF) { // For an OfflineAudioContext, we need to make sure the HRTFDatabase diff --git a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h index 1b9cbbc32cb..8fe0ec50822 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h @@ -71,6 +71,7 @@ class PannerHandler final : public AudioHandler { ~PannerHandler() override; // AudioHandler + void ProcessIfNecessary(uint32_t frames_to_process) override; void Process(uint32_t frames_to_process) override; void ProcessSampleAccurateValues(AudioBus* destination, const AudioBus* source, diff --git a/chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.cc b/chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.cc index 78dafb2d847..b8a64742a0a 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/periodic_wave.cc @@ -49,8 +49,6 @@ const unsigned kMaxPeriodicWaveSize = 16384; const float kCentsPerRange = 1200 / kNumberOfOctaveBands; -using namespace vector_math; - PeriodicWave* PeriodicWave::Create(BaseAudioContext& context, const Vector<float>& real, const Vector<float>& imag, @@ -251,9 +249,9 @@ void PeriodicWave::CreateBandLimitedTables(const float* real_data, // arrays. Need to scale the data by fftSize to remove the scaling that the // inverse IFFT would do. float scale = fft_size; - Vsmul(real_data, 1, &scale, real_p, 1, number_of_components); + vector_math::Vsmul(real_data, 1, &scale, real_p, 1, number_of_components); scale = -scale; - Vsmul(imag_data, 1, &scale, imag_p, 1, number_of_components); + vector_math::Vsmul(imag_data, 1, &scale, imag_p, 1, number_of_components); // Find the starting bin where we should start culling. We need to clear // out the highest frequencies to band-limit the waveform. @@ -288,7 +286,7 @@ void PeriodicWave::CreateBandLimitedTables(const float* real_data, if (!disable_normalization) { if (!range_index) { float max_value; - Vmaxmgv(data, 1, &max_value, fft_size); + vector_math::Vmaxmgv(data, 1, &max_value, fft_size); if (max_value) normalization_scale = 1.0f / max_value; @@ -296,7 +294,7 @@ void PeriodicWave::CreateBandLimitedTables(const float* real_data, } // Apply normalization scale. - Vsmul(data, 1, &normalization_scale, data, 1, fft_size); + vector_math::Vsmul(data, 1, &normalization_scale, data, 1, fft_size); } } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc index 9f7119bb6cd..58caf2b93a0 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_node.cc @@ -198,28 +198,33 @@ void RealtimeAudioDestinationHandler::Render( // Only pull on the audio graph if we have not stopped the destination. It // takes time for the destination to stop, but we want to stop pulling before // the destination has actually stopped. - if (IsPullingAudioGraphAllowed()) { - // Renders the graph by pulling all the input(s) to this node. This will in - // turn pull on their input(s), all the way backwards through the graph. - AudioBus* rendered_bus = Input(0).Pull(destination_bus, number_of_frames); - - DCHECK(rendered_bus); - if (!rendered_bus) { - // AudioNodeInput might be in the middle of destruction. Then the internal - // summing bus will return as nullptr. Then zero out the output. + { + MutexTryLocker try_locker(context->GetTearDownMutex()); + if (try_locker.Locked() && IsPullingAudioGraphAllowed()) { + // Renders the graph by pulling all the inputs to this node. This will + // in turn pull on their inputs, all the way backwards through the graph. + AudioBus* rendered_bus = Input(0).Pull(destination_bus, number_of_frames); + + DCHECK(rendered_bus); + if (!rendered_bus) { + // AudioNodeInput might be in the middle of destruction. Then the + // internal summing bus will return as nullptr. Then zero out the + // output. + destination_bus->Zero(); + } else if (rendered_bus != destination_bus) { + // In-place processing was not possible. Copy the rendererd result to + // the given |destination_bus| buffer. + destination_bus->CopyFrom(*rendered_bus); + } + } else { destination_bus->Zero(); - } else if (rendered_bus != destination_bus) { - // In-place processing was not possible. Copy the rendererd result to the - // given |destination_bus| buffer. - destination_bus->CopyFrom(*rendered_bus); } - } else { - destination_bus->Zero(); - } - // Processes "automatic" nodes that are not connected to anything. This can - // be done after copying because it does not affect the rendered result. - context->GetDeferredTaskHandler().ProcessAutomaticPullNodes(number_of_frames); + // Processes "automatic" nodes that are not connected to anything. This can + // be done after copying because it does not affect the rendered result. + context->GetDeferredTaskHandler().ProcessAutomaticPullNodes( + number_of_frames); + } context->HandlePostRenderTasks(); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.cc index f81fa99e6a3..540b62de4ab 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_node.cc @@ -125,12 +125,11 @@ NotShared<DOMFloat32Array> WaveShaperNode::curve() { return NotShared<DOMFloat32Array>(nullptr); unsigned size = curve->size(); - scoped_refptr<WTF::Float32Array> new_curve = WTF::Float32Array::Create(size); - memcpy(new_curve->Data(), curve->data(), sizeof(float) * size); + NotShared<DOMFloat32Array> result(DOMFloat32Array::Create(size)); + memcpy(result.View()->Data(), curve->data(), sizeof(float) * size); - return NotShared<DOMFloat32Array>( - DOMFloat32Array::Create(std::move(new_curve))); + return result; } void WaveShaperNode::setOversample(const String& type) { diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.h b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.h index c561e1cfd54..cb56a462f5d 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.h @@ -38,7 +38,7 @@ class DatabaseThread; class ExecutionContext; class SecurityOrigin; -class DatabaseContext final : public GarbageCollectedFinalized<DatabaseContext>, +class DatabaseContext final : public GarbageCollected<DatabaseContext>, public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(DatabaseContext); diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.h b/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.h index 9eeae61fa89..3f5faf80f52 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.h @@ -43,7 +43,7 @@ class DatabaseTask; class SQLTransactionClient; class SQLTransactionCoordinator; -class DatabaseThread : public GarbageCollectedFinalized<DatabaseThread> { +class DatabaseThread final : public GarbageCollected<DatabaseThread> { public: DatabaseThread(); ~DatabaseThread(); diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h index dadec74db1c..19490afaa05 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.h @@ -39,8 +39,8 @@ namespace blink { class Database; -class InspectorDatabaseResource - : public GarbageCollectedFinalized<InspectorDatabaseResource> { +class InspectorDatabaseResource final + : public GarbageCollected<InspectorDatabaseResource> { public: InspectorDatabaseResource(Database*, const String& domain, diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.h index e6d736ad69c..dfe45739142 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.h @@ -45,8 +45,7 @@ class SQLTransaction; class SQLStatement final : public GarbageCollected<SQLStatement> { public: - class OnSuccessCallback - : public GarbageCollectedFinalized<OnSuccessCallback> { + class OnSuccessCallback : public GarbageCollected<OnSuccessCallback> { public: virtual ~OnSuccessCallback() = default; virtual void Trace(blink::Visitor*) {} @@ -73,7 +72,7 @@ class SQLStatement final : public GarbageCollected<SQLStatement> { Member<V8SQLStatementCallback> callback_; }; - class OnErrorCallback : public GarbageCollectedFinalized<OnErrorCallback> { + class OnErrorCallback : public GarbageCollected<OnErrorCallback> { public: virtual ~OnErrorCallback() = default; virtual void Trace(blink::Visitor*) {} diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.h index cc1756d369e..788633e4a14 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.h @@ -42,8 +42,7 @@ class SQLErrorData; class SQLResultSet; class SQLStatement; -class SQLStatementBackend final - : public GarbageCollectedFinalized<SQLStatementBackend> { +class SQLStatementBackend final : public GarbageCollected<SQLStatementBackend> { public: SQLStatementBackend(SQLStatement*, const String& statement, diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc index d8d85d19cb6..776d50e2724 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc @@ -347,7 +347,7 @@ void SQLTransaction::executeSql(ScriptState* script_state, void SQLTransaction::executeSql( ScriptState* script_state, const String& sql_statement, - const base::Optional<Vector<ScriptValue>>& arguments, + const base::Optional<HeapVector<ScriptValue>>& arguments, V8SQLStatementCallback* callback, V8SQLStatementErrorCallback* callback_error, ExceptionState& exception_state) { diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.h index 916d3f16d22..74d99c733fe 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.h @@ -56,8 +56,7 @@ class SQLTransaction final : public ScriptWrappable, DEFINE_WRAPPERTYPEINFO(); public: - class OnProcessCallback - : public GarbageCollectedFinalized<OnProcessCallback> { + class OnProcessCallback : public GarbageCollected<OnProcessCallback> { public: virtual ~OnProcessCallback() = default; virtual void Trace(blink::Visitor*) {} @@ -84,8 +83,7 @@ class SQLTransaction final : public ScriptWrappable, Member<V8SQLTransactionCallback> callback_; }; - class OnSuccessCallback - : public GarbageCollectedFinalized<OnSuccessCallback> { + class OnSuccessCallback : public GarbageCollected<OnSuccessCallback> { public: virtual ~OnSuccessCallback() = default; virtual void Trace(blink::Visitor*) {} @@ -111,7 +109,7 @@ class SQLTransaction final : public ScriptWrappable, Member<V8VoidCallback> callback_; }; - class OnErrorCallback : public GarbageCollectedFinalized<OnErrorCallback> { + class OnErrorCallback : public GarbageCollected<OnErrorCallback> { public: virtual ~OnErrorCallback() = default; virtual void Trace(blink::Visitor*) {} @@ -161,7 +159,7 @@ class SQLTransaction final : public ScriptWrappable, void executeSql(ScriptState*, const String& sql_statement, ExceptionState&); void executeSql(ScriptState*, const String& sql_statement, - const base::Optional<Vector<ScriptValue>>& arguments, + const base::Optional<HeapVector<ScriptValue>>& arguments, V8SQLStatementCallback*, V8SQLStatementErrorCallback*, ExceptionState&); diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.h index 3525a917caf..8c82b2eeb08 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.h @@ -47,8 +47,7 @@ class SQLTransaction; class SQLTransactionBackend; class SQLValue; -class SQLTransactionWrapper - : public GarbageCollectedFinalized<SQLTransactionWrapper> { +class SQLTransactionWrapper : public GarbageCollected<SQLTransactionWrapper> { public: virtual ~SQLTransactionWrapper() = default; virtual void Trace(blink::Visitor* visitor) {} @@ -59,7 +58,7 @@ class SQLTransactionWrapper }; class SQLTransactionBackend final - : public GarbageCollectedFinalized<SQLTransactionBackend>, + : public GarbageCollected<SQLTransactionBackend>, public SQLTransactionStateMachine<SQLTransactionBackend> { public: SQLTransactionBackend(Database*, diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h index 35e5be3d4f7..593bc5b3293 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.h @@ -44,8 +44,8 @@ namespace blink { class SQLTransactionBackend; -class SQLTransactionCoordinator - : public GarbageCollectedFinalized<SQLTransactionCoordinator> { +class SQLTransactionCoordinator final + : public GarbageCollected<SQLTransactionCoordinator> { public: SQLTransactionCoordinator(); void Trace(blink::Visitor*); diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.cc index 2762ed835db..afc4438a382 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs_file.cc @@ -146,6 +146,7 @@ SandboxedVfsFile* SandboxedVfsFile::FromSqliteFile(sqlite3_file* sqlite_file) { int SandboxedVfsFile::Close() { file_.Close(); + delete this; return SQLITE_OK; } diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc index c671a2a7776..aa45e44a2ad 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc @@ -143,7 +143,7 @@ ScriptValue EXTDisjointTimerQuery::getQueryEXT(ScriptState* script_state, GLenum pname) { WebGLExtensionScopedContext scoped(this); if (scoped.IsLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (pname == GL_QUERY_COUNTER_BITS_EXT) { if (target == GL_TIMESTAMP_EXT || target == GL_TIME_ELAPSED_EXT) { @@ -153,22 +153,22 @@ ScriptValue EXTDisjointTimerQuery::getQueryEXT(ScriptState* script_state, } scoped.Context()->SynthesizeGLError(GL_INVALID_ENUM, "getQuery", "invalid target/pname combination"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if (target == GL_TIME_ELAPSED_EXT && pname == GL_CURRENT_QUERY) { return current_elapsed_query_ ? WebGLAny(script_state, current_elapsed_query_) - : ScriptValue::CreateNull(script_state); + : ScriptValue::CreateNull(script_state->GetIsolate()); } if (target == GL_TIMESTAMP_EXT && pname == GL_CURRENT_QUERY) { - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } scoped.Context()->SynthesizeGLError(GL_INVALID_ENUM, "getQuery", "invalid target/pname combination"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } ScriptValue EXTDisjointTimerQuery::getQueryObjectEXT(ScriptState* script_state, @@ -176,15 +176,15 @@ ScriptValue EXTDisjointTimerQuery::getQueryObjectEXT(ScriptState* script_state, GLenum pname) { WebGLExtensionScopedContext scoped(this); if (scoped.IsLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (!scoped.Context()->ValidateWebGLObject("getQueryObjectEXT", query)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (current_elapsed_query_ == query) { scoped.Context()->SynthesizeGLError( GL_INVALID_OPERATION, "getQueryObjectEXT", "query is currently active"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } switch (pname) { @@ -202,7 +202,7 @@ ScriptValue EXTDisjointTimerQuery::getQueryObjectEXT(ScriptState* script_state, break; } - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } void EXTDisjointTimerQuery::Trace(blink::Visitor* visitor) { diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc index 00e91fcb9b1..b196c45c175 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc @@ -11,6 +11,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/webgl_any.h" #include "third_party/blink/renderer/modules/webgl/webgl_program.h" #include "third_party/blink/renderer/modules/webgl/webgl_uniform_location.h" +#include "third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -69,21 +70,71 @@ void WebGL2ComputeRenderingContextBase::dispatchComputeIndirect( ContextGL()->DispatchComputeIndirect(static_cast<GLintptr>(offset)); } +void WebGL2ComputeRenderingContextBase::drawArraysIndirect( + GLenum mode, + int64_t offset) { + if (!ValidateValueFitNonNegInt32("drawArraysIndirect", "offset", offset)) + return; + + if (!ValidateDrawArrays("drawArraysIndirect")) + return; + + if (!bound_vertex_array_object_->IsAllEnabledAttribBufferBound()) { + SynthesizeGLError(GL_INVALID_OPERATION, "drawArraysIndirect", + "no buffer is bound to enabled attribute"); + return; + } + + ScopedRGBEmulationColorMask emulation_color_mask(this, color_mask_, + drawing_buffer_.get()); + OnBeforeDrawCall(); + ContextGL()->DrawArraysIndirect( + mode, reinterpret_cast<void*>(static_cast<intptr_t>(offset))); +} + +void WebGL2ComputeRenderingContextBase::drawElementsIndirect( + GLenum mode, + GLenum type, + int64_t offset) { + if (!ValidateValueFitNonNegInt32("drawElementsIndirect", "offset", offset)) + return; + + // The buffer currently bound to the (GL_)DRAW_INDIRECT_BUFFER binding might + // be unpopulated at this point, so the validation of element array buffer + // offset in it needs to be deferred. By feeding a dummy in-range offset value + // here, other validation logic for indexed drawing can be reused. + int64_t dummy_offset = 0; + if (!ValidateDrawElements("drawElementsIndirect", type, dummy_offset)) + return; + + if (!bound_vertex_array_object_->IsAllEnabledAttribBufferBound()) { + SynthesizeGLError(GL_INVALID_OPERATION, "drawElementsIndirect", + "no buffer is bound to enabled attribute"); + return; + } + + ScopedRGBEmulationColorMask emulation_color_mask(this, color_mask_, + drawing_buffer_.get()); + OnBeforeDrawCall(); + ContextGL()->DrawElementsIndirect( + mode, type, reinterpret_cast<void*>(static_cast<intptr_t>(offset))); +} + ScriptValue WebGL2ComputeRenderingContextBase::getProgramInterfaceParameter( ScriptState* script_state, WebGLProgram* program, GLenum program_interface, GLenum pname) { if (!ValidateWebGLProgramOrShader("getProgramInterfaceParameter", program)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (!ValidateProgramInterface( "getProgramInterfaceParameter", program_interface)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (program_interface == GL_ATOMIC_COUNTER_BUFFER && pname == GL_MAX_NAME_LENGTH) { SynthesizeGLError(GL_INVALID_OPERATION, "getProgramInterfaceParameter", "atomic counter resources are not assigned name strings"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if (program_interface != GL_ATOMIC_COUNTER_BUFFER && program_interface != GL_SHADER_STORAGE_BLOCK && @@ -92,7 +143,7 @@ ScriptValue WebGL2ComputeRenderingContextBase::getProgramInterfaceParameter( SynthesizeGLError( GL_INVALID_OPERATION, "getProgramInterfaceParameter", "invalid parameter name for the specified program interface"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } switch (pname) { @@ -107,7 +158,7 @@ ScriptValue WebGL2ComputeRenderingContextBase::getProgramInterfaceParameter( default: SynthesizeGLError(GL_INVALID_ENUM, "getProgramInterfaceParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -164,7 +215,7 @@ String WebGL2ComputeRenderingContextBase::getProgramResourceName( return String(name.get(), static_cast<uint32_t>(length)); } -base::Optional<Vector<ScriptValue>> +base::Optional<HeapVector<ScriptValue>> WebGL2ComputeRenderingContextBase::getProgramResource( ScriptState* script_state, WebGLProgram* program, @@ -229,7 +280,7 @@ WebGL2ComputeRenderingContextBase::getProgramResource( // Interpret the returned values and construct the result array. The type of // each array element is the natural type for the requested property. - Vector<ScriptValue> result; + HeapVector<ScriptValue> result; wtf_size_t auxiliary_param_index = 0; wtf_size_t extended_param_index = auxiliary_params.size(); for (GLenum prop : props) { @@ -346,7 +397,7 @@ ScriptValue WebGL2ComputeRenderingContextBase::getParameter( ScriptState* script_state, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_SHADING_LANGUAGE_VERSION: { return WebGLAny( @@ -397,14 +448,14 @@ ScriptValue WebGL2ComputeRenderingContextBase::getIndexedParameter( GLenum target, GLuint index) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (target) { case GL_ATOMIC_COUNTER_BUFFER_BINDING: if (index >= bound_indexed_atomic_counter_buffers_.size()) { SynthesizeGLError(GL_INVALID_VALUE, "getIndexedParameter", "index out of range"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } return WebGLAny(script_state, bound_indexed_atomic_counter_buffers_[index].Get()); @@ -412,7 +463,7 @@ ScriptValue WebGL2ComputeRenderingContextBase::getIndexedParameter( if (index >= bound_indexed_shader_storage_buffers_.size()) { SynthesizeGLError(GL_INVALID_VALUE, "getIndexedParameter", "index out of range"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } return WebGLAny(script_state, bound_indexed_shader_storage_buffers_[index].Get()); @@ -620,11 +671,12 @@ ScriptValue WebGL2ComputeRenderingContextBase::WrapLocation( } case GL_UNIFORM: { if (location == -1) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); DCHECK_GE(location, 0); WebGLUniformLocation* uniform_location = WebGLUniformLocation::Create(program, location); - return ScriptValue(script_state, ToV8(uniform_location, script_state)); + return ScriptValue(script_state->GetIsolate(), + ToV8(uniform_location, script_state)); } default: { return WebGLAny(script_state, location); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h index c120a67e5a6..0953f26e985 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.h @@ -21,6 +21,10 @@ class WebGL2ComputeRenderingContextBase : public WebGL2RenderingContextBase { void dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ); void dispatchComputeIndirect(int64_t offset); + /* Draw indirect */ + void drawArraysIndirect(GLenum mode, int64_t offset); + void drawElementsIndirect(GLenum mode, GLenum type, int64_t offset); + /* Program interface query */ ScriptValue getProgramInterfaceParameter(ScriptState*, WebGLProgram*, @@ -32,7 +36,7 @@ class WebGL2ComputeRenderingContextBase : public WebGL2RenderingContextBase { String getProgramResourceName(WebGLProgram*, GLenum program_interface, GLuint index); - base::Optional<Vector<ScriptValue>> getProgramResource( + base::Optional<HeapVector<ScriptValue>> getProgramResource( ScriptState*, WebGLProgram*, GLenum program_interface, diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl index f63b65181ac..2dd697ff573 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.idl @@ -94,6 +94,10 @@ interface mixin WebGL2ComputeRenderingContextBase { void dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ); void dispatchComputeIndirect(GLintptr offset); + /* Draw indirect */ + void drawArraysIndirect(GLenum mode, GLintptr offset); + void drawElementsIndirect(GLenum mode, GLenum type, GLintptr offset); + /* Program interface query */ [CallWith=ScriptState] any getProgramInterfaceParameter(WebGLProgram program, GLenum programInterface, GLenum pname); GLuint getProgramResourceIndex(WebGLProgram program, GLenum programInterface, DOMString name); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc index 82dcc844fde..23713f10315 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc @@ -146,7 +146,7 @@ void WebGL2RenderingContext::RegisterContextExtensions() { RegisterExtension<WebGLMultiDrawInstanced>(webgl_multi_draw_instanced_, kDraftExtension); RegisterExtension<WebGLVideoTexture>(webgl_video_texture_, kDraftExtension); - RegisterExtension<OVRMultiview2>(ovr_multiview2_, kDraftExtension); + RegisterExtension<OVRMultiview2>(ovr_multiview2_); } void WebGL2RenderingContext::Trace(blink::Visitor* visitor) { diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc index 133cfbeeb9e..04915cb1372 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc @@ -487,12 +487,12 @@ ScriptValue WebGL2RenderingContextBase::getInternalformatParameter( GLenum internalformat, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (target != GL_RENDERBUFFER) { SynthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter", "invalid target"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } switch (internalformat) { @@ -549,13 +549,13 @@ ScriptValue WebGL2RenderingContextBase::getInternalformatParameter( SynthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter", "invalid internalformat when EXT_color_buffer_float " "is not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } break; default: SynthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter", "invalid internalformat"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } switch (pname) { @@ -577,7 +577,7 @@ ScriptValue WebGL2RenderingContextBase::getInternalformatParameter( default: SynthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3935,7 +3935,7 @@ ScriptValue WebGL2RenderingContextBase::getQuery(ScriptState* script_state, GLenum target, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (ExtensionEnabled(kEXTDisjointTimerQueryWebGL2Name)) { if (pname == GL_QUERY_COUNTER_BITS_EXT) { @@ -3946,23 +3946,23 @@ ScriptValue WebGL2RenderingContextBase::getQuery(ScriptState* script_state, } SynthesizeGLError(GL_INVALID_ENUM, "getQuery", "invalid target/pname combination"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if (target == GL_TIME_ELAPSED_EXT && pname == GL_CURRENT_QUERY) { return current_elapsed_query_ ? WebGLAny(script_state, current_elapsed_query_) - : ScriptValue::CreateNull(script_state); + : ScriptValue::CreateNull(script_state->GetIsolate()); } if (target == GL_TIMESTAMP_EXT && pname == GL_CURRENT_QUERY) { - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } if (pname != GL_CURRENT_QUERY) { SynthesizeGLError(GL_INVALID_ENUM, "getQuery", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } switch (target) { @@ -3977,9 +3977,9 @@ ScriptValue WebGL2RenderingContextBase::getQuery(ScriptState* script_state, current_transform_feedback_primitives_written_query_); default: SynthesizeGLError(GL_INVALID_ENUM, "getQuery", "invalid target"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } ScriptValue WebGL2RenderingContextBase::getQueryParameter( @@ -3987,21 +3987,21 @@ ScriptValue WebGL2RenderingContextBase::getQueryParameter( WebGLQuery* query, GLenum pname) { if (!ValidateWebGLObject("getQueryParameter", query)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); // Query is non-null at this point. if (!query->GetTarget()) { SynthesizeGLError(GL_INVALID_OPERATION, "getQueryParameter", "'query' is not a query object yet, since it has't been " "used by beginQuery"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if (query == current_boolean_occlusion_query_ || query == current_transform_feedback_primitives_written_query_ || query == current_elapsed_query_) { SynthesizeGLError(GL_INVALID_OPERATION, "getQueryParameter", "query is currently active"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } switch (pname) { @@ -4016,7 +4016,7 @@ ScriptValue WebGL2RenderingContextBase::getQueryParameter( default: SynthesizeGLError(GL_INVALID_ENUM, "getQueryParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -4152,6 +4152,13 @@ void WebGL2RenderingContextBase::SamplerParameter(WebGLSampler* sampler, return; } break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + if (!ExtensionEnabled(kEXTTextureFilterAnisotropicName)) { + SynthesizeGLError(GL_INVALID_ENUM, "samplerParameter", + "EXT_texture_filter_anisotropic not enabled"); + return; + } + break; default: SynthesizeGLError(GL_INVALID_ENUM, "samplerParameter", "invalid parameter name"); @@ -4182,7 +4189,7 @@ ScriptValue WebGL2RenderingContextBase::getSamplerParameter( WebGLSampler* sampler, GLenum pname) { if (!ValidateWebGLObject("getSamplerParameter", sampler)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_TEXTURE_COMPARE_FUNC: @@ -4202,10 +4209,20 @@ ScriptValue WebGL2RenderingContextBase::getSamplerParameter( ContextGL()->GetSamplerParameterfv(ObjectOrZero(sampler), pname, &value); return WebGLAny(script_state, value); } + case GL_TEXTURE_MAX_ANISOTROPY_EXT: { + if (!ExtensionEnabled(kEXTTextureFilterAnisotropicName)) { + SynthesizeGLError(GL_INVALID_ENUM, "samplerParameter", + "EXT_texture_filter_anisotropic not enabled"); + return ScriptValue::CreateNull(script_state->GetIsolate()); + } + GLfloat value = 0.f; + ContextGL()->GetSamplerParameterfv(ObjectOrZero(sampler), pname, &value); + return WebGLAny(script_state, value); + } default: SynthesizeGLError(GL_INVALID_ENUM, "getSamplerParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -4297,7 +4314,7 @@ ScriptValue WebGL2RenderingContextBase::getSyncParameter( WebGLSync* sync, GLenum pname) { if (!ValidateWebGLObject("getSyncParameter", sync)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_OBJECT_TYPE: @@ -4310,7 +4327,7 @@ ScriptValue WebGL2RenderingContextBase::getSyncParameter( default: SynthesizeGLError(GL_INVALID_ENUM, "getSyncParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -4644,7 +4661,7 @@ ScriptValue WebGL2RenderingContextBase::getIndexedParameter( GLenum target, GLuint index) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (target) { case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: { @@ -4653,7 +4670,7 @@ ScriptValue WebGL2RenderingContextBase::getIndexedParameter( index, &buffer)) { SynthesizeGLError(GL_INVALID_VALUE, "getIndexedParameter", "index out of range"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } return WebGLAny(script_state, buffer); } @@ -4661,7 +4678,7 @@ ScriptValue WebGL2RenderingContextBase::getIndexedParameter( if (index >= bound_indexed_uniform_buffers_.size()) { SynthesizeGLError(GL_INVALID_VALUE, "getIndexedParameter", "index out of range"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } return WebGLAny(script_state, bound_indexed_uniform_buffers_[index].Get()); @@ -4676,7 +4693,7 @@ ScriptValue WebGL2RenderingContextBase::getIndexedParameter( default: SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -4701,7 +4718,7 @@ ScriptValue WebGL2RenderingContextBase::getActiveUniforms( const Vector<GLuint>& uniform_indices, GLenum pname) { if (!ValidateWebGLProgramOrShader("getActiveUniforms", program)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); enum ReturnType { kEnumType, kUnsignedIntType, kIntType, kBoolType }; @@ -4725,7 +4742,7 @@ ScriptValue WebGL2RenderingContextBase::getActiveUniforms( default: SynthesizeGLError(GL_INVALID_ENUM, "getActiveUniforms", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLint active_uniforms = -1; @@ -4738,7 +4755,7 @@ ScriptValue WebGL2RenderingContextBase::getActiveUniforms( if (index >= active_uniforms_unsigned) { SynthesizeGLError(GL_INVALID_VALUE, "getActiveUniforms", "uniform index greater than ACTIVE_UNIFORMS"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -4770,7 +4787,7 @@ ScriptValue WebGL2RenderingContextBase::getActiveUniforms( } default: NOTREACHED(); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -4813,11 +4830,11 @@ ScriptValue WebGL2RenderingContextBase::getActiveUniformBlockParameter( GLuint uniform_block_index, GLenum pname) { if (!ValidateWebGLProgramOrShader("getActiveUniformBlockParameter", program)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (!ValidateUniformBlockIndex("getActiveUniformBlockParameter", program, uniform_block_index)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_UNIFORM_BLOCK_BINDING: @@ -4852,7 +4869,7 @@ ScriptValue WebGL2RenderingContextBase::getActiveUniformBlockParameter( default: SynthesizeGLError(GL_INVALID_ENUM, "getActiveUniformBlockParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -5016,7 +5033,7 @@ void WebGL2RenderingContextBase::deleteFramebuffer( ScriptValue WebGL2RenderingContextBase::getParameter(ScriptState* script_state, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_SHADING_LANGUAGE_VERSION: { return WebGLAny( @@ -5138,7 +5155,7 @@ ScriptValue WebGL2RenderingContextBase::getParameter(ScriptState* script_state, if (!transform_feedback_binding_->IsDefaultObject()) { return WebGLAny(script_state, transform_feedback_binding_.Get()); } - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_TRANSFORM_FEEDBACK_PAUSED: return GetBooleanParameter(script_state, pname); case GL_UNIFORM_BUFFER_BINDING: @@ -5162,7 +5179,7 @@ ScriptValue WebGL2RenderingContextBase::getParameter(ScriptState* script_state, SynthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, " "EXT_disjoint_timer_query_webgl2 not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_GPU_DISJOINT_EXT: if (ExtensionEnabled(kEXTDisjointTimerQueryWebGL2Name)) { return GetBooleanParameter(script_state, GL_GPU_DISJOINT_EXT); @@ -5170,7 +5187,7 @@ ScriptValue WebGL2RenderingContextBase::getParameter(ScriptState* script_state, SynthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, " "EXT_disjoint_timer_query_webgl2 not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: return WebGLRenderingContextBase::getParameter(script_state, pname); @@ -5557,7 +5574,7 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter( const char kFunctionName[] = "getFramebufferAttachmentParameter"; if (isContextLost() || !ValidateGetFramebufferAttachmentParameterFunc( kFunctionName, target, attachment)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); WebGLFramebuffer* framebuffer_binding = GetFramebufferBinding(target); DCHECK(!framebuffer_binding || framebuffer_binding->Object()); @@ -5578,7 +5595,7 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter( default: SynthesizeGLError(GL_INVALID_OPERATION, kFunctionName, "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } switch (pname) { @@ -5612,17 +5629,17 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter( return WebGLAny(script_state, 0); SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, "invalid parameter name, OVR_multiview2 not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR: if (ExtensionEnabled(kOVRMultiview2Name)) return WebGLAny(script_state, 0); SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, "invalid parameter name, OVR_multiview2 not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -5636,7 +5653,7 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter( SynthesizeGLError( GL_INVALID_OPERATION, kFunctionName, "different objects bound to DEPTH_ATTACHMENT and STENCIL_ATTACHMENT"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } attachment_object = depth_attachment; } else { @@ -5648,11 +5665,11 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter( case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: return WebGLAny(script_state, GL_NONE); case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: SynthesizeGLError(GL_INVALID_OPERATION, kFunctionName, "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } DCHECK(attachment_object->IsTexture() || attachment_object->IsRenderbuffer()); @@ -5686,7 +5703,7 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter( SynthesizeGLError( GL_INVALID_OPERATION, kFunctionName, "COMPONENT_TYPE can't be queried for DEPTH_STENCIL_ATTACHMENT"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } FALLTHROUGH; case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: { @@ -5700,7 +5717,7 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter( if (!ExtensionEnabled(kOVRMultiview2Name)) { SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, "invalid parameter name, OVR_multiview2 not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLint value = 0; ContextGL()->GetFramebufferAttachmentParameteriv(target, attachment, @@ -5711,7 +5728,7 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter( break; } SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } void WebGL2RenderingContextBase::Trace(blink::Visitor* visitor) { @@ -5769,7 +5786,7 @@ ScriptValue WebGL2RenderingContextBase::getTexParameter( GLenum target, GLenum pname) { if (isContextLost() || !ValidateTextureBinding("getTexParameter", target)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_TEXTURE_WRAP_R: diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc index 444834b91c6..5f30971ef34 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.cc @@ -12,7 +12,7 @@ WebGLCompressedTextureETC::WebGLCompressedTextureETC( WebGLRenderingContextBase* context) : WebGLExtension(context) { context->ExtensionsUtil()->EnsureExtensionEnabled( - "GL_CHROMIUM_compressed_texture_etc"); + "GL_ANGLE_compressed_texture_etc"); context->AddCompressedTextureFormat(GL_COMPRESSED_R11_EAC); context->AddCompressedTextureFormat(GL_COMPRESSED_SIGNED_R11_EAC); context->AddCompressedTextureFormat(GL_COMPRESSED_RGB8_ETC2); @@ -38,8 +38,7 @@ WebGLCompressedTextureETC* WebGLCompressedTextureETC::Create( bool WebGLCompressedTextureETC::Supported(WebGLRenderingContextBase* context) { Extensions3DUtil* extensions_util = context->ExtensionsUtil(); - return extensions_util->SupportsExtension( - "GL_CHROMIUM_compressed_texture_etc"); + return extensions_util->SupportsExtension("GL_ANGLE_compressed_texture_etc"); } const char* WebGLCompressedTextureETC::ExtensionName() { diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index 1a094f9a03b..03338285aa6 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc @@ -28,6 +28,7 @@ #include <memory> #include <utility> +#include "base/feature_list.h" #include "base/numerics/checked_math.h" #include "base/stl_util.h" #include "build/build_config.h" @@ -115,6 +116,10 @@ #include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h" namespace blink { +namespace { +const base::Feature kLowLatencyWebGLSwapChain{ + "LowLatencyWebGLSwapChain", base::FEATURE_DISABLED_BY_DEFAULT}; +} // namespace bool WebGLRenderingContextBase::webgl_context_limits_initialized_ = false; unsigned WebGLRenderingContextBase::max_active_webgl_contexts_ = 0; @@ -440,6 +445,7 @@ void StripComments::Process(UChar c) { break; case kMiddleOfLine: + case kInPreprocessorDirective: if (c == '/' && Peek(temp)) { if (temp == '/') { parse_state_ = kInSingleLineComment; @@ -463,14 +469,6 @@ void StripComments::Process(UChar c) { Emit(c); break; - case kInPreprocessorDirective: - // No matter what the character is, just pass it - // through. Do not parse comments in this state. This - // might not be the right thing to do long term, but it - // should handle the #error preprocessor directive. - Emit(c); - break; - case kInSingleLineComment: // Line-continuation characters are processed before comment processing. // Advance string if a new line character is immediately behind @@ -772,9 +770,11 @@ WebGLRenderingContextBase::GetStaticBitmapImage( } scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage( - AccelerationHint hint) const { + AccelerationHint hint) { if (!GetDrawingBuffer()) return nullptr; + + ScopedFramebufferRestorer fbo_restorer(this); GetDrawingBuffer()->ResolveAndBindForReadAndDraw(); // Use the drawing buffer size here instead of the canvas size to ensure that // sizing is consistent for the GetStaticBitmapImage() result. The forced @@ -1097,7 +1097,7 @@ scoped_refptr<DrawingBuffer> WebGLRenderingContextBase::CreateDrawingBuffer( : DrawingBuffer::kAllowChromiumImage; bool using_swap_chain = - RuntimeEnabledFeatures::WebGLSwapChainEnabled() && + base::FeatureList::IsEnabled(kLowLatencyWebGLSwapChain) && context_provider->GetCapabilities().shared_image_swap_chain && CreationAttributes().desynchronized; @@ -1391,22 +1391,31 @@ void WebGLRenderingContextBase::DidDraw() { CanvasRenderingContext::DidDraw(); } -void WebGLRenderingContextBase::PushFrame() { +bool WebGLRenderingContextBase::PushFrame() { int width = GetDrawingBuffer()->Size().Width(); int height = GetDrawingBuffer()->Size().Height(); + int submitted_frame = false; if (PaintRenderingResultsToCanvas(kBackBuffer)) { if (Host()->GetOrCreateCanvasResourceProvider(kPreferAcceleration)) { - Host()->PushFrame(Host()->ResourceProvider()->ProduceCanvasResource(), - SkIRect::MakeWH(width, height)); + submitted_frame = + Host()->PushFrame(Host()->ResourceProvider()->ProduceCanvasResource(), + SkIRect::MakeWH(width, height)); } } MarkLayerComposited(); + return submitted_frame; } void WebGLRenderingContextBase::FinalizeFrame() { if (GetDrawingBuffer() && GetDrawingBuffer()->UsingSwapChain()) GetDrawingBuffer()->PresentSwapChain(); marked_canvas_dirty_ = false; + + // For low-latency canvases + const bool webgl_overlay_enabled = + RuntimeEnabledFeatures::WebGLImageChromiumEnabled() || UsingSwapChain(); + if (canvas() && canvas()->LowLatencyEnabled() && !webgl_overlay_enabled) + PaintRenderingResultsToCanvas(kBackBuffer); } void WebGLRenderingContextBase::OnErrorMessage(const char* message, @@ -1611,7 +1620,7 @@ bool WebGLRenderingContextBase::ContextCreatedOnXRCompatibleAdapter() { bool WebGLRenderingContextBase::CopyRenderingResultsFromDrawingBuffer( CanvasResourceProvider* resource_provider, - SourceDrawingBuffer source_buffer) const { + SourceDrawingBuffer source_buffer) { if (!drawing_buffer_) return false; if (resource_provider->IsAccelerated()) { @@ -1657,8 +1666,7 @@ IntSize WebGLRenderingContextBase::DrawingBufferSize() const { return GetDrawingBuffer()->Size(); } -scoped_refptr<Uint8Array> -WebGLRenderingContextBase::PaintRenderingResultsToDataArray( +sk_sp<SkData> WebGLRenderingContextBase::PaintRenderingResultsToDataArray( SourceDrawingBuffer source_buffer) { if (isContextLost()) return nullptr; @@ -2911,7 +2919,7 @@ ScriptValue WebGLRenderingContextBase::getBufferParameter( GLenum target, GLenum pname) { if (isContextLost() || !ValidateBufferTarget("getBufferParameter", target)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_BUFFER_USAGE: { @@ -2929,7 +2937,7 @@ ScriptValue WebGLRenderingContextBase::getBufferParameter( default: SynthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3033,7 +3041,7 @@ ScriptValue WebGLRenderingContextBase::getExtension(ScriptState* script_state, ToV8(extension, script_state->GetContext()->Global(), script_state->GetIsolate()); - return ScriptValue(script_state, wrapped_extension); + return ScriptValue(script_state->GetIsolate(), wrapped_extension); } ScriptValue WebGLRenderingContextBase::getFramebufferAttachmentParameter( @@ -3044,18 +3052,18 @@ ScriptValue WebGLRenderingContextBase::getFramebufferAttachmentParameter( if (isContextLost() || !ValidateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (!framebuffer_binding_ || !framebuffer_binding_->Object()) { SynthesizeGLError(GL_INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if (framebuffer_binding_ && framebuffer_binding_->Opaque()) { SynthesizeGLError(GL_INVALID_OPERATION, "getFramebufferAttachmentParameter", "cannot query parameters of an opaque framebuffer"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } WebGLSharedObject* attachment_object = @@ -3067,7 +3075,7 @@ ScriptValue WebGLRenderingContextBase::getFramebufferAttachmentParameter( // specifies INVALID_OPERATION. SynthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } DCHECK(attachment_object->IsTexture() || attachment_object->IsRenderbuffer()); @@ -3093,11 +3101,11 @@ ScriptValue WebGLRenderingContextBase::getFramebufferAttachmentParameter( } SynthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: SynthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } else { switch (pname) { @@ -3114,11 +3122,11 @@ ScriptValue WebGLRenderingContextBase::getFramebufferAttachmentParameter( } SynthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: SynthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } } @@ -3126,7 +3134,7 @@ ScriptValue WebGLRenderingContextBase::getFramebufferAttachmentParameter( ScriptValue WebGLRenderingContextBase::getParameter(ScriptState* script_state, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); const int kIntZero = 0; switch (pname) { case GL_ACTIVE_TEXTURE: @@ -3336,7 +3344,7 @@ ScriptValue WebGLRenderingContextBase::getParameter(ScriptState* script_state, SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case WebGLDebugRendererInfo::kUnmaskedRendererWebgl: if (ExtensionEnabled(kWebGLDebugRendererInfoName)) return WebGLAny(script_state, @@ -3344,7 +3352,7 @@ ScriptValue WebGLRenderingContextBase::getParameter(ScriptState* script_state, SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case WebGLDebugRendererInfo::kUnmaskedVendorWebgl: if (ExtensionEnabled(kWebGLDebugRendererInfoName)) return WebGLAny(script_state, @@ -3352,59 +3360,60 @@ ScriptValue WebGLRenderingContextBase::getParameter(ScriptState* script_state, SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object if (ExtensionEnabled(kOESVertexArrayObjectName) || IsWebGL2OrHigher()) { if (!bound_vertex_array_object_->IsDefaultObject()) return WebGLAny(script_state, bound_vertex_array_object_.Get()); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic - if (ExtensionEnabled(kEXTTextureFilterAnisotropicName)) - return GetUnsignedIntParameter(script_state, - GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT); + if (ExtensionEnabled(kEXTTextureFilterAnisotropicName)) { + return GetFloatParameter(script_state, + GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT); + } SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_MAX_COLOR_ATTACHMENTS_EXT: // EXT_draw_buffers BEGIN if (ExtensionEnabled(kWebGLDrawBuffersName) || IsWebGL2OrHigher()) return WebGLAny(script_state, MaxColorAttachments()); SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_MAX_DRAW_BUFFERS_EXT: if (ExtensionEnabled(kWebGLDrawBuffersName) || IsWebGL2OrHigher()) return WebGLAny(script_state, MaxDrawBuffers()); SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_TIMESTAMP_EXT: if (ExtensionEnabled(kEXTDisjointTimerQueryName)) return WebGLAny(script_state, 0); SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, EXT_disjoint_timer_query not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_GPU_DISJOINT_EXT: if (ExtensionEnabled(kEXTDisjointTimerQueryName)) return GetBooleanParameter(script_state, GL_GPU_DISJOINT_EXT); SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, EXT_disjoint_timer_query not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_MAX_VIEWS_OVR: if (ExtensionEnabled(kOVRMultiview2Name)) return GetIntParameter(script_state, pname); SynthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OVR_multiview2 not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: if ((ExtensionEnabled(kWebGLDrawBuffersName) || IsWebGL2OrHigher()) && pname >= GL_DRAW_BUFFER0_EXT && @@ -3418,7 +3427,7 @@ ScriptValue WebGLRenderingContextBase::getParameter(ScriptState* script_state, } SynthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3427,7 +3436,7 @@ ScriptValue WebGLRenderingContextBase::getProgramParameter( WebGLProgram* program, GLenum pname) { if (!ValidateWebGLProgramOrShader("getProgramParamter", program)) { - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLint value = 0; @@ -3443,7 +3452,7 @@ ScriptValue WebGLRenderingContextBase::getProgramParameter( if (!ExtensionEnabled(kKHRParallelShaderCompileName)) { SynthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } bool completed; if (checkProgramCompletionQueryAvailable(program, &completed)) { @@ -3455,7 +3464,7 @@ ScriptValue WebGLRenderingContextBase::getProgramParameter( if (!IsWebGL2OrHigher()) { SynthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } FALLTHROUGH; case GL_ATTACHED_SHADERS: @@ -3467,7 +3476,7 @@ ScriptValue WebGLRenderingContextBase::getProgramParameter( if (!IsWebGL2OrHigher()) { SynthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } ContextGL()->GetProgramiv(ObjectOrZero(program), pname, &value); return WebGLAny(script_state, static_cast<unsigned>(value)); @@ -3480,7 +3489,7 @@ ScriptValue WebGLRenderingContextBase::getProgramParameter( default: SynthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3496,16 +3505,16 @@ ScriptValue WebGLRenderingContextBase::getRenderbufferParameter( GLenum target, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (target != GL_RENDERBUFFER) { SynthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid target"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if (!renderbuffer_binding_ || !renderbuffer_binding_->Object()) { SynthesizeGLError(GL_INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLint value = 0; @@ -3514,7 +3523,7 @@ ScriptValue WebGLRenderingContextBase::getRenderbufferParameter( if (!IsWebGL2OrHigher()) { SynthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } FALLTHROUGH; case GL_RENDERBUFFER_WIDTH: @@ -3534,7 +3543,7 @@ ScriptValue WebGLRenderingContextBase::getRenderbufferParameter( default: SynthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3543,7 +3552,7 @@ ScriptValue WebGLRenderingContextBase::getShaderParameter( WebGLShader* shader, GLenum pname) { if (!ValidateWebGLProgramOrShader("getShaderParameter", shader)) { - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLint value = 0; switch (pname) { @@ -3556,7 +3565,7 @@ ScriptValue WebGLRenderingContextBase::getShaderParameter( if (!ExtensionEnabled(kKHRParallelShaderCompileName)) { SynthesizeGLError(GL_INVALID_ENUM, "getShaderParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } ContextGL()->GetShaderiv(ObjectOrZero(shader), pname, &value); return WebGLAny(script_state, static_cast<bool>(value)); @@ -3566,7 +3575,7 @@ ScriptValue WebGLRenderingContextBase::getShaderParameter( default: SynthesizeGLError(GL_INVALID_ENUM, "getShaderParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3637,9 +3646,9 @@ ScriptValue WebGLRenderingContextBase::getTexParameter( GLenum target, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (!ValidateTextureBinding("getTexParameter", target)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_TEXTURE_MAG_FILTER: case GL_TEXTURE_MIN_FILTER: @@ -3658,11 +3667,11 @@ ScriptValue WebGLRenderingContextBase::getTexParameter( SynthesizeGLError( GL_INVALID_ENUM, "getTexParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: SynthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3671,12 +3680,12 @@ ScriptValue WebGLRenderingContextBase::getUniform( WebGLProgram* program, const WebGLUniformLocation* uniform_location) { if (!ValidateWebGLProgramOrShader("getUniform", program)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); DCHECK(uniform_location); if (uniform_location->Program() != program) { SynthesizeGLError(GL_INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLint location = uniform_location->Location(); @@ -3685,11 +3694,11 @@ ScriptValue WebGLRenderingContextBase::getUniform( ContextGL()->GetProgramiv(program_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length); if (max_name_length < 0) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (max_name_length == 0) { SynthesizeGLError(GL_INVALID_VALUE, "getUniform", "no active uniforms exist"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } // FIXME: make this more efficient using WebGLUniformLocation and caching @@ -3707,7 +3716,7 @@ ScriptValue WebGLRenderingContextBase::getUniform( &size, &type, reinterpret_cast<GLchar*>(name_ptr)); if (size < 0) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); String name(name_impl->Substring(0, name_length)); StringBuilder name_builder; // Strip "[0]" from the name if it's an array. @@ -3802,7 +3811,7 @@ ScriptValue WebGLRenderingContextBase::getUniform( SynthesizeGLError( GL_INVALID_VALUE, "getUniform", "unhandled type, WEBGL_video_texture extension not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } base_type = GL_INT; length = 1; @@ -3812,7 +3821,7 @@ ScriptValue WebGLRenderingContextBase::getUniform( // Can't handle this type SynthesizeGLError(GL_INVALID_VALUE, "getUniform", "unhandled type"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } // handle GLenums for WebGL 2.0 or higher switch (type) { @@ -3887,7 +3896,7 @@ ScriptValue WebGLRenderingContextBase::getUniform( if (context_type_ != Platform::kWebGL2ComputeContextType) { SynthesizeGLError(GL_INVALID_VALUE, "getUniform", "unhandled type"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } base_type = GL_INT; length = 1; @@ -3897,7 +3906,7 @@ ScriptValue WebGLRenderingContextBase::getUniform( // Can't handle this type SynthesizeGLError(GL_INVALID_VALUE, "getUniform", "unhandled type"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } switch (base_type) { @@ -3944,7 +3953,7 @@ ScriptValue WebGLRenderingContextBase::getUniform( // If we get here, something went wrong in our unfortunately complex logic // above SynthesizeGLError(GL_INVALID_VALUE, "getUniform", "unknown error"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } WebGLUniformLocation* WebGLRenderingContextBase::getUniformLocation( @@ -3975,11 +3984,11 @@ ScriptValue WebGLRenderingContextBase::getVertexAttrib( GLuint index, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (index >= max_vertex_attribs_) { SynthesizeGLError(GL_INVALID_VALUE, "getVertexAttrib", "index out of range"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if ((ExtensionEnabled(kANGLEInstancedArraysName) || IsWebGL2OrHigher()) && @@ -4033,7 +4042,7 @@ ScriptValue WebGLRenderingContextBase::getVertexAttrib( NOTREACHED(); break; } - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } case GL_VERTEX_ATTRIB_ARRAY_INTEGER: if (IsWebGL2OrHigher()) { @@ -4045,7 +4054,7 @@ ScriptValue WebGLRenderingContextBase::getVertexAttrib( default: SynthesizeGLError(GL_INVALID_ENUM, "getVertexAttrib", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -5455,9 +5464,13 @@ void WebGLRenderingContextBase::TexImageHelperCanvasRenderingContextHost( // TODO(crbug.com/612542): Implement GPU-to-GPU copy path for more // cases, like copying to layers of 3D textures, and elements of // 2D texture arrays. + bool flip_y = unpack_flip_y_; + if (is_origin_top_left_ && is_webgl_canvas) + flip_y = !flip_y; + TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset, zoffset, format, type, image.get(), - WebGLImageConversion::kHtmlDomCanvas, unpack_flip_y_, + WebGLImageConversion::kHtmlDomCanvas, flip_y, unpack_premultiply_alpha_, source_sub_rectangle, depth, unpack_image_height); } @@ -5722,7 +5735,7 @@ void WebGLRenderingContextBase::TexImageHelperImageBitmap( SkPixmap pixmap; uint8_t* pixel_data_ptr = nullptr; - scoped_refptr<Uint8Array> pixel_data; + Vector<uint8_t> pixel_data; // In the case where an ImageBitmap is not texture backed, peekPixels() always // succeed. However, when it is texture backed and !canUseTexImageByGPU, we // do a GPU read back. @@ -5732,7 +5745,7 @@ void WebGLRenderingContextBase::TexImageHelperImageBitmap( } else { pixel_data = bitmap->CopyBitmapData( bitmap->IsPremultiplied() ? kPremultiplyAlpha : kUnpremultiplyAlpha); - pixel_data_ptr = pixel_data->Data(); + pixel_data_ptr = pixel_data.data(); } Vector<uint8_t> data; bool need_conversion = true; @@ -6803,7 +6816,7 @@ ScriptValue WebGLRenderingContextBase::GetIntParameter( if (value == 0) { // This indicates read framebuffer is incomplete and an // INVALID_OPERATION has been generated. - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } break; default: @@ -7502,9 +7515,12 @@ void WebGLRenderingContextBase::PrintGLErrorToConsole(const String& message) { } void WebGLRenderingContextBase::PrintWarningToConsole(const String& message) { - Host()->GetTopExecutionContext()->AddConsoleMessage( - ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering, - mojom::ConsoleMessageLevel::kWarning, message)); + blink::ExecutionContext* context = Host()->GetTopExecutionContext(); + if (context) { + context->AddConsoleMessage( + ConsoleMessage::Create(mojom::ConsoleMessageSource::kRendering, + mojom::ConsoleMessageLevel::kWarning, message)); + } } bool WebGLRenderingContextBase::ValidateFramebufferFuncParameters( diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h index c2fc04ae55e..8368b2766c2 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h @@ -56,6 +56,7 @@ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES3/gl31.h" +#include "third_party/skia/include/core/SkData.h" namespace cc { class Layer; @@ -566,8 +567,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, void MarkLayerComposited() override; - scoped_refptr<Uint8Array> PaintRenderingResultsToDataArray( - SourceDrawingBuffer) override; + sk_sp<SkData> PaintRenderingResultsToDataArray(SourceDrawingBuffer) override; void ProvideBackBufferToResourceProvider() const override; unsigned MaxVertexAttribs() const { return max_vertex_attribs_; } @@ -596,7 +596,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, }; scoped_refptr<StaticBitmapImage> GetImage( - AccelerationHint = kPreferAcceleration) const override; + AccelerationHint = kPreferAcceleration) override; void SetFilterQuality(SkFilterQuality) override; bool IsWebGL2OrHigher() { return context_type_ == Platform::kWebGL2ContextType || @@ -669,7 +669,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, void DidDraw(const SkIRect&) override; void DidDraw() override; void FinalizeFrame() override; - void PushFrame() override; + bool PushFrame() override; // DrawingBuffer::Client implementation. bool DrawingBufferClientIsBoundForDraw() override; @@ -1740,7 +1740,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, bool ContextCreatedOnXRCompatibleAdapter(); bool CopyRenderingResultsFromDrawingBuffer(CanvasResourceProvider*, - SourceDrawingBuffer) const; + SourceDrawingBuffer); void HoldReferenceToDrawingBuffer(DrawingBuffer*); static void InitializeWebGLContextLimits( diff --git a/chromium/third_party/blink/renderer/modules/webgpu/BUILD.gn b/chromium/third_party/blink/renderer/modules/webgpu/BUILD.gn index 0837d1e3b19..ef46d408147 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/webgpu/BUILD.gn @@ -35,6 +35,8 @@ blink_modules_sources("webgpu") { "gpu_compute_pipeline.h", "gpu_device.cc", "gpu_device.h", + "gpu_device_lost_info.cc", + "gpu_device_lost_info.h", "gpu_fence.cc", "gpu_fence.h", "gpu_out_of_memory_error.cc", diff --git a/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc b/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc index 8689267ffbd..af1fb2af52e 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc @@ -6,10 +6,10 @@ #include <dawn/dawn.h> -#include "third_party/blink/renderer/modules/webgpu/gpu_color.h" -#include "third_party/blink/renderer/modules/webgpu/gpu_extent_3d.h" -#include "third_party/blink/renderer/modules/webgpu/gpu_origin_3d.h" -#include "third_party/blink/renderer/modules/webgpu/gpu_pipeline_stage_descriptor.h" +#include "third_party/blink/renderer/bindings/modules/v8/double_sequence_or_gpu_color_dict.h" +#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_extent_3d_dict.h" +#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_origin_3d_dict.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.h" #include "third_party/blink/renderer/modules/webgpu/gpu_shader_module.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -32,6 +32,9 @@ DawnBindingType AsDawnEnum<DawnBindingType>(const WTF::String& webgpu_enum) { if (webgpu_enum == "sampled-texture") { return DAWN_BINDING_TYPE_SAMPLED_TEXTURE; } + if (webgpu_enum == "storage-texture") { + return DAWN_BINDING_TYPE_STORAGE_TEXTURE; + } NOTREACHED(); return DAWN_BINDING_TYPE_FORCE32; } @@ -291,6 +294,9 @@ DawnStoreOp AsDawnEnum<DawnStoreOp>(const WTF::String& webgpu_enum) { if (webgpu_enum == "store") { return DAWN_STORE_OP_STORE; } + if (webgpu_enum == "clear") { + return DAWN_STORE_OP_CLEAR; + } NOTREACHED(); return DAWN_STORE_OP_FORCE32; } @@ -420,154 +426,57 @@ DawnInputStepMode AsDawnEnum<DawnInputStepMode>( template <> DawnVertexFormat AsDawnEnum<DawnVertexFormat>(const WTF::String& webgpu_enum) { - if (webgpu_enum == "uchar") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "uchar2") { return DAWN_VERTEX_FORMAT_UCHAR2; } - if (webgpu_enum == "uchar3") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "uchar4") { return DAWN_VERTEX_FORMAT_UCHAR4; } - if (webgpu_enum == "char") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "char2") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } - if (webgpu_enum == "char3") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; + return DAWN_VERTEX_FORMAT_CHAR2; } if (webgpu_enum == "char4") { return DAWN_VERTEX_FORMAT_CHAR4; } - if (webgpu_enum == "ucharnorm") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "uchar2norm") { return DAWN_VERTEX_FORMAT_UCHAR2_NORM; } - if (webgpu_enum == "uchar3norm") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "uchar4norm") { return DAWN_VERTEX_FORMAT_UCHAR4_NORM; } - if (webgpu_enum == "uchar4norm-bgra") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } - if (webgpu_enum == "charnorm") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "char2norm") { return DAWN_VERTEX_FORMAT_CHAR2_NORM; } - if (webgpu_enum == "char3norm") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "char4norm") { return DAWN_VERTEX_FORMAT_CHAR4_NORM; } - if (webgpu_enum == "ushort") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "ushort2") { return DAWN_VERTEX_FORMAT_USHORT2; } - if (webgpu_enum == "ushort3") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "ushort4") { return DAWN_VERTEX_FORMAT_USHORT4; } - if (webgpu_enum == "short") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "short2") { return DAWN_VERTEX_FORMAT_SHORT2; } - if (webgpu_enum == "short3") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "short4") { return DAWN_VERTEX_FORMAT_SHORT4; } - if (webgpu_enum == "ushortnorm") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "ushort2norm") { return DAWN_VERTEX_FORMAT_USHORT2_NORM; } - if (webgpu_enum == "ushort3norm") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "ushort4norm") { return DAWN_VERTEX_FORMAT_USHORT4_NORM; } - if (webgpu_enum == "shortnorm") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "short2norm") { return DAWN_VERTEX_FORMAT_SHORT2_NORM; } - if (webgpu_enum == "short3norm") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "short4norm") { return DAWN_VERTEX_FORMAT_SHORT4_NORM; } - if (webgpu_enum == "half") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "half2") { return DAWN_VERTEX_FORMAT_HALF2; } - if (webgpu_enum == "half3") { - // TODO(crbug.com/dawn/41): Implement remaining vertex formats - NOTREACHED(); - return DAWN_VERTEX_FORMAT_FORCE32; - } if (webgpu_enum == "half4") { return DAWN_VERTEX_FORMAT_HALF4; } @@ -665,7 +574,50 @@ DawnFrontFace AsDawnEnum<DawnFrontFace>(const WTF::String& webgpu_enum) { return DAWN_FRONT_FACE_FORCE32; } -DawnColor AsDawnType(const GPUColor* webgpu_color) { +template <> +DawnTextureAspect AsDawnEnum<DawnTextureAspect>( + const WTF::String& webgpu_enum) { + if (webgpu_enum == "all") { + return DAWN_TEXTURE_ASPECT_ALL; + } + if (webgpu_enum == "stencil-only") { + return DAWN_TEXTURE_ASPECT_STENCIL_ONLY; + } + if (webgpu_enum == "depth-only") { + return DAWN_TEXTURE_ASPECT_DEPTH_ONLY; + } + NOTREACHED(); + return DAWN_TEXTURE_ASPECT_FORCE32; +} + +template <> +DawnErrorFilter AsDawnEnum<DawnErrorFilter>(const WTF::String& webgpu_enum) { + if (webgpu_enum == "none") { + return DAWN_ERROR_FILTER_NONE; + } + if (webgpu_enum == "out-of-memory") { + return DAWN_ERROR_FILTER_OUT_OF_MEMORY; + } + if (webgpu_enum == "validation") { + return DAWN_ERROR_FILTER_VALIDATION; + } + NOTREACHED(); + return DAWN_ERROR_FILTER_FORCE32; +} + +DawnColor AsDawnColor(const Vector<double>& webgpu_color) { + DCHECK_EQ(webgpu_color.size(), 4UL); + + DawnColor dawn_color = {}; + dawn_color.r = webgpu_color[0]; + dawn_color.g = webgpu_color[1]; + dawn_color.b = webgpu_color[2]; + dawn_color.a = webgpu_color[3]; + + return dawn_color; +} + +DawnColor AsDawnType(const GPUColorDict* webgpu_color) { DCHECK(webgpu_color); DawnColor dawn_color = {}; @@ -677,30 +629,77 @@ DawnColor AsDawnType(const GPUColor* webgpu_color) { return dawn_color; } -DawnExtent3D AsDawnType(const GPUExtent3D* webgpu_extent) { +DawnColor AsDawnType(const DoubleSequenceOrGPUColorDict* webgpu_color) { + DCHECK(webgpu_color); + + if (webgpu_color->IsDoubleSequence()) { + return AsDawnColor(webgpu_color->GetAsDoubleSequence()); + } else if (webgpu_color->IsGPUColorDict()) { + return AsDawnType(webgpu_color->GetAsGPUColorDict()); + } + NOTREACHED(); + DawnColor dawn_color = {}; + return dawn_color; +} + +DawnExtent3D AsDawnType( + const UnsignedLongSequenceOrGPUExtent3DDict* webgpu_extent) { DCHECK(webgpu_extent); DawnExtent3D dawn_extent = {}; - dawn_extent.width = webgpu_extent->width(); - dawn_extent.height = webgpu_extent->height(); - dawn_extent.depth = webgpu_extent->depth(); + + if (webgpu_extent->IsUnsignedLongSequence()) { + const Vector<uint32_t>& webgpu_extent_sequence = + webgpu_extent->GetAsUnsignedLongSequence(); + DCHECK_EQ(webgpu_extent_sequence.size(), 3UL); + dawn_extent.width = webgpu_extent_sequence[0]; + dawn_extent.height = webgpu_extent_sequence[1]; + dawn_extent.depth = webgpu_extent_sequence[2]; + + } else if (webgpu_extent->IsGPUExtent3DDict()) { + const GPUExtent3DDict* webgpu_extent_3d_dict = + webgpu_extent->GetAsGPUExtent3DDict(); + dawn_extent.width = webgpu_extent_3d_dict->width(); + dawn_extent.height = webgpu_extent_3d_dict->height(); + dawn_extent.depth = webgpu_extent_3d_dict->depth(); + + } else { + NOTREACHED(); + } return dawn_extent; } -DawnOrigin3D AsDawnType(const GPUOrigin3D* webgpu_origin) { +DawnOrigin3D AsDawnType( + const UnsignedLongSequenceOrGPUOrigin3DDict* webgpu_origin) { DCHECK(webgpu_origin); DawnOrigin3D dawn_origin = {}; - dawn_origin.x = webgpu_origin->x(); - dawn_origin.y = webgpu_origin->y(); - dawn_origin.z = webgpu_origin->z(); + + if (webgpu_origin->IsUnsignedLongSequence()) { + const Vector<uint32_t>& webgpu_origin_sequence = + webgpu_origin->GetAsUnsignedLongSequence(); + DCHECK_EQ(webgpu_origin_sequence.size(), 3UL); + dawn_origin.x = webgpu_origin_sequence[0]; + dawn_origin.y = webgpu_origin_sequence[1]; + dawn_origin.z = webgpu_origin_sequence[2]; + + } else if (webgpu_origin->IsGPUOrigin3DDict()) { + const GPUOrigin3DDict* webgpu_origin_3d_dict = + webgpu_origin->GetAsGPUOrigin3DDict(); + dawn_origin.x = webgpu_origin_3d_dict->x(); + dawn_origin.y = webgpu_origin_3d_dict->y(); + dawn_origin.z = webgpu_origin_3d_dict->z(); + + } else { + NOTREACHED(); + } return dawn_origin; } -OwnedPipelineStageDescriptor AsDawnType( - const GPUPipelineStageDescriptor* webgpu_stage) { +OwnedProgrammableStageDescriptor AsDawnType( + const GPUProgrammableStageDescriptor* webgpu_stage) { DCHECK(webgpu_stage); std::string entry_point = webgpu_stage->entryPoint().Ascii(); @@ -712,7 +711,7 @@ OwnedPipelineStageDescriptor AsDawnType( char* entry_point_ptr = entry_point_keepalive.get(); memcpy(entry_point_ptr, entry_point.c_str(), byte_size); - DawnPipelineStageDescriptor dawn_stage = {}; + DawnProgrammableStageDescriptor dawn_stage = {}; dawn_stage.module = webgpu_stage->module()->GetHandle(); dawn_stage.entryPoint = entry_point_ptr; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h b/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h index b86fa804de7..7411163de4b 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h @@ -19,10 +19,11 @@ namespace blink { -class GPUColor; -class GPUExtent3D; -class GPUOrigin3D; -class GPUPipelineStageDescriptor; +class DoubleSequenceOrGPUColorDict; +class GPUColorDict; +class GPUProgrammableStageDescriptor; +class UnsignedLongSequenceOrGPUExtent3DDict; +class UnsignedLongSequenceOrGPUOrigin3DDict; // Convert WebGPU bitfield values to Dawn enums. These have the same value. template <typename DawnEnum> @@ -37,13 +38,16 @@ DawnEnum AsDawnEnum(const WTF::String& webgpu_enum); // These conversions are used multiple times and are declared here. Conversions // used only once, for example for object construction, are defined // individually. -DawnColor AsDawnType(const GPUColor*); -DawnExtent3D AsDawnType(const GPUExtent3D*); -DawnOrigin3D AsDawnType(const GPUOrigin3D*); - -using OwnedPipelineStageDescriptor = - std::tuple<DawnPipelineStageDescriptor, std::unique_ptr<char[]>>; -OwnedPipelineStageDescriptor AsDawnType(const GPUPipelineStageDescriptor*); +DawnColor AsDawnColor(const Vector<double>&); +DawnColor AsDawnType(const GPUColorDict*); +DawnColor AsDawnType(const DoubleSequenceOrGPUColorDict*); +DawnExtent3D AsDawnType(const UnsignedLongSequenceOrGPUExtent3DDict*); +DawnOrigin3D AsDawnType(const UnsignedLongSequenceOrGPUOrigin3DDict*); + +using OwnedProgrammableStageDescriptor = + std::tuple<DawnProgrammableStageDescriptor, std::unique_ptr<char[]>>; +OwnedProgrammableStageDescriptor AsDawnType( + const GPUProgrammableStageDescriptor*); // WebGPU objects are converted to Dawn objects by getting the opaque handle // which can be passed to Dawn. diff --git a/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc b/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc index 0521f0d56e1..8ce13313c75 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc @@ -12,8 +12,6 @@ DawnObjectBase::DawnObjectBase( scoped_refptr<DawnControlClientHolder> dawn_control_client) : dawn_control_client_(std::move(dawn_control_client)) {} -DawnObjectBase::~DawnObjectBase() = default; - const scoped_refptr<DawnControlClientHolder>& DawnObjectBase::GetDawnControlClient() const { return dawn_control_client_; @@ -34,6 +32,8 @@ const DawnProcTable& DawnObjectBase::GetProcs() const { DawnObjectImpl::DawnObjectImpl(GPUDevice* device) : DawnObjectBase(device->GetDawnControlClient()), device_(device) {} +DawnObjectImpl::~DawnObjectImpl() = default; + void DawnObjectImpl::Trace(blink::Visitor* visitor) { visitor->Trace(device_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h b/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h index 06c66ace749..7b47862450a 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_DAWN_OBJECT_H_ #include <dawn/dawn.h> +#include <dawn/dawn_proc_table.h> #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -28,10 +29,9 @@ class Visitor; // The DawnControlClientHolder is used to hold the WebGPUInterface and keep // track of whether or not the client has been destroyed. If the client is // destroyed, we should not call any Dawn functions. -class DawnObjectBase : public ScriptWrappable { +class DawnObjectBase { public: DawnObjectBase(scoped_refptr<DawnControlClientHolder> dawn_control_client); - ~DawnObjectBase() override; const scoped_refptr<DawnControlClientHolder>& GetDawnControlClient() const; bool IsDawnControlClientDestroyed() const; @@ -42,9 +42,10 @@ class DawnObjectBase : public ScriptWrappable { scoped_refptr<DawnControlClientHolder> dawn_control_client_; }; -class DawnObjectImpl : public DawnObjectBase { +class DawnObjectImpl : public ScriptWrappable, public DawnObjectBase { public: DawnObjectImpl(GPUDevice* device); + ~DawnObjectImpl() override; void Trace(blink::Visitor* visitor) override; @@ -57,6 +58,7 @@ class DawnObject : public DawnObjectImpl { public: DawnObject(GPUDevice* device, Handle handle) : DawnObjectImpl(device), handle_(handle) {} + ~DawnObject() override = default; Handle GetHandle() const { return handle_; } diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc index d4829e40c57..75c64330192 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc @@ -57,7 +57,7 @@ void GPU::Trace(blink::Visitor* visitor) { } void GPU::ContextDestroyed(ExecutionContext* execution_context) { - dawn_control_client_->MarkDestroyed(); + dawn_control_client_->Destroy(); } ScriptPromise GPU::requestAdapter(ScriptState* script_state, @@ -65,16 +65,14 @@ ScriptPromise GPU::requestAdapter(ScriptState* script_state, auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); - if (options->powerPreference()) { - ExecutionContext::From(script_state) - ->AddConsoleMessage(ConsoleMessage::Create( - mojom::ConsoleMessageSource::kJavaScript, - mojom::ConsoleMessageLevel::kWarning, - "The powerPreference option is not implemented yet.")); + // For now we choose kHighPerformance by default. + gpu::webgpu::PowerPreference power_preference = + gpu::webgpu::PowerPreference::kHighPerformance; + if (options->powerPreference() == "low-power") { + power_preference = gpu::webgpu::PowerPreference::kLowPower; } - - // TODO(enga): Request the adapter from the WebGPUInterface. - GPUAdapter* adapter = GPUAdapter::Create("Default", dawn_control_client_); + GPUAdapter* adapter = + GPUAdapter::Create("Default", power_preference, dawn_control_client_); resolver->Resolve(adapter); return promise; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu.idl index 2e5f6ebf708..393ae11f7f8 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu.idl @@ -4,11 +4,16 @@ // https://gpuweb.github.io/gpuweb/ +typedef unsigned long long GPUBufferSize; +typedef (sequence<double> or GPUColorDict) GPUColor; +typedef (sequence<unsigned long> or GPUExtent3DDict) GPUExtent3D; +typedef (sequence<unsigned long> or GPUOrigin3DDict) GPUOrigin3D; + [ RuntimeEnabled=WebGPU ] interface GPU { [ RuntimeEnabled=WebGPU, CallWith=ScriptState - ] Promise<GPUAdapter> requestAdapter(optional GPURequestAdapterOptions options); + ] Promise<GPUAdapter> requestAdapter(optional GPURequestAdapterOptions options = {}); }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc index 4e89c557d38..4c262c61aa5 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.cc @@ -6,20 +6,26 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_request_adapter_options.h" namespace blink { // static GPUAdapter* GPUAdapter::Create( const String& name, + gpu::webgpu::PowerPreference power_preference, scoped_refptr<DawnControlClientHolder> dawn_control_client) { - return MakeGarbageCollected<GPUAdapter>(name, std::move(dawn_control_client)); + return MakeGarbageCollected<GPUAdapter>(name, power_preference, + std::move(dawn_control_client)); } GPUAdapter::GPUAdapter( const String& name, + gpu::webgpu::PowerPreference power_preference, scoped_refptr<DawnControlClientHolder> dawn_control_client) - : DawnObjectBase(std::move(dawn_control_client)), name_(name) {} + : DawnObjectBase(dawn_control_client), name_(name) { + dawn_control_client->GetInterface()->RequestAdapter(power_preference); +} const String& GPUAdapter::name() const { return name_; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.h index abc9594273d..afbed689c85 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_ADAPTER_H_ #include "base/memory/scoped_refptr.h" +#include "gpu/command_buffer/client/webgpu_interface.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" @@ -16,14 +17,16 @@ namespace blink { class GPUDeviceDescriptor; -class GPUAdapter final : public DawnObjectBase { +class GPUAdapter final : public ScriptWrappable, public DawnObjectBase { DEFINE_WRAPPERTYPEINFO(); public: static GPUAdapter* Create( const String& name, + gpu::webgpu::PowerPreference power_preference, scoped_refptr<DawnControlClientHolder> dawn_control_client); GPUAdapter(const String& name, + gpu::webgpu::PowerPreference power_preference, scoped_refptr<DawnControlClientHolder> dawn_control_client); const String& name() const; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl index 4edcf4170ee..0c14346816e 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl @@ -9,5 +9,5 @@ ] interface GPUAdapter { readonly attribute DOMString name; - [CallWith=ScriptState] Promise<GPUDevice> requestDevice(optional GPUDeviceDescriptor descriptor); + [CallWith=ScriptState] Promise<GPUDevice> requestDevice(optional GPUDeviceDescriptor descriptor = {}); }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc index 63333d41e73..0aee4c2b18d 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group.cc @@ -59,6 +59,9 @@ GPUBindGroup* GPUBindGroup::Create(GPUDevice* device, dawn_desc.layout = AsDawnType(webgpu_desc->layout()); dawn_desc.bindingCount = binding_count; dawn_desc.bindings = bindings.get(); + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } return MakeGarbageCollected<GPUBindGroup>( device, device->GetProcs().deviceCreateBindGroup(device->GetHandle(), diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.idl index ab56efc0743..c347eed9402 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.idl @@ -4,7 +4,7 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUBindGroupDescriptor { +dictionary GPUBindGroupDescriptor : GPUObjectDescriptorBase { required GPUBindGroupLayout layout; required sequence<GPUBindGroupBinding> bindings; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc index 859082ccf42..3bc7266415c 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc @@ -18,10 +18,12 @@ DawnBindGroupLayoutBinding AsDawnType( dawn_binding.type = AsDawnEnum<DawnBindingType>(webgpu_binding->type()); dawn_binding.visibility = AsDawnEnum<DawnShaderStage>(webgpu_binding->visibility()); + dawn_binding.textureDimension = + AsDawnEnum<DawnTextureViewDimension>(webgpu_binding->textureDimension()); dawn_binding.textureComponentType = AsDawnEnum<DawnTextureComponentType>( webgpu_binding->textureComponentType()); dawn_binding.multisampled = webgpu_binding->multisampled(); - dawn_binding.dynamic = webgpu_binding->dynamic(); + dawn_binding.hasDynamicOffset = webgpu_binding->hasDynamicOffset(); return dawn_binding; } @@ -43,6 +45,9 @@ GPUBindGroupLayout* GPUBindGroupLayout::Create( dawn_desc.nextInChain = nullptr; dawn_desc.bindingCount = binding_count; dawn_desc.bindings = bindings.get(); + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } return MakeGarbageCollected<GPUBindGroupLayout>( device, device->GetProcs().deviceCreateBindGroupLayout( diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_binding.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_binding.idl index 372f4086b14..141823e5bf2 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_binding.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_binding.idl @@ -8,9 +8,10 @@ dictionary GPUBindGroupLayoutBinding { required unsigned long binding; required GPUShaderStageFlags visibility; required GPUBindingType type; + GPUTextureViewDimension textureDimension = "2d"; GPUTextureComponentType textureComponentType = "float"; boolean multisampled = false; - boolean dynamic = false; + boolean hasDynamicOffset = false; }; enum GPUBindingType { @@ -19,6 +20,7 @@ enum GPUBindingType { "readonly-storage-buffer", "sampler", "sampled-texture", + "storage-texture", }; enum GPUTextureComponentType { diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.idl index 74663eabc35..96f07ac5e21 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.idl @@ -4,6 +4,6 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUBindGroupLayoutDescriptor { +dictionary GPUBindGroupLayoutDescriptor : GPUObjectDescriptorBase { required sequence<GPUBindGroupLayoutBinding> bindings; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc index a17386b6426..81e8cfbd89d 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc @@ -51,6 +51,9 @@ DawnBufferDescriptor AsDawnType(const GPUBufferDescriptor* webgpu_desc) { dawn_desc.nextInChain = nullptr; dawn_desc.usage = AsDawnEnum<DawnBufferUsage>(webgpu_desc->usage()); dawn_desc.size = webgpu_desc->size(); + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } return dawn_desc; } diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_binding.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_binding.idl index e3ee3c6fb99..af62cf63455 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_binding.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_binding.idl @@ -6,7 +6,7 @@ dictionary GPUBufferBinding { required GPUBuffer buffer; - unsigned long long offset = 0; + GPUBufferSize offset = 0; // If size is undefined, use the whole size of the buffer. - unsigned long long size; + GPUBufferSize size; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.idl index 0ba2fb0edbb..2b18ef078bf 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.idl @@ -6,7 +6,7 @@ dictionary GPUBufferCopyView { required GPUBuffer buffer; - unsigned long long offset = 0; + GPUBufferSize offset = 0; required unsigned long rowPitch; required unsigned long imageHeight; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_descriptor.idl index f36194db5ca..27216d32484 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_descriptor.idl @@ -4,7 +4,7 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUBufferDescriptor { - required unsigned long long size; +dictionary GPUBufferDescriptor : GPUObjectDescriptorBase { + required GPUBufferSize size; required GPUBufferUsageFlags usage; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_usage.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_usage.h index 01924b0043e..5c922e7e413 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_usage.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_usage.h @@ -14,7 +14,6 @@ class GPUBufferUsage : public ScriptWrappable { public: // gpu_buffer_usage.idl - static constexpr uint32_t kNone = 0; static constexpr uint32_t kMapRead = 1; static constexpr uint32_t kMapWrite = 2; static constexpr uint32_t kCopySrc = 4; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_usage.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_usage.idl index 981d67faaa0..b49cc104204 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_usage.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer_usage.idl @@ -8,14 +8,13 @@ typedef unsigned long GPUBufferUsageFlags; [ RuntimeEnabled=WebGPU ] interface GPUBufferUsage { - const unsigned long NONE = 0; - const unsigned long MAP_READ = 1; - const unsigned long MAP_WRITE = 2; - const unsigned long COPY_SRC = 4; - const unsigned long COPY_DST = 8; - const unsigned long INDEX = 16; - const unsigned long VERTEX = 32; - const unsigned long UNIFORM = 64; - const unsigned long STORAGE = 128; - const unsigned long INDIRECT = 256; + const GPUBufferUsageFlags MAP_READ = 1; + const GPUBufferUsageFlags MAP_WRITE = 2; + const GPUBufferUsageFlags COPY_SRC = 4; + const GPUBufferUsageFlags COPY_DST = 8; + const GPUBufferUsageFlags INDEX = 16; + const GPUBufferUsageFlags VERTEX = 32; + const GPUBufferUsageFlags UNIFORM = 64; + const GPUBufferUsageFlags STORAGE = 128; + const GPUBufferUsageFlags INDIRECT = 256; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc index 5c5f063093e..773faf3070d 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc @@ -80,4 +80,17 @@ GPUSwapChain* GPUCanvasContext::configureSwapChain( return swapchain_; } +ScriptPromise GPUCanvasContext::getSwapChainPreferredFormat( + ScriptState* script_state, + const GPUDevice* device) { + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + + // TODO(crbug.com/1007166): Return actual preferred format for the swap chain. + resolver->Resolve("bgra8unorm"); + + return promise; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h index 03602229816..e5d4c54ef62 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h @@ -45,7 +45,7 @@ class GPUCanvasContext : public CanvasRenderingContext { // CanvasRenderingContext implementation ContextType GetContextType() const override; void SetCanvasGetContextResult(RenderingContext&) final; - scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) const final { + scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final { return nullptr; } void SetIsHidden(bool) override {} @@ -62,6 +62,8 @@ class GPUCanvasContext : public CanvasRenderingContext { // gpu_canvas_context.idl GPUSwapChain* configureSwapChain(const GPUSwapChainDescriptor* descriptor); + ScriptPromise getSwapChainPreferredFormat(ScriptState* script_state, + const GPUDevice* device); private: DISALLOW_COPY_AND_ASSIGN(GPUCanvasContext); diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl index 5e4ac97377a..feb476c9ab5 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl @@ -8,4 +8,6 @@ RuntimeEnabled=WebGPU ] interface GPUCanvasContext { GPUSwapChain configureSwapChain(GPUSwapChainDescriptor descriptor); + + [CallWith=ScriptState] Promise<GPUTextureFormat> getSwapChainPreferredFormat(GPUDevice device); }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_dict.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_dict.idl new file mode 100644 index 00000000000..1759ca47004 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_dict.idl @@ -0,0 +1,12 @@ +// 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://gpuweb.github.io/gpuweb/ + +dictionary GPUColorDict { + required double r; + required double g; + required double b; + required double a; +}; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_state_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_state_descriptor.idl index 165f7594fa2..07e114c7cda 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_state_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_state_descriptor.idl @@ -7,7 +7,7 @@ dictionary GPUColorStateDescriptor { required GPUTextureFormat format; - GPUBlendDescriptor alphaBlend; - GPUBlendDescriptor colorBlend; + GPUBlendDescriptor alphaBlend = {}; + GPUBlendDescriptor colorBlend = {}; GPUColorWriteFlags writeMask = 15; // GPUColorWrite.ALL }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_write.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_write.h index 429220b4d5e..4df070ed6b8 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_write.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_write.h @@ -14,7 +14,6 @@ class GPUColorWrite : public ScriptWrappable { public: // gpu_color_write.idl - static constexpr uint32_t kNone = 0; static constexpr uint32_t kRed = 1; static constexpr uint32_t kGreen = 2; static constexpr uint32_t kBlue = 4; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_write.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_write.idl index a28647f7112..a71fbafd0f2 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_write.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_color_write.idl @@ -8,10 +8,9 @@ typedef unsigned long GPUColorWriteFlags; [ RuntimeEnabled=WebGPU ] interface GPUColorWrite { - const unsigned long NONE = 0; - const unsigned long RED = 1; - const unsigned long GREEN = 2; - const unsigned long BLUE = 4; - const unsigned long ALPHA = 8; - const unsigned long ALL = 15; + const GPUColorWriteFlags RED = 1; + const GPUColorWriteFlags GREEN = 2; + const GPUColorWriteFlags BLUE = 4; + const GPUColorWriteFlags ALPHA = 8; + const GPUColorWriteFlags ALL = 15; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_color.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_buffer_descriptor.idl index 3055ed714c4..700ed995e07 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_color.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_buffer_descriptor.idl @@ -4,9 +4,5 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUColor { - required float r; - required float g; - required float b; - required float a; +dictionary GPUCommandBufferDescriptor : GPUObjectDescriptorBase { }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc index 438330e58cc..3afc4108da6 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc @@ -4,15 +4,18 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h" +#include "third_party/blink/renderer/bindings/modules/v8/double_sequence_or_gpu_color_dict.h" +#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_extent_3d_dict.h" +#include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_sequence_or_gpu_origin_3d_dict.h" #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" #include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h" #include "third_party/blink/renderer/modules/webgpu/gpu_buffer_copy_view.h" #include "third_party/blink/renderer/modules/webgpu/gpu_command_buffer.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_command_buffer_descriptor.h" #include "third_party/blink/renderer/modules/webgpu/gpu_command_encoder_descriptor.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_compute_pass_descriptor.h" #include "third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" -#include "third_party/blink/renderer/modules/webgpu/gpu_extent_3d.h" -#include "third_party/blink/renderer/modules/webgpu/gpu_origin_3d.h" #include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment_descriptor.h" #include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.h" #include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_descriptor.h" @@ -23,6 +26,31 @@ namespace blink { +bool ValidateCopySize(UnsignedLongSequenceOrGPUExtent3DDict& copy_size, + ExceptionState& exception_state) { + if (copy_size.IsUnsignedLongSequence() && + copy_size.GetAsUnsignedLongSequence().size() != 3) { + exception_state.ThrowRangeError("copySize length must be 3"); + return false; + } + return true; +} + +bool ValidateTextureCopyView(GPUTextureCopyView* texture_copy_view, + ExceptionState& exception_state) { + DCHECK(texture_copy_view); + + const UnsignedLongSequenceOrGPUOrigin3DDict origin = + texture_copy_view->origin(); + if (origin.IsUnsignedLongSequence() && + origin.GetAsUnsignedLongSequence().size() != 3) { + exception_state.ThrowRangeError( + "texture copy view origin length must be 3"); + return false; + } + return true; +} + DawnRenderPassColorAttachmentDescriptor AsDawnType( const GPURenderPassColorAttachmentDescriptor* webgpu_desc) { DCHECK(webgpu_desc); @@ -37,8 +65,14 @@ DawnRenderPassColorAttachmentDescriptor AsDawnType( const WTF::String& gpuLoadOp = webgpu_desc->loadValue().GetAsGPULoadOp(); dawn_desc.loadOp = AsDawnEnum<DawnLoadOp>(gpuLoadOp); - } else if (webgpu_desc->loadValue().IsGPUColor()) { - GPUColor* gpuColor = webgpu_desc->loadValue().GetAsGPUColor(); + } else if (webgpu_desc->loadValue().IsDoubleSequence()) { + const Vector<double>& gpuColor = + webgpu_desc->loadValue().GetAsDoubleSequence(); + dawn_desc.loadOp = DAWN_LOAD_OP_CLEAR; + dawn_desc.clearColor = AsDawnColor(gpuColor); + + } else if (webgpu_desc->loadValue().IsGPUColorDict()) { + const GPUColorDict* gpuColor = webgpu_desc->loadValue().GetAsGPUColorDict(); dawn_desc.loadOp = DAWN_LOAD_OP_CLEAR; dawn_desc.clearColor = AsDawnType(gpuColor); @@ -82,9 +116,10 @@ DawnRenderPassDepthStencilAttachmentDescriptor AsDawnType( dawn_desc.stencilLoadOp = AsDawnEnum<DawnLoadOp>(gpuLoadOp); dawn_desc.clearStencil = 0; - } else if (webgpu_desc->stencilLoadValue().IsLong()) { + } else if (webgpu_desc->stencilLoadValue().IsUnsignedLong()) { dawn_desc.stencilLoadOp = DAWN_LOAD_OP_CLEAR; - dawn_desc.clearStencil = webgpu_desc->stencilLoadValue().GetAsLong(); + dawn_desc.clearStencil = + webgpu_desc->stencilLoadValue().GetAsUnsignedLong(); } else { NOTREACHED(); @@ -119,7 +154,7 @@ DawnTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view) { dawn_view.texture = webgpu_view->texture()->GetHandle(); dawn_view.mipLevel = webgpu_view->mipLevel(); dawn_view.arrayLayer = webgpu_view->arrayLayer(); - dawn_view.origin = AsDawnType(webgpu_view->origin()); + dawn_view.origin = AsDawnType(&webgpu_view->origin()); return dawn_view; } @@ -130,6 +165,9 @@ DawnCommandEncoderDescriptor AsDawnType( DawnCommandEncoderDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } return dawn_desc; } @@ -168,33 +206,39 @@ GPUCommandEncoder::~GPUCommandEncoder() { } GPURenderPassEncoder* GPUCommandEncoder::beginRenderPass( - const GPURenderPassDescriptor* descriptor) { + const GPURenderPassDescriptor* descriptor, + ExceptionState& exception_state) { DCHECK(descriptor); uint32_t color_attachment_count = static_cast<uint32_t>(descriptor->colorAttachments().size()); + // Check loadValue color is correctly formatted before further processing. + for (wtf_size_t i = 0; i < color_attachment_count; ++i) { + const GPURenderPassColorAttachmentDescriptor* color_attachment = + descriptor->colorAttachments()[i]; + const GPULoadOpOrDoubleSequenceOrGPUColorDict load_value = + color_attachment->loadValue(); + + if (load_value.IsDoubleSequence() && + load_value.GetAsDoubleSequence().size() != 4) { + exception_state.ThrowRangeError("loadValue color size must be 4"); + return nullptr; + } + } + DawnRenderPassDescriptor dawn_desc = {}; dawn_desc.colorAttachmentCount = color_attachment_count; dawn_desc.colorAttachments = nullptr; + if (descriptor->hasLabel()) { + dawn_desc.label = descriptor->label().Utf8().data(); + } - using DescriptorPtr = DawnRenderPassColorAttachmentDescriptor*; - using DescriptorArray = DawnRenderPassColorAttachmentDescriptor[]; - using DescriptorPtrArray = DescriptorPtr[]; - - std::unique_ptr<DescriptorArray> color_attachments; - std::unique_ptr<DescriptorPtrArray> color_attachment_ptrs; + std::unique_ptr<DawnRenderPassColorAttachmentDescriptor[]> color_attachments; if (color_attachment_count > 0) { color_attachments = AsDawnType(descriptor->colorAttachments()); - - color_attachment_ptrs = std::unique_ptr<DescriptorPtrArray>( - new DescriptorPtr[color_attachment_count]); - - for (uint32_t i = 0; i < color_attachment_count; ++i) { - color_attachment_ptrs[i] = color_attachments.get() + i; - } - dawn_desc.colorAttachments = color_attachment_ptrs.get(); + dawn_desc.colorAttachments = color_attachments.get(); } DawnRenderPassDepthStencilAttachmentDescriptor depthStencilAttachment = {}; @@ -210,9 +254,16 @@ GPURenderPassEncoder* GPUCommandEncoder::beginRenderPass( GetProcs().commandEncoderBeginRenderPass(GetHandle(), &dawn_desc)); } -GPUComputePassEncoder* GPUCommandEncoder::beginComputePass() { +GPUComputePassEncoder* GPUCommandEncoder::beginComputePass( + const GPUComputePassDescriptor* descriptor) { + DawnComputePassDescriptor dawn_desc = {}; + if (descriptor->hasLabel()) { + dawn_desc.label = descriptor->label().Utf8().data(); + } + return GPUComputePassEncoder::Create( - device_, GetProcs().commandEncoderBeginComputePass(GetHandle(), nullptr)); + device_, + GetProcs().commandEncoderBeginComputePass(GetHandle(), &dawn_desc)); } void GPUCommandEncoder::copyBufferToBuffer(GPUBuffer* src, @@ -227,42 +278,84 @@ void GPUCommandEncoder::copyBufferToBuffer(GPUBuffer* src, dst_offset, size); } -void GPUCommandEncoder::copyBufferToTexture(GPUBufferCopyView* source, - GPUTextureCopyView* destination, - GPUExtent3D* copy_size) { +void GPUCommandEncoder::copyBufferToTexture( + GPUBufferCopyView* source, + GPUTextureCopyView* destination, + UnsignedLongSequenceOrGPUExtent3DDict& copy_size, + ExceptionState& exception_state) { + if (!ValidateCopySize(copy_size, exception_state) || + !ValidateTextureCopyView(destination, exception_state)) { + return; + } + DawnBufferCopyView dawn_source = AsDawnType(source); DawnTextureCopyView dawn_destination = AsDawnType(destination); - DawnExtent3D dawn_copy_size = AsDawnType(copy_size); + DawnExtent3D dawn_copy_size = AsDawnType(©_size); GetProcs().commandEncoderCopyBufferToTexture( GetHandle(), &dawn_source, &dawn_destination, &dawn_copy_size); } -void GPUCommandEncoder::copyTextureToBuffer(GPUTextureCopyView* source, - GPUBufferCopyView* destination, - GPUExtent3D* copy_size) { +void GPUCommandEncoder::copyTextureToBuffer( + GPUTextureCopyView* source, + GPUBufferCopyView* destination, + UnsignedLongSequenceOrGPUExtent3DDict& copy_size, + ExceptionState& exception_state) { + if (!ValidateCopySize(copy_size, exception_state) || + !ValidateTextureCopyView(source, exception_state)) { + return; + } + DawnTextureCopyView dawn_source = AsDawnType(source); DawnBufferCopyView dawn_destination = AsDawnType(destination); - DawnExtent3D dawn_copy_size = AsDawnType(copy_size); + DawnExtent3D dawn_copy_size = AsDawnType(©_size); GetProcs().commandEncoderCopyTextureToBuffer( GetHandle(), &dawn_source, &dawn_destination, &dawn_copy_size); } -void GPUCommandEncoder::copyTextureToTexture(GPUTextureCopyView* source, - GPUTextureCopyView* destination, - GPUExtent3D* copy_size) { +void GPUCommandEncoder::copyTextureToTexture( + GPUTextureCopyView* source, + GPUTextureCopyView* destination, + UnsignedLongSequenceOrGPUExtent3DDict& copy_size, + ExceptionState& exception_state) { + if (!ValidateCopySize(copy_size, exception_state) || + !ValidateTextureCopyView(source, exception_state) || + !ValidateTextureCopyView(destination, exception_state)) { + return; + } + DawnTextureCopyView dawn_source = AsDawnType(source); DawnTextureCopyView dawn_destination = AsDawnType(destination); - DawnExtent3D dawn_copy_size = AsDawnType(copy_size); + DawnExtent3D dawn_copy_size = AsDawnType(©_size); GetProcs().commandEncoderCopyTextureToTexture( GetHandle(), &dawn_source, &dawn_destination, &dawn_copy_size); } -GPUCommandBuffer* GPUCommandEncoder::finish() { +void GPUCommandEncoder::pushDebugGroup(String groupLabel) { + GetProcs().commandEncoderPushDebugGroup(GetHandle(), + groupLabel.Utf8().data()); +} + +void GPUCommandEncoder::popDebugGroup() { + GetProcs().commandEncoderPopDebugGroup(GetHandle()); +} + +void GPUCommandEncoder::insertDebugMarker(String markerLabel) { + GetProcs().commandEncoderInsertDebugMarker(GetHandle(), + markerLabel.Utf8().data()); +} + +GPUCommandBuffer* GPUCommandEncoder::finish( + const GPUCommandBufferDescriptor* descriptor) { + DawnCommandBufferDescriptor dawn_desc = {}; + if (descriptor->hasLabel()) { + dawn_desc.label = descriptor->label().Utf8().data(); + } + return GPUCommandBuffer::Create( - device_, GetProcs().commandEncoderFinish(GetHandle(), nullptr)); + device_, GetProcs().commandEncoderFinish(GetHandle(), &dawn_desc)); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h index adb50dc5bec..d00bb828491 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h @@ -6,18 +6,22 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_COMMAND_ENCODER_H_ #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" namespace blink { +class ExceptionState; class GPUBuffer; class GPUBufferCopyView; class GPUCommandBuffer; +class GPUCommandBufferDescriptor; class GPUCommandEncoderDescriptor; +class GPUComputePassDescriptor; class GPUComputePassEncoder; -class GPUExtent3D; class GPURenderPassDescriptor; class GPURenderPassEncoder; class GPUTextureCopyView; +class UnsignedLongSequenceOrGPUExtent3DDict; class GPUCommandEncoder : public DawnObject<DawnCommandEncoder> { DEFINE_WRAPPERTYPEINFO(); @@ -32,8 +36,10 @@ class GPUCommandEncoder : public DawnObject<DawnCommandEncoder> { // gpu_command_encoder.idl GPURenderPassEncoder* beginRenderPass( - const GPURenderPassDescriptor* descriptor); - GPUComputePassEncoder* beginComputePass(); + const GPURenderPassDescriptor* descriptor, + ExceptionState& exception_state); + GPUComputePassEncoder* beginComputePass( + const GPUComputePassDescriptor* descriptor); void copyBufferToBuffer(GPUBuffer* src, uint64_t src_offset, GPUBuffer* dst, @@ -41,14 +47,20 @@ class GPUCommandEncoder : public DawnObject<DawnCommandEncoder> { uint64_t size); void copyBufferToTexture(GPUBufferCopyView* source, GPUTextureCopyView* destination, - GPUExtent3D* copy_size); + UnsignedLongSequenceOrGPUExtent3DDict& copy_size, + ExceptionState& exception_state); void copyTextureToBuffer(GPUTextureCopyView* source, GPUBufferCopyView* destination, - GPUExtent3D* copy_size); + UnsignedLongSequenceOrGPUExtent3DDict& copy_size, + ExceptionState& exception_state); void copyTextureToTexture(GPUTextureCopyView* source, GPUTextureCopyView* destination, - GPUExtent3D* copy_size); - GPUCommandBuffer* finish(); + UnsignedLongSequenceOrGPUExtent3DDict& copy_size, + ExceptionState& exception_state); + void pushDebugGroup(String groupLabel); + void popDebugGroup(); + void insertDebugMarker(String markerLabel); + GPUCommandBuffer* finish(const GPUCommandBufferDescriptor* descriptor); private: DISALLOW_COPY_AND_ASSIGN(GPUCommandEncoder); diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl index 1a76aca161f..574ec01e66b 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl @@ -7,28 +7,34 @@ [ RuntimeEnabled=WebGPU ] interface GPUCommandEncoder { - GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor); - GPUComputePassEncoder beginComputePass(); + [RaisesException] GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor descriptor); + GPUComputePassEncoder beginComputePass(optional GPUComputePassDescriptor descriptor = {}); void copyBufferToBuffer( - GPUBuffer src, unsigned long long srcOffset, - GPUBuffer dst, unsigned long long dstOffset, - unsigned long long size); + GPUBuffer src, + GPUBufferSize srcOffset, + GPUBuffer dst, + GPUBufferSize dstOffset, + GPUBufferSize size); - void copyBufferToTexture( + [RaisesException] void copyBufferToTexture( GPUBufferCopyView source, GPUTextureCopyView destination, GPUExtent3D copySize); - void copyTextureToBuffer( + [RaisesException] void copyTextureToBuffer( GPUTextureCopyView source, GPUBufferCopyView destination, GPUExtent3D copySize); - void copyTextureToTexture( + [RaisesException] void copyTextureToTexture( GPUTextureCopyView source, GPUTextureCopyView destination, GPUExtent3D copySize); - GPUCommandBuffer finish(); + void pushDebugGroup(DOMString groupLabel); + void popDebugGroup(); + void insertDebugMarker(DOMString markerLabel); + + GPUCommandBuffer finish(optional GPUCommandBufferDescriptor descriptor = {}); }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder_descriptor.idl index 0cef584d579..e28ac16410c 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_command_encoder_descriptor.idl @@ -4,5 +4,5 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUCommandEncoderDescriptor { +dictionary GPUCommandEncoderDescriptor : GPUObjectDescriptorBase { }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_origin_3d.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_descriptor.idl index d1359bac418..5dcd9e84457 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_origin_3d.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_descriptor.idl @@ -4,8 +4,5 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUOrigin3D { - required unsigned long x; - required unsigned long y; - required unsigned long z; +dictionary GPUComputePassDescriptor : GPUObjectDescriptorBase { }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl index 75149c6848e..dd75cea414b 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl @@ -7,21 +7,13 @@ [ RuntimeEnabled=WebGPU ] interface GPUComputePassEncoder { - // GPUProgrammablePassEncoder methods - void setBindGroup(unsigned long index, - GPUBindGroup bindGroup, - optional sequence<unsigned long long> dynamicOffsets = []); - void pushDebugGroup(DOMString groupLabel); - void popDebugGroup(); - void insertDebugMarker(DOMString markerLabel); - void setPipeline(GPUComputePipeline pipeline); - void dispatch(unsigned long x, optional unsigned long y = 1, optional unsigned long z = 1); void dispatchIndirect(GPUBuffer indirectBuffer, - unsigned long long indirectOffset); + GPUBufferSize indirectOffset); void endPass(); }; +GPUComputePassEncoder includes GPUProgrammablePassEncoder; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc index f3ab8365659..4da7c3c5a23 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.cc @@ -8,7 +8,7 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline_descriptor.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" #include "third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.h" -#include "third_party/blink/renderer/modules/webgpu/gpu_pipeline_stage_descriptor.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.h" #include "third_party/blink/renderer/modules/webgpu/gpu_shader_module.h" namespace blink { @@ -23,6 +23,9 @@ GPUComputePipeline* GPUComputePipeline::Create( DawnComputePipelineDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; dawn_desc.layout = AsDawnType(webgpu_desc->layout()); + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } auto compute_stage = AsDawnType(webgpu_desc->computeStage()); dawn_desc.computeStage = std::get<0>(compute_stage); diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline_descriptor.idl index aefb71c1512..6d6d8fd23ea 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline_descriptor.idl @@ -5,5 +5,5 @@ // https://gpuweb.github.io/gpuweb/ dictionary GPUComputePipelineDescriptor : GPUPipelineDescriptorBase { - required GPUPipelineStageDescriptor computeStage; + required GPUProgrammableStageDescriptor computeStage; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_depth_stencil_state_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_depth_stencil_state_descriptor.idl index 03f2efe2066..9bf8f07ac93 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_depth_stencil_state_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_depth_stencil_state_descriptor.idl @@ -10,8 +10,8 @@ dictionary GPUDepthStencilStateDescriptor { boolean depthWriteEnabled = false; GPUCompareFunction depthCompare = "always"; - required GPUStencilStateFaceDescriptor stencilFront; - required GPUStencilStateFaceDescriptor stencilBack; + GPUStencilStateFaceDescriptor stencilFront = {}; + GPUStencilStateFaceDescriptor stencilBack = {}; unsigned long stencilReadMask = 0xFFFFFFFF; unsigned long stencilWriteMask = 0xFFFFFFFF; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc index cee563d23e6..1604383f6c8 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc @@ -7,8 +7,10 @@ #include "gpu/command_buffer/client/webgpu_interface.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/modules/event_target_modules.h" +#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" #include "third_party/blink/renderer/modules/webgpu/gpu_adapter.h" #include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h" #include "third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.h" @@ -16,6 +18,7 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_command_encoder.h" #include "third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h" #include "third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.h" #include "third_party/blink/renderer/modules/webgpu/gpu_queue.h" #include "third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h" @@ -23,6 +26,8 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_sampler.h" #include "third_party/blink/renderer/modules/webgpu/gpu_shader_module.h" #include "third_party/blink/renderer/modules/webgpu/gpu_texture.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event_init.h" namespace blink { @@ -41,10 +46,14 @@ GPUDevice::GPUDevice(ExecutionContext* execution_context, scoped_refptr<DawnControlClientHolder> dawn_control_client, GPUAdapter* adapter, const GPUDeviceDescriptor* descriptor) - : DawnObject(dawn_control_client, + : ContextClient(execution_context), + DawnObject(dawn_control_client, dawn_control_client->GetInterface()->GetDefaultDevice()), adapter_(adapter), queue_(GPUQueue::Create(this, GetProcs().deviceCreateQueue(GetHandle()))), + lost_property_(MakeGarbageCollected<LostProperty>(execution_context, + this, + LostProperty::kLost)), error_callback_( BindRepeatingDawnCallback(&GPUDevice::OnUncapturedError, WrapWeakPersistent(this), @@ -72,17 +81,44 @@ void GPUDevice::OnUncapturedError(ExecutionContext* execution_context, mojom::ConsoleMessageLevel::kWarning, message); execution_context->AddConsoleMessage(console_message); } + + // TODO: Use device lost callback instead of uncaptured error callback. + if (errorType == DAWN_ERROR_TYPE_DEVICE_LOST && + lost_property_->GetState() == ScriptPromisePropertyBase::kPending) { + GPUDeviceLostInfo* device_lost_info = GPUDeviceLostInfo::Create(message); + lost_property_->Resolve(device_lost_info); + } + + GPUUncapturedErrorEventInit* init = GPUUncapturedErrorEventInit::Create(); + if (errorType == DAWN_ERROR_TYPE_VALIDATION) { + GPUValidationError* error = GPUValidationError::Create(message); + init->setError( + GPUOutOfMemoryErrorOrGPUValidationError::FromGPUValidationError(error)); + } else if (errorType == DAWN_ERROR_TYPE_OUT_OF_MEMORY) { + GPUOutOfMemoryError* error = GPUOutOfMemoryError::Create(); + init->setError( + GPUOutOfMemoryErrorOrGPUValidationError::FromGPUOutOfMemoryError( + error)); + } else { + return; + } + this->DispatchEvent(*GPUUncapturedErrorEvent::Create( + event_type_names::kUncapturederror, init)); } GPUAdapter* GPUDevice::adapter() const { return adapter_; } +ScriptPromise GPUDevice::lost(ScriptState* script_state) { + return lost_property_->Promise(script_state->World()); +} + GPUBuffer* GPUDevice::createBuffer(const GPUBufferDescriptor* descriptor) { return GPUBuffer::Create(this, descriptor); } -WTF::Vector<ScriptValue> GPUDevice::createBufferMapped( +HeapVector<ScriptValue> GPUDevice::createBufferMapped( ScriptState* script_state, const GPUBufferDescriptor* descriptor, ExceptionState& exception_state) { @@ -94,9 +130,9 @@ WTF::Vector<ScriptValue> GPUDevice::createBufferMapped( v8::Isolate* isolate = script_state->GetIsolate(); v8::Local<v8::Object> creation_context = script_state->GetContext()->Global(); - return WTF::Vector<ScriptValue>({ - ScriptValue(script_state, ToV8(gpu_buffer, creation_context, isolate)), - ScriptValue(script_state, ToV8(array_buffer, creation_context, isolate)), + return HeapVector<ScriptValue>({ + ScriptValue(isolate, ToV8(gpu_buffer, creation_context, isolate)), + ScriptValue(isolate, ToV8(array_buffer, creation_context, isolate)), }); } @@ -117,7 +153,7 @@ ScriptPromise GPUDevice::createBufferMappedAsync( ToV8(array_buffer, creation_context, isolate), }; - ScriptValue result(script_state, v8::Array::New(isolate, elements, 2)); + ScriptValue result(isolate, v8::Array::New(isolate, elements, 2)); auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); @@ -137,8 +173,9 @@ ScriptPromise GPUDevice::createBufferMappedAsync( return promise; } -GPUTexture* GPUDevice::createTexture(const GPUTextureDescriptor* descriptor) { - return GPUTexture::Create(this, descriptor); +GPUTexture* GPUDevice::createTexture(const GPUTextureDescriptor* descriptor, + ExceptionState& exception_state) { + return GPUTexture::Create(this, descriptor, exception_state); } GPUSampler* GPUDevice::createSampler(const GPUSamplerDescriptor* descriptor) { @@ -190,10 +227,74 @@ GPUQueue* GPUDevice::getQueue() { return queue_; } +void GPUDevice::pushErrorScope(const WTF::String& filter) { + GetProcs().devicePushErrorScope(GetHandle(), + AsDawnEnum<DawnErrorFilter>(filter)); +} + +ScriptPromise GPUDevice::popErrorScope(ScriptState* script_state) { + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + + auto* callback = + BindDawnCallback(&GPUDevice::OnPopErrorScopeCallback, + WrapPersistent(this), WrapPersistent(resolver)); + + if (!GetProcs().devicePopErrorScope(GetHandle(), callback->UnboundCallback(), + callback->AsUserdata())) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kOperationError, "No error scopes to pop.")); + delete callback; + return promise; + } + + // WebGPU guarantees callbacks complete in finite time. Flush now so that + // commands reach the GPU process. TODO(enga): This should happen at the end + // of the task. + GetInterface()->FlushCommands(); + + return promise; +} + +void GPUDevice::OnPopErrorScopeCallback(ScriptPromiseResolver* resolver, + DawnErrorType type, + const char* message) { + v8::Isolate* isolate = resolver->GetScriptState()->GetIsolate(); + switch (type) { + case DAWN_ERROR_TYPE_NO_ERROR: + resolver->Resolve(v8::Null(isolate)); + break; + case DAWN_ERROR_TYPE_OUT_OF_MEMORY: + resolver->Resolve(GPUOutOfMemoryError::Create()); + break; + case DAWN_ERROR_TYPE_VALIDATION: + resolver->Resolve(GPUValidationError::Create(message)); + break; + case DAWN_ERROR_TYPE_UNKNOWN: + case DAWN_ERROR_TYPE_DEVICE_LOST: + resolver->Reject( + MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError)); + break; + default: + NOTREACHED(); + } +} + +ExecutionContext* GPUDevice::GetExecutionContext() const { + return ContextClient::GetExecutionContext(); +} + +const AtomicString& GPUDevice::InterfaceName() const { + return event_target_names::kGPUDevice; +} + void GPUDevice::Trace(blink::Visitor* visitor) { visitor->Trace(adapter_); visitor->Trace(queue_); - DawnObject<DawnDevice>::Trace(visitor); + visitor->Trace(lost_property_); + ContextClient::Trace(visitor); + EventTargetWithInlineData::Trace(visitor); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h index e2b11122e7d..1f172691fae 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h @@ -7,6 +7,9 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_property.h" +#include "third_party/blink/renderer/core/dom/events/event_target.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/webgpu/dawn_callback.h" #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" @@ -26,6 +29,7 @@ class GPUBindGroupLayoutDescriptor; class GPUComputePipeline; class GPUComputePipelineDescriptor; class GPUDeviceDescriptor; +class GPUDeviceLostInfo; class GPUPipelineLayout; class GPUPipelineLayoutDescriptor; class GPUQueue; @@ -39,9 +43,13 @@ class GPUShaderModule; class GPUShaderModuleDescriptor; class GPUTexture; class GPUTextureDescriptor; +class ScriptPromiseResolver; class ScriptState; -class GPUDevice final : public DawnObject<DawnDevice> { +class GPUDevice final : public EventTargetWithInlineData, + public ContextClient, + public DawnObject<DawnDevice> { + USING_GARBAGE_COLLECTED_MIXIN(GPUDevice); DEFINE_WRAPPERTYPEINFO(); public: @@ -60,16 +68,18 @@ class GPUDevice final : public DawnObject<DawnDevice> { // gpu_device.idl GPUAdapter* adapter() const; + ScriptPromise lost(ScriptState* script_state); GPUBuffer* createBuffer(const GPUBufferDescriptor* descriptor); - WTF::Vector<ScriptValue> createBufferMapped( + HeapVector<ScriptValue> createBufferMapped( ScriptState* script_state, const GPUBufferDescriptor* descriptor, ExceptionState& exception_state); ScriptPromise createBufferMappedAsync(ScriptState* script_state, const GPUBufferDescriptor* descriptor, ExceptionState& exception_state); - GPUTexture* createTexture(const GPUTextureDescriptor* descriptor); + GPUTexture* createTexture(const GPUTextureDescriptor* descriptor, + ExceptionState& exception_state); GPUSampler* createSampler(const GPUSamplerDescriptor* descriptor); GPUBindGroup* createBindGroup(const GPUBindGroupDescriptor* descriptor); @@ -93,13 +103,31 @@ class GPUDevice final : public DawnObject<DawnDevice> { GPUQueue* getQueue(); + void pushErrorScope(const WTF::String& filter); + ScriptPromise popErrorScope(ScriptState* script_state); + + DEFINE_ATTRIBUTE_EVENT_LISTENER(uncapturederror, kUncapturederror) + + // EventTarget overrides. + const AtomicString& InterfaceName() const override; + ExecutionContext* GetExecutionContext() const override; + private: + using LostProperty = ScriptPromiseProperty<Member<GPUDevice>, + Member<GPUDeviceLostInfo>, + ToV8UndefinedGenerator>; + void OnUncapturedError(ExecutionContext* execution_context, DawnErrorType errorType, const char* message); + void OnPopErrorScopeCallback(ScriptPromiseResolver* resolver, + DawnErrorType type, + const char* message); + Member<GPUAdapter> adapter_; Member<GPUQueue> queue_; + Member<LostProperty> lost_property_; std::unique_ptr< DawnCallback<base::RepeatingCallback<void(DawnErrorType, const char*)>>> error_callback_; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.idl index cc32b405661..56e9b385828 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.idl @@ -6,14 +6,15 @@ [ RuntimeEnabled=WebGPU -] interface GPUDevice { +] interface GPUDevice : EventTarget { readonly attribute GPUAdapter adapter; + [CallWith=ScriptState] readonly attribute Promise<GPUDeviceLostInfo> lost; GPUBuffer createBuffer(GPUBufferDescriptor descriptor); [CallWith=ScriptState, RaisesException] GPUMappedBuffer createBufferMapped(GPUBufferDescriptor descriptor); [CallWith=ScriptState, RaisesException] Promise<GPUMappedBuffer> createBufferMappedAsync(GPUBufferDescriptor descriptor); - GPUTexture createTexture(GPUTextureDescriptor descriptor); - GPUSampler createSampler(GPUSamplerDescriptor descriptor); + [RaisesException] GPUTexture createTexture(GPUTextureDescriptor descriptor); + GPUSampler createSampler(optional GPUSamplerDescriptor descriptor = {}); GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor); GPUBindGroupLayout createBindGroupLayout(GPUBindGroupLayoutDescriptor descriptor); @@ -23,9 +24,20 @@ [CallWith=ScriptState] GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor); GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor); - GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor); + GPUCommandEncoder createCommandEncoder(optional GPUCommandEncoderDescriptor descriptor = {}); GPURenderBundleEncoder createRenderBundleEncoder(GPURenderBundleEncoderDescriptor descriptor); GPUQueue getQueue(); + + void pushErrorScope(GPUErrorFilter filter); + [CallWith=ScriptState] Promise<GPUError?> popErrorScope(); + + attribute EventHandler onuncapturederror; +}; + +enum GPUErrorFilter { + "none", + "out-of-memory", + "validation" }; typedef sequence<any> GPUMappedBuffer; // [GPUBuffer, ArrayBuffer] diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.idl index a5983c8dde5..83468228edd 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.idl @@ -4,7 +4,7 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUDeviceDescriptor { - GPUExtensions extensions; - GPULimits limits; +dictionary GPUDeviceDescriptor : GPUObjectDescriptorBase { + GPUExtensions extensions = {}; + GPULimits limits = {}; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.cc new file mode 100644 index 00000000000..3a6f1022868 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.cc @@ -0,0 +1,22 @@ +// 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. + +#include "third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h" + +namespace blink { + +// static +GPUDeviceLostInfo* GPUDeviceLostInfo::Create(const String& message) { + return MakeGarbageCollected<GPUDeviceLostInfo>(message); +} + +GPUDeviceLostInfo::GPUDeviceLostInfo(const String& message) { + message_ = message; +} + +const String& GPUDeviceLostInfo::message() const { + return message_; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h new file mode 100644 index 00000000000..db6b2142a98 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.h @@ -0,0 +1,31 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_DEVICE_LOST_INFO_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_DEVICE_LOST_INFO_H_ + +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +class GPUDeviceLostInfo : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + static GPUDeviceLostInfo* Create(const String& message); + GPUDeviceLostInfo(const String& message); + + // gpu_device_lost_info.idl + const String& message() const; + + private: + String message_; + + DISALLOW_COPY_AND_ASSIGN(GPUDeviceLostInfo); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_DEVICE_LOST_INFO_H_ diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.idl new file mode 100644 index 00000000000..44fd3a1d16f --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.idl @@ -0,0 +1,12 @@ +// 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://gpuweb.github.io/gpuweb/ + +[ + RuntimeEnabled=WebGPU +] interface GPUDeviceLostInfo { + readonly attribute DOMString message; +}; + diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_extent_3d.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_extent_3d_dict.idl index 19b45af4747..ef2da9fd7e0 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_extent_3d.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_extent_3d_dict.idl @@ -4,7 +4,7 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUExtent3D { +dictionary GPUExtent3DDict { required unsigned long width; required unsigned long height; required unsigned long depth; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_fence_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_fence_descriptor.idl index 4a94de1c80f..e5ce2679eb3 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_fence_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_fence_descriptor.idl @@ -4,6 +4,6 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUFenceDescriptor { +dictionary GPUFenceDescriptor : GPUObjectDescriptorBase { unsigned long long initialValue = 0; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_object_descriptor_base.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_object_descriptor_base.idl new file mode 100644 index 00000000000..020c0e21584 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_object_descriptor_base.idl @@ -0,0 +1,9 @@ +// 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://gpuweb.github.io/gpuweb/ + +dictionary GPUObjectDescriptorBase { + DOMString? label; +}; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_origin_3d_dict.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_origin_3d_dict.idl new file mode 100644 index 00000000000..741be633dc0 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_origin_3d_dict.idl @@ -0,0 +1,11 @@ +// 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://gpuweb.github.io/gpuweb/ + +dictionary GPUOrigin3DDict { + unsigned long x = 0; + unsigned long y = 0; + unsigned long z = 0; +}; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_descriptor_base.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_descriptor_base.idl index 417592f8b5f..d2cadf779a9 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_descriptor_base.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_descriptor_base.idl @@ -4,7 +4,6 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUPipelineDescriptorBase { - DOMString label; +dictionary GPUPipelineDescriptorBase : GPUObjectDescriptorBase { required GPUPipelineLayout layout; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc index 1f62227b7f2..97a617285e4 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.cc @@ -29,6 +29,9 @@ GPUPipelineLayout* GPUPipelineLayout::Create( dawn_desc.nextInChain = nullptr; dawn_desc.bindGroupLayoutCount = bind_group_layout_count; dawn_desc.bindGroupLayouts = bind_group_layouts.get(); + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } return MakeGarbageCollected<GPUPipelineLayout>( device, device->GetProcs().deviceCreatePipelineLayout(device->GetHandle(), diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout_descriptor.idl index e6fbc7b06ee..7d78d369ac9 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout_descriptor.idl @@ -4,6 +4,6 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUPipelineLayoutDescriptor { +dictionary GPUPipelineLayoutDescriptor : GPUObjectDescriptorBase { required sequence<GPUBindGroupLayout> bindGroupLayouts; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.idl new file mode 100644 index 00000000000..4d57cefafdd --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.idl @@ -0,0 +1,16 @@ +// 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://gpuweb.github.io/gpuweb/ + +[ + RuntimeEnabled=WebGPU +] interface mixin GPUProgrammablePassEncoder { + void setBindGroup(unsigned long index, GPUBindGroup bindGroup, + optional sequence<GPUBufferSize> dynamicOffsets = []); + + void pushDebugGroup(DOMString groupLabel); + void popDebugGroup(); + void insertDebugMarker(DOMString markerLabel); +}; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_stage_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl index dc75910a740..a2cdfd81029 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_pipeline_stage_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl @@ -4,7 +4,7 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUPipelineStageDescriptor { +dictionary GPUProgrammableStageDescriptor { required GPUShaderModule module; required DOMString entryPoint; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc index f1cd037f6d0..a4a5a0dd2ac 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc @@ -51,6 +51,9 @@ GPUFence* GPUQueue::createFence(const GPUFenceDescriptor* descriptor) { DawnFenceDescriptor desc = {}; desc.nextInChain = nullptr; desc.initialValue = descriptor->initialValue(); + if (descriptor->hasLabel()) { + desc.label = descriptor->label().Utf8().data(); + } return GPUFence::Create(device_, GetProcs().queueCreateFence(GetHandle(), &desc)); diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl index cafda6861d9..2cb3f9cab9b 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl @@ -9,6 +9,6 @@ ] interface GPUQueue { void submit(sequence<GPUCommandBuffer> buffers); - GPUFence createFence(optional GPUFenceDescriptor descriptor); + GPUFence createFence(optional GPUFenceDescriptor descriptor = {}); void signal(GPUFence fence, unsigned long long signalValue); }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_descriptor.idl index 662df784dc8..257e326dc68 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_descriptor.idl @@ -4,5 +4,5 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPURenderBundleDescriptor { +dictionary GPURenderBundleDescriptor : GPUObjectDescriptorBase { }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc index 4dfd4989b09..78def74489b 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc @@ -7,7 +7,6 @@ #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" #include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h" #include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h" -#include "third_party/blink/renderer/modules/webgpu/gpu_color.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" #include "third_party/blink/renderer/modules/webgpu/gpu_render_bundle.h" #include "third_party/blink/renderer/modules/webgpu/gpu_render_bundle_descriptor.h" @@ -38,6 +37,9 @@ GPURenderBundleEncoder* GPURenderBundleEncoder::Create( dawn_desc.colorFormats = color_formats.get(); dawn_desc.depthStencilFormat = depth_stencil_format; dawn_desc.sampleCount = webgpu_desc->sampleCount(); + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } return MakeGarbageCollected<GPURenderBundleEncoder>( device, device->GetProcs().deviceCreateRenderBundleEncoder( @@ -89,22 +91,11 @@ void GPURenderBundleEncoder::setIndexBuffer(GPUBuffer* buffer, offset); } -void GPURenderBundleEncoder::setVertexBuffers( - uint32_t startSlot, - const HeapVector<Member<GPUBuffer>>& buffers, - const Vector<uint64_t>& offsets, - ExceptionState& exception_state) { - if (buffers.size() != offsets.size()) { - exception_state.ThrowRangeError( - "buffers array and offsets array must be the same length"); - return; - } - - std::unique_ptr<DawnBuffer[]> dawn_buffers = AsDawnType(buffers); - - GetProcs().renderBundleEncoderSetVertexBuffers( - GetHandle(), startSlot, buffers.size(), dawn_buffers.get(), - offsets.data()); +void GPURenderBundleEncoder::setVertexBuffer(uint32_t slot, + const GPUBuffer* buffer, + uint64_t offset) { + GetProcs().renderBundleEncoderSetVertexBuffer(GetHandle(), slot, + buffer->GetHandle(), offset); } void GPURenderBundleEncoder::draw(uint32_t vertexCount, @@ -141,6 +132,9 @@ GPURenderBundle* GPURenderBundleEncoder::finish( const GPURenderBundleDescriptor* webgpu_desc) { DawnRenderBundleDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } DawnRenderBundle render_bundle = GetProcs().renderBundleEncoderFinish(GetHandle(), &dawn_desc); diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h index 39f8b79953a..a8015a71d73 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h @@ -39,10 +39,7 @@ class GPURenderBundleEncoder : public DawnObject<DawnRenderBundleEncoder> { void setPipeline(GPURenderPipeline* pipeline); void setIndexBuffer(GPUBuffer* buffer, uint64_t offset); - void setVertexBuffers(uint32_t startSlot, - const HeapVector<Member<GPUBuffer>>& buffers, - const Vector<uint64_t>& offsets, - ExceptionState& exception_state); + void setVertexBuffer(uint32_t slot, const GPUBuffer* buffer, uint64_t offset); void draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.idl index 6d3a898be0d..1ee0037875f 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.idl @@ -7,32 +7,7 @@ [ RuntimeEnabled=WebGPU ] interface GPURenderBundleEncoder { - // GPUProgrammablePassEncoder methods - void setBindGroup(unsigned long index, - GPUBindGroup bindGroup, - optional sequence<unsigned long long> dynamicOffsets = []); - void pushDebugGroup(DOMString groupLabel); - void popDebugGroup(); - void insertDebugMarker(DOMString markerLabel); - - // GPURenderEncoderBase methods - void setPipeline(GPURenderPipeline pipeline); - void setIndexBuffer(GPUBuffer buffer, unsigned long long offset); - [RaisesException] void setVertexBuffers(unsigned long startSlot, - sequence<GPUBuffer> buffers, - sequence<unsigned long long> offsets); - void draw(unsigned long vertexCount, unsigned long instanceCount, - unsigned long firstVertex, - unsigned long firstInstance); - void drawIndexed(unsigned long indexCount, unsigned long instanceCount, - unsigned long firstIndex, - long baseVertex, - unsigned long firstInstance); - void drawIndirect(GPUBuffer indirectBuffer, - unsigned long long indirectOffset); - void drawIndexedIndirect(GPUBuffer indirectBuffer, - unsigned long long indirectOffset); - - // GPURenderBundleEncoder methods - GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor); + GPURenderBundle finish(optional GPURenderBundleDescriptor descriptor = {}); }; +GPURenderBundleEncoder includes GPUProgrammablePassEncoder; +GPURenderBundleEncoder includes GPURenderEncoderBase; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder_descriptor.idl index 222ef60356d..14c8bd4eecb 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder_descriptor.idl @@ -4,7 +4,7 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPURenderBundleEncoderDescriptor { +dictionary GPURenderBundleEncoderDescriptor : GPUObjectDescriptorBase { required sequence<GPUTextureFormat> colorFormats; GPUTextureFormat depthStencilFormat; unsigned long sampleCount = 1; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_encoder_base.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_encoder_base.idl new file mode 100644 index 00000000000..ea5c4c6e9d3 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_encoder_base.idl @@ -0,0 +1,29 @@ +// 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://gpuweb.github.io/gpuweb/ + +[ + RuntimeEnabled=WebGPU +] interface mixin GPURenderEncoderBase { + void setPipeline(GPURenderPipeline pipeline); + + void setIndexBuffer(GPUBuffer buffer, optional GPUBufferSize offset = 0); + void setVertexBuffer(unsigned long slot, + GPUBuffer buffer, + optional GPUBufferSize offset = 0); + + void draw(unsigned long vertexCount, unsigned long instanceCount, + unsigned long firstVertex, + unsigned long firstInstance); + void drawIndexed(unsigned long indexCount, unsigned long instanceCount, + unsigned long firstIndex, + long baseVertex, + unsigned long firstInstance); + + void drawIndirect(GPUBuffer indirectBuffer, + GPUBufferSize indirectOffset); + void drawIndexedIndirect(GPUBuffer indirectBuffer, + GPUBufferSize indirectOffset); +}; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.idl index 63c9b326ff1..3d325417185 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.idl @@ -10,6 +10,6 @@ dictionary GPURenderPassDepthStencilAttachmentDescriptor { required (GPULoadOp or float) depthLoadValue; required GPUStoreOp depthStoreOp; - required (GPULoadOp or long) stencilLoadValue; + required (GPULoadOp or unsigned long) stencilLoadValue; required GPUStoreOp stencilStoreOp; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_descriptor.idl index cb0bcdbb106..9589242ac4f 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_descriptor.idl @@ -4,7 +4,7 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPURenderPassDescriptor { +dictionary GPURenderPassDescriptor : GPUObjectDescriptorBase { required sequence<GPURenderPassColorAttachmentDescriptor> colorAttachments; GPURenderPassDepthStencilAttachmentDescriptor depthStencilAttachment; }; @@ -14,5 +14,6 @@ enum GPULoadOp { }; enum GPUStoreOp { - "store" + "store", + "clear" }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc index 4378f95b533..6214d6742ed 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc @@ -4,10 +4,10 @@ #include "third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h" +#include "third_party/blink/renderer/bindings/modules/v8/double_sequence_or_gpu_color_dict.h" #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h" #include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h" #include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h" -#include "third_party/blink/renderer/modules/webgpu/gpu_color.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" #include "third_party/blink/renderer/modules/webgpu/gpu_render_bundle.h" #include "third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.h" @@ -61,8 +61,14 @@ void GPURenderPassEncoder::setPipeline(GPURenderPipeline* pipeline) { GetProcs().renderPassEncoderSetPipeline(GetHandle(), pipeline->GetHandle()); } -void GPURenderPassEncoder::setBlendColor(GPUColor* color) { - DawnColor dawn_color = AsDawnType(color); +void GPURenderPassEncoder::setBlendColor(DoubleSequenceOrGPUColorDict& color, + ExceptionState& exception_state) { + if (color.IsDoubleSequence() && color.GetAsDoubleSequence().size() != 4) { + exception_state.ThrowRangeError("color size must be 4"); + return; + } + + DawnColor dawn_color = AsDawnType(&color); GetProcs().renderPassEncoderSetBlendColor(GetHandle(), &dawn_color); } @@ -92,22 +98,11 @@ void GPURenderPassEncoder::setIndexBuffer(GPUBuffer* buffer, uint64_t offset) { offset); } -void GPURenderPassEncoder::setVertexBuffers( - uint32_t startSlot, - const HeapVector<Member<GPUBuffer>>& buffers, - const Vector<uint64_t>& offsets, - ExceptionState& exception_state) { - if (buffers.size() != offsets.size()) { - exception_state.ThrowRangeError( - "buffers array and offsets array must be the same length"); - return; - } - - std::unique_ptr<DawnBuffer[]> dawn_buffers = AsDawnType(buffers); - - GetProcs().renderPassEncoderSetVertexBuffers( - GetHandle(), startSlot, buffers.size(), dawn_buffers.get(), - offsets.data()); +void GPURenderPassEncoder::setVertexBuffer(uint32_t slot, + const GPUBuffer* buffer, + const uint64_t offset) { + GetProcs().renderPassEncoderSetVertexBuffer(GetHandle(), slot, + buffer->GetHandle(), offset); } void GPURenderPassEncoder::draw(uint32_t vertexCount, diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h index f270ea8d822..03622039cd3 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h @@ -12,7 +12,7 @@ namespace blink { class GPUBindGroup; class GPUBuffer; -class GPUColor; +class DoubleSequenceOrGPUColorDict; class GPURenderBundle; class GPURenderPipeline; @@ -36,7 +36,8 @@ class GPURenderPassEncoder : public DawnObject<DawnRenderPassEncoder> { void insertDebugMarker(String markerLabel); void setPipeline(GPURenderPipeline* pipeline); - void setBlendColor(GPUColor* color); + void setBlendColor(DoubleSequenceOrGPUColorDict& color, + ExceptionState& exception_state); void setStencilReference(uint32_t reference); void setViewport(float x, float y, @@ -46,10 +47,9 @@ class GPURenderPassEncoder : public DawnObject<DawnRenderPassEncoder> { float maxDepth); void setScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height); void setIndexBuffer(GPUBuffer* buffer, uint64_t offset); - void setVertexBuffers(uint32_t startSlot, - const HeapVector<Member<GPUBuffer>>& buffers, - const Vector<uint64_t>& offsets, - ExceptionState& exception_state); + void setVertexBuffer(uint32_t slot, + const GPUBuffer* buffer, + const uint64_t offset); void draw(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl index b3db8006310..524f750a6db 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl @@ -7,39 +7,18 @@ [ RuntimeEnabled=WebGPU ] interface GPURenderPassEncoder { - // GPUProgrammablePassEncoder methods - void setBindGroup(unsigned long index, - GPUBindGroup bindGroup, - optional sequence<unsigned long long> dynamicOffsets = []); - void pushDebugGroup(DOMString groupLabel); - void popDebugGroup(); - void insertDebugMarker(DOMString markerLabel); - - void setPipeline(GPURenderPipeline pipeline); - - void setBlendColor(GPUColor color); - void setStencilReference(unsigned long reference); void setViewport(float x, float y, float width, float height, float minDepth, float maxDepth); + void setScissorRect(unsigned long x, unsigned long y, unsigned long width, unsigned long height); - void setIndexBuffer(GPUBuffer buffer, unsigned long long offset); - [RaisesException] void setVertexBuffers(unsigned long startSlot, - sequence<GPUBuffer> buffers, - sequence<unsigned long long> offsets); - void draw(unsigned long vertexCount, unsigned long instanceCount, - unsigned long firstVertex, - unsigned long firstInstance); - void drawIndexed(unsigned long indexCount, unsigned long instanceCount, - unsigned long firstIndex, - long baseVertex, - unsigned long firstInstance); - void drawIndirect(GPUBuffer indirectBuffer, - unsigned long long indirectOffset); - void drawIndexedIndirect(GPUBuffer indirectBuffer, - unsigned long long indirectOffset); + + [RaisesException] void setBlendColor(GPUColor color); + void setStencilReference(unsigned long reference); void executeBundles(sequence<GPURenderBundle> bundles); void endPass(); }; +GPURenderPassEncoder includes GPUProgrammablePassEncoder; +GPURenderPassEncoder includes GPURenderEncoderBase; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc index 1af046f0103..658342cec45 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.cc @@ -41,17 +41,8 @@ DawnColorStateDescriptor AsDawnType( DawnColorStateDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; - - GPUBlendDescriptor* gpu_alpha_blend = webgpu_desc->hasAlphaBlend() - ? webgpu_desc->alphaBlend() - : GPUBlendDescriptor::Create(); - dawn_desc.alphaBlend = AsDawnType(gpu_alpha_blend); - - GPUBlendDescriptor* gpu_color_blend = webgpu_desc->hasColorBlend() - ? webgpu_desc->colorBlend() - : GPUBlendDescriptor::Create(); - dawn_desc.colorBlend = AsDawnType(gpu_color_blend); - + dawn_desc.alphaBlend = AsDawnType(webgpu_desc->alphaBlend()); + dawn_desc.colorBlend = AsDawnType(webgpu_desc->colorBlend()); dawn_desc.writeMask = AsDawnEnum<DawnColorWriteMask>(webgpu_desc->writeMask()); dawn_desc.format = AsDawnEnum<DawnTextureFormat>(webgpu_desc->format()); @@ -177,6 +168,9 @@ DawnVertexInputInfo GPUVertexInputAsDawnInputState( // stopped appending to the vector so the pointers aren't invalidated. uint32_t attributeIndex = 0; for (DawnVertexBufferDescriptor& buffer : dawn_vertex_buffers) { + if (buffer.attributeCount == 0) { + continue; + } buffer.attributes = &dawn_vertex_attributes[attributeIndex]; attributeIndex += buffer.attributeCount; } @@ -217,11 +211,14 @@ GPURenderPipeline* GPURenderPipeline::Create( DawnRenderPipelineDescriptor dawn_desc = {}; dawn_desc.nextInChain = nullptr; dawn_desc.layout = AsDawnType(webgpu_desc->layout()); + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } - OwnedPipelineStageDescriptor vertex_stage_info = + OwnedProgrammableStageDescriptor vertex_stage_info = AsDawnType(webgpu_desc->vertexStage()); dawn_desc.vertexStage = std::get<0>(vertex_stage_info); - OwnedPipelineStageDescriptor fragment_stage_info; + OwnedProgrammableStageDescriptor fragment_stage_info; if (webgpu_desc->hasFragmentStage()) { fragment_stage_info = AsDawnType(webgpu_desc->fragmentStage()); dawn_desc.fragmentStage = &std::get<0>(fragment_stage_info); @@ -229,34 +226,24 @@ GPURenderPipeline* GPURenderPipeline::Create( dawn_desc.fragmentStage = nullptr; } - DawnVertexInputInfo vertex_input_info; - if (webgpu_desc->hasVertexInput()) { - // TODO(crbug.com/dawn/131): Update Dawn to match WebGPU vertex input - v8::Isolate* isolate = script_state->GetIsolate(); - ExceptionState exception_state(isolate, - ExceptionState::kConstructionContext, - "GPUVertexInputDescriptor"); - vertex_input_info = GPUVertexInputAsDawnInputState( - isolate, webgpu_desc->vertexInput(), exception_state); - dawn_desc.vertexInput = &std::get<0>(vertex_input_info); - - if (exception_state.HadException()) { - return nullptr; - } - } else { - dawn_desc.vertexInput = nullptr; + // TODO(crbug.com/dawn/131): Update Dawn to match WebGPU vertex input + v8::Isolate* isolate = script_state->GetIsolate(); + ExceptionState exception_state(isolate, ExceptionState::kConstructionContext, + "GPUVertexInputDescriptor"); + DawnVertexInputInfo vertex_input_info = GPUVertexInputAsDawnInputState( + isolate, webgpu_desc->vertexInput(), exception_state); + dawn_desc.vertexInput = &std::get<0>(vertex_input_info); + + if (exception_state.HadException()) { + return nullptr; } dawn_desc.primitiveTopology = AsDawnEnum<DawnPrimitiveTopology>(webgpu_desc->primitiveTopology()); DawnRasterizationStateDescriptor rasterization_state; - if (webgpu_desc->hasRasterizationState()) { - rasterization_state = AsDawnType(webgpu_desc->rasterizationState()); - dawn_desc.rasterizationState = &rasterization_state; - } else { - dawn_desc.rasterizationState = nullptr; - } + rasterization_state = AsDawnType(webgpu_desc->rasterizationState()); + dawn_desc.rasterizationState = &rasterization_state; dawn_desc.sampleCount = webgpu_desc->sampleCount(); @@ -273,8 +260,7 @@ GPURenderPipeline* GPURenderPipeline::Create( dawn_desc.colorStateCount = static_cast<uint32_t>(webgpu_desc->colorStates().size()); - DawnColorStateDescriptor* color_state_descriptors = color_states.get(); - dawn_desc.colorStates = &color_state_descriptors; + dawn_desc.colorStates = color_states.get(); dawn_desc.sampleMask = webgpu_desc->sampleMask(); dawn_desc.alphaToCoverageEnabled = webgpu_desc->alphaToCoverageEnabled(); diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline_descriptor.idl index 4fe019c6062..0017094c86b 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline_descriptor.idl @@ -5,14 +5,14 @@ // https://gpuweb.github.io/gpuweb/ dictionary GPURenderPipelineDescriptor : GPUPipelineDescriptorBase { - required GPUPipelineStageDescriptor vertexStage; - GPUPipelineStageDescriptor fragmentStage; + required GPUProgrammableStageDescriptor vertexStage; + GPUProgrammableStageDescriptor fragmentStage; required GPUPrimitiveTopology primitiveTopology; - GPURasterizationStateDescriptor rasterizationState; + GPURasterizationStateDescriptor rasterizationState = {}; required sequence<GPUColorStateDescriptor> colorStates; GPUDepthStencilStateDescriptor depthStencilState; - GPUVertexInputDescriptor vertexInput; + GPUVertexInputDescriptor vertexInput = {}; unsigned long sampleCount = 1; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc index 0b21805d3f6..37aa1f668ac 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc @@ -29,8 +29,10 @@ DawnSamplerDescriptor AsDawnType(const GPUSamplerDescriptor* webgpu_desc) { AsDawnEnum<DawnFilterMode>(webgpu_desc->mipmapFilter()); dawn_desc.lodMinClamp = webgpu_desc->lodMinClamp(); dawn_desc.lodMaxClamp = webgpu_desc->lodMaxClamp(); - dawn_desc.compare = - AsDawnEnum<DawnCompareFunction>(webgpu_desc->compareFunction()); + dawn_desc.compare = AsDawnEnum<DawnCompareFunction>(webgpu_desc->compare()); + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } return dawn_desc; } diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler_descriptor.idl index 4eb8b2be28f..22e45466911 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_sampler_descriptor.idl @@ -4,7 +4,7 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUSamplerDescriptor { +dictionary GPUSamplerDescriptor : GPUObjectDescriptorBase { GPUAddressMode addressModeU = "clamp-to-edge"; GPUAddressMode addressModeV = "clamp-to-edge"; GPUAddressMode addressModeW = "clamp-to-edge"; @@ -13,7 +13,7 @@ dictionary GPUSamplerDescriptor { GPUFilterMode mipmapFilter = "nearest"; float lodMinClamp = 0; float lodMaxClamp = 0xffffffff; - GPUCompareFunction compareFunction = "never"; + GPUCompareFunction compare = "never"; }; enum GPUAddressMode { diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc index 16c65e4a074..edd4004cfb1 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module.cc @@ -18,6 +18,9 @@ DawnShaderModuleDescriptor AsDawnType( dawn_desc.nextInChain = nullptr; dawn_desc.code = webgpu_desc->code().View()->Data(); dawn_desc.codeSize = webgpu_desc->code().View()->length(); + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } return dawn_desc; } diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl index 640d87576de..976f406838a 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl @@ -4,8 +4,7 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUShaderModuleDescriptor { - DOMString label; +dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase { // TODO(kainino): should be: // [AllowShared, FlexibleArrayBufferView] required ArrayBufferView code; // (or BufferSource?) diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_stage.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_stage.h index 6ab71b94a14..07b664900f5 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_stage.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_stage.h @@ -14,7 +14,6 @@ class GPUShaderStage : public ScriptWrappable { public: // gpu_shader_stage.idl - static constexpr uint32_t kNone = 0; static constexpr uint32_t kVertex = 1; static constexpr uint32_t kFragment = 2; static constexpr uint32_t kCompute = 4; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_stage.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_stage.idl index 54f85887df4..546221e2a07 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_stage.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_shader_stage.idl @@ -8,8 +8,7 @@ typedef unsigned long GPUShaderStageFlags; [ RuntimeEnabled=WebGPU ] interface GPUShaderStage { - const unsigned long NONE = 0; - const unsigned long VERTEX = 1; - const unsigned long FRAGMENT = 2; - const unsigned long COMPUTE = 4; + const GPUShaderStageFlags VERTEX = 1; + const GPUShaderStageFlags FRAGMENT = 2; + const GPUShaderStageFlags COMPUTE = 4; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc index a400bf0e62b..9521cc2d7fd 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.cc @@ -24,6 +24,7 @@ GPUSwapChain::GPUSwapChain(GPUCanvasContext* context, device_(descriptor->device()), context_(context), usage_(AsDawnEnum<DawnTextureUsage>(descriptor->usage())) { + // TODO: Use label from GPUObjectDescriptorBase. swap_buffers_ = base::AdoptRef(new WebGPUSwapBufferProvider( this, GetDawnControlClient(), usage_, AsDawnEnum<DawnTextureFormat>(descriptor->format()))); diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h index b644bba9dd7..edaedbfd219 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain.h @@ -19,7 +19,8 @@ class GPUDevice; class GPUSwapChainDescriptor; class GPUTexture; -class GPUSwapChain : public DawnObjectBase, +class GPUSwapChain : public ScriptWrappable, + public DawnObjectBase, public WebGPUSwapBufferProvider::Client { DEFINE_WRAPPERTYPEINFO(); diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain_descriptor.idl index 073b8e0c697..48bdb46c8ee 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_swap_chain_descriptor.idl @@ -4,7 +4,7 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUSwapChainDescriptor { +dictionary GPUSwapChainDescriptor : GPUObjectDescriptorBase { required GPUDevice device; required GPUTextureFormat format; GPUTextureUsageFlags usage = 16; // GPUTextureUsage.OUTPUT_ATTACHMENT diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.cc index 6006899d80d..9a4ec197e86 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.cc @@ -22,11 +22,14 @@ DawnTextureDescriptor AsDawnType(const GPUTextureDescriptor* webgpu_desc) { dawn_desc.usage = static_cast<DawnTextureUsage>(webgpu_desc->usage()); dawn_desc.dimension = AsDawnEnum<DawnTextureDimension>(webgpu_desc->dimension()); - dawn_desc.size = AsDawnType(webgpu_desc->size()); + dawn_desc.size = AsDawnType(&webgpu_desc->size()); dawn_desc.arrayLayerCount = webgpu_desc->arrayLayerCount(); dawn_desc.format = AsDawnEnum<DawnTextureFormat>(webgpu_desc->format()); dawn_desc.mipLevelCount = webgpu_desc->mipLevelCount(); dawn_desc.sampleCount = webgpu_desc->sampleCount(); + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } return dawn_desc; } @@ -44,6 +47,10 @@ DawnTextureViewDescriptor AsDawnType( dawn_desc.mipLevelCount = webgpu_desc->mipLevelCount(); dawn_desc.baseArrayLayer = webgpu_desc->baseArrayLayer(); dawn_desc.arrayLayerCount = webgpu_desc->arrayLayerCount(); + dawn_desc.aspect = AsDawnEnum<DawnTextureAspect>(webgpu_desc->aspect()); + if (webgpu_desc->hasLabel()) { + dawn_desc.label = webgpu_desc->label().Utf8().data(); + } return dawn_desc; } @@ -52,9 +59,19 @@ DawnTextureViewDescriptor AsDawnType( // static GPUTexture* GPUTexture::Create(GPUDevice* device, - const GPUTextureDescriptor* webgpu_desc) { + const GPUTextureDescriptor* webgpu_desc, + ExceptionState& exception_state) { DCHECK(device); DCHECK(webgpu_desc); + + // Check size is correctly formatted before further processing. + const UnsignedLongSequenceOrGPUExtent3DDict& size = webgpu_desc->size(); + if (size.IsUnsignedLongSequence() && + size.GetAsUnsignedLongSequence().size() != 3) { + exception_state.ThrowRangeError("size length must be 3"); + return nullptr; + } + DawnTextureDescriptor dawn_desc = AsDawnType(webgpu_desc); return MakeGarbageCollected<GPUTexture>( diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.h index 2063c416819..a137fdc8771 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.h @@ -9,6 +9,7 @@ namespace blink { +class ExceptionState; class GPUTextureDescriptor; class GPUTextureView; class GPUTextureViewDescriptor; @@ -18,7 +19,8 @@ class GPUTexture : public DawnObject<DawnTexture> { public: static GPUTexture* Create(GPUDevice* device, - const GPUTextureDescriptor* webgpu_desc); + const GPUTextureDescriptor* webgpu_desc, + ExceptionState& exception_state); explicit GPUTexture(GPUDevice* device, DawnTexture texture); ~GPUTexture() override; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.idl index cdbcb367fe0..67904ef9d39 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture.idl @@ -7,6 +7,6 @@ [ RuntimeEnabled=WebGPU ] interface GPUTexture { - GPUTextureView createView(optional GPUTextureViewDescriptor desc); + GPUTextureView createView(optional GPUTextureViewDescriptor descriptor = {}); void destroy(); }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl index c0630b90bf3..0f9f85c1920 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl @@ -8,5 +8,5 @@ dictionary GPUTextureCopyView { required GPUTexture texture; unsigned long mipLevel = 0; unsigned long arrayLayer = 0; - required GPUOrigin3D origin; + GPUOrigin3D origin = {}; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl index b838a4cb0d9..e7b7b96b274 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl @@ -4,7 +4,7 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUTextureDescriptor { +dictionary GPUTextureDescriptor : GPUObjectDescriptorBase { required GPUExtent3D size; unsigned long arrayLayerCount = 1; unsigned long mipLevelCount = 1; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_usage.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_usage.h index 30ec2618ac3..4455467dafc 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_usage.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_usage.h @@ -14,7 +14,6 @@ class GPUTextureUsage : public ScriptWrappable { public: // gpu_texture_usage.idl - static constexpr uint32_t kNone = 0; static constexpr uint32_t kCopySrc = 1; static constexpr uint32_t kCopyDst = 2; static constexpr uint32_t kSampled = 4; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_usage.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_usage.idl index 8a5c208a29b..d8139ba2073 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_usage.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_usage.idl @@ -8,10 +8,9 @@ typedef unsigned long GPUTextureUsageFlags; [ RuntimeEnabled=WebGPU ] interface GPUTextureUsage { - const unsigned long NONE = 0; - const unsigned long COPY_SRC = 1; - const unsigned long COPY_DST = 2; - const unsigned long SAMPLED = 4; - const unsigned long STORAGE = 8; - const unsigned long OUTPUT_ATTACHMENT = 16; + const GPUTextureUsageFlags COPY_SRC = 1; + const GPUTextureUsageFlags COPY_DST = 2; + const GPUTextureUsageFlags SAMPLED = 4; + const GPUTextureUsageFlags STORAGE = 8; + const GPUTextureUsageFlags OUTPUT_ATTACHMENT = 16; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view_descriptor.idl index 551d2923ce8..ec3b27af8cb 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_view_descriptor.idl @@ -4,7 +4,7 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUTextureViewDescriptor { +dictionary GPUTextureViewDescriptor : GPUObjectDescriptorBase { GPUTextureFormat format; GPUTextureViewDimension dimension; GPUTextureAspect aspect = "all"; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.idl index 515407bcef1..80bed55a9d4 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.idl @@ -8,4 +8,5 @@ Constructor(DOMString type, GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict), RuntimeEnabled=WebGPU ] interface GPUUncapturedErrorEvent : Event { + readonly attribute GPUError error; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_vertex_attribute_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_vertex_attribute_descriptor.idl index 297b7f9e64f..3e92bd06e85 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_vertex_attribute_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_vertex_attribute_descriptor.idl @@ -4,12 +4,10 @@ // https://gpuweb.github.io/gpuweb/ -typedef unsigned long GPUShaderAttributeIndex; - dictionary GPUVertexAttributeDescriptor { - unsigned long long offset = 0; + GPUBufferSize offset = 0; required GPUVertexFormat format; - required GPUShaderAttributeIndex shaderLocation; + required unsigned long shaderLocation; }; enum GPUVertexFormat { diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_vertex_buffer_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_vertex_buffer_descriptor.idl index b6ab1912f63..a6967902644 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_vertex_buffer_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_vertex_buffer_descriptor.idl @@ -5,7 +5,7 @@ // https://gpuweb.github.io/gpuweb/ dictionary GPUVertexBufferDescriptor { - required unsigned long long stride; + required GPUBufferSize stride; GPUInputStepMode stepMode = "vertex"; required sequence<GPUVertexAttributeDescriptor> attributeSet; }; diff --git a/chromium/third_party/blink/renderer/modules/webmidi/DEPS b/chromium/third_party/blink/renderer/modules/webmidi/DEPS index 9e5294b9d10..35e7842acbb 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/DEPS +++ b/chromium/third_party/blink/renderer/modules/webmidi/DEPS @@ -1,5 +1,6 @@ include_rules = [ "+media/midi/midi_service.mojom-blink.h", + "+media/midi/midi_service.mojom-blink-forward.h", "-third_party/blink/renderer/modules", "+third_party/blink/renderer/modules/event_modules.h", "+third_party/blink/renderer/modules/event_target_modules.h", diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.h index 0d81d1909ac..73a42977dfa 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.h +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.h @@ -32,7 +32,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBMIDI_MIDI_ACCESS_H_ #include <memory> -#include "media/midi/midi_service.mojom-blink.h" +#include "media/midi/midi_service.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h" diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h index e347e495e10..b3271887604 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.h @@ -6,10 +6,10 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBMIDI_MIDI_ACCESS_INITIALIZER_H_ #include <memory> -#include "media/midi/midi_service.mojom-blink.h" +#include "media/midi/midi_service.mojom-blink-forward.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/permissions/permission.mojom-blink.h" -#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.h" +#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/modules/modules_export.h" diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.h index f09b3b0aa4b..23d2067d9f2 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.h +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.h @@ -31,7 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBMIDI_MIDI_INPUT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBMIDI_MIDI_INPUT_H_ -#include "media/midi/midi_service.mojom-blink.h" +#include "media/midi/midi_service.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/event_target_modules.h" #include "third_party/blink/renderer/modules/webmidi/midi_port.h" diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.h index 0f62c6e6f62..f7c92147e0c 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.h +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.h @@ -31,7 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBMIDI_MIDI_PORT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBMIDI_MIDI_PORT_H_ -#include "media/midi/midi_service.mojom-blink.h" +#include "media/midi/midi_service.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" diff --git a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc index 21433d18aff..ac930802c90 100644 --- a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc +++ b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc @@ -7,7 +7,7 @@ #include <stdint.h> #include <utility> -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -198,7 +198,7 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state, } // See https://bit.ly/2S0zRAS for task types. - frame->GetInterfaceProvider().GetInterface( + frame->GetBrowserInterfaceBroker().GetInterface( service_remote_.BindNewPipeAndPassReceiver( frame->GetTaskRunner(TaskType::kMiscPlatformAPI))); service_remote_.set_disconnect_handler(WTF::Bind( diff --git a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.h b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.h index af3c18e45e1..23ff0e6bc91 100644 --- a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.h +++ b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.h @@ -24,7 +24,7 @@ class Navigator; class ShareData; class MODULES_EXPORT NavigatorShare final - : public GarbageCollectedFinalized<NavigatorShare>, + : public GarbageCollected<NavigatorShare>, public Supplement<Navigator> { USING_GARBAGE_COLLECTED_MIXIN(NavigatorShare); diff --git a/chromium/third_party/blink/renderer/modules/webshare/navigator_share_test.cc b/chromium/third_party/blink/renderer/modules/webshare/navigator_share_test.cc index a0c8268afa4..1f615675b3a 100644 --- a/chromium/third_party/blink/renderer/modules/webshare/navigator_share_test.cc +++ b/chromium/third_party/blink/renderer/modules/webshare/navigator_share_test.cc @@ -6,8 +6,8 @@ #include <memory> #include <utility> -#include "services/service_manager/public/cpp/interface_provider.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/fileapi/file.h" @@ -112,14 +112,20 @@ class NavigatorShareTest : public testing::Test { nullptr /* extra_data */); test::RunPendingTasks(); - service_manager::InterfaceProvider::TestApi test_api( - &GetFrame().GetInterfaceProvider()); - test_api.SetBinderForName( + GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting( ShareService::Name_, WTF::BindRepeating(&MockShareService::Bind, WTF::Unretained(&mock_share_service_))); } + void TearDown() override { + // Remove the testing binder to avoid crashes between tests caused by + // MockShareService rebinding an already-bound Binding. + // See https://crbug.com/1010116 for more information. + GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting( + ShareService::Name_, {}); + } + public: MockShareService mock_share_service_; diff --git a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h index 1736f885d2b..6fd0d7871cb 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h +++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h @@ -152,7 +152,7 @@ class MODULES_EXPORT DOMWebSocket : public EventTargetWithInlineData, private: // FIXME: This should inherit blink::EventQueue. - class EventQueue final : public GarbageCollectedFinalized<EventQueue> { + class EventQueue final : public GarbageCollected<EventQueue> { public: static EventQueue* Create(EventTarget* target) { return MakeGarbageCollected<EventQueue>(target); diff --git a/chromium/third_party/blink/renderer/modules/websockets/mock_websocket_channel.h b/chromium/third_party/blink/renderer/modules/websockets/mock_websocket_channel.h index 3c9e0aa78ed..8e8574b589a 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/mock_websocket_channel.h +++ b/chromium/third_party/blink/renderer/modules/websockets/mock_websocket_channel.h @@ -9,7 +9,7 @@ #include "base/memory/scoped_refptr.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h" +#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink-forward.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/modules/websockets/websocket_channel.h" #include "third_party/blink/renderer/platform/blob/blob_data.h" @@ -52,6 +52,7 @@ class MockWebSocketChannel : public WebSocketChannel { FailMock(reason, level, location.get()); } MOCK_METHOD0(Disconnect, void()); + MOCK_METHOD0(CancelHandshake, void()); MOCK_METHOD0(ApplyBackpressure, void()); MOCK_METHOD0(RemoveBackpressure, void()); }; diff --git a/chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_channel_client_proxy.h b/chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_channel_client_proxy.h index 80159e0405f..bf525db6a34 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_channel_client_proxy.h +++ b/chromium/third_party/blink/renderer/modules/websockets/web_pepper_socket_channel_client_proxy.h @@ -21,7 +21,7 @@ namespace blink { // WebPepperSocketImpl cannot be on Oilpan's heap. Thus we need to introduce a // proxy class to decouple WebPepperSocketImpl from WebSocketChannelClient. class WebPepperSocketChannelClientProxy final - : public GarbageCollectedFinalized<WebPepperSocketChannelClientProxy>, + : public GarbageCollected<WebPepperSocketChannelClientProxy>, public WebSocketChannelClient { USING_GARBAGE_COLLECTED_MIXIN(WebPepperSocketChannelClientProxy); diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h index 5c90167724d..5b315322efc 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h @@ -47,7 +47,7 @@ class DOMArrayBuffer; class KURL; class MODULES_EXPORT WebSocketChannel - : public GarbageCollectedFinalized<WebSocketChannel> { + : public GarbageCollected<WebSocketChannel> { public: enum class SendResult { SENT_SYNCHRONOUSLY, CALLBACK_WILL_BE_CALLED }; @@ -102,6 +102,10 @@ class MODULES_EXPORT WebSocketChannel // Do not call any methods after calling this method. virtual void Disconnect() = 0; // Will suppress didClose(). + // Cancel the WebSocket handshake. Does nothing if the connection is already + // established. Do not call any other methods after this one. + virtual void CancelHandshake() = 0; + // Clients can call ApplyBackpressure() to indicate that they want to stop // receiving new messages. WebSocketChannelClient::DidReceive*Message() may // still be called after this, until existing flow control quota is used up. diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc index d0a92c7b31b..3a3cac1ad1c 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc @@ -66,6 +66,8 @@ #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/shared_buffer.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" +#include "third_party/blink/renderer/platform/wtf/text/ascii_ctype.h" +#include "third_party/blink/renderer/platform/wtf/text/string_impl.h" namespace blink { @@ -79,7 +81,7 @@ enum WebSocketOpCode { } // namespace class WebSocketChannelImpl::BlobLoader final - : public GarbageCollectedFinalized<WebSocketChannelImpl::BlobLoader>, + : public GarbageCollected<WebSocketChannelImpl::BlobLoader>, public FileReaderLoaderClient { public: BlobLoader(scoped_refptr<BlobDataHandle>, @@ -102,8 +104,8 @@ class WebSocketChannelImpl::BlobLoader final std::unique_ptr<FileReaderLoader> loader_; }; -class WebSocketChannelImpl::Message - : public GarbageCollectedFinalized<WebSocketChannelImpl::Message> { +class WebSocketChannelImpl::Message final + : public GarbageCollected<WebSocketChannelImpl::Message> { public: Message(const std::string&, base::OnceClosure completion_callback); explicit Message(scoped_refptr<BlobDataHandle>); @@ -415,6 +417,18 @@ void WebSocketChannelImpl::Disconnect() { Dispose(); } +void WebSocketChannelImpl::CancelHandshake() { + NETWORK_DVLOG(1) << this << " CancelHandshake()"; + if (GetState() != State::kConnecting) + return; + + // This may still disconnect even if the handshake is complete if we haven't + // got the message yet. + // TODO(ricea): Plumb it through to the network stack to fix the race + // condition. + Disconnect(); +} + void WebSocketChannelImpl::ApplyBackpressure() { backpressure_ = true; } @@ -439,31 +453,26 @@ void WebSocketChannelImpl::OnOpeningHandshakeStarted( handshake_request_ = std::move(request); } -void WebSocketChannelImpl::OnResponseReceived( - network::mojom::blink::WebSocketHandshakeResponsePtr response) { - DCHECK_EQ(GetState(), State::kConnecting); - NETWORK_DVLOG(1) << this << " OnResponseReceived(" - << response->url.GetString() << ")"; - TRACE_EVENT_INSTANT1( - "devtools.timeline", "WebSocketReceiveHandshakeResponse", - TRACE_EVENT_SCOPE_THREAD, "data", - InspectorWebSocketEvent::Data(execution_context_, identifier_)); - probe::DidReceiveWebSocketHandshakeResponse(execution_context_, identifier_, - handshake_request_.get(), - response.get()); - handshake_request_ = nullptr; -} - void WebSocketChannelImpl::OnConnectionEstablished( mojo::PendingRemote<network::mojom::blink::WebSocket> websocket, mojo::PendingReceiver<network::mojom::blink::WebSocketClient> client_receiver, const String& protocol, const String& extensions, + network::mojom::blink::WebSocketHandshakeResponsePtr response, mojo::ScopedDataPipeConsumerHandle readable) { DCHECK_EQ(GetState(), State::kConnecting); NETWORK_DVLOG(1) << this << " OnConnectionEstablished(" << protocol << ", " << extensions << ")"; + TRACE_EVENT_INSTANT1( + "devtools.timeline", "WebSocketReceiveHandshakeResponse", + TRACE_EVENT_SCOPE_THREAD, "data", + InspectorWebSocketEvent::Data(execution_context_, identifier_)); + probe::DidReceiveWebSocketHandshakeResponse(execution_context_, identifier_, + handshake_request_.get(), + response.get()); + handshake_request_ = nullptr; + // From now on, we will detect mojo errors via |client_receiver_|. handshake_client_receiver_.reset(); client_receiver_.Bind( @@ -625,15 +634,8 @@ void WebSocketChannelImpl::SendAndAdjustQuota( network::mojom::blink::WebSocketMessageType type, base::span<const char> data, uint64_t* consumed_buffered_amount) { - // TODO(darin): Avoid this copy. - Vector<uint8_t> data_to_pass; - // This cast is always valid because the data size is limited by - // sending_quota_, which is controlled by the browser process and in practice - // is always much smaller than 4GB. - // TODO(ricea): Change the type of sending_quota_ to wtf_size_t. - data_to_pass.ReserveInitialCapacity(static_cast<wtf_size_t>(data.size())); - data_to_pass.Append(data.data(), static_cast<wtf_size_t>(data.size())); - + base::span<const uint8_t> data_to_pass( + reinterpret_cast<const uint8_t*>(data.data()), data.size()); websocket_->SendFrame(fin, type, data_to_pass); sending_quota_ -= data.size(); @@ -887,12 +889,22 @@ void WebSocketChannelImpl::ConsumeDataFrame( return; } + // TODO(yoichio): Do this after EndReadData by reading |message_chunks_| + // instead. + if (receiving_message_type_is_text_ && received_text_is_all_ascii_) { + for (size_t i = 0; i < size; i++) { + if (!IsASCII(data[i])) { + received_text_is_all_ascii_ = false; + break; + } + } + } + if (!fin) { message_chunks_.Append(base::make_span(data, size)); return; } - const wtf_size_t message_size = static_cast<wtf_size_t>(message_size_so_far); Vector<base::span<const char>> chunks = message_chunks_.GetView(); if (size > 0) { chunks.push_back(base::make_span(data, size)); @@ -904,20 +916,8 @@ void WebSocketChannelImpl::ConsumeDataFrame( false, chunks); if (receiving_message_type_is_text_) { - Vector<char> flatten; - base::span<const char> span; - if (chunks.size() > 1) { - flatten.ReserveCapacity(message_size); - for (const auto& chunk : chunks) { - flatten.Append(chunk.data(), static_cast<wtf_size_t>(chunk.size())); - } - span = base::make_span(flatten.data(), flatten.size()); - } else if (chunks.size() == 1) { - span = chunks[0]; - } - String message = span.size() > 0 - ? String::FromUTF8(span.data(), span.size()) - : g_empty_string; + String message = GetTextMessage( + chunks, static_cast<wtf_size_t>(message_size_so_far + size)); if (message.IsNull()) { FailAsError("Could not decode a text frame as UTF-8."); } else { @@ -927,6 +927,47 @@ void WebSocketChannelImpl::ConsumeDataFrame( client_->DidReceiveBinaryMessage(chunks); } message_chunks_.Clear(); + received_text_is_all_ascii_ = true; +} + +String WebSocketChannelImpl::GetTextMessage( + const Vector<base::span<const char>>& chunks, + wtf_size_t size) { + DCHECK(receiving_message_type_is_text_); + + if (size == 0) { + return g_empty_string; + } + + // We can skip UTF8 encoding if received text contains only ASCII. + // We do this in order to avoid constructing a temporary buffer. + if (received_text_is_all_ascii_) { + LChar* buffer; + scoped_refptr<StringImpl> string_impl = + StringImpl::CreateUninitialized(size, buffer); + size_t index = 0; + for (const auto& chunk : chunks) { + DCHECK_LE(index + chunk.size(), size); + memcpy(buffer + index, chunk.data(), chunk.size()); + index += chunk.size(); + } + DCHECK_EQ(index, size); + return String(std::move(string_impl)); + } + + Vector<char> flatten; + base::span<const char> span; + if (chunks.size() > 1) { + flatten.ReserveCapacity(size); + for (const auto& chunk : chunks) { + flatten.Append(chunk.data(), static_cast<wtf_size_t>(chunk.size())); + } + span = base::make_span(flatten.data(), flatten.size()); + } else if (chunks.size() == 1) { + span = chunks[0]; + } + DCHECK_EQ(span.size(), size); + return String::FromUTF8(span.data(), span.size()); } void WebSocketChannelImpl::OnConnectionError(const base::Location& set_from, @@ -949,6 +990,7 @@ void WebSocketChannelImpl::OnConnectionError(const base::Location& set_from, } void WebSocketChannelImpl::Dispose() { + message_chunks_.Reset(); has_initiated_opening_handshake_ = true; feature_handle_for_scheduler_.reset(); handshake_throttle_.reset(); diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h index c5f5b5b4372..318b7d7a213 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl.h @@ -42,7 +42,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/system/simple_watcher.h" #include "services/network/public/mojom/websocket.mojom-blink.h" -#include "third_party/blink/public/mojom/websockets/websocket_connector.mojom-blink.h" +#include "third_party/blink/public/mojom/websockets/websocket_connector.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" #include "third_party/blink/renderer/core/fileapi/blob.h" #include "third_party/blink/renderer/modules/modules_export.h" @@ -107,20 +107,20 @@ class MODULES_EXPORT WebSocketChannelImpl final mojom::ConsoleMessageLevel, std::unique_ptr<SourceLocation>) override; void Disconnect() override; + void CancelHandshake() override; void ApplyBackpressure() override; void RemoveBackpressure() override; // network::mojom::blink::WebSocketHandshakeClient methods: void OnOpeningHandshakeStarted( network::mojom::blink::WebSocketHandshakeRequestPtr) override; - void OnResponseReceived( - network::mojom::blink::WebSocketHandshakeResponsePtr) override; void OnConnectionEstablished( mojo::PendingRemote<network::mojom::blink::WebSocket> websocket, mojo::PendingReceiver<network::mojom::blink::WebSocketClient> client_receiver, const String& selected_protocol, const String& extensions, + network::mojom::blink::WebSocketHandshakeResponsePtr, mojo::ScopedDataPipeConsumerHandle readable) override; // network::mojom::blink::WebSocketClient methods: @@ -228,6 +228,8 @@ class MODULES_EXPORT WebSocketChannelImpl final network::mojom::blink::WebSocketMessageType type, const char* data, size_t data_size); + String GetTextMessage(const Vector<base::span<const char>>& chunks, + wtf_size_t size); void OnConnectionError(const base::Location& set_from, uint32_t custom_reason, const std::string& description); @@ -243,6 +245,7 @@ class MODULES_EXPORT WebSocketChannelImpl final bool backpressure_ = false; bool receiving_message_type_is_text_ = false; + bool received_text_is_all_ascii_ = true; bool throttle_passed_ = false; bool has_initiated_opening_handshake_ = false; uint64_t sending_quota_ = 0; diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc index 84ec7583387..4231f311c15 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc @@ -14,6 +14,7 @@ #include "mojo/public/cpp/bindings/receiver_set.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/websockets/websocket_connector.mojom-blink.h" #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/websocket_handshake_throttle.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -41,7 +42,7 @@ namespace blink { typedef testing::StrictMock<testing::MockFunction<void(int)>> Checkpoint; class MockWebSocketChannelClient - : public GarbageCollectedFinalized<MockWebSocketChannelClient>, + : public GarbageCollected<MockWebSocketChannelClient>, public WebSocketChannelClient { USING_GARBAGE_COLLECTED_MIXIN(MockWebSocketChannelClient); @@ -112,8 +113,10 @@ class WebSocketChannelImplTest : public PageTestBase { void SendFrame(bool fin, WebSocketMessageType type, - const Vector<uint8_t>& data) override { - frames_.push_back(Frame{fin, type, data}); + base::span<const uint8_t> data) override { + Vector<uint8_t> data_to_pass; + data_to_pass.AppendRange(data.begin(), data.end()); + frames_.push_back(Frame{fin, type, std::move(data_to_pass)}); } void StartReceiving() override { DCHECK(!is_start_receiving_called_); @@ -235,10 +238,14 @@ class WebSocketChannelImplTest : public PageTestBase { auto websocket = std::make_unique<TestWebSocket>( websocket_to_pass.InitWithNewPipeAndPassReceiver()); + auto response = network::mojom::blink::WebSocketHandshakeResponse::New(); + response->http_version = network::mojom::blink::HttpVersion::New(); + response->status_text = ""; + response->headers_text = ""; handshake_client->OnConnectionEstablished( std::move(websocket_to_pass), client_remote.InitWithNewPipeAndPassReceiver(), selected_protocol, - extensions, std::move(readable)); + extensions, std::move(response), std::move(readable)); client->Bind(std::move(client_remote)); return websocket; } diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_message_chunk_accumulator.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_message_chunk_accumulator.cc index 0080e5bbe81..21affd2886c 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_message_chunk_accumulator.cc +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_message_chunk_accumulator.cc @@ -81,6 +81,14 @@ void WebSocketMessageChunkAccumulator::Clear() { } } +void WebSocketMessageChunkAccumulator::Reset() { + segments_.clear(); + pool_.clear(); + size_ = 0; + num_pooled_segments_to_be_removed_ = 0; + timer_.Stop(); +} + void WebSocketMessageChunkAccumulator::OnTimerFired(TimerBase*) { DCHECK(!timer_.IsActive()); const auto to_be_removed = diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_message_chunk_accumulator.h b/chromium/third_party/blink/renderer/modules/websockets/websocket_message_chunk_accumulator.h index 2558fd545bd..c3c7ee16ac8 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_message_chunk_accumulator.h +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_message_chunk_accumulator.h @@ -43,6 +43,9 @@ class MODULES_EXPORT WebSocketMessageChunkAccumulator final { // uses for certain amount of time. void Clear(); + // Clear all stored data and cancel timers. + void Reset(); + // The regions will be available until Clear() is called. Vector<base::span<const char>> GetView() const; diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc index 49252d33cb8..c33cdbc2653 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc @@ -14,6 +14,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_websocket_close_info.h" +#include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/streams/readable_stream.h" #include "third_party/blink/renderer/core/streams/readable_stream_default_controller_interface.h" @@ -467,8 +468,6 @@ void WebSocketStream::DidConnect(const String& subprotocol, return; common_.SetState(WebSocketCommon::kOpen); was_ever_connected_ = true; - // Don't read all of a huge initial message before read() has been called. - channel_->ApplyBackpressure(); auto* connection = MakeGarbageCollected<WebSocketConnection>(); connection->setProtocol(subprotocol); connection->setExtensions(extensions); @@ -598,7 +597,24 @@ void WebSocketStream::Connect(ScriptState* script_state, DVLOG(1) << "WebSocketStream " << this << " Connect() url=" << url << " options=" << options; - // TODO(ricea): Support AbortSignal. + // Don't read all of a huge initial message before read() has been called. + channel_->ApplyBackpressure(); + + auto* signal = options->signal(); + if (signal && signal->aborted()) { + auto exception = V8ThrowDOMException::CreateOrEmpty( + script_state->GetIsolate(), DOMExceptionCode::kAbortError, + "WebSocket handshake was aborted"); + connection_resolver_->Reject(exception); + closed_resolver_->Reject(exception); + return; + } + + if (signal) { + signal->AddAlgorithm( + WTF::Bind(&WebSocketStream::OnAbort, WrapWeakPersistent(this))); + } + auto result = common_.Connect( ExecutionContext::From(script_state), url, options->hasProtocols() ? options->protocols() : Vector<String>(), @@ -680,6 +696,22 @@ v8::Local<v8::Value> WebSocketStream::CreateNetworkErrorDOMException() { "A network error occurred"); } +void WebSocketStream::OnAbort() { + DVLOG(1) << "WebSocketStream " << this << " OnAbort()"; + + if (was_ever_connected_ || !channel_) + return; + + channel_->CancelHandshake(); + channel_ = nullptr; + + auto exception = V8ThrowDOMException::CreateOrEmpty( + script_state_->GetIsolate(), DOMExceptionCode::kAbortError, + "WebSocket handshake was aborted"); + connection_resolver_->Reject(exception); + closed_resolver_->Reject(exception); +} + WebSocketCloseInfo* WebSocketStream::MakeCloseInfo(uint16_t code, const String& reason) { DVLOG(1) << "WebSocketStream MakeCloseInfo() code=" << code diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h index 1438614eb5f..df0ecc29756 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h @@ -108,6 +108,7 @@ class MODULES_EXPORT WebSocketStream final void CloseInternal(int code, const String& reason, ExceptionState& exception_state); + void OnAbort(); v8::Local<v8::Value> CreateNetworkErrorDOMException(); static WebSocketCloseInfo* MakeCloseInfo(uint16_t code, const String& reason); diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream_test.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream_test.cc index 554ed5942fc..d33f4504c64 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream_test.cc +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream_test.cc @@ -10,13 +10,19 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h" +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h" +#include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/modules/websockets/mock_websocket_channel.h" #include "third_party/blink/renderer/modules/websockets/websocket_channel.h" #include "third_party/blink/renderer/modules/websockets/websocket_channel_client.h" #include "third_party/blink/renderer/modules/websockets/websocket_close_info.h" #include "third_party/blink/renderer/modules/websockets/websocket_stream_options.h" #include "third_party/blink/renderer/platform/bindings/exception_code.h" +#include "third_party/blink/renderer/platform/bindings/v8_binding.h" namespace blink { @@ -56,6 +62,39 @@ class WebSocketStreamTest : public ::testing::Test { channel_, exception_state); } + bool IsDOMException(ScriptState* script_state, + ScriptValue value, + DOMExceptionCode code) { + auto* dom_exception = V8DOMException::ToImplWithTypeCheck( + script_state->GetIsolate(), value.V8Value()); + if (!dom_exception) + return false; + + return dom_exception->code() == static_cast<uint16_t>(code); + } + + // Returns the value of the property |key| on object |object|, stringified as + // a UTF-8 encoded std::string so that it can be compared and printed by + // EXPECT_EQ. |object| must have been verified to be a v8::Object. |key| must + // be encoded as latin1. undefined and null values are stringified as + // "undefined" and "null" respectively. "undefined" is also used to mean "not + // found". + std::string PropertyAsString(ScriptState* script_state, + v8::Local<v8::Value> object, + String key) { + v8::Local<v8::Value> value; + auto* isolate = script_state->GetIsolate(); + if (!object.As<v8::Object>() + ->GetRealNamedProperty(script_state->GetContext(), + V8String(isolate, key)) + .ToLocal(&value)) { + value = v8::Undefined(isolate); + } + + v8::String::Utf8Value utf8value(isolate, value); + return std::string(*utf8value, utf8value.length()); + } + private: Persistent<MockWebSocketChannel> channel_; }; @@ -63,6 +102,9 @@ class WebSocketStreamTest : public ::testing::Test { TEST_F(WebSocketStreamTest, ConstructWithBadURL) { V8TestingScope scope; auto& exception_state = scope.GetExceptionState(); + + EXPECT_CALL(Channel(), ApplyBackpressure()); + auto* stream = Create(scope.GetScriptState(), "bad-scheme:", exception_state); EXPECT_FALSE(stream); @@ -72,7 +114,7 @@ TEST_F(WebSocketStreamTest, ConstructWithBadURL) { EXPECT_EQ( "The URL's scheme must be either 'ws' or 'wss'. 'bad-scheme' is not " "allowed.", - scope.GetExceptionState().Message()); + exception_state.Message()); } // Most coverage for bad constructor arguments is provided by @@ -84,6 +126,7 @@ TEST_F(WebSocketStreamTest, Connect) { { InSequence s; + EXPECT_CALL(Channel(), ApplyBackpressure()); EXPECT_CALL(Channel(), Connect(KURL("ws://example.com/hoge"), String())) .WillOnce(Return(true)); } @@ -100,6 +143,7 @@ TEST_F(WebSocketStreamTest, ConnectWithProtocols) { { InSequence s; + EXPECT_CALL(Channel(), ApplyBackpressure()); EXPECT_CALL(Channel(), Connect(KURL("ws://example.com/chat"), String("chat0, chat1"))) .WillOnce(Return(true)); @@ -119,22 +163,36 @@ TEST_F(WebSocketStreamTest, ConnectWithFailedHandshake) { { InSequence s; + EXPECT_CALL(Channel(), ApplyBackpressure()); EXPECT_CALL(Channel(), Connect(KURL("ws://example.com/chat"), String())) .WillOnce(Return(true)); EXPECT_CALL(Channel(), Disconnect()); } - auto* stream = Create(scope.GetScriptState(), "ws://example.com/chat", - ASSERT_NO_EXCEPTION); + auto* script_state = scope.GetScriptState(); + auto* stream = + Create(script_state, "ws://example.com/chat", ASSERT_NO_EXCEPTION); EXPECT_TRUE(stream); EXPECT_EQ(KURL("ws://example.com/chat"), stream->url()); + ScriptPromiseTester connection_tester(script_state, + stream->connection(script_state)); + ScriptPromiseTester closed_tester(script_state, stream->closed(script_state)); + stream->DidError(); stream->DidClose(WebSocketChannelClient::kClosingHandshakeIncomplete, WebSocketChannel::kCloseEventCodeAbnormalClosure, String()); - // TODO(ricea): Verify the promises are rejected correctly. + connection_tester.WaitUntilSettled(); + closed_tester.WaitUntilSettled(); + + EXPECT_TRUE(connection_tester.IsRejected()); + EXPECT_TRUE(IsDOMException(script_state, connection_tester.Value(), + DOMExceptionCode::kNetworkError)); + EXPECT_TRUE(closed_tester.IsRejected()); + EXPECT_TRUE(IsDOMException(script_state, closed_tester.Value(), + DOMExceptionCode::kNetworkError)); } TEST_F(WebSocketStreamTest, ConnectWithSuccessfulHandshake) { @@ -143,25 +201,41 @@ TEST_F(WebSocketStreamTest, ConnectWithSuccessfulHandshake) { { InSequence s; + EXPECT_CALL(Channel(), ApplyBackpressure()); EXPECT_CALL(Channel(), Connect(KURL("ws://example.com/chat"), String("chat"))) .WillOnce(Return(true)); - EXPECT_CALL(Channel(), ApplyBackpressure()); EXPECT_CALL(checkpoint, Call(1)); EXPECT_CALL(Channel(), Close(1001, String())); } auto* options = WebSocketStreamOptions::Create(); options->setProtocols({"chat"}); - auto* stream = Create(scope.GetScriptState(), "ws://example.com/chat", - options, ASSERT_NO_EXCEPTION); + auto* script_state = scope.GetScriptState(); + auto* stream = Create(script_state, "ws://example.com/chat", options, + ASSERT_NO_EXCEPTION); EXPECT_TRUE(stream); EXPECT_EQ(KURL("ws://example.com/chat"), stream->url()); + ScriptPromiseTester connection_tester(script_state, + stream->connection(script_state)); + stream->DidConnect("chat", "permessage-deflate"); - // TODO(ricea): Verify the connection promise is resolved correctly. + connection_tester.WaitUntilSettled(); + + EXPECT_TRUE(connection_tester.IsFulfilled()); + v8::Local<v8::Value> value = connection_tester.Value().V8Value(); + ASSERT_FALSE(value.IsEmpty()); + ASSERT_TRUE(value->IsObject()); + EXPECT_EQ(PropertyAsString(script_state, value, "readable"), + "[object ReadableStream]"); + EXPECT_EQ(PropertyAsString(script_state, value, "writable"), + "[object WritableStream]"); + EXPECT_EQ(PropertyAsString(script_state, value, "protocol"), "chat"); + EXPECT_EQ(PropertyAsString(script_state, value, "extensions"), + "permessage-deflate"); // Destruction of V8TestingScope causes Close() to be called. checkpoint.Call(1); @@ -172,22 +246,36 @@ TEST_F(WebSocketStreamTest, ConnectThenCloseCleanly) { { InSequence s; + EXPECT_CALL(Channel(), ApplyBackpressure()); EXPECT_CALL(Channel(), Connect(KURL("ws://example.com/echo"), String())) .WillOnce(Return(true)); - EXPECT_CALL(Channel(), ApplyBackpressure()); EXPECT_CALL(Channel(), Close(-1, String(""))); EXPECT_CALL(Channel(), Disconnect()); } - auto* stream = Create(scope.GetScriptState(), "ws://example.com/echo", - ASSERT_NO_EXCEPTION); + auto* script_state = scope.GetScriptState(); + auto* stream = + Create(script_state, "ws://example.com/echo", ASSERT_NO_EXCEPTION); EXPECT_TRUE(stream); stream->DidConnect("", ""); + + ScriptPromiseTester closed_tester(script_state, stream->closed(script_state)); + stream->close(MakeGarbageCollected<WebSocketCloseInfo>(), scope.GetExceptionState()); stream->DidClose(WebSocketChannelClient::kClosingHandshakeComplete, 1005, ""); + + closed_tester.WaitUntilSettled(); + EXPECT_TRUE(closed_tester.IsFulfilled()); + ASSERT_TRUE(closed_tester.Value().IsObject()); + EXPECT_EQ( + PropertyAsString(script_state, closed_tester.Value().V8Value(), "code"), + "1005"); + EXPECT_EQ( + PropertyAsString(script_state, closed_tester.Value().V8Value(), "reason"), + ""); } TEST_F(WebSocketStreamTest, CloseDuringHandshake) { @@ -195,6 +283,7 @@ TEST_F(WebSocketStreamTest, CloseDuringHandshake) { { InSequence s; + EXPECT_CALL(Channel(), ApplyBackpressure()); EXPECT_CALL(Channel(), Connect(KURL("ws://example.com/echo"), String())) .WillOnce(Return(true)); EXPECT_CALL( @@ -205,15 +294,30 @@ TEST_F(WebSocketStreamTest, CloseDuringHandshake) { EXPECT_CALL(Channel(), Disconnect()); } + auto* script_state = scope.GetScriptState(); auto* stream = Create(scope.GetScriptState(), "ws://example.com/echo", ASSERT_NO_EXCEPTION); EXPECT_TRUE(stream); + ScriptPromiseTester connection_tester(script_state, + stream->connection(script_state)); + ScriptPromiseTester closed_tester(script_state, stream->closed(script_state)); + stream->close(MakeGarbageCollected<WebSocketCloseInfo>(), scope.GetExceptionState()); stream->DidClose(WebSocketChannelClient::kClosingHandshakeIncomplete, 1006, ""); + + connection_tester.WaitUntilSettled(); + closed_tester.WaitUntilSettled(); + + EXPECT_TRUE(connection_tester.IsRejected()); + EXPECT_TRUE(IsDOMException(script_state, connection_tester.Value(), + DOMExceptionCode::kNetworkError)); + EXPECT_TRUE(closed_tester.IsRejected()); + EXPECT_TRUE(IsDOMException(script_state, closed_tester.Value(), + DOMExceptionCode::kNetworkError)); } } // namespace diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.cc b/chromium/third_party/blink/renderer/modules/webusb/usb.cc index 2585c1b6cd2..cbe336ae699 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb.cc +++ b/chromium/third_party/blink/renderer/modules/webusb/usb.cc @@ -9,7 +9,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "services/device/public/mojom/usb_device.mojom-blink.h" #include "services/device/public/mojom/usb_enumeration_options.mojom-blink.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -299,7 +299,7 @@ void USB::EnsureServiceConnection() { // See https://bit.ly/2S0zRAS for task types. auto task_runner = GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI); - GetExecutionContext()->GetInterfaceProvider()->GetInterface( + GetExecutionContext()->GetBrowserInterfaceBroker().GetInterface( service_.BindNewPipeAndPassReceiver(task_runner)); service_.set_disconnect_handler( WTF::Bind(&USB::OnServiceConnectionError, WrapWeakPersistent(this))); diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.h b/chromium/third_party/blink/renderer/modules/webusb/usb.h index 39dbd680878..5a8d54156fa 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb.h @@ -7,7 +7,7 @@ #include "mojo/public/cpp/bindings/associated_receiver.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/device/public/mojom/usb_manager.mojom-blink.h" +#include "services/device/public/mojom/usb_manager.mojom-blink-forward.h" #include "services/device/public/mojom/usb_manager_client.mojom-blink.h" #include "third_party/blink/public/mojom/usb/web_usb_service.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc index 35f15124faf..5985cec332c 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc @@ -349,16 +349,24 @@ ScriptPromise USBDevice::controlTransferIn( unsigned length) { auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); - if (EnsureDeviceConfigured(resolver)) { - auto parameters = ConvertControlTransferParameters(setup, resolver); - if (parameters) { - device_requests_.insert(resolver); - device_->ControlTransferIn( - std::move(parameters), length, 0, - WTF::Bind(&USBDevice::AsyncControlTransferIn, WrapPersistent(this), - WrapPersistent(resolver))); - } + if (!EnsureNoDeviceOrInterfaceChangeInProgress(resolver)) + return promise; + + if (!opened_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, kOpenRequired)); + return promise; } + + auto parameters = ConvertControlTransferParameters(setup, resolver); + if (!parameters) + return promise; + + device_requests_.insert(resolver); + device_->ControlTransferIn( + std::move(parameters), length, 0, + WTF::Bind(&USBDevice::AsyncControlTransferIn, WrapPersistent(this), + WrapPersistent(resolver))); return promise; } @@ -367,16 +375,24 @@ ScriptPromise USBDevice::controlTransferOut( const USBControlTransferParameters* setup) { auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); - if (EnsureDeviceConfigured(resolver)) { - auto parameters = ConvertControlTransferParameters(setup, resolver); - if (parameters) { - device_requests_.insert(resolver); - device_->ControlTransferOut( - std::move(parameters), Vector<uint8_t>(), 0, - WTF::Bind(&USBDevice::AsyncControlTransferOut, WrapPersistent(this), - 0, WrapPersistent(resolver))); - } + if (!EnsureNoDeviceOrInterfaceChangeInProgress(resolver)) + return promise; + + if (!opened_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, kOpenRequired)); + return promise; } + + auto parameters = ConvertControlTransferParameters(setup, resolver); + if (!parameters) + return promise; + + device_requests_.insert(resolver); + device_->ControlTransferOut( + std::move(parameters), Vector<uint8_t>(), 0, + WTF::Bind(&USBDevice::AsyncControlTransferOut, WrapPersistent(this), 0, + WrapPersistent(resolver))); return promise; } @@ -386,9 +402,15 @@ ScriptPromise USBDevice::controlTransferOut( const ArrayBufferOrArrayBufferView& data) { auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); - if (!EnsureDeviceConfigured(resolver)) + if (!EnsureNoDeviceOrInterfaceChangeInProgress(resolver)) return promise; + if (!opened_) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, kOpenRequired)); + return promise; + } + auto parameters = ConvertControlTransferParameters(setup, resolver); if (!parameters) return promise; @@ -589,62 +611,83 @@ bool USBDevice::IsProtectedInterfaceClass(wtf_size_t interface_index) const { return false; } -bool USBDevice::EnsureNoDeviceOrInterfaceChangeInProgress( +bool USBDevice::EnsureNoDeviceChangeInProgress( ScriptPromiseResolver* resolver) const { if (!device_) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kNotFoundError, kDeviceDisconnected)); - } else if (device_state_change_in_progress_) { + return false; + } + + if (device_state_change_in_progress_) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, kDeviceStateChangeInProgress)); - } else if (AnyInterfaceChangeInProgress()) { + return false; + } + + return true; +} + +bool USBDevice::EnsureNoDeviceOrInterfaceChangeInProgress( + ScriptPromiseResolver* resolver) const { + if (!EnsureNoDeviceChangeInProgress(resolver)) + return false; + + if (AnyInterfaceChangeInProgress()) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, kInterfaceStateChangeInProgress)); - } else { - return true; + return false; } - return false; + + return true; } bool USBDevice::EnsureDeviceConfigured(ScriptPromiseResolver* resolver) const { - if (!device_) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotFoundError, kDeviceDisconnected)); - } else if (device_state_change_in_progress_) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, kDeviceStateChangeInProgress)); - } else if (!opened_) { + if (!EnsureNoDeviceChangeInProgress(resolver)) + return false; + + if (!opened_) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, kOpenRequired)); - } else if (configuration_index_ == kNotFound) { + return false; + } + + if (configuration_index_ == kNotFound) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, "The device must have a configuration selected.")); - } else { - return true; + return false; } - return false; + + return true; } bool USBDevice::EnsureInterfaceClaimed(uint8_t interface_number, ScriptPromiseResolver* resolver) const { if (!EnsureDeviceConfigured(resolver)) return false; + wtf_size_t interface_index = FindInterfaceIndex(interface_number); if (interface_index == kNotFound) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kNotFoundError, kInterfaceNotFound)); - } else if (interface_state_change_in_progress_[interface_index]) { + return false; + } + + if (interface_state_change_in_progress_[interface_index]) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, kInterfaceStateChangeInProgress)); - } else if (!claimed_interfaces_[interface_index]) { + return false; + } + + if (!claimed_interfaces_[interface_index]) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, "The specified interface has not been claimed.")); - } else { - return true; + return false; } - return false; + + return true; } bool USBDevice::EnsureEndpointAvailable(bool in_transfer, @@ -652,12 +695,14 @@ bool USBDevice::EnsureEndpointAvailable(bool in_transfer, ScriptPromiseResolver* resolver) const { if (!EnsureDeviceConfigured(resolver)) return false; + if (endpoint_number == 0 || endpoint_number >= kEndpointsBitsNumber) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kIndexSizeError, "The specified endpoint number is out of range.")); return false; } + auto& bit_vector = in_transfer ? in_endpoints_ : out_endpoints_; if (!bit_vector[endpoint_number - 1]) { resolver->Reject(MakeGarbageCollected<DOMException>( @@ -667,6 +712,7 @@ bool USBDevice::EnsureEndpointAvailable(bool in_transfer, "interface.")); return false; } + return true; } diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_device.h b/chromium/third_party/blink/renderer/modules/webusb/usb_device.h index d6319b55d1f..774a66bd3ce 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_device.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_device.h @@ -116,6 +116,7 @@ class USBDevice : public ScriptWrappable, public ContextLifecycleObserver { wtf_size_t FindAlternateIndex(wtf_size_t interface_index, uint8_t alternate_setting) const; bool IsProtectedInterfaceClass(wtf_size_t interface_index) const; + bool EnsureNoDeviceChangeInProgress(ScriptPromiseResolver*) const; bool EnsureNoDeviceOrInterfaceChangeInProgress(ScriptPromiseResolver*) const; bool EnsureDeviceConfigured(ScriptPromiseResolver*) const; bool EnsureInterfaceClaimed(uint8_t interface_number, diff --git a/chromium/third_party/blink/renderer/modules/xr/BUILD.gn b/chromium/third_party/blink/renderer/modules/xr/BUILD.gn index d6dfe7219d7..ac6f487986f 100644 --- a/chromium/third_party/blink/renderer/modules/xr/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/xr/BUILD.gn @@ -44,6 +44,8 @@ blink_modules_sources("xr") { "xr_input_source_event.h", "xr_input_sources_change_event.cc", "xr_input_sources_change_event.h", + "xr_native_origin_information.cc", + "xr_native_origin_information.h", "xr_object_space.h", "xr_plane.cc", "xr_plane.h", diff --git a/chromium/third_party/blink/renderer/modules/xr/DEPS b/chromium/third_party/blink/renderer/modules/xr/DEPS index a66627d651d..ab8648248ac 100644 --- a/chromium/third_party/blink/renderer/modules/xr/DEPS +++ b/chromium/third_party/blink/renderer/modules/xr/DEPS @@ -2,6 +2,7 @@ include_rules = [ "+mojo/public/cpp/bindings/binding.h", "+mojo/public/cpp/system/platform_handle.h", "+device/vr/public/mojom/vr_service.mojom-blink.h", + "+device/vr/public/mojom/vr_service.mojom-blink-forward.h", "+gpu/command_buffer/client/gles2_interface.h", "+gpu/command_buffer/common/mailbox_holder.h", "+services/metrics/public/cpp/ukm_builders.h", diff --git a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.h b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.h index 988e4025266..5ed2491e47d 100644 --- a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.h +++ b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.h @@ -15,9 +15,8 @@ namespace blink { class Document; class XR; -class MODULES_EXPORT NavigatorXR final - : public GarbageCollectedFinalized<NavigatorXR>, - public Supplement<Navigator> { +class MODULES_EXPORT NavigatorXR final : public GarbageCollected<NavigatorXR>, + public Supplement<Navigator> { USING_GARBAGE_COLLECTED_MIXIN(NavigatorXR); public: diff --git a/chromium/third_party/blink/renderer/modules/xr/xr.cc b/chromium/third_party/blink/renderer/modules/xr/xr.cc index 7a66e509c20..72a09f5e834 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr.cc @@ -7,14 +7,18 @@ #include <utility> #include "services/metrics/public/cpp/ukm_builders.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/public/platform/interface_provider.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/fullscreen/fullscreen.h" +#include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/modules/event_modules.h" #include "third_party/blink/renderer/modules/event_target_modules.h" @@ -25,6 +29,7 @@ #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/text/string_view.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + namespace blink { namespace { @@ -52,6 +57,20 @@ const char kImmersiveArModeNotValid[] = "Failed to execute '%s' on 'XR': The provided value 'immersive-ar' is not " "a valid enum value of type XRSessionMode."; +constexpr device::mojom::XRSessionFeature kDefaultImmersiveVrFeatures[] = { + device::mojom::XRSessionFeature::REF_SPACE_VIEWER, + device::mojom::XRSessionFeature::REF_SPACE_LOCAL, +}; + +constexpr device::mojom::XRSessionFeature kDefaultImmersiveArFeatures[] = { + device::mojom::XRSessionFeature::REF_SPACE_VIEWER, + device::mojom::XRSessionFeature::REF_SPACE_LOCAL, +}; + +constexpr device::mojom::XRSessionFeature kDefaultInlineFeatures[] = { + device::mojom::XRSessionFeature::REF_SPACE_VIEWER, +}; + // Helper method to convert session mode into Mojo options. device::mojom::blink::XRSessionOptionsPtr convertModeToMojo( XRSession::SessionMode mode) { @@ -79,7 +98,7 @@ XRSession::SessionMode stringToSessionMode(const String& mode_string) { return XRSession::kModeInline; } -const char* SessionModeToString(XRSession::SessionMode session_mode) { +const char* SessionModeToString(const XRSession::SessionMode& session_mode) { switch (session_mode) { case XRSession::SessionMode::kModeInline: return "inline"; @@ -97,6 +116,7 @@ const char* SessionModeToString(XRSession::SessionMode session_mode) { // unrecognized, returns nullopt. Based on the spec: // https://immersive-web.github.io/webxr/#feature-name base::Optional<device::mojom::XRSessionFeature> StringToXRSessionFeature( + const Document* doc, const String& feature_string) { if (feature_string == "viewer") { return device::mojom::XRSessionFeature::REF_SPACE_VIEWER; @@ -108,6 +128,9 @@ base::Optional<device::mojom::XRSessionFeature> StringToXRSessionFeature( return device::mojom::XRSessionFeature::REF_SPACE_BOUNDED_FLOOR; } else if (feature_string == "unbounded") { return device::mojom::XRSessionFeature::REF_SPACE_UNBOUNDED; + } else if (RuntimeEnabledFeatures::WebXRARDOMOverlayEnabled(doc) && + feature_string == "dom-overlay-for-handheld-ar") { + return device::mojom::XRSessionFeature::DOM_OVERLAY_FOR_HANDHELD_AR; } return base::nullopt; @@ -124,41 +147,27 @@ bool IsFeatureValidForMode(device::mojom::XRSessionFeature feature, case device::mojom::XRSessionFeature::REF_SPACE_UNBOUNDED: return mode == XRSession::kModeImmersiveVR || mode == XRSession::kModeImmersiveAR; + case device::mojom::XRSessionFeature::DOM_OVERLAY_FOR_HANDHELD_AR: + return mode == XRSession::kModeImmersiveAR; } } -template <typename Fn> -XRSessionFeatureSet ParseRequestedFeatures( - const WTF::Vector<ScriptValue>& features, - XRSession::SessionMode session_mode, - Fn&& error_fn) { - XRSessionFeatureSet result; - - // Iterate over all requested features, even if intermediate - // elements are found to be invalid. - for (const auto& feature : features) { - String feature_string; - if (feature.ToString(feature_string)) { - auto feature_enum = StringToXRSessionFeature(feature_string); +bool HasRequiredFeaturePolicy(const Document* doc, + device::mojom::XRSessionFeature feature) { + if (!doc) + return false; - if (!feature_enum) { - String error_message = - "Unrecognized feature requested: " + feature_string; - error_fn(std::move(error_message)); - } else if (!IsFeatureValidForMode(feature_enum.value(), session_mode)) { - String error_message = - "Feature '" + feature_string + - "' is not supported for mode: " + SessionModeToString(session_mode); - error_fn(std::move(error_message)); - } else { - result.insert(feature_enum.value()); - } - } else { - error_fn("Unrecognized feature value"); - } + switch (feature) { + case device::mojom::XRSessionFeature::REF_SPACE_VIEWER: + return true; + case device::mojom::XRSessionFeature::REF_SPACE_LOCAL: + case device::mojom::XRSessionFeature::REF_SPACE_LOCAL_FLOOR: + case device::mojom::XRSessionFeature::REF_SPACE_BOUNDED_FLOOR: + case device::mojom::XRSessionFeature::REF_SPACE_UNBOUNDED: + case device::mojom::XRSessionFeature::DOM_OVERLAY_FOR_HANDHELD_AR: + return doc->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebXr, + ReportOptions::kReportOnFailure); } - - return result; } // Ensure that the immersive session request is allowed, if not @@ -177,11 +186,6 @@ const char* CheckImmersiveSessionRequestAllowed(LocalFrame* frame, return kPageNotVisible; } - if (!doc->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebXr, - ReportOptions::kReportOnFailure)) { - return kFeaturePolicyBlocked; - } - // Consent occurs in the Browser process. return nullptr; @@ -194,7 +198,6 @@ const char* CheckImmersiveSessionRequestAllowed(LocalFrame* frame, // https://immersive-web.github.io/webxr/#inline-session-request-is-allowed const char* XR::CheckInlineSessionRequestAllowed( LocalFrame* frame, - Document* doc, const PendingRequestSessionQuery& query) { // Without user activation, we must reject the session if *any* features // (optional or required) were present, whether or not they were recognized. @@ -219,26 +222,33 @@ const char* XR::CheckInlineSessionRequestAllowed( } } - // Make sure the WebXR feature policy is enabled - if (!doc->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebXr, - ReportOptions::kReportOnFailure)) { - return kFeaturePolicyBlocked; - } - return nullptr; } XR::PendingSupportsSessionQuery::PendingSupportsSessionQuery( ScriptPromiseResolver* resolver, - XRSession::SessionMode session_mode) - : resolver_(resolver), mode_(session_mode) {} + XRSession::SessionMode session_mode, + bool throw_on_unsupported) + : resolver_(resolver), + mode_(session_mode), + throw_on_unsupported_(throw_on_unsupported) {} void XR::PendingSupportsSessionQuery::Trace(blink::Visitor* visitor) { visitor->Trace(resolver_); } -void XR::PendingSupportsSessionQuery::Resolve() { - resolver_->Resolve(); +void XR::PendingSupportsSessionQuery::Resolve(bool supported, + ExceptionState* exception_state) { + if (throw_on_unsupported_) { + if (supported) { + resolver_->Resolve(); + } else { + RejectWithDOMException(DOMExceptionCode::kNotSupportedError, + kSessionNotSupported, exception_state); + } + } else { + resolver_->Resolve(supported); + } } void XR::PendingSupportsSessionQuery::RejectWithDOMException( @@ -248,7 +258,11 @@ void XR::PendingSupportsSessionQuery::RejectWithDOMException( DCHECK_NE(exception_code, DOMExceptionCode::kSecurityError); if (exception_state) { + // The generated bindings will reject the returned promise for us. + // Detaching the resolver prevents it from thinking we abandoned + // the promise. exception_state->ThrowDOMException(exception_code, message); + resolver_->Detach(); } else { resolver_->Reject( MakeGarbageCollected<DOMException>(exception_code, message)); @@ -259,7 +273,11 @@ void XR::PendingSupportsSessionQuery::RejectWithSecurityError( const String& sanitized_message, ExceptionState* exception_state) { if (exception_state) { + // The generated V8 bindings will reject the returned promise for us. + // Detaching the resolver prevents it from thinking we abandoned + // the promise. exception_state->ThrowSecurityError(sanitized_message); + resolver_->Detach(); } else { resolver_->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kSecurityError, sanitized_message)); @@ -270,7 +288,11 @@ void XR::PendingSupportsSessionQuery::RejectWithTypeError( const String& message, ExceptionState* exception_state) { if (exception_state) { + // The generated bindings will reject the returned promise for us. + // Detaching the resolver prevents it from thinking we abandoned + // the promise. exception_state->ThrowTypeError(message); + resolver_->Detach(); } else { resolver_->Reject(V8ThrowException::CreateTypeError( resolver_->GetScriptState()->GetIsolate(), message)); @@ -306,6 +328,7 @@ void XR::PendingRequestSessionQuery::RejectWithDOMException( if (exception_state) { exception_state->ThrowDOMException(exception_code, message); + resolver_->Detach(); } else { resolver_->Reject( MakeGarbageCollected<DOMException>(exception_code, message)); @@ -319,6 +342,7 @@ void XR::PendingRequestSessionQuery::RejectWithSecurityError( ExceptionState* exception_state) { if (exception_state) { exception_state->ThrowSecurityError(sanitized_message); + resolver_->Detach(); } else { resolver_->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kSecurityError, sanitized_message)); @@ -332,6 +356,7 @@ void XR::PendingRequestSessionQuery::RejectWithTypeError( ExceptionState* exception_state) { if (exception_state) { exception_state->ThrowTypeError(message); + resolver_->Detach(); } else { resolver_->Reject(V8ThrowException::CreateTypeError( GetScriptState()->GetIsolate(), message)); @@ -405,9 +430,10 @@ XR::XR(LocalFrame& frame, int64_t ukm_source_id) {SchedulingPolicy::RecordMetricsForBackForwardCache()})) { // See https://bit.ly/2S0zRAS for task types. DCHECK(frame.IsAttached()); - frame.GetInterfaceProvider().GetInterface(mojo::MakeRequest( - &service_, frame.GetTaskRunner(TaskType::kMiscPlatformAPI))); - service_.set_connection_error_handler( + frame.GetBrowserInterfaceBroker().GetInterface( + service_.BindNewPipeAndPassReceiver( + frame.GetTaskRunner(TaskType::kMiscPlatformAPI))); + service_.set_disconnect_handler( WTF::Bind(&XR::Dispose, WrapWeakPersistent(this))); } @@ -441,19 +467,9 @@ XRFrameProvider* XR::frameProvider() { return frame_provider_; } -bool XR::CanRequestNonImmersiveFrameData() const { - return !!magic_window_provider_; -} - -void XR::GetNonImmersiveFrameData( - device::mojom::blink::XRFrameDataRequestOptionsPtr options, - device::mojom::blink::XRFrameDataProvider::GetFrameDataCallback callback) { - DCHECK(CanRequestNonImmersiveFrameData()); - magic_window_provider_->GetFrameData(std::move(options), std::move(callback)); -} - -const device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr& -XR::xrEnvironmentProviderPtr() { +const mojo::AssociatedRemote< + device::mojom::blink::XREnvironmentIntegrationProvider>& +XR::xrEnvironmentProviderRemote() { return environment_provider_; } @@ -465,26 +481,87 @@ void XR::AddEnvironmentProviderErrorHandler( void XR::ExitPresent() { DCHECK(service_); service_->ExitPresent(); + + // If the document was potentially being shown in a DOM overlay via + // fullscreened elements, make sure to clear any fullscreen states on exiting + // the session. This avoids a race condition: + // - browser side ends session and exits fullscreen (i.e. back button) + // - renderer processes WebViewImpl::ExitFullscreen via ChromeClient + // - JS application sets a new element to fullscreen, this is allowed + // because doc->IsImmersiveArOverlay() is still true at this point + // - renderer processes XR session shutdown (this method) + // - browser re-enters fullscreen unexpectedly + LocalFrame* frame = GetFrame(); + if (!frame) + return; + + Document* doc = frame->GetDocument(); + DCHECK(doc); + if (doc->IsImmersiveArOverlay()) { + doc->SetIsImmersiveArOverlay(false); + Element* fullscreen_element = Fullscreen::FullscreenElementFrom(*doc); + if (fullscreen_element) { + // "ua_originated" means that the browser process already exited + // fullscreen. Set it to false because we need the browser process + // to get notified that it needs to exit fullscreen. Use + // FullyExitFullscreen to ensure that we return to non-fullscreen mode. + // ExitFullscreen only unfullscreens a single element, potentially + // leaving others in fullscreen mode. + constexpr bool kUaOriginated = false; + Fullscreen::FullyExitFullscreen(*doc, kUaOriginated); + } + // Restore the FrameView background color that was changed in + // OnRequestSessionReturned. + auto* frame_view = doc->GetLayoutView()->GetFrameView(); + // SetBaseBackgroundColor updates composited layer mappings. + // That DCHECKs IsAllowedToQueryCompositingState which requires + // DocumentLifecycle >= kInCompositingUpdate. + frame_view->UpdateLifecycleToCompositingInputsClean(); + frame_view->SetBaseBackgroundColor(original_base_background_color_); + } +} + +void XR::SetFramesThrottled(const XRSession* session, bool throttled) { + // The service only cares if the immersive session is throttling frames. + if (session->immersive()) { + // If we have an immersive session, we should have a service. + DCHECK(service_); + service_->SetFramesThrottled(throttled); + } } ScriptPromise XR::supportsSession(ScriptState* script_state, const String& mode, ExceptionState& exception_state) { - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); + return InternalIsSessionSupported(script_state, mode, exception_state, true); +} + +ScriptPromise XR::isSessionSupported(ScriptState* script_state, + const String& mode, + ExceptionState& exception_state) { + return InternalIsSessionSupported(script_state, mode, exception_state, false); +} +ScriptPromise XR::InternalIsSessionSupported(ScriptState* script_state, + const String& mode, + ExceptionState& exception_state, + bool throw_on_unsupported) { LocalFrame* frame = GetFrame(); Document* doc = frame ? frame->GetDocument() : nullptr; if (!doc) { // Reject if the frame or document is inaccessible. exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, kNavigatorDetachedError); - return promise; + return ScriptPromise(); // Will be rejected by generated bindings } + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + XRSession::SessionMode session_mode = stringToSessionMode(mode); PendingSupportsSessionQuery* query = - MakeGarbageCollected<PendingSupportsSessionQuery>(resolver, session_mode); + MakeGarbageCollected<PendingSupportsSessionQuery>(resolver, session_mode, + throw_on_unsupported); if (session_mode == XRSession::kModeImmersiveAR && !RuntimeEnabledFeatures::WebXRARModuleEnabled(doc)) { @@ -494,6 +571,12 @@ ScriptPromise XR::supportsSession(ScriptState* script_state, return promise; } + if (session_mode == XRSession::kModeInline) { + // inline sessions are always supported. + query->Resolve(true); + return promise; + } + if (!doc->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebXr, ReportOptions::kReportOnFailure)) { // Only allow the call to be made if the appropriate feature policy is in @@ -502,27 +585,21 @@ ScriptPromise XR::supportsSession(ScriptState* script_state, return promise; } - if (session_mode == XRSession::kModeInline) { - // `inline` sessions are always supported if not blocked by feature policy. - query->Resolve(); - } else { - if (!service_) { - // If we don't have a service at the time we reach this call it indicates - // that there's no WebXR hardware. Reject as not supported. - query->RejectWithDOMException(DOMExceptionCode::kNotSupportedError, - kSessionNotSupported, &exception_state); - return promise; - } + if (!service_) { + // If we don't have a service at the time we reach this call it indicates + // that there's no WebXR hardware. Reject as not supported. + query->Resolve(false, &exception_state); + return promise; + } - device::mojom::blink::XRSessionOptionsPtr session_options = - convertModeToMojo(query->mode()); + device::mojom::blink::XRSessionOptionsPtr session_options = + convertModeToMojo(query->mode()); - outstanding_support_queries_.insert(query); - service_->SupportsSession( - std::move(session_options), - WTF::Bind(&XR::OnSupportsSessionReturned, WrapPersistent(this), - WrapPersistent(query))); - } + outstanding_support_queries_.insert(query); + service_->SupportsSession( + std::move(session_options), + WTF::Bind(&XR::OnSupportsSessionReturned, WrapPersistent(this), + WrapPersistent(query))); return promise; } @@ -539,15 +616,6 @@ void XR::RequestImmersiveSession(LocalFrame* frame, did_log_request_immersive_session_ = true; } - // If its an immersive AR session, make sure that feature is enabled - if (query->mode() == XRSession::kModeImmersiveAR && - !RuntimeEnabledFeatures::WebXRARModuleEnabled(doc)) { - query->RejectWithTypeError( - String::Format(kImmersiveArModeNotValid, "requestSession"), - exception_state); - return; - } - // Make sure the request is allowed auto* immersive_session_request_error = CheckImmersiveSessionRequestAllowed(frame, doc); @@ -593,12 +661,11 @@ void XR::RequestImmersiveSession(LocalFrame* frame, } void XR::RequestInlineSession(LocalFrame* frame, - Document* doc, PendingRequestSessionQuery* query, ExceptionState* exception_state) { // Make sure the inline session request was allowed auto* inline_session_request_error = - CheckInlineSessionRequestAllowed(frame, doc, *query); + CheckInlineSessionRequestAllowed(frame, *query); if (inline_session_request_error) { query->RejectWithSecurityError(inline_session_request_error, exception_state); @@ -634,15 +701,57 @@ void XR::RequestInlineSession(LocalFrame* frame, WrapPersistent(query))); } +XR::RequestedXRSessionFeatureSet XR::ParseRequestedFeatures( + Document* doc, + const HeapVector<ScriptValue>& features, + const XRSession::SessionMode& session_mode, + mojom::ConsoleMessageLevel error_level) { + RequestedXRSessionFeatureSet result; + + // Iterate over all requested features, even if intermediate + // elements are found to be invalid. + for (const auto& feature : features) { + String feature_string; + if (feature.ToString(feature_string)) { + auto feature_enum = StringToXRSessionFeature(doc, feature_string); + + if (!feature_enum) { + GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create( + mojom::ConsoleMessageSource::kJavaScript, error_level, + "Unrecognized feature requested: " + feature_string)); + result.invalid_features = true; + } else if (!IsFeatureValidForMode(feature_enum.value(), session_mode)) { + GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create( + mojom::ConsoleMessageSource::kJavaScript, error_level, + "Feature '" + feature_string + "' is not supported for mode: " + + SessionModeToString(session_mode))); + result.invalid_features = true; + } else if (!HasRequiredFeaturePolicy(doc, feature_enum.value())) { + GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create( + mojom::ConsoleMessageSource::kJavaScript, error_level, + "Feature '" + feature_string + + "' is not permitted by feature policy")); + result.invalid_features = true; + } else { + result.valid_features.insert(feature_enum.value()); + } + } else { + GetExecutionContext()->AddConsoleMessage( + ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript, + error_level, "Unrecognized feature value")); + result.invalid_features = true; + } + } + + return result; +} + ScriptPromise XR::requestSession(ScriptState* script_state, const String& mode, XRSessionInit* session_init, ExceptionState& exception_state) { // TODO(https://crbug.com/968622): Make sure we don't forget to call // metrics-related methods when the promise gets resolved/rejected. - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - LocalFrame* frame = GetFrame(); Document* doc = frame ? frame->GetDocument() : nullptr; if (!doc) { @@ -652,51 +761,69 @@ ScriptPromise XR::requestSession(ScriptState* script_state, // Document to get UkmRecorder anyway). exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, kNavigatorDetachedError); - return promise; + return ScriptPromise(); // Will be rejected by generated bindings } XRSession::SessionMode session_mode = stringToSessionMode(mode); + // If the request is for immersive-ar, ensure that feature is enabled. + if (session_mode == XRSession::kModeImmersiveAR && + !RuntimeEnabledFeatures::WebXRARModuleEnabled(doc)) { + exception_state.ThrowTypeError( + String::Format(kImmersiveArModeNotValid, "requestSession")); + + // We haven't created the query yet, so we can't use it to implicitly log + // our metrics for us, so explicitly log it here, as the query requires the + // features to be parsed before it can be built. + ukm::builders::XR_WebXR_SessionRequest(GetSourceId()) + .SetMode(static_cast<int64_t>(session_mode)) + .SetStatus(static_cast<int64_t>(SessionRequestStatus::kOtherError)) + .Record(doc->UkmRecorder()); + return ScriptPromise(); + } + // Parse required feature strings RequestedXRSessionFeatureSet required_features; if (session_init && session_init->hasRequiredFeatures()) { - required_features.valid_features = ParseRequestedFeatures( - session_init->requiredFeatures(), session_mode, - [&](const String& error) { - GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create( - mojom::ConsoleMessageSource::kJavaScript, - mojom::ConsoleMessageLevel::kError, error)); - required_features.invalid_features = true; - }); + required_features = ParseRequestedFeatures( + doc, session_init->requiredFeatures(), session_mode, + mojom::ConsoleMessageLevel::kError); } // Parse optional feature strings RequestedXRSessionFeatureSet optional_features; if (session_init && session_init->hasOptionalFeatures()) { - optional_features.valid_features = ParseRequestedFeatures( - session_init->optionalFeatures(), session_mode, - [&](const String& error) { - GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create( - mojom::ConsoleMessageSource::kJavaScript, - mojom::ConsoleMessageLevel::kWarning, error)); - optional_features.invalid_features = true; - }); + optional_features = ParseRequestedFeatures( + doc, session_init->optionalFeatures(), session_mode, + mojom::ConsoleMessageLevel::kWarning); } // Certain session modes imply default features. - // Add those default features as optional features now. + // Add those default features as required features now. + base::span<const device::mojom::XRSessionFeature> default_features; switch (session_mode) { case XRSession::kModeImmersiveVR: + default_features = kDefaultImmersiveVrFeatures; + break; case XRSession::kModeImmersiveAR: - optional_features.valid_features.insert( - device::mojom::XRSessionFeature::REF_SPACE_LOCAL); - FALLTHROUGH; + default_features = kDefaultImmersiveArFeatures; + break; case XRSession::kModeInline: - optional_features.valid_features.insert( - device::mojom::XRSessionFeature::REF_SPACE_VIEWER); + default_features = kDefaultInlineFeatures; break; } + for (const auto& feature : default_features) { + if (HasRequiredFeaturePolicy(doc, feature)) { + required_features.valid_features.insert(feature); + } else { + required_features.invalid_features = true; + } + } + + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + PendingRequestSessionQuery* query = MakeGarbageCollected<PendingRequestSessionQuery>( GetSourceId(), resolver, session_mode, std::move(required_features), @@ -708,7 +835,7 @@ ScriptPromise XR::requestSession(ScriptState* script_state, RequestImmersiveSession(frame, doc, query, &exception_state); break; case XRSession::kModeInline: - RequestInlineSession(frame, doc, query, &exception_state); + RequestInlineSession(frame, query, &exception_state); break; } @@ -719,7 +846,11 @@ ScriptPromise XR::requestSession(ScriptState* script_state, // changed. For example, if a new physical device was connected to the system, // it might be able to support immersive sessions, where it couldn't before. void XR::OnDeviceChanged() { - DispatchEvent(*blink::Event::Create(event_type_names::kDevicechange)); + LocalFrame* frame = GetFrame(); + Document* doc = frame ? frame->GetDocument() : nullptr; + if (doc && doc->IsFeatureEnabled(mojom::FeaturePolicyFeature::kWebXr)) { + DispatchEvent(*blink::Event::Create(event_type_names::kDevicechange)); + } } void XR::OnSupportsSessionReturned(PendingSupportsSessionQuery* query, @@ -728,13 +859,7 @@ void XR::OnSupportsSessionReturned(PendingSupportsSessionQuery* query, // promise, so remove it from our outstanding list. DCHECK(outstanding_support_queries_.Contains(query)); outstanding_support_queries_.erase(query); - - if (supports_session) { - query->Resolve(); - } else { - query->RejectWithDOMException(DOMExceptionCode::kNotSupportedError, - kSessionNotSupported, nullptr); - } + query->Resolve(supports_session); } void XR::OnRequestSessionReturned( @@ -798,33 +923,74 @@ void XR::OnRequestSessionReturned( } XRSession* session = CreateSession( - query->mode(), blend_mode, std::move(session_ptr->client_request), + query->mode(), blend_mode, std::move(session_ptr->client_receiver), std::move(session_ptr->display_info), session_ptr->uses_input_eventing, enabled_features); + frameProvider()->OnSessionStarted(session, std::move(session_ptr)); + if (query->mode() == XRSession::kModeImmersiveVR || query->mode() == XRSession::kModeImmersiveAR) { - frameProvider()->BeginImmersiveSession(session, std::move(session_ptr)); if (environment_integration) { // See Task Sources spreadsheet for more information: // https://docs.google.com/spreadsheets/d/1b-dus1Ug3A8y0lX0blkmOjJILisUASdj8x9YN_XMwYc/view - frameProvider()->GetDataProvider()->GetEnvironmentIntegrationProvider( - mojo::MakeRequest(&environment_provider_, - GetExecutionContext()->GetTaskRunner( - TaskType::kMiscPlatformAPI))); - environment_provider_.set_connection_error_handler(WTF::Bind( + frameProvider() + ->GetImmersiveDataProvider() + ->GetEnvironmentIntegrationProvider( + environment_provider_.BindNewEndpointAndPassReceiver( + GetExecutionContext()->GetTaskRunner( + TaskType::kMiscPlatformAPI))); + environment_provider_.set_disconnect_handler(WTF::Bind( &XR::OnEnvironmentProviderDisconnect, WrapWeakPersistent(this))); + + session->OnEnvironmentProviderCreated(); + + LocalFrame* frame = GetFrame(); + DCHECK(frame); + + if (enabled_features.Contains( + device::mojom::XRSessionFeature::DOM_OVERLAY_FOR_HANDHELD_AR)) { + // The session is using DOM overlay mode. + Document* doc = frame->GetDocument(); + DCHECK(doc); + doc->SetIsImmersiveArOverlay(true); + + // Save the current base background color (restored in ExitPresent), + // and set a transparent background for the FrameView. + auto* frame_view = doc->GetLayoutView()->GetFrameView(); + // SetBaseBackgroundColor updates composited layer mappings. + // That DCHECKs IsAllowedToQueryCompositingState which requires + // DocumentLifecycle >= kInCompositingUpdate. + frame_view->UpdateLifecycleToCompositingInputsClean(); + original_base_background_color_ = frame_view->BaseBackgroundColor(); + frame_view->SetBaseBackgroundColor(Color::kTransparent); + + // In DOM overlay mode, entering fullscreen mode needs to be triggered + // from the Renderer by actually fullscreening an element. If there + // is no current fullscreen element, fullscreen the <body> element + // for now. The JS application can use enterFullscreen to change this. + // + // A TabObserver on the browser side exits the session if there's + // no longer a fullscreen element, for example if the JS app manually + // unfullscreens the "body" element. That ensures we don't end up in a + // hybrid non-fullscreen AR state. + Element* fullscreen_element = Fullscreen::FullscreenElementFrom(*doc); + if (!fullscreen_element) { + Element* body = doc->body(); + DCHECK(body); + // FIXME: this is the "prefixed" version that doesn't generate a + // fullscreenchange event and auto-hides navigation bars. Should the + // event be generated? + Fullscreen::RequestFullscreen(*body); + } + } } if (query->mode() == XRSession::kModeImmersiveVR && session->UsesInputEventing()) { - frameProvider()->GetDataProvider()->SetInputSourceButtonListener( + frameProvider()->GetImmersiveDataProvider()->SetInputSourceButtonListener( session->GetInputClickListener()); } - } else { - magic_window_provider_.Bind(std::move(session_ptr->data_provider)); - magic_window_provider_.set_connection_error_handler(WTF::Bind( - &XR::OnMagicWindowProviderDisconnect, WrapWeakPersistent(this))); } UseCounter::Count(ExecutionContext::From(query->GetScriptState()), @@ -870,15 +1036,15 @@ void XR::ContextDestroyed(ExecutionContext*) { XRSession* XR::CreateSession( XRSession::SessionMode mode, XRSession::EnvironmentBlendMode blend_mode, - device::mojom::blink::XRSessionClientRequest client_request, + mojo::PendingReceiver<device::mojom::blink::XRSessionClient> + client_receiver, device::mojom::blink::VRDisplayInfoPtr display_info, bool uses_input_eventing, XRSessionFeatureSet enabled_features, bool sensorless_session) { XRSession* session = MakeGarbageCollected<XRSession>( - this, client_request ? std::move(client_request) : nullptr, mode, - blend_mode, uses_input_eventing, sensorless_session, - std::move(enabled_features)); + this, std::move(client_receiver), mode, blend_mode, uses_input_eventing, + sensorless_session, std::move(enabled_features)); if (display_info) session->SetXRDisplayInfo(std::move(display_info)); sessions_.insert(session); @@ -906,7 +1072,8 @@ XRSession* XR::CreateSensorlessInlineSession() { // TODO(https://crbug.com/944936): The blend mode could be "additive". XRSession::EnvironmentBlendMode blend_mode = XRSession::kBlendModeOpaque; return CreateSession(XRSession::kModeInline, blend_mode, - nullptr /* client request */, nullptr /* display_info */, + mojo::NullReceiver() /* client receiver */, + nullptr /* display_info */, false /* uses_input_eventing */, {device::mojom::XRSessionFeature::REF_SPACE_VIEWER}, true /* sensorless_session */); @@ -950,17 +1117,6 @@ void XR::OnEnvironmentProviderDisconnect() { environment_provider_.reset(); } -// Ends all non-immersive sessions when the magic window provider got -// disconnected. -void XR::OnMagicWindowProviderDisconnect() { - for (auto& session : sessions_) { - if (!session->immersive() && !session->ended()) { - session->ForceEnd(); - } - } - magic_window_provider_.reset(); -} - void XR::Trace(blink::Visitor* visitor) { visitor->Trace(frame_provider_); visitor->Trace(sessions_); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr.h b/chromium/third_party/blink/renderer/modules/xr/xr.h index b5ca34a5c4d..654c7199eb4 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr.h @@ -6,7 +6,10 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_H_ #include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" @@ -14,6 +17,7 @@ #include "third_party/blink/renderer/core/page/focus_changed_observer.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" #include "third_party/blink/renderer/modules/xr/xr_session_init.h" +#include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -46,6 +50,9 @@ class XR final : public EventTargetWithInlineData, ScriptPromise supportsSession(ScriptState*, const String&, ExceptionState& exception_state); + ScriptPromise isSessionSupported(ScriptState*, + const String&, + ExceptionState& exception_state); ScriptPromise requestSession(ScriptState*, const String&, XRSessionInit*, @@ -53,13 +60,9 @@ class XR final : public EventTargetWithInlineData, XRFrameProvider* frameProvider(); - bool CanRequestNonImmersiveFrameData() const; - void GetNonImmersiveFrameData( - device::mojom::blink::XRFrameDataRequestOptionsPtr, - device::mojom::blink::XRFrameDataProvider::GetFrameDataCallback); - - const device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr& - xrEnvironmentProviderPtr(); + const mojo::AssociatedRemote< + device::mojom::blink::XREnvironmentIntegrationProvider>& + xrEnvironmentProviderRemote(); // VRServiceClient overrides. void OnDeviceChanged() override; @@ -79,11 +82,15 @@ class XR final : public EventTargetWithInlineData, int64_t GetSourceId() const { return ukm_source_id_; } using EnvironmentProviderErrorCallback = base::OnceCallback<void()>; + // Registers a callback that'll be invoked when mojo invokes a disconnect + // handler on the underlying XREnvironmentIntegrationProvider remote. void AddEnvironmentProviderErrorHandler( EnvironmentProviderErrorCallback callback); void ExitPresent(); + void SetFramesThrottled(const XRSession* session, bool throttled); + base::TimeTicks NavigationStart() const { return navigation_start_; } private: @@ -109,7 +116,7 @@ class XR final : public EventTargetWithInlineData, // ScriptPromiseResolver that allows us to add additional logic as certain // things related to promise's life cycle happen. class PendingRequestSessionQuery final - : public GarbageCollectedFinalized<PendingRequestSessionQuery> { + : public GarbageCollected<PendingRequestSessionQuery> { public: PendingRequestSessionQuery(int64_t ukm_source_id, ScriptPromiseResolver* resolver, @@ -175,11 +182,13 @@ class XR final : public EventTargetWithInlineData, class PendingSupportsSessionQuery final : public GarbageCollected<PendingSupportsSessionQuery> { public: - PendingSupportsSessionQuery(ScriptPromiseResolver*, XRSession::SessionMode); + PendingSupportsSessionQuery(ScriptPromiseResolver*, + XRSession::SessionMode, + bool throw_on_unsupported); virtual ~PendingSupportsSessionQuery() = default; // Resolves underlying promise. - void Resolve(); + void Resolve(bool supported, ExceptionState* exception_state = nullptr); // Rejects underlying promise with a DOMException. // Do not call this with |DOMExceptionCode::kSecurityError|, use @@ -202,6 +211,8 @@ class XR final : public EventTargetWithInlineData, void RejectWithTypeError(const String& message, ExceptionState* exception_state); + bool ThrowOnUnsupported() const { return throw_on_unsupported_; } + XRSession::SessionMode mode() const; virtual void Trace(blink::Visitor*); @@ -210,21 +221,33 @@ class XR final : public EventTargetWithInlineData, Member<ScriptPromiseResolver> resolver_; const XRSession::SessionMode mode_; + // Only set when calling the deprecated supportsSession method. + const bool throw_on_unsupported_ = false; + DISALLOW_COPY_AND_ASSIGN(PendingSupportsSessionQuery); }; + ScriptPromise InternalIsSessionSupported(ScriptState*, + const String&, + ExceptionState& exception_state, + bool throw_on_unsupported); + const char* CheckInlineSessionRequestAllowed( LocalFrame* frame, - Document* doc, const PendingRequestSessionQuery& query); + RequestedXRSessionFeatureSet ParseRequestedFeatures( + Document* doc, + const HeapVector<ScriptValue>& features, + const XRSession::SessionMode& session_mode, + mojom::ConsoleMessageLevel error_level); + void RequestImmersiveSession(LocalFrame* frame, Document* doc, PendingRequestSessionQuery* query, ExceptionState* exception_state); void RequestInlineSession(LocalFrame* frame, - Document* doc, PendingRequestSessionQuery* query, ExceptionState* exception_state); @@ -243,7 +266,8 @@ class XR final : public EventTargetWithInlineData, XRSession* CreateSession( XRSession::SessionMode mode, XRSession::EnvironmentBlendMode blend_mode, - device::mojom::blink::XRSessionClientRequest client_request, + mojo::PendingReceiver<device::mojom::blink::XRSessionClient> + client_receiver, device::mojom::blink::VRDisplayInfoPtr display_info, bool uses_input_eventing, XRSessionFeatureSet enabled_features, @@ -256,7 +280,6 @@ class XR final : public EventTargetWithInlineData, void Dispose(); void OnEnvironmentProviderDisconnect(); - void OnMagicWindowProviderDisconnect(); // Indicates whether use of requestDevice has already been logged. bool did_log_supports_immersive_ = false; @@ -275,9 +298,8 @@ class XR final : public EventTargetWithInlineData, Member<XRFrameProvider> frame_provider_; HeapHashSet<WeakMember<XRSession>> sessions_; - device::mojom::blink::VRServicePtr service_; - device::mojom::blink::XRFrameDataProviderPtr magic_window_provider_; - device::mojom::blink::XREnvironmentIntegrationProviderAssociatedPtr + mojo::Remote<device::mojom::blink::VRService> service_; + mojo::AssociatedRemote<device::mojom::blink::XREnvironmentIntegrationProvider> environment_provider_; mojo::Receiver<device::mojom::blink::VRServiceClient> receiver_{this}; @@ -287,6 +309,9 @@ class XR final : public EventTargetWithInlineData, FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle feature_handle_for_scheduler_; + + // In DOM overlay mode, save and restore the FrameView background color. + Color original_base_background_color_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr.idl b/chromium/third_party/blink/renderer/modules/xr/xr.idl index a1dab899bba..93aba883d87 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr.idl @@ -9,6 +9,7 @@ RuntimeEnabled=WebXR ] interface XR : EventTarget { attribute EventHandler ondevicechange; - [CallWith=ScriptState, MeasureAs=XRSupportsSession, RaisesException] Promise<void> supportsSession(XRSessionMode mode); + [CallWith=ScriptState, DeprecateAs=XRSupportsSession, RaisesException] Promise<void> supportsSession(XRSessionMode mode); + [CallWith=ScriptState, MeasureAs=XRIsSessionSupported, RaisesException] Promise<boolean> isSessionSupported(XRSessionMode mode); [CallWith=ScriptState, MeasureAs=XRRequestSession, RaisesException] Promise<XRSession> requestSession(XRSessionMode mode, optional XRSessionInit options); }; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc index 2d04e94018a..322a48a67b2 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc @@ -10,10 +10,10 @@ namespace blink { -XRAnchor::XRAnchor(int32_t id, XRSession* session) +XRAnchor::XRAnchor(uint32_t id, XRSession* session) : id_(id), session_(session), anchor_data_(base::nullopt) {} -XRAnchor::XRAnchor(int32_t id, +XRAnchor::XRAnchor(uint32_t id, XRSession* session, const device::mojom::blink::XRAnchorDataPtr& anchor_data, double timestamp) @@ -32,6 +32,10 @@ void XRAnchor::Update(const device::mojom::blink::XRAnchorDataPtr& anchor_data, } } +uint32_t XRAnchor::id() const { + return id_; +} + XRSpace* XRAnchor::anchorSpace() const { if (!anchor_data_) { return nullptr; @@ -68,8 +72,7 @@ double XRAnchor::lastChangedTime(bool& is_null) const { } void XRAnchor::detach() { - // TODO(992033): Actually detach anchor once anchor creation is implemented. - DVLOG(2) << "Detaching anchor, id_=" << id_; + session_->xr()->xrEnvironmentProviderRemote()->DetachAnchor(id_); } void XRAnchor::Trace(blink::Visitor* visitor) { diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.h b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.h index fdec8bbb45b..2cc7d985129 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.h @@ -8,7 +8,7 @@ #include <memory> #include "base/optional.h" -#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" @@ -21,13 +21,15 @@ class XRAnchor : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - XRAnchor(int32_t id, XRSession* session); + XRAnchor(uint32_t id, XRSession* session); - XRAnchor(int32_t id, + XRAnchor(uint32_t id, XRSession* session, const device::mojom::blink::XRAnchorDataPtr& anchor_data, double timestamp); + uint32_t id() const; + XRSpace* anchorSpace() const; TransformationMatrix poseMatrix() const; @@ -54,7 +56,7 @@ class XRAnchor : public ScriptWrappable { double timestamp); }; - const int32_t id_; + const uint32_t id_; Member<XRSession> session_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc b/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc index 03f07672b15..e5a389abe64 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc @@ -23,7 +23,8 @@ XRBoundedReferenceSpace::XRBoundedReferenceSpace( XRBoundedReferenceSpace::~XRBoundedReferenceSpace() = default; // No default pose for bounded reference spaces. -std::unique_ptr<TransformationMatrix> XRBoundedReferenceSpace::DefaultPose() { +std::unique_ptr<TransformationMatrix> +XRBoundedReferenceSpace::DefaultViewerPose() { return nullptr; } @@ -40,12 +41,14 @@ void XRBoundedReferenceSpace::EnsureUpdated() { if (display_info && display_info->stage_parameters) { // Use the transform given by xrDisplayInfo's stage_parameters if available. - floor_level_transform_ = std::make_unique<TransformationMatrix>( + bounded_space_from_mojo_ = std::make_unique<TransformationMatrix>( display_info->stage_parameters->standing_transform.matrix()); // In order to ensure that the bounds continue to line up with the user's // physical environment we need to transform by the inverse of the - // originOffset. + // originOffset. TODO(https://crbug.com/1008466): move originOffset to + // separate class? If yes, that class would need to apply a transform + // in the boundsGeometry accessor. TransformationMatrix bounds_transform = InverseOriginOffsetMatrix(); if (display_info->stage_parameters->bounds) { @@ -78,31 +81,28 @@ void XRBoundedReferenceSpace::EnsureUpdated() { } else { // If stage parameters aren't available set the transform to null, which // will subsequently cause this reference space to return null poses. - floor_level_transform_.reset(); + bounded_space_from_mojo_.reset(); bounds_geometry_.clear(); } DispatchEvent(*XRReferenceSpaceEvent::Create(event_type_names::kReset, this)); } -// Transforms a given pose from a "base" reference space used by the XR -// service to the bounded (floor level) reference space. Ideally in the future -// this reference space can be used without additional transforms, with -// the various XR backends returning poses already in the right space. -std::unique_ptr<TransformationMatrix> -XRBoundedReferenceSpace::TransformBasePose( - const TransformationMatrix& base_pose) { +// Gets the pose of the mojo origin in this reference space, corresponding to a +// transform from mojo coordinates to reference space coordinates. Ideally in +// the future this reference space can be used without additional transforms, +// with the various XR backends returning poses already in the right space. +std::unique_ptr<TransformationMatrix> XRBoundedReferenceSpace::SpaceFromMojo( + const TransformationMatrix& mojo_from_viewer) { EnsureUpdated(); // If the reference space has a transform apply it to the base pose and return // that, otherwise return null. - if (floor_level_transform_) { - std::unique_ptr<TransformationMatrix> pose( - std::make_unique<TransformationMatrix>(*floor_level_transform_)); - pose->Multiply(base_pose); - return pose; + if (bounded_space_from_mojo_) { + std::unique_ptr<TransformationMatrix> space_from_mojo( + std::make_unique<TransformationMatrix>(*bounded_space_from_mojo_)); + return space_from_mojo; } - return nullptr; } @@ -111,6 +111,11 @@ HeapVector<Member<DOMPointReadOnly>> XRBoundedReferenceSpace::boundsGeometry() { return bounds_geometry_; } +base::Optional<XRNativeOriginInformation> +XRBoundedReferenceSpace::NativeOrigin() const { + return XRNativeOriginInformation::Create(this); +} + void XRBoundedReferenceSpace::Trace(blink::Visitor* visitor) { visitor->Trace(bounds_geometry_); XRReferenceSpace::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h b/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h index 61b1170bb0b..8f871b2a961 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h @@ -19,12 +19,14 @@ class XRBoundedReferenceSpace final : public XRReferenceSpace { XRBoundedReferenceSpace(XRSession*, XRRigidTransform*); ~XRBoundedReferenceSpace() override; - std::unique_ptr<TransformationMatrix> DefaultPose() override; - std::unique_ptr<TransformationMatrix> TransformBasePose( - const TransformationMatrix& base_pose) override; + std::unique_ptr<TransformationMatrix> DefaultViewerPose() override; + std::unique_ptr<TransformationMatrix> SpaceFromMojo( + const TransformationMatrix& mojo_from_viewer) override; HeapVector<Member<DOMPointReadOnly>> boundsGeometry(); + base::Optional<XRNativeOriginInformation> NativeOrigin() const override; + void Trace(blink::Visitor*) override; void OnReset() override; @@ -36,7 +38,7 @@ class XRBoundedReferenceSpace final : public XRReferenceSpace { void EnsureUpdated(); HeapVector<Member<DOMPointReadOnly>> bounds_geometry_; - std::unique_ptr<TransformationMatrix> floor_level_transform_; + std::unique_ptr<TransformationMatrix> bounded_space_from_mojo_; unsigned int stage_parameters_id_ = 0; }; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc b/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc index bc88ea5d0bb..e40a41feac4 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc @@ -55,8 +55,7 @@ XRCanvasInputProvider::XRCanvasInputProvider(XRSession* session, canvas->addEventListener(event_type_names::kPointercancel, listener_); } -XRCanvasInputProvider::~XRCanvasInputProvider() { -} +XRCanvasInputProvider::~XRCanvasInputProvider() {} void XRCanvasInputProvider::Stop() { if (!listener_) { @@ -111,11 +110,12 @@ void XRCanvasInputProvider::UpdateInputSource(PointerEvent* event) { // projection matrix to get a 3D point in space, which is then returned in // matrix form so we can use it as an XRInputSource's pointerMatrix. XRViewData& view = session_->views()[0]; - TransformationMatrix pointer_transform_matrix = view.UnprojectPointer( + TransformationMatrix viewer_from_pointer = view.UnprojectPointer( element_x, element_y, canvas_->OffsetWidth(), canvas_->OffsetHeight()); - // Update the input source's pointer matrix. - input_source_->SetPointerTransformMatrix(&pointer_transform_matrix); + // Update the pointer pose in input space. For screen tapping, input + // space is equivalent to viewer space. + input_source_->SetInputFromPointer(&viewer_from_pointer); } void XRCanvasInputProvider::ClearInputSource() { diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h b/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h index 4f0d67b1ade..3662b8d72ad 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h @@ -19,9 +19,8 @@ class PointerEvent; class XRInputSource; class XRSession; -class XRCanvasInputProvider - : public GarbageCollectedFinalized<XRCanvasInputProvider>, - public NameClient { +class XRCanvasInputProvider : public GarbageCollected<XRCanvasInputProvider>, + public NameClient { public: XRCanvasInputProvider(XRSession*, HTMLCanvasElement*); virtual ~XRCanvasInputProvider(); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame.cc b/chromium/third_party/blink/renderer/modules/xr/xr_frame.cc index 5df159ab468..c8a138d86e2 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/xr/xr_frame.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/modules/xr/xr_hit_test_source.h" #include "third_party/blink/renderer/modules/xr/xr_input_source.h" #include "third_party/blink/renderer/modules/xr/xr_reference_space.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" @@ -26,6 +27,9 @@ const char kNonAnimationFrame[] = const char kSessionMismatch[] = "XRSpace and XRFrame sessions do not match."; +const char kCannotReportPoses[] = + "Poses cannot be given out for the current state."; + } // namespace XRFrame::XRFrame(XRSession* session, XRWorldInformation* world_information) @@ -56,10 +60,16 @@ XRViewerPose* XRFrame::getViewerPose(XRReferenceSpace* reference_space, return nullptr; } + if (!session_->CanReportPoses()) { + exception_state.ThrowSecurityError(kCannotReportPoses); + return nullptr; + } + session_->LogGetPose(); std::unique_ptr<TransformationMatrix> pose = - reference_space->GetViewerPoseMatrix(base_pose_matrix_.get()); + reference_space->SpaceFromViewerWithDefaultAndOffset( + mojo_from_viewer_.get()); if (!pose) { return nullptr; } @@ -84,6 +94,9 @@ XRPose* XRFrame::getPose(XRSpace* space_A, } if (!space_A || !space_B) { + DVLOG(2) << __func__ + << " : space_A or space_B is null, space_A =" << space_A + << ", space_B = " << space_B; return nullptr; } @@ -99,11 +112,18 @@ XRPose* XRFrame::getPose(XRSpace* space_A, return nullptr; } - return space_A->getPose(space_B, base_pose_matrix_.get()); + if (!session_->CanReportPoses()) { + exception_state.ThrowSecurityError(kCannotReportPoses); + return nullptr; + } + + return space_A->getPose(space_B, mojo_from_viewer_.get()); } -void XRFrame::SetBasePoseMatrix(const TransformationMatrix& base_pose_matrix) { - base_pose_matrix_ = std::make_unique<TransformationMatrix>(base_pose_matrix); +void XRFrame::SetMojoFromViewer(const TransformationMatrix& mojo_from_viewer, + bool emulated_position) { + mojo_from_viewer_ = std::make_unique<TransformationMatrix>(mojo_from_viewer); + emulated_position_ = emulated_position; } void XRFrame::Deactivate() { @@ -112,9 +132,10 @@ void XRFrame::Deactivate() { } HeapVector<Member<XRHitTestResult>> XRFrame::getHitTestResults( - XRHitTestSource* hitTestSource, - XRSpace* relativeTo) { - return {}; + XRHitTestSource* hit_test_source) { + if (!session_->ValidateHitTestSourceExists(hit_test_source)) + return {}; + return hit_test_source->Results(); } void XRFrame::Trace(blink::Visitor* visitor) { diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame.h b/chromium/third_party/blink/renderer/modules/xr/xr_frame.h index 7b2e808bc49..8cbd0fba270 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.h @@ -7,7 +7,7 @@ #include <memory> -#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -41,7 +41,7 @@ class XRFrame final : public ScriptWrappable { XRWorldInformation* worldInformation() const { return world_information_; } XRAnchorSet* trackedAnchors() const; - void SetBasePoseMatrix(const TransformationMatrix&); + void SetMojoFromViewer(const TransformationMatrix&, bool emulated_position); void Trace(blink::Visitor*) override; @@ -52,8 +52,9 @@ class XRFrame final : public ScriptWrappable { } HeapVector<Member<XRHitTestResult>> getHitTestResults( - XRHitTestSource* hitTestSource, - XRSpace* relativeTo); + XRHitTestSource* hit_test_source); + + bool EmulatedPosition() const { return emulated_position_; } private: std::unique_ptr<TransformationMatrix> GetAdjustedPoseMatrix(XRSpace*) const; @@ -64,8 +65,9 @@ class XRFrame final : public ScriptWrappable { const Member<XRSession> session_; - // Maps from mojo space to headset space. - std::unique_ptr<TransformationMatrix> base_pose_matrix_; + // Viewer pose in mojo space, the matrix maps from viewer (headset) space to + // mojo space. + std::unique_ptr<TransformationMatrix> mojo_from_viewer_; // Frames are only active during callbacks. getPose and getViewerPose should // only be called from JS on active frames. @@ -75,6 +77,8 @@ class XRFrame final : public ScriptWrappable { // animation frames. getViewerPose should only be called from JS on active // animation frames. bool is_animation_frame_ = false; + + bool emulated_position_ = false; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl b/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl index 53851b1a99b..90ed5d2adba 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl @@ -19,5 +19,5 @@ [RaisesException] XRViewerPose? getViewerPose(XRReferenceSpace referenceSpace); [RaisesException] XRPose? getPose(XRSpace space, XRSpace relativeTo); - [RuntimeEnabled=WebXRHitTest] FrozenArray<XRHitTestResult> getHitTestResults(XRHitTestSource hitTestSource, [DefaultValue=Undefined] optional XRSpace relativeTo); + [RuntimeEnabled=WebXRHitTest] FrozenArray<XRHitTestResult> getHitTestResults(XRHitTestSource hitTestSource); }; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc b/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc index b50db17d5e3..6ef38e31eae 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.cc @@ -66,33 +66,50 @@ XRFrameProvider::XRFrameProvider(XR* xr) frame_transport_ = MakeGarbageCollected<XRFrameTransport>(); } -void XRFrameProvider::BeginImmersiveSession( +void XRFrameProvider::OnSessionStarted( XRSession* session, device::mojom::blink::XRSessionPtr session_ptr) { - // Make sure the session is indeed an immersive one. - DCHECK(session && session->immersive()); - - // Ensure we can only have one immersive session at a time. - DCHECK(!immersive_session_); - DCHECK(session_ptr->data_provider); - DCHECK(session_ptr->submit_frame_sink); - - immersive_session_ = session; + DCHECK(session); - immersive_data_provider_.Bind(std::move(session_ptr->data_provider)); - immersive_data_provider_.set_connection_error_handler(WTF::Bind( - &XRFrameProvider::OnProviderConnectionError, WrapWeakPersistent(this))); + if (session->immersive()) { + // Ensure we can only have one immersive session at a time. + DCHECK(!immersive_session_); + DCHECK(session_ptr->data_provider); + DCHECK(session_ptr->submit_frame_sink); + + immersive_session_ = session; + + immersive_data_provider_.Bind(std::move(session_ptr->data_provider)); + immersive_data_provider_.set_disconnect_handler( + WTF::Bind(&XRFrameProvider::OnProviderConnectionError, + WrapWeakPersistent(this), WrapWeakPersistent(session))); + + immersive_presentation_provider_.Bind( + std::move(session_ptr->submit_frame_sink->provider)); + immersive_presentation_provider_.set_disconnect_handler( + WTF::Bind(&XRFrameProvider::OnProviderConnectionError, + WrapWeakPersistent(this), WrapWeakPersistent(session))); + + frame_transport_->BindSubmitFrameClient( + std::move(session_ptr->submit_frame_sink->client_receiver)); + frame_transport_->SetTransportOptions( + std::move(session_ptr->submit_frame_sink->transport_options)); + frame_transport_->PresentChange(); + } else { + // If a non-immersive session doesn't have a data provider, we don't + // need to store a reference to it. + if (!session_ptr->data_provider) { + return; + } - presentation_provider_.Bind( - std::move(session_ptr->submit_frame_sink->provider)); - presentation_provider_.set_connection_error_handler(WTF::Bind( - &XRFrameProvider::OnProviderConnectionError, WrapWeakPersistent(this))); + mojo::Remote<device::mojom::blink::XRFrameDataProvider> data_provider; + data_provider.Bind(std::move(session_ptr->data_provider)); + data_provider.set_disconnect_handler( + WTF::Bind(&XRFrameProvider::OnProviderConnectionError, + WrapWeakPersistent(this), WrapWeakPersistent(session))); - frame_transport_->BindSubmitFrameClient( - std::move(session_ptr->submit_frame_sink->client_request)); - frame_transport_->SetTransportOptions( - std::move(session_ptr->submit_frame_sink->transport_options)); - frame_transport_->PresentChange(); + non_immersive_data_providers_.insert(session, std::move(data_provider)); + } } void XRFrameProvider::OnFocusChanged() { @@ -112,35 +129,41 @@ void XRFrameProvider::OnFocusChanged() { // Ends the immersive session when the presentation or immersive data provider // got disconnected. -void XRFrameProvider::OnProviderConnectionError() { - presentation_provider_.reset(); - immersive_data_provider_.reset(); - if (vsync_connection_failed_) - return; - immersive_session_->ForceEnd(); - vsync_connection_failed_ = true; +void XRFrameProvider::OnProviderConnectionError(XRSession* session) { + // This will call into |OnSessionEnded|, unless it has already ended. + session->ForceEnd(); } -// Called by the immersive session when it is ended. -void XRFrameProvider::OnImmersiveSessionEnded() { - if (!immersive_session_) - return; - - xr_->ExitPresent(); - - immersive_session_ = nullptr; - pending_immersive_vsync_ = false; - frame_id_ = -1; - presentation_provider_.reset(); - immersive_data_provider_.reset(); - - frame_transport_ = MakeGarbageCollected<XRFrameTransport>(); +void XRFrameProvider::OnSessionEnded(XRSession* session) { + if (session->immersive()) { + DCHECK(session == immersive_session_); + + xr_->ExitPresent(); + + immersive_session_ = nullptr; + pending_immersive_vsync_ = false; + frame_id_ = -1; + immersive_presentation_provider_.reset(); + immersive_data_provider_.reset(); + immersive_frame_pose_ = nullptr; + is_immersive_frame_position_emulated_ = false; + + frame_transport_ = MakeGarbageCollected<XRFrameTransport>(); + + // When we no longer have an active immersive session schedule all the + // outstanding frames that were requested while the immersive session was + // active. + if (requesting_sessions_.size() > 0) { + for (auto& session : requesting_sessions_) { + RequestNonImmersiveFrameData(session.key.Get()); + } - // When we no longer have an active immersive session schedule all the - // outstanding frames that were requested while the immersive session was - // active. - if (requesting_sessions_.size() > 0) - ScheduleNonImmersiveFrame(nullptr); + ScheduleNonImmersiveFrame(nullptr); + } + } else { + non_immersive_data_providers_.erase(session); + requesting_sessions_.erase(session); + } } // Schedule a session to be notified when the next XR frame is available. @@ -159,13 +182,19 @@ void XRFrameProvider::RequestFrame(XRSession* session) { // Non-immersive frame logic. - requesting_sessions_.push_back(session); + // Duplicate frame requests are treated as a no-op. + if (requesting_sessions_.Contains(session)) { + return; + } + requesting_sessions_.insert(session, nullptr); // If there's an active immersive session save the request but suppress // processing it until the immersive session is no longer active. - if (immersive_session_) + if (immersive_session_) { return; + } + RequestNonImmersiveFrameData(session); ScheduleNonImmersiveFrame(std::move(options)); } @@ -201,23 +230,9 @@ void XRFrameProvider::ScheduleNonImmersiveFrame( if (!doc) return; - // This is cleared by either OnNonImmersiveFrameData (GetFrameData callback, - // used if we have a magic window provider), or by OnNonImmersiveVSync - // (XRFrameProviderRequestCallback's invoke, used if there's no magic window - // provider). pending_non_immersive_vsync_ = true; - // If we have a Magic Window provider, request frame data and flag that - // we're waiting for it. If not, clear any pose data, so that - // ProcessScheduledFrame handles it appropriately. - if (xr_->CanRequestNonImmersiveFrameData()) { - xr_->GetNonImmersiveFrameData( - std::move(options), WTF::Bind(&XRFrameProvider::OnNonImmersiveFrameData, - WrapWeakPersistent(this))); - } else { - frame_pose_ = nullptr; - } - + // Calls |OnNonImmersiveVSync| doc->RequestAnimationFrame( MakeGarbageCollected<XRFrameProviderRequestCallback>(this)); } @@ -226,7 +241,6 @@ void XRFrameProvider::OnImmersiveFrameData( device::mojom::blink::XRFrameDataPtr data) { TRACE_EVENT0("gpu", __FUNCTION__); DVLOG(2) << __FUNCTION__; - vsync_connection_failed_ = false; if (!data) { return; } @@ -250,7 +264,14 @@ void XRFrameProvider::OnImmersiveFrameData( .MonotonicTimeToZeroBasedDocumentTime(monotonic_time_now) .InMillisecondsF(); - frame_pose_ = std::move(data->pose); + immersive_frame_pose_ = std::move(data->pose); + if (immersive_frame_pose_) { + is_immersive_frame_position_emulated_ = + immersive_frame_pose_->emulated_position; + } else { + is_immersive_frame_position_emulated_ = true; + } + frame_id_ = data->frame_id; buffer_mailbox_holder_ = data->buffer_holder; @@ -291,13 +312,13 @@ void XRFrameProvider::OnNonImmersiveVSync(double high_res_now_ms) { } void XRFrameProvider::OnNonImmersiveFrameData( + XRSession* session, device::mojom::blink::XRFrameDataPtr frame_data) { TRACE_EVENT0("gpu", __FUNCTION__); DVLOG(2) << __FUNCTION__; // TODO(https://crbug.com/837834): add unit tests for this code path. - pending_non_immersive_vsync_ = false; LocalFrame* frame = xr_->GetFrame(); if (!frame) return; @@ -305,17 +326,48 @@ void XRFrameProvider::OnNonImmersiveFrameData( if (!doc) return; - if (!frame_data) { + // Look up the request for this session. The session may have ended between + // when the request was sent and this callback, so skip it in that case. + auto request = requesting_sessions_.find(session); + if (request == requesting_sessions_.end()) { + return; + } + + if (frame_data) { + request->value = std::move(frame_data->pose); + } else { // Unexpectedly didn't get frame data, and we don't have a timestamp. // Try to request a regular animation frame to avoid getting stuck. DVLOG(1) << __FUNCTION__ << ": NO FRAME DATA!"; - frame_pose_ = nullptr; + request->value = nullptr; doc->RequestAnimationFrame( MakeGarbageCollected<XRFrameProviderRequestCallback>(this)); - return; } +} - frame_pose_ = std::move(frame_data->pose); +void XRFrameProvider::RequestNonImmersiveFrameData(XRSession* session) { + DCHECK(session); + DCHECK(!session->immersive()); + DCHECK(!immersive_session_); + + // The requesting_sessions_ entry for this session must have already + // been created in |RequestFrame|. + auto request = requesting_sessions_.find(session); + DCHECK(request != requesting_sessions_.end()); + + auto provider = non_immersive_data_providers_.find(session); + if (provider == non_immersive_data_providers_.end()) { + request->value = nullptr; + } else { + auto& data_provider = provider->value; + auto options = device::mojom::blink::XRFrameDataRequestOptions::New( + session->worldTrackingState()->planeDetectionState()->enabled()); + + data_provider->GetFrameData( + std::move(options), + WTF::Bind(&XRFrameProvider::OnNonImmersiveFrameData, + WrapWeakPersistent(this), WrapWeakPersistent(session))); + } } void XRFrameProvider::ProcessScheduledFrame( @@ -332,11 +384,24 @@ void XRFrameProvider::ProcessScheduledFrame( } if (immersive_session_) { - if (frame_pose_) { + // We need to ensure that pose data is valid for the duration of the frame, + // because input events may call into |session.end()| which will destroy + // this data otherwise. Move the data into local scope here so that it can't + // be destroyed. + auto frame_pose = std::move(immersive_frame_pose_); + + // Prior to updating input source state, update the state needed to create + // presentation frame as newly created presentation frame will get passed to + // the input source select[/start/end] events. + immersive_session_->UpdatePresentationFrameState( + high_res_now_ms, getPoseMatrix(frame_pose), frame_data, + is_immersive_frame_position_emulated_); + + if (frame_pose) { base::span<const device::mojom::blink::XRInputSourceStatePtr> input_states; - if (frame_pose_->input_state.has_value()) - input_states = frame_pose_->input_state.value(); + if (frame_pose->input_state.has_value()) + input_states = frame_pose->input_state.value(); immersive_session_->OnInputStateChange(frame_id_, input_states); } @@ -346,18 +411,17 @@ void XRFrameProvider::ProcessScheduledFrame( if (!immersive_session_) return; - if (frame_pose_ && frame_pose_->pose_reset) { + if (frame_pose && frame_pose->pose_reset) { immersive_session_->OnPoseReset(); } // Check if immersive session is still set as OnPoseReset may have allowed a // ForceEndSession to be triggered. - if (!immersive_session_) + if (!immersive_session_) { return; + } // If there's an immersive session active only process its frame. - std::unique_ptr<TransformationMatrix> pose_matrix = - getPoseMatrix(frame_pose_); #if DCHECK_IS_ON() // Sanity check: if drawing into a shared buffer, the optional mailbox // holder must be present. Exception is the first immersive frame after a @@ -375,35 +439,38 @@ void XRFrameProvider::ProcessScheduledFrame( if (frame_data && frame_data->stage_parameters_updated) { immersive_session_->UpdateStageParameters(frame_data->stage_parameters); } - if (frame_data) { - immersive_session_->OnFrame(high_res_now_ms, std::move(pose_matrix), - buffer_mailbox_holder_, - frame_data->detected_planes_data); - } else { - immersive_session_->OnFrame(high_res_now_ms, std::move(pose_matrix), - buffer_mailbox_holder_, nullptr); - } + + immersive_session_->OnFrame(high_res_now_ms, buffer_mailbox_holder_); } else { // In the process of fulfilling the frame requests for each session they are // extremely likely to request another frame. Work off of a separate list // from the requests to prevent infinite loops. - DCHECK(processing_sessions_.IsEmpty()); - swap(requesting_sessions_, processing_sessions_); + decltype(requesting_sessions_) processing_sessions; + swap(requesting_sessions_, processing_sessions); // Inform sessions with a pending request of the new frame - for (unsigned i = 0; i < processing_sessions_.size(); ++i) { - XRSession* session = processing_sessions_.at(i).Get(); + for (auto& request : processing_sessions) { + XRSession* session = request.key.Get(); // If the session was terminated between requesting and now, we shouldn't // process anything further. if (session->ended()) continue; - if (frame_pose_) { + const auto& frame_pose = request.value; + + // Prior to updating input source state, update the state needed to create + // presentation frame as newly created presentation frame will get passed + // to the input source select[/start/end] events. + session->UpdatePresentationFrameState( + high_res_now_ms, getPoseMatrix(frame_pose), frame_data, + true /* Non-immersive positions are always emulated */); + + if (frame_pose) { base::span<const device::mojom::blink::XRInputSourceStatePtr> input_states; - if (frame_pose_->input_state.has_value()) - input_states = frame_pose_->input_state.value(); + if (frame_pose->input_state.has_value()) + input_states = frame_pose->input_state.value(); session->OnInputStateChange(frame_id_, input_states); } @@ -413,7 +480,7 @@ void XRFrameProvider::ProcessScheduledFrame( if (session->ended()) continue; - if (frame_pose_ && frame_pose_->pose_reset) { + if (frame_pose && frame_pose->pose_reset) { session->OnPoseReset(); } @@ -421,18 +488,8 @@ void XRFrameProvider::ProcessScheduledFrame( if (session->ended()) continue; - std::unique_ptr<TransformationMatrix> pose_matrix = - getPoseMatrix(frame_pose_); - if (frame_data) { - session->OnFrame(high_res_now_ms, std::move(pose_matrix), base::nullopt, - frame_data->detected_planes_data); - } else { - session->OnFrame(high_res_now_ms, std::move(pose_matrix), base::nullopt, - nullptr); - } + session->OnFrame(high_res_now_ms, base::nullopt); } - - processing_sessions_.clear(); } } @@ -440,7 +497,7 @@ void XRFrameProvider::SubmitWebGLLayer(XRWebGLLayer* layer, bool was_changed) { DCHECK(layer); DCHECK(immersive_session_); DCHECK(layer->session() == immersive_session_); - if (!presentation_provider_.is_bound()) + if (!immersive_presentation_provider_.is_bound()) return; TRACE_EVENT1("gpu", "XRFrameProvider::SubmitWebGLLayer", "frame", frame_id_); @@ -459,7 +516,7 @@ void XRFrameProvider::SubmitWebGLLayer(XRWebGLLayer* layer, bool was_changed) { if (!was_changed) { // Just tell the device side that there was no submitted frame instead of // executing the implicit end-of-frame submit. - frame_transport_->FrameSubmitMissing(presentation_provider_.get(), + frame_transport_->FrameSubmitMissing(immersive_presentation_provider_.get(), webgl_context->ContextGL(), frame_id_); return; } @@ -475,9 +532,9 @@ void XRFrameProvider::SubmitWebGLLayer(XRWebGLLayer* layer, bool was_changed) { bool needs_copy = false; DVLOG(3) << __FUNCTION__ << ": FrameSubmit for SharedBuffer mode"; frame_transport_->FrameSubmit( - presentation_provider_.get(), webgl_context->ContextGL(), webgl_context, - std::move(image_ref), std::move(image_release_callback), frame_id_, - needs_copy); + immersive_presentation_provider_.get(), webgl_context->ContextGL(), + webgl_context, std::move(image_ref), std::move(image_release_callback), + frame_id_, needs_copy); return; } @@ -499,9 +556,9 @@ void XRFrameProvider::SubmitWebGLLayer(XRWebGLLayer* layer, bool was_changed) { bool needs_copy = immersive_session_->External(); frame_transport_->FrameSubmit( - presentation_provider_.get(), webgl_context->ContextGL(), webgl_context, - std::move(image_ref), std::move(image_release_callback), frame_id_, - needs_copy); + immersive_presentation_provider_.get(), webgl_context->ContextGL(), + webgl_context, std::move(image_ref), std::move(image_release_callback), + frame_id_, needs_copy); // Reset our frame id, since anything we'd want to do (resizing/etc) can // no-longer happen to this frame. @@ -512,7 +569,7 @@ void XRFrameProvider::SubmitWebGLLayer(XRWebGLLayer* layer, bool was_changed) { // the moment. Will need an overhaul when we get more robust layering support. void XRFrameProvider::UpdateWebGLLayerViewports(XRWebGLLayer* layer) { DCHECK(layer->session() == immersive_session_); - DCHECK(presentation_provider_); + DCHECK(immersive_presentation_provider_); XRViewport* left = layer->GetViewportForEye(XRView::kEyeLeft); XRViewport* right = layer->GetViewportForEye(XRView::kEyeRight); @@ -538,12 +595,12 @@ void XRFrameProvider::UpdateWebGLLayerViewports(XRWebGLLayer* layer) { static_cast<float>(right->height()) / height) : WebFloatRect(); - presentation_provider_->UpdateLayerBounds( + immersive_presentation_provider_->UpdateLayerBounds( frame_id_, left_coords, right_coords, WebSize(width, height)); } void XRFrameProvider::Dispose() { - presentation_provider_.reset(); + immersive_presentation_provider_.reset(); immersive_data_provider_.reset(); // TODO(bajones): Do something for outstanding frame requests? } @@ -552,8 +609,8 @@ void XRFrameProvider::Trace(blink::Visitor* visitor) { visitor->Trace(xr_); visitor->Trace(frame_transport_); visitor->Trace(immersive_session_); + visitor->Trace(non_immersive_data_providers_); visitor->Trace(requesting_sessions_); - visitor->Trace(processing_sessions_); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.h b/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.h index 41f7a064114..8fd58cc40a5 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame_provider.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_FRAME_PROVIDER_H_ #include "device/vr/public/mojom/vr_service.mojom-blink.h" -#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -21,17 +21,15 @@ class XRWebGLLayer; // This class manages requesting and dispatching frame updates, which includes // pose information for a given XRDevice. -class XRFrameProvider final - : public GarbageCollectedFinalized<XRFrameProvider> { +class XRFrameProvider final : public GarbageCollected<XRFrameProvider> { public: explicit XRFrameProvider(XR*); XRSession* immersive_session() const { return immersive_session_; } - device::mojom::blink::XRPresentationClientPtr GetSubmitFrameClient(); - void BeginImmersiveSession(XRSession* session, - device::mojom::blink::XRSessionPtr session_ptr); - void OnImmersiveSessionEnded(); + void OnSessionStarted(XRSession* session, + device::mojom::blink::XRSessionPtr session_ptr); + void OnSessionEnded(XRSession* session); void RequestFrame(XRSession*); @@ -43,7 +41,7 @@ class XRFrameProvider final void Dispose(); void OnFocusChanged(); - device::mojom::blink::XRFrameDataProvider* GetDataProvider() { + device::mojom::blink::XRFrameDataProvider* GetImmersiveDataProvider() { return immersive_data_provider_.get(); } @@ -51,30 +49,47 @@ class XRFrameProvider final private: void OnImmersiveFrameData(device::mojom::blink::XRFrameDataPtr data); - void OnNonImmersiveFrameData(device::mojom::blink::XRFrameDataPtr data); + void OnNonImmersiveFrameData(XRSession* session, + device::mojom::blink::XRFrameDataPtr data); + + // Posts a request to the |XRFrameDataProvider| for the given session for + // frame data. If the given session has no provider, it will be given null + // frame data. + void RequestNonImmersiveFrameData(XRSession* session); // TODO(https://crbug.com/955819): options should be removed from those // methods as they'll no longer be passed on a per-frame basis. void ScheduleImmersiveFrame( device::mojom::blink::XRFrameDataRequestOptionsPtr options); + + // Schedules an animation frame to service all non-immersive requesting + // sessions. This will be postponed if there is a currently running immmersive + // session. void ScheduleNonImmersiveFrame( device::mojom::blink::XRFrameDataRequestOptionsPtr options); - void OnProviderConnectionError(); + void OnProviderConnectionError(XRSession* session); void ProcessScheduledFrame(device::mojom::blink::XRFrameDataPtr frame_data, double high_res_now_ms); const Member<XR> xr_; + + // Immersive session state Member<XRSession> immersive_session_; Member<XRFrameTransport> frame_transport_; - - // Non-immersive Sessions which have requested a frame update. - HeapVector<Member<XRSession>> requesting_sessions_; - HeapVector<Member<XRSession>> processing_sessions_; - - device::mojom::blink::XRPresentationProviderPtr presentation_provider_; - device::mojom::blink::XRFrameDataProviderPtr immersive_data_provider_; - device::mojom::blink::VRPosePtr frame_pose_; + mojo::Remote<device::mojom::blink::XRFrameDataProvider> + immersive_data_provider_; + mojo::Remote<device::mojom::blink::XRPresentationProvider> + immersive_presentation_provider_; + device::mojom::blink::VRPosePtr immersive_frame_pose_; + bool is_immersive_frame_position_emulated_ = false; + + // Non-immersive session state + HeapHashMap<Member<XRSession>, + mojo::Remote<device::mojom::blink::XRFrameDataProvider>> + non_immersive_data_providers_; + HeapHashMap<Member<XRSession>, device::mojom::blink::VRPosePtr> + requesting_sessions_; // This frame ID is XR-specific and is used to track when frames arrive at the // XR compositor so that it knows which poses to use, when to apply bounds @@ -82,7 +97,6 @@ class XRFrameProvider final int16_t frame_id_ = -1; bool pending_immersive_vsync_ = false; bool pending_non_immersive_vsync_ = false; - bool vsync_connection_failed_ = false; base::Optional<gpu::MailboxHolder> buffer_mailbox_holder_; bool last_has_focus_ = false; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h b/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h index 5698febc27f..d5258abdb28 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.h @@ -17,7 +17,7 @@ class XRFrame; class XRSession; class XRFrameRequestCallbackCollection final - : public GarbageCollectedFinalized<XRFrameRequestCallbackCollection>, + : public GarbageCollected<XRFrameRequestCallbackCollection>, public NameClient { public: explicit XRFrameRequestCallbackCollection(ExecutionContext*); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.cc b/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.cc index 7c5fd7987b0..0eb6ff3e93b 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.cc @@ -15,7 +15,7 @@ XRGripSpace::XRGripSpace(XRSession* session, XRInputSource* source) : XRSpace(session), input_source_(source) {} XRPose* XRGripSpace::getPose(XRSpace* other_space, - const TransformationMatrix* base_pose_matrix) { + const TransformationMatrix* mojo_from_viewer) { // Grip is only available when using tracked pointer for input. if (input_source_->TargetRayMode() != device::mojom::XRTargetRayMode::POINTING) { @@ -23,26 +23,34 @@ XRPose* XRGripSpace::getPose(XRSpace* other_space, } // Make sure the required pose matrices are available. - if (!base_pose_matrix || !input_source_->BasePose()) { + if (!mojo_from_viewer || !input_source_->MojoFromInput()) { return nullptr; } - std::unique_ptr<TransformationMatrix> grip_pose = - other_space->TransformBaseInputPose(*(input_source_->BasePose()), - *base_pose_matrix); - - if (!grip_pose) { + // Calculate grip pose in other_space, aka other_from_grip + std::unique_ptr<TransformationMatrix> other_from_grip = + other_space->SpaceFromInputForViewer(*(input_source_->MojoFromInput()), + *mojo_from_viewer); + if (!other_from_grip) { return nullptr; } // Account for any changes made to the reference space's origin offset so // that things like teleportation works. - TransformationMatrix adjusted_pose = - other_space->InverseOriginOffsetMatrix().Multiply(*grip_pose); - return MakeGarbageCollected<XRPose>(adjusted_pose, + // + // This is offset_from_grip = offset_from_other * other_from_grip, + // where offset_from_other = inverse(other_from_offset). + // TODO(https://crbug.com/1008466): move originOffset to separate class? + TransformationMatrix offset_from_grip = + other_space->InverseOriginOffsetMatrix().Multiply(*other_from_grip); + return MakeGarbageCollected<XRPose>(offset_from_grip, input_source_->emulatedPosition()); } +base::Optional<XRNativeOriginInformation> XRGripSpace::NativeOrigin() const { + return input_source_->nativeOrigin(); +} + void XRGripSpace::Trace(blink::Visitor* visitor) { visitor->Trace(input_source_); XRSpace::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.h b/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.h index f24ad46fbf0..0ffa42e6525 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_grip_space.h @@ -13,10 +13,12 @@ namespace blink { class XRGripSpace : public XRSpace { public: - XRGripSpace(XRSession*, XRInputSource*); + XRGripSpace(XRSession* session, XRInputSource* input_source); XRPose* getPose(XRSpace* other_space, const TransformationMatrix* base_pose_matrix) override; + base::Optional<XRNativeOriginInformation> NativeOrigin() const override; + void Trace(blink::Visitor*) override; private: diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options.cc b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options.cc index 90e870addef..73d366ffd7a 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options.cc @@ -2,16 +2,38 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "xr_hit_test_options.h" +#include "third_party/blink/renderer/modules/xr/xr_hit_test_options.h" + +#include "third_party/blink/renderer/modules/xr/xr_hit_test_options_init.h" +#include "third_party/blink/renderer/modules/xr/xr_ray.h" +#include "third_party/blink/renderer/modules/xr/xr_space.h" namespace blink { +XRHitTestOptions::XRHitTestOptions(XRHitTestOptionsInit* options_init) { + DCHECK(options_init); + + space_ = options_init->space(); + + if (options_init->hasOffsetRay()) { + ray_ = options_init->offsetRay(); + } else { + ray_ = MakeGarbageCollected<XRRay>(); + } +} + +void XRHitTestOptions::Trace(blink::Visitor* visitor) { + visitor->Trace(space_); + visitor->Trace(ray_); + ScriptWrappable::Trace(visitor); +} + XRSpace* XRHitTestOptions::space() const { - return nullptr; + return space_; } XRRay* XRHitTestOptions::offsetRay() const { - return nullptr; + return ray_; } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options.h b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options.h index 1c83d5eca17..0c671b1378c 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_options.h @@ -11,13 +11,22 @@ namespace blink { class XRRay; class XRSpace; +class XRHitTestOptionsInit; class XRHitTestOptions : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: + explicit XRHitTestOptions(XRHitTestOptionsInit* options_init); + XRSpace* space() const; XRRay* offsetRay() const; + + void Trace(blink::Visitor* visitor) override; + + private: + Member<XRSpace> space_; + Member<XRRay> ray_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc index da4a2a0d22e..dd3bc4c2eef 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.cc @@ -2,16 +2,41 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "xr_hit_test_result.h" +#include "third_party/blink/renderer/modules/xr/xr_hit_test_result.h" + +#include "third_party/blink/renderer/modules/xr/xr_hit_test_source.h" +#include "third_party/blink/renderer/modules/xr/xr_pose.h" +#include "third_party/blink/renderer/modules/xr/xr_space.h" namespace blink { +XRHitTestResult::XRHitTestResult(XRHitTestSource* hit_test_source, + const TransformationMatrix& pose) + : hit_test_source_(hit_test_source), + pose_(std::make_unique<TransformationMatrix>(pose)) {} + XRHitTestOptions* XRHitTestResult::hitTestOptions() const { - return nullptr; + return hit_test_source_->hitTestOptions(); +} + +XRPose* XRHitTestResult::getPose(XRSpace* relative_to) { + DCHECK(relative_to->MojoFromSpace()); + + auto mojo_from_this = *pose_; + + auto mojo_from_other = *relative_to->MojoFromSpace(); + DCHECK(mojo_from_other.IsInvertible()); + + auto other_from_mojo = mojo_from_other.Inverse(); + + auto other_from_this = other_from_mojo * mojo_from_this; + + return MakeGarbageCollected<XRPose>(other_from_this, false); } -XRRigidTransform* XRHitTestResult::transform() const { - return nullptr; +void XRHitTestResult::Trace(blink::Visitor* visitor) { + visitor->Trace(hit_test_source_); + ScriptWrappable::Trace(visitor); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.h b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.h index f1c96dcf46a..37526c06384 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.h @@ -9,15 +9,28 @@ namespace blink { +class TransformationMatrix; class XRHitTestOptions; -class XRRigidTransform; +class XRHitTestSource; +class XRPose; +class XRSpace; class XRHitTestResult : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: + XRHitTestResult(XRHitTestSource* hit_test_source, + const TransformationMatrix& pose); + XRHitTestOptions* hitTestOptions() const; - XRRigidTransform* transform() const; + + XRPose* getPose(XRSpace* relative_to); + + void Trace(blink::Visitor* visitor) override; + + private: + Member<XRHitTestSource> hit_test_source_; + std::unique_ptr<TransformationMatrix> pose_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl index f286d65cd40..7c3cd75e8d9 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl @@ -5,5 +5,6 @@ [SecureContext, Exposed=Window, RuntimeEnabled=WebXRHitTest] interface XRHitTestResult { readonly attribute XRHitTestOptions hitTestOptions; - readonly attribute XRRigidTransform transform; + + XRPose? getPose(XRSpace relative_to); }; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc index 1fe50a99f91..f1435ee342c 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.cc @@ -2,12 +2,48 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "xr_hit_test_source.h" +#include "third_party/blink/renderer/modules/xr/xr_hit_test_source.h" + +#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "third_party/blink/renderer/modules/xr/xr_hit_test_options.h" +#include "third_party/blink/renderer/modules/xr/xr_hit_test_result.h" namespace blink { +XRHitTestSource::XRHitTestSource(uint32_t id, XRHitTestOptions* options) + : id_(id), options_(options) {} + +uint32_t XRHitTestSource::id() const { + return id_; +} + XRHitTestOptions* XRHitTestSource::hitTestOptions() const { - return nullptr; + return options_; +} + +HeapVector<Member<XRHitTestResult>> XRHitTestSource::Results() { + HeapVector<Member<XRHitTestResult>> results; + + for (const auto& result : last_frame_results_) { + results.emplace_back(MakeGarbageCollected<XRHitTestResult>(this, *result)); + } + + return results; +} + +void XRHitTestSource::Update( + const WTF::Vector<device::mojom::blink::XRHitResultPtr>& hit_test_results) { + last_frame_results_.clear(); + + for (auto& result : hit_test_results) { + last_frame_results_.push_back( + std::make_unique<TransformationMatrix>(result->hit_matrix.matrix())); + } +} + +void XRHitTestSource::Trace(blink::Visitor* visitor) { + visitor->Trace(options_); + ScriptWrappable::Trace(visitor); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.h b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.h index 2c7f2da57af..78c6c0b0576 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_hit_test_source.h @@ -5,17 +5,43 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_HIT_TEST_SOURCE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_HIT_TEST_SOURCE_H_ +#include <memory> + #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" +#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" + namespace blink { class XRHitTestOptions; +class XRHitTestResult; class XRHitTestSource : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: + XRHitTestSource(uint32_t id, XRHitTestOptions* options); + + uint32_t id() const; + XRHitTestOptions* hitTestOptions() const; + + // Returns a vector of XRHitTestResults that were obtained during last frame + // update. This method is not exposed to JavaScript. + HeapVector<Member<XRHitTestResult>> Results(); + + void Update(const WTF::Vector<device::mojom::blink::XRHitResultPtr>& + hit_test_results); + + void Trace(blink::Visitor*) override; + + private: + const uint32_t id_; + + Member<XRHitTestOptions> options_; + + Vector<std::unique_ptr<TransformationMatrix>> last_frame_results_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source.cc b/chromium/third_party/blink/renderer/modules/xr/xr_input_source.cc index 47d2d2fdd6f..66154cdf7a8 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source.cc @@ -79,9 +79,8 @@ XRInputSource* XRInputSource::CreateOrUpdateFrom( updated_source->state_.target_ray_mode = desc->target_ray_mode; updated_source->state_.handedness = desc->handedness; - updated_source->state_.emulated_position = desc->emulated_position; - updated_source->pointer_transform_matrix_ = + updated_source->input_from_pointer_ = TryGetTransformationMatrix(desc->pointer_offset); updated_source->state_.profiles.clear(); @@ -90,7 +89,9 @@ XRInputSource* XRInputSource::CreateOrUpdateFrom( } } - updated_source->base_pose_matrix_ = TryGetTransformationMatrix(state->grip); + updated_source->mojo_from_input_ = TryGetTransformationMatrix(state->grip); + + updated_source->state_.emulated_position = state->emulated_position; return updated_source; } @@ -114,10 +115,10 @@ XRInputSource::XRInputSource(const XRInputSource& other) MakeGarbageCollected<XRTargetRaySpace>(other.session_, this)), grip_space_(MakeGarbageCollected<XRGripSpace>(other.session_, this)), gamepad_(other.gamepad_), - base_pose_matrix_( - TryGetTransformationMatrix(other.base_pose_matrix_.get())), - pointer_transform_matrix_( - TryGetTransformationMatrix(other.pointer_transform_matrix_.get())) {} + mojo_from_input_( + TryGetTransformationMatrix(other.mojo_from_input_.get())), + input_from_pointer_( + TryGetTransformationMatrix(other.input_from_pointer_.get())) {} const String XRInputSource::handedness() const { switch (state_.handedness) { @@ -186,10 +187,9 @@ bool XRInputSource::InvalidatesSameObject( return false; } -void XRInputSource::SetPointerTransformMatrix( - const TransformationMatrix* pointer_transform_matrix) { - pointer_transform_matrix_ = - TryGetTransformationMatrix(pointer_transform_matrix); +void XRInputSource::SetInputFromPointer( + const TransformationMatrix* input_from_pointer) { + input_from_pointer_ = TryGetTransformationMatrix(input_from_pointer); } void XRInputSource::SetGamepadConnected(bool state) { @@ -211,6 +211,10 @@ void XRInputSource::UpdateGamepad( } } +base::Optional<XRNativeOriginInformation> XRInputSource::nativeOrigin() const { + return XRNativeOriginInformation::Create(this); +} + void XRInputSource::OnSelectStart() { // Discard duplicate events and ones after the session has ended. if (state_.primary_input_pressed || session_->ended()) diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source.h b/chromium/third_party/blink/renderer/modules/xr/xr_input_source.h index 34a6cb76bf0..492043dcd6d 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source.h @@ -5,8 +5,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCE_H_ -#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/gamepad/gamepad.h" +#include "third_party/blink/renderer/modules/xr/xr_native_origin_information.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/transforms/transformation_matrix.h" @@ -59,7 +60,7 @@ class XRInputSource : public ScriptWrappable, public Gamepad::Client { uint32_t source_id() const { return state_.source_id; } - void SetPointerTransformMatrix(const TransformationMatrix*); + void SetInputFromPointer(const TransformationMatrix*); void SetGamepadConnected(bool state); // Gamepad::Client @@ -74,13 +75,15 @@ class XRInputSource : public ScriptWrappable, public Gamepad::Client { device::mojom::XRTargetRayMode TargetRayMode() const { return state_.target_ray_mode; } - const TransformationMatrix* BasePose() const { - return base_pose_matrix_.get(); + const TransformationMatrix* MojoFromInput() const { + return mojo_from_input_.get(); } - const TransformationMatrix* PointerTransform() const { - return pointer_transform_matrix_.get(); + const TransformationMatrix* InputFromPointer() const { + return input_from_pointer_.get(); } + base::Optional<XRNativeOriginInformation> nativeOrigin() const; + void OnSelectStart(); void OnSelectEnd(UserActivation user_activation); void OnSelect(); @@ -132,11 +135,14 @@ class XRInputSource : public ScriptWrappable, public Gamepad::Client { Member<XRGripSpace> grip_space_; Member<Gamepad> gamepad_; - std::unique_ptr<TransformationMatrix> base_pose_matrix_; + // Input device pose in mojo space. This is the grip pose for + // tracked controllers, and the viewer pose for screen input. + std::unique_ptr<TransformationMatrix> mojo_from_input_; - // This is the transform to apply to the base_pose_matrix_ to get the pointer - // matrix. In most cases it should be static. - std::unique_ptr<TransformationMatrix> pointer_transform_matrix_; + // Pointer pose in input device space, this is the transform to apply to + // mojo_from_input_ to get the pointer matrix. In most cases it should be + // static. + std::unique_ptr<TransformationMatrix> input_from_pointer_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source.idl b/chromium/third_party/blink/renderer/modules/xr/xr_input_source.idl index d1869d2fe85..78ee80c2c2c 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source.idl @@ -23,6 +23,6 @@ enum XRTargetRayMode { readonly attribute XRTargetRayMode targetRayMode; [SameObject] readonly attribute XRSpace targetRaySpace; [SameObject] readonly attribute XRSpace? gripSpace; - [SameObject, Measure] readonly attribute Gamepad? gamepad; + [SameObject, Measure, RuntimeEnabled=WebXrGamepadModule] readonly attribute Gamepad? gamepad; [SameObject, SaveSameObject] readonly attribute FrozenArray<DOMString> profiles; }; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.cc b/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.cc new file mode 100644 index 00000000000..f25edd1b6d1 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.cc @@ -0,0 +1,87 @@ +// 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. + +#include "third_party/blink/renderer/modules/xr/xr_native_origin_information.h" + +#include "third_party/blink/renderer/modules/xr/type_converters.h" +#include "third_party/blink/renderer/modules/xr/xr_anchor.h" +#include "third_party/blink/renderer/modules/xr/xr_input_source.h" +#include "third_party/blink/renderer/modules/xr/xr_plane.h" +#include "third_party/blink/renderer/modules/xr/xr_reference_space.h" + +namespace blink { + +base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create( + const XRAnchor* anchor) { + DCHECK(anchor); + return XRNativeOriginInformation(Type::Anchor, anchor->id()); +} + +base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create( + const XRInputSource* input_source) { + DCHECK(input_source); + return XRNativeOriginInformation(Type::InputSource, + input_source->source_id()); +} + +base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create( + const XRPlane* plane) { + DCHECK(plane); + return XRNativeOriginInformation(Type::Plane, plane->id()); +} + +base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create( + const XRReferenceSpace* reference_space) { + DCHECK(reference_space); + switch (reference_space->GetType()) { + case XRReferenceSpace::Type::kTypeBoundedFloor: + return XRNativeOriginInformation( + Type::ReferenceSpace, + device::mojom::XRReferenceSpaceCategory::BOUNDED_FLOOR); + case XRReferenceSpace::Type::kTypeUnbounded: + return XRNativeOriginInformation( + Type::ReferenceSpace, + device::mojom::XRReferenceSpaceCategory::UNBOUNDED); + case XRReferenceSpace::Type::kTypeLocalFloor: + return XRNativeOriginInformation( + Type::ReferenceSpace, + device::mojom::XRReferenceSpaceCategory::LOCAL_FLOOR); + case XRReferenceSpace::Type::kTypeLocal: + return XRNativeOriginInformation( + Type::ReferenceSpace, device::mojom::XRReferenceSpaceCategory::LOCAL); + case XRReferenceSpace::Type::kTypeViewer: + return XRNativeOriginInformation( + Type::ReferenceSpace, + device::mojom::XRReferenceSpaceCategory::VIEWER); + } +} + +XRNativeOriginInformation::XRNativeOriginInformation(Type type, uint32_t id) + : type_(type), id_(id) {} + +XRNativeOriginInformation::XRNativeOriginInformation( + Type type, + device::mojom::XRReferenceSpaceCategory reference_space_category) + : type_(type), reference_space_category_(reference_space_category) {} + +device::mojom::blink::XRNativeOriginInformationPtr +XRNativeOriginInformation::ToMojo() const { + switch (type_) { + case XRNativeOriginInformation::Type::Anchor: + return device::mojom::blink::XRNativeOriginInformation::NewAnchorId(id_); + + case XRNativeOriginInformation::Type::InputSource: + return device::mojom::blink::XRNativeOriginInformation::NewInputSourceId( + id_); + + case XRNativeOriginInformation::Type::Plane: + return device::mojom::blink::XRNativeOriginInformation::NewPlaneId(id_); + + case XRNativeOriginInformation::Type::ReferenceSpace: + return device::mojom::blink::XRNativeOriginInformation:: + NewReferenceSpaceCategory(reference_space_category_); + } +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.h b/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.h new file mode 100644 index 00000000000..e517126a5d8 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/xr/xr_native_origin_information.h @@ -0,0 +1,59 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_NATIVE_ORIGIN_INFORMATION_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_NATIVE_ORIGIN_INFORMATION_H_ + +#include <cstdint> + +#include "device/vr/public/mojom/vr_service.mojom-blink.h" + +namespace blink { + +class XRAnchor; +class XRInputSource; +class XRPlane; +class XRReferenceSpace; + +// XRNativeOriginInformation carries all the information that is required to +// uniquely identify a native origin on the device side. Native origin roughly +// represents anything that is known and tracked by the device, for example +// anchors, planes, input sources, reference spaces. +class XRNativeOriginInformation { + public: + XRNativeOriginInformation(XRNativeOriginInformation&& other) = default; + + device::mojom::blink::XRNativeOriginInformationPtr ToMojo() const; + + static base::Optional<XRNativeOriginInformation> Create( + const XRAnchor* anchor); + static base::Optional<XRNativeOriginInformation> Create( + const XRInputSource* input_source); + static base::Optional<XRNativeOriginInformation> Create(const XRPlane* plane); + static base::Optional<XRNativeOriginInformation> Create( + const XRReferenceSpace* reference_space); + + private: + enum class Type : int32_t { ReferenceSpace, InputSource, Anchor, Plane }; + + XRNativeOriginInformation() = delete; + XRNativeOriginInformation(const XRNativeOriginInformation& other) = delete; + void operator=(const XRNativeOriginInformation& other) = delete; + + XRNativeOriginInformation(Type type, uint32_t id); + XRNativeOriginInformation( + Type type, + device::mojom::XRReferenceSpaceCategory reference_space_type); + + const Type type_; + + const union { + uint32_t id_; + device::mojom::XRReferenceSpaceCategory reference_space_category_; + }; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_NATIVE_ORIGIN_INFORMATION_H_ diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_object_space.h b/chromium/third_party/blink/renderer/modules/xr/xr_object_space.h index 82992113d9b..a35b6894c01 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_object_space.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_object_space.h @@ -21,14 +21,18 @@ class XRObjectSpace : public XRSpace { explicit XRObjectSpace(XRSession* session, const T* object) : XRSpace(session), object_(object) {} - std::unique_ptr<TransformationMatrix> GetTransformToMojoSpace() override { - auto mojo_to_object = object_->poseMatrix(); + std::unique_ptr<TransformationMatrix> MojoFromSpace() override { + auto object_from_mojo = object_->poseMatrix(); - if (!mojo_to_object.IsInvertible()) { + if (!object_from_mojo.IsInvertible()) { return nullptr; } - return std::make_unique<TransformationMatrix>(mojo_to_object.Inverse()); + return std::make_unique<TransformationMatrix>(object_from_mojo.Inverse()); + } + + base::Optional<XRNativeOriginInformation> NativeOrigin() const override { + return XRNativeOriginInformation::Create(object_); } void Trace(blink::Visitor* visitor) override { diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane.cc b/chromium/third_party/blink/renderer/modules/xr/xr_plane.cc index ce7c5cb5398..e7cb010e658 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_plane.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane.cc @@ -13,7 +13,7 @@ namespace blink { -XRPlane::XRPlane(int32_t id, +XRPlane::XRPlane(uint32_t id, XRSession* session, const device::mojom::blink::XRPlaneDataPtr& plane_data, double timestamp) @@ -26,7 +26,7 @@ XRPlane::XRPlane(int32_t id, plane_data->polygon), timestamp) {} -XRPlane::XRPlane(int32_t id, +XRPlane::XRPlane(uint32_t id, XRSession* session, const base::Optional<Orientation>& orientation, const TransformationMatrix& pose_matrix, @@ -41,7 +41,7 @@ XRPlane::XRPlane(int32_t id, DVLOG(3) << __func__; } -int32_t XRPlane::id() const { +uint32_t XRPlane::id() const { return id_; } @@ -83,14 +83,10 @@ HeapVector<Member<DOMPointReadOnly>> XRPlane::polygon() const { ScriptPromise XRPlane::createAnchor(ScriptState* script_state, XRRigidTransform* initial_pose, - XRSpace* space) { - // TODO(https://crbug.com/992033): Implement anchor creation from a plane - // instead of rejecting the promise. This'll cause the string literal used - // below to be removed. - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - "Device does not support anchors!")); + XRSpace* space, + ExceptionState& exception_state) { + return session_->CreateAnchor(script_state, initial_pose, space, this, + exception_state); } void XRPlane::Update(const device::mojom::blink::XRPlaneDataPtr& plane_data, diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane.h b/chromium/third_party/blink/renderer/modules/xr/xr_plane.h index 1bde0499cd1..6d8c219b9d0 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_plane.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane.h @@ -8,7 +8,7 @@ #include <memory> #include "base/optional.h" -#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/geometry/dom_point_read_only.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" @@ -16,6 +16,7 @@ namespace blink { +class ExceptionState; class XRRigidTransform; class XRSession; class XRSpace; @@ -26,18 +27,18 @@ class XRPlane : public ScriptWrappable { public: enum Orientation { kHorizontal, kVertical }; - XRPlane(int32_t id, + XRPlane(uint32_t id, XRSession* session, const device::mojom::blink::XRPlaneDataPtr& plane_data, double timestamp); - XRPlane(int32_t id, + XRPlane(uint32_t id, XRSession* session, const base::Optional<Orientation>& orientation, const TransformationMatrix& pose_matrix, const HeapVector<Member<DOMPointReadOnly>>& polygon, double timestamp); - int32_t id() const; + uint32_t id() const; XRSpace* planeSpace() const; @@ -49,7 +50,8 @@ class XRPlane : public ScriptWrappable { ScriptPromise createAnchor(ScriptState* script_state, XRRigidTransform* initial_pose, - XRSpace* space); + XRSpace* space, + ExceptionState& exception_state); // Updates plane data from passed in |plane_data|. The resulting instance // should be equivalent to the instance that would be create by calling @@ -60,7 +62,7 @@ class XRPlane : public ScriptWrappable { void Trace(blink::Visitor* visitor) override; private: - const int32_t id_; + const uint32_t id_; HeapVector<Member<DOMPointReadOnly>> polygon_; base::Optional<Orientation> orientation_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane.idl b/chromium/third_party/blink/renderer/modules/xr/xr_plane.idl index 9528f82d4ac..2c2f6820fa4 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_plane.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane.idl @@ -20,5 +20,5 @@ interface XRPlane { readonly attribute XRPlaneOrientation? orientation; readonly attribute DOMHighResTimeStamp lastChangedTime; - [RuntimeEnabled=WebXRAnchors, CallWith=ScriptState] Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose, XRSpace space); + [RuntimeEnabled=WebXRAnchors, CallWith=ScriptState, RaisesException] Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose, XRSpace space); }; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc b/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc index 9e695382345..17139f4e613 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc @@ -13,13 +13,17 @@ #include "third_party/blink/renderer/modules/xr/xr_rigid_transform.h" #include "third_party/blink/renderer/modules/xr/xr_utils.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "ui/gfx/geometry/quaternion.h" #include "ui/gfx/geometry/vector3d_f.h" namespace blink { +XRRay::XRRay() { + origin_ = DOMPointReadOnly::Create(0.0, 0.0, 0.0, 1.0); + direction_ = DOMPointReadOnly::Create(0.0, 0.0, -1.0, 0.0); +} + XRRay::XRRay(const TransformationMatrix& matrix, ExceptionState& exception_state) { Set(matrix, exception_state); @@ -60,7 +64,8 @@ void XRRay::Set(const TransformationMatrix& matrix, } // Sets member variables from passed in |origin| and |direction|. -// All constructors eventually invoke this method. +// All constructors with the exception of default constructor eventually invoke +// this method. // If the |direction|'s length is 0, this method will initialize direction to // default vector (0, 0, -1). void XRRay::Set(FloatPoint3D origin, @@ -184,12 +189,25 @@ DOMFloat32Array* XRRay::matrix() { // onto translation (i.e. translation * rotation) in column-vector notation. // Step 8: Set ray’s internal matrix to matrix matrix_ = transformationMatrixToDOMFloat32Array(matrix); + if (!raw_matrix_) { + raw_matrix_ = std::make_unique<TransformationMatrix>(matrix); + } else { + *raw_matrix_ = matrix; + } } // Step 9: Return matrix return matrix_; } +TransformationMatrix XRRay::RawMatrix() { + matrix(); + + DCHECK(raw_matrix_); + + return *raw_matrix_; +} + void XRRay::Trace(blink::Visitor* visitor) { visitor->Trace(origin_); visitor->Trace(direction_); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_ray.h b/chromium/third_party/blink/renderer/modules/xr/xr_ray.h index 369fefe0b82..f76b7ac2566 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_ray.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_ray.h @@ -11,19 +11,20 @@ #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/geometry/float_point_3d.h" #include "third_party/blink/renderer/platform/heap/member.h" +#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" namespace blink { class DOMPointInit; class DOMPointReadOnly; class ExceptionState; -class TransformationMatrix; class XRRigidTransform; class XRRay final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: + XRRay(); explicit XRRay(const TransformationMatrix& matrix, ExceptionState& exception_state); explicit XRRay(XRRigidTransform* transform, ExceptionState& exception_state); @@ -36,6 +37,10 @@ class XRRay final : public ScriptWrappable { DOMPointReadOnly* direction() const { return direction_; } DOMFloat32Array* matrix(); + // Calling |RawMatrix()| is equivalent to calling |matrix()| w.r.t. the data + // that will be returned, the only difference is the returned type. + TransformationMatrix RawMatrix(); + static XRRay* Create(ExceptionState& exception_state); static XRRay* Create(DOMPointInit* origin, ExceptionState& exception_state); static XRRay* Create(DOMPointInit* origin, @@ -55,6 +60,7 @@ class XRRay final : public ScriptWrappable { Member<DOMPointReadOnly> origin_; Member<DOMPointReadOnly> direction_; Member<DOMFloat32Array> matrix_; + std::unique_ptr<TransformationMatrix> raw_matrix_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.cc b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.cc index d79de50e223..a4b669e7b13 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.cc @@ -48,54 +48,57 @@ XRReferenceSpace::~XRReferenceSpace() = default; XRPose* XRReferenceSpace::getPose( XRSpace* other_space, - const TransformationMatrix* base_pose_matrix) { + const TransformationMatrix* mojo_from_viewer) { if (type_ == Type::kTypeViewer) { - std::unique_ptr<TransformationMatrix> viewer_pose_matrix = - other_space->GetViewerPoseMatrix(base_pose_matrix); - if (!viewer_pose_matrix) { + std::unique_ptr<TransformationMatrix> other_offsetspace_from_viewer = + other_space->SpaceFromViewerWithDefaultAndOffset(mojo_from_viewer); + if (!other_offsetspace_from_viewer) { return nullptr; } - return MakeGarbageCollected<XRPose>(*viewer_pose_matrix, + + auto viewer_from_offset = OriginOffsetMatrix(); + + auto other_offsetspace_from_offset = + *other_offsetspace_from_viewer * viewer_from_offset; + + return MakeGarbageCollected<XRPose>(other_offsetspace_from_offset, session()->EmulatedPosition()); } else { - return XRSpace::getPose(other_space, base_pose_matrix); + return XRSpace::getPose(other_space, mojo_from_viewer); } } -void XRReferenceSpace::UpdateFloorLevelTransform() { +void XRReferenceSpace::SetFloorFromMojo() { const device::mojom::blink::VRDisplayInfoPtr& display_info = session()->GetVRDisplayInfo(); if (display_info && display_info->stage_parameters) { // Use the transform given by xrDisplayInfo's stage_parameters if available. - floor_level_transform_ = std::make_unique<TransformationMatrix>( + floor_from_mojo_ = std::make_unique<TransformationMatrix>( display_info->stage_parameters->standing_transform.matrix()); } else { // Otherwise, create a transform based on the default emulated height. - floor_level_transform_ = std::make_unique<TransformationMatrix>(); - floor_level_transform_->Translate3d(0, kDefaultEmulationHeightMeters, 0); + floor_from_mojo_ = std::make_unique<TransformationMatrix>(); + floor_from_mojo_->Translate3d(0, kDefaultEmulationHeightMeters, 0); } display_info_id_ = session()->DisplayInfoPtrId(); } -// Returns a default pose if no base pose is available. Only applicable to -// viewer reference spaces. -std::unique_ptr<TransformationMatrix> XRReferenceSpace::DefaultPose() { +// Returns a default viewer pose if no actual viewer pose is available. Only +// applicable to viewer reference spaces. +std::unique_ptr<TransformationMatrix> XRReferenceSpace::DefaultViewerPose() { // A viewer reference space always returns an identity matrix. return type_ == Type::kTypeViewer ? std::make_unique<TransformationMatrix>() : nullptr; } -// Transforms a given pose from a "base" reference space used by the XR -// service to the space represenced by this reference space. -std::unique_ptr<TransformationMatrix> XRReferenceSpace::TransformBasePose( - const TransformationMatrix& base_pose) { +std::unique_ptr<TransformationMatrix> XRReferenceSpace::SpaceFromMojo( + const TransformationMatrix& mojo_from_viewer) { switch (type_) { case Type::kTypeLocal: - // Currently all base poses are 'local' poses, so return directly. - return std::make_unique<TransformationMatrix>(base_pose); - break; + // Currently 'local' space is equivalent to mojo space. + return std::make_unique<TransformationMatrix>(); case Type::kTypeLocalFloor: // Currently all base poses are 'local' space, so use of 'local-floor' // reference spaces requires adjustment. Ideally the service will @@ -105,57 +108,77 @@ std::unique_ptr<TransformationMatrix> XRReferenceSpace::TransformBasePose( // Check first to see if the xrDisplayInfo has updated since the last // call. If so, update the floor-level transform. if (display_info_id_ != session()->DisplayInfoPtrId()) - UpdateFloorLevelTransform(); - - // Apply the floor-level transform to the base pose. - if (floor_level_transform_) { - auto pose = - std::make_unique<TransformationMatrix>(*floor_level_transform_); - pose->Multiply(base_pose); - return pose; - } - break; + SetFloorFromMojo(); + return std::make_unique<TransformationMatrix>(*floor_from_mojo_); case Type::kTypeViewer: - // Always return the default pose because we will only get here for an - // "viewer" reference space. - return DefaultPose(); + // Return viewer_from_mojo which is the inverse of mojo_from_viewer. + return std::make_unique<TransformationMatrix>(mojo_from_viewer.Inverse()); case Type::kTypeUnbounded: // For now we assume that poses returned by systems that support unbounded - // reference spaces are already in the correct space. - return std::make_unique<TransformationMatrix>(base_pose); + // reference spaces are already in the correct space. Return an identity. + return std::make_unique<TransformationMatrix>(); case Type::kTypeBoundedFloor: + NOTREACHED() << "kTypeBoundedFloor should be handled by subclass"; break; } return nullptr; } -// Serves the same purpose as TransformBasePose, but for input poses. Needs to -// know the head pose so that cases like the viewer frame of reference can -// properly adjust the input's relative position. -std::unique_ptr<TransformationMatrix> XRReferenceSpace::TransformBaseInputPose( - const TransformationMatrix& base_input_pose, - const TransformationMatrix& base_pose) { - return TransformBasePose(base_input_pose); +// Returns the refspace-from-viewerspace transform, corresponding to the pose of +// the viewer in this space. This takes the mojo_from_viewer transform (viewer +// pose in mojo space) as input, and left-multiplies space_from_mojo onto that. +std::unique_ptr<TransformationMatrix> XRReferenceSpace::SpaceFromViewer( + const TransformationMatrix& mojo_from_viewer) { + if (type_ == Type::kTypeViewer) { + // Special case for viewer space, always return an identity matrix + // explicitly. In theory the default behavior of multiplying SpaceFromMojo * + // MojoFromViewer would be equivalent, but that would likely return an + // almost-identity due to rounding errors. + return std::make_unique<TransformationMatrix>(); + } + + // Return space_from_viewer = space_from_mojo * mojo_from_viewer + auto space_from_viewer = SpaceFromMojo(mojo_from_viewer); + if (!space_from_viewer) + return nullptr; + space_from_viewer->Multiply(mojo_from_viewer); + return space_from_viewer; } -std::unique_ptr<TransformationMatrix> -XRReferenceSpace::GetTransformToMojoSpace() { +std::unique_ptr<TransformationMatrix> XRReferenceSpace::SpaceFromInputForViewer( + const TransformationMatrix& mojo_from_input, + const TransformationMatrix& mojo_from_viewer) { + // Return space_from_input = space_from_mojo * mojo_from_input + auto space_from_input = SpaceFromMojo(mojo_from_viewer); + if (!space_from_input) + return nullptr; + space_from_input->Multiply(mojo_from_input); + return space_from_input; +} + +std::unique_ptr<TransformationMatrix> XRReferenceSpace::MojoFromSpace() { // XRReferenceSpace doesn't do anything special with the base pose, but // derived reference spaces (bounded, unbounded, stationary, etc.) have their // own custom behavior. + + // Calculate the offset space's pose (including originOffset) in mojo + // space. TransformationMatrix identity; - std::unique_ptr<TransformationMatrix> transform_matrix = - TransformBasePose(identity); + std::unique_ptr<TransformationMatrix> mojo_from_offsetspace = + SpaceFromViewer(identity); - if (!transform_matrix) { + if (!mojo_from_offsetspace) { // Transform wasn't possible. return nullptr; } // Must account for position and orientation defined by origin offset. - transform_matrix->Multiply(origin_offset_->TransformMatrix()); - return transform_matrix; + // Result is mojo_from_offset = mojo_from_ref * ref_from_offset, + // where ref_from_offset is originOffset's transform matrix. + // TODO(https://crbug.com/1008466): move originOffset to separate class? + mojo_from_offsetspace->Multiply(origin_offset_->TransformMatrix()); + return mojo_from_offsetspace; } TransformationMatrix XRReferenceSpace::OriginOffsetMatrix() { @@ -166,6 +189,10 @@ TransformationMatrix XRReferenceSpace::InverseOriginOffsetMatrix() { return origin_offset_->InverseTransformMatrix(); } +XRReferenceSpace::Type XRReferenceSpace::GetType() const { + return type_; +} + XRReferenceSpace* XRReferenceSpace::getOffsetReferenceSpace( XRRigidTransform* additional_offset) { auto matrix = @@ -181,6 +208,11 @@ XRReferenceSpace* XRReferenceSpace::cloneWithOriginOffset( type_); } +base::Optional<XRNativeOriginInformation> XRReferenceSpace::NativeOrigin() + const { + return XRNativeOriginInformation::Create(this); +} + void XRReferenceSpace::Trace(blink::Visitor* visitor) { visitor->Trace(origin_offset_); XRSpace::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.h b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.h index c4e012b34b8..dd112382514 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space.h @@ -30,28 +30,36 @@ class XRReferenceSpace : public XRSpace { static Type StringToReferenceSpaceType(const String& reference_space_type); - XRReferenceSpace(XRSession*, Type); - XRReferenceSpace(XRSession*, XRRigidTransform*, Type); + XRReferenceSpace(XRSession* session, Type type); + XRReferenceSpace(XRSession* session, + XRRigidTransform* origin_offset, + Type type); ~XRReferenceSpace() override; XRPose* getPose(XRSpace* other_space, - const TransformationMatrix* base_pose_matrix) override; - std::unique_ptr<TransformationMatrix> DefaultPose() override; - std::unique_ptr<TransformationMatrix> TransformBasePose( - const TransformationMatrix& base_pose) override; - std::unique_ptr<TransformationMatrix> TransformBaseInputPose( - const TransformationMatrix& base_input_pose, - const TransformationMatrix& base_pose) override; - - std::unique_ptr<TransformationMatrix> GetTransformToMojoSpace() override; + const TransformationMatrix* mojo_from_viewer) override; + std::unique_ptr<TransformationMatrix> DefaultViewerPose() override; + std::unique_ptr<TransformationMatrix> SpaceFromMojo( + const TransformationMatrix& mojo_from_viewer) override; + std::unique_ptr<TransformationMatrix> SpaceFromViewer( + const TransformationMatrix& mojo_from_viewer) override; + std::unique_ptr<TransformationMatrix> SpaceFromInputForViewer( + const TransformationMatrix& mojo_from_input, + const TransformationMatrix& mojo_from_viewer) override; + + std::unique_ptr<TransformationMatrix> MojoFromSpace() override; TransformationMatrix OriginOffsetMatrix() override; TransformationMatrix InverseOriginOffsetMatrix() override; + Type GetType() const; + XRReferenceSpace* getOffsetReferenceSpace(XRRigidTransform* transform); DEFINE_ATTRIBUTE_EVENT_LISTENER(reset, kReset) + base::Optional<XRNativeOriginInformation> NativeOrigin() const override; + void Trace(blink::Visitor*) override; virtual void OnReset(); @@ -60,11 +68,11 @@ class XRReferenceSpace : public XRSpace { virtual XRReferenceSpace* cloneWithOriginOffset( XRRigidTransform* origin_offset); - void UpdateFloorLevelTransform(); + void SetFloorFromMojo(); unsigned int display_info_id_ = 0; - std::unique_ptr<TransformationMatrix> floor_level_transform_; + std::unique_ptr<TransformationMatrix> floor_from_mojo_; Member<XRRigidTransform> origin_offset_; Type type_; }; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session.cc b/chromium/third_party/blink/renderer/modules/xr/xr_session.cc index 54c599d12e9..514986217e2 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_session.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.cc @@ -7,6 +7,8 @@ #include <memory> #include <utility> +#include "third_party/blink/renderer/core/inspector/console_message.h" + #include "base/auto_reset.h" #include "base/metrics/histogram_macros.h" #include "services/metrics/public/cpp/ukm_builders.h" @@ -21,13 +23,17 @@ #include "third_party/blink/renderer/modules/event_target_modules.h" #include "third_party/blink/renderer/modules/screen_orientation/screen_orientation.h" #include "third_party/blink/renderer/modules/xr/xr.h" +#include "third_party/blink/renderer/modules/xr/xr_anchor_set.h" #include "third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h" #include "third_party/blink/renderer/modules/xr/xr_canvas_input_provider.h" #include "third_party/blink/renderer/modules/xr/xr_frame.h" #include "third_party/blink/renderer/modules/xr/xr_frame_provider.h" #include "third_party/blink/renderer/modules/xr/xr_hit_result.h" +#include "third_party/blink/renderer/modules/xr/xr_hit_test_options.h" +#include "third_party/blink/renderer/modules/xr/xr_hit_test_source.h" #include "third_party/blink/renderer/modules/xr/xr_input_source_event.h" #include "third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h" +#include "third_party/blink/renderer/modules/xr/xr_plane.h" #include "third_party/blink/renderer/modules/xr/xr_ray.h" #include "third_party/blink/renderer/modules/xr/xr_reference_space.h" #include "third_party/blink/renderer/modules/xr/xr_render_state.h" @@ -59,12 +65,28 @@ const char kInlineVerticalFOVNotSupported[] = const char kNoSpaceSpecified[] = "No XRSpace specified."; +const char kNoRigidTransformSpecified[] = "No XRRigidTransform specified."; + const char kHitTestNotSupported[] = "Device does not support hit-test!"; const char kAnchorsNotSupported[] = "Device does not support anchors!"; const char kDeviceDisconnected[] = "The XR device has been disconnected."; +const char kNonInvertibleMatrix[] = + "The operation encountered non-invertible matrix and could not be " + "completed."; + +const char kUnableToDecomposeMatrix[] = + "The operation was unable to decompose a matrix and could not be " + "completed."; + +const char kUnableToRetrieveNativeOrigin[] = + "The operation was unable to retrieve the native origin from XRSpace and " + "could not be completed."; + +const char kHitTestSubscriptionFailed[] = "Hit test subscription failed."; + const double kDegToRad = M_PI / 180.0; // Indices into the views array. @@ -135,7 +157,8 @@ class XRSession::XRSessionResizeObserverDelegate final XRSession::XRSession( XR* xr, - device::mojom::blink::XRSessionClientRequest client_request, + mojo::PendingReceiver<device::mojom::blink::XRSessionClient> + client_receiver, XRSession::SessionMode mode, EnvironmentBlendMode environment_blend_mode, bool uses_input_eventing, @@ -148,16 +171,15 @@ XRSession::XRSession( world_information_(MakeGarbageCollected<XRWorldInformation>(this)), enabled_features_(std::move(enabled_features)), input_sources_(MakeGarbageCollected<XRInputSourceArray>()), - client_binding_(this, std::move(client_request)), - input_binding_(this), + client_receiver_(this, std::move(client_receiver)), callback_collection_( MakeGarbageCollected<XRFrameRequestCallbackCollection>( xr_->GetExecutionContext())), uses_input_eventing_(uses_input_eventing), sensorless_session_(sensorless_session) { render_state_ = MakeGarbageCollected<XRRenderState>(immersive()); - blurred_ = !HasAppropriateFocus(); - visibility_state_string_ = HasAppropriateFocus() ? "visible" : "hidden"; + // Ensure that frame focus is considered in the initial visibilityState. + UpdateVisibilityState(); switch (environment_blend_mode) { case kBlendModeOpaque: @@ -175,6 +197,32 @@ XRSession::XRSession( } } +const String XRSession::visibilityState() const { + switch (visibility_state_) { + case XRVisibilityState::VISIBLE: + return "visible"; + case XRVisibilityState::VISIBLE_BLURRED: + return "visible-blurred"; + case XRVisibilityState::HIDDEN: + return "hidden"; + } +} + +XRAnchorSet* XRSession::trackedAnchors() const { + DVLOG(3) << __func__; + + HeapHashSet<Member<XRAnchor>> result; + + if (is_tracked_anchors_null_) + return nullptr; + + for (auto& anchor_id_and_anchor : anchor_ids_to_anchors_) { + result.insert(anchor_id_and_anchor.value); + } + + return MakeGarbageCollected<XRAnchorSet>(result); +} + bool XRSession::immersive() const { return mode_ == kModeImmersiveVR || mode_ == kModeImmersiveAR; } @@ -187,13 +235,10 @@ const AtomicString& XRSession::InterfaceName() const { return event_target_names::kXRSession; } -device::mojom::blink::XRInputSourceButtonListenerAssociatedPtrInfo +mojo::PendingAssociatedRemote<device::mojom::blink::XRInputSourceButtonListener> XRSession::GetInputClickListener() { - DCHECK(!input_binding_); - device::mojom::blink::XRInputSourceButtonListenerAssociatedPtrInfo - input_listener; - input_binding_.Bind(MakeRequest(&input_listener)); - return input_listener; + DCHECK(!input_receiver_.is_bound()); + return input_receiver_.BindNewEndpointAndPassRemote(); } void XRSession::updateRenderState(XRRenderStateInit* init, @@ -210,36 +255,20 @@ void XRSession::updateRenderState(XRRenderStateInit* init, return; } - if (init->hasBaseLayer() && init->baseLayer()) { - // Validate that any baseLayer provided was created with this session. - if (init->baseLayer()->session() != this) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - kIncompatibleLayer); - return; - } - - // If the baseLayer was previously null and there are outstanding rAF - // callbacks, kick off a new frame request to flush them out. - if (!render_state_->baseLayer() && !pending_frame_ && - !callback_collection_->IsEmpty()) { - // Kick off a request for a new XR frame. - xr_->frameProvider()->RequestFrame(this); - pending_frame_ = true; - } - - if (!immersive() && init->baseLayer()->output_canvas()) { - // If the output canvas was previously null and there are outstanding rAF - // callbacks, kick off a new frame request to flush them out. - if (!render_state_->output_canvas() && !pending_frame_ && - !callback_collection_->IsEmpty()) { - // Kick off a request for a new XR frame. - xr_->frameProvider()->RequestFrame(this); - pending_frame_ = true; - } - } + // Validate that any baseLayer provided was created with this session. + if (init->hasBaseLayer() && init->baseLayer() && + init->baseLayer()->session() != this) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kIncompatibleLayer); + return; } pending_render_state_.push_back(init); + + // Updating our render state may have caused us to be in a state where we + // should be requesting frames again. Kick off a new frame request in case + // there are any pending callbacks to flush them out. + MaybeRequestFrame(); } void XRSession::updateWorldTrackingState( @@ -273,12 +302,14 @@ void XRSession::UpdateStageParameters( SetXRDisplayInfo(std::move(display_info)); } -ScriptPromise XRSession::requestReferenceSpace(ScriptState* script_state, - const String& type) { +ScriptPromise XRSession::requestReferenceSpace( + ScriptState* script_state, + const String& type, + ExceptionState& exception_state) { if (ended_) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, kSessionEnded)); + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kSessionEnded); + return ScriptPromise(); } XRReferenceSpace::Type requested_type = @@ -289,10 +320,9 @@ ScriptPromise XRSession::requestReferenceSpace(ScriptState* script_state, if (sensorless_session_ && requested_type != XRReferenceSpace::Type::kTypeViewer) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - kReferenceSpaceNotSupported)); + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + kReferenceSpaceNotSupported); + return ScriptPromise(); } // If the session feature required by this reference space type is not @@ -300,10 +330,9 @@ ScriptPromise XRSession::requestReferenceSpace(ScriptState* script_state, auto type_as_feature = MapReferenceSpaceTypeToFeature(requested_type); if (!type_as_feature || !enabled_features_.Contains(type_as_feature.value())) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - kReferenceSpaceNotSupported)); + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + kReferenceSpaceNotSupported); + return ScriptPromise(); } XRReferenceSpace* reference_space = nullptr; @@ -341,10 +370,9 @@ ScriptPromise XRSession::requestReferenceSpace(ScriptState* script_state, // If the above switch statement failed to assign to reference_space, // it's because the reference space wasn't supported by the device. if (!reference_space) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - kReferenceSpaceNotSupported)); + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + kReferenceSpaceNotSupported); + return ScriptPromise(); } DCHECK(reference_space); @@ -360,29 +388,122 @@ ScriptPromise XRSession::requestReferenceSpace(ScriptState* script_state, return promise; } +ScriptPromise XRSession::CreateAnchor(ScriptState* script_state, + XRRigidTransform* initial_pose, + XRSpace* space, + XRPlane* plane, + ExceptionState& exception_state) { + if (ended_) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kSessionEnded); + return ScriptPromise(); + } + + if (!initial_pose) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kNoRigidTransformSpecified); + return ScriptPromise(); + } + + if (!space) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kNoSpaceSpecified); + return ScriptPromise(); + } + + // Reject the promise if device doesn't support the anchors API. + if (!xr_->xrEnvironmentProviderRemote()) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kAnchorsNotSupported); + return ScriptPromise(); + } + + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + + // Transformation from passed in |space| to mojo space. + std::unique_ptr<TransformationMatrix> mojo_from_space = + space->MojoFromSpace(); + + DVLOG(3) << __func__ + << ": mojo_from_space = " << mojo_from_space->ToString(true); + + // Matrix will be null if transformation from object space to mojo space is + // not invertible, log & bail out in that case. + if (!mojo_from_space || !mojo_from_space->IsInvertible()) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kNonInvertibleMatrix); + return ScriptPromise(); + } + + auto space_from_mojo = mojo_from_space->Inverse(); + + DVLOG(3) << __func__ + << ": space_from_mojo = " << space_from_mojo.ToString(true); + + // Transformation from passed in pose to |space|. + auto mojo_from_initial_pose = initial_pose->TransformMatrix(); + auto space_from_initial_pose = space_from_mojo * mojo_from_initial_pose; + + DVLOG(3) << __func__ << ": mojo_from_initial_pose = " + << mojo_from_initial_pose.ToString(true); + + DVLOG(3) << __func__ << ": space_from_initial_pose = " + << space_from_initial_pose.ToString(true); + + TransformationMatrix::DecomposedType decomposed; + if (!space_from_initial_pose.Decompose(decomposed)) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kUnableToDecomposeMatrix); + return ScriptPromise(); + } + + device::mojom::blink::VRPosePtr pose_ptr = + device::mojom::blink::VRPose::New(); + + pose_ptr->orientation = + gfx::Quaternion(-decomposed.quaternion_x, -decomposed.quaternion_y, + -decomposed.quaternion_z, decomposed.quaternion_w); + pose_ptr->position = blink::WebFloatPoint3D( + decomposed.translate_x, decomposed.translate_y, decomposed.translate_z); + + DVLOG(3) << __func__ + << ": pose_ptr->orientation = " << pose_ptr->orientation->ToString() + << ", pose_ptr->position = [" << pose_ptr->position->x << ", " + << pose_ptr->position->y << ", " << pose_ptr->position->z << "]"; + + if (plane) { + xr_->xrEnvironmentProviderRemote()->CreatePlaneAnchor( + std::move(pose_ptr), plane->id(), + WTF::Bind(&XRSession::OnCreateAnchorResult, WrapPersistent(this), + WrapPersistent(resolver))); + } else { + xr_->xrEnvironmentProviderRemote()->CreateAnchor( + std::move(pose_ptr), + WTF::Bind(&XRSession::OnCreateAnchorResult, WrapPersistent(this), + WrapPersistent(resolver))); + } + create_anchor_promises_.insert(resolver); + + return promise; +} + ScriptPromise XRSession::createAnchor(ScriptState* script_state, XRRigidTransform* initial_pose, - XRSpace* space) { - // TODO(https://crbug.com/992033): Implement anchor creation from a session - // instead of rejecting the promise. - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - kAnchorsNotSupported)); + XRSpace* space, + ExceptionState& exception_state) { + return CreateAnchor(script_state, initial_pose, space, nullptr, + exception_state); } int XRSession::requestAnimationFrame(V8XRFrameRequestCallback* callback) { - TRACE_EVENT0("gpu", __FUNCTION__); + TRACE_EVENT0("gpu", __func__); // Don't allow any new frame requests once the session is ended. if (ended_) return 0; int id = callback_collection_->RegisterCallback(callback); - if (!pending_frame_) { - // Kick off a request for a new XR frame. - xr_->frameProvider()->RequestFrame(this); - pending_frame_ = true; - } + MaybeRequestFrame(); return id; } @@ -404,25 +525,26 @@ XRInputSourceArray* XRSession::inputSources() const { ScriptPromise XRSession::requestHitTest(ScriptState* script_state, XRRay* ray, - XRSpace* space) { + XRSpace* space, + ExceptionState& exception_state) { + DVLOG(2) << __func__; + if (ended_) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, kSessionEnded)); + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kSessionEnded); + return ScriptPromise(); } if (!space) { - return ScriptPromise::Reject( - script_state, V8ThrowException::CreateTypeError( - script_state->GetIsolate(), kNoSpaceSpecified)); + exception_state.ThrowTypeError(kNoSpaceSpecified); + return ScriptPromise(); } // Reject the promise if device doesn't support the hit-test API. - if (!xr_->xrEnvironmentProviderPtr()) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - kHitTestNotSupported)); + if (!xr_->xrEnvironmentProviderRemote()) { + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + kHitTestNotSupported); + return ScriptPromise(); } device::mojom::blink::XRRayPtr ray_mojo = device::mojom::blink::XRRay::New(); @@ -436,8 +558,7 @@ ScriptPromise XRSession::requestHitTest(ScriptState* script_state, auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); - EnsureEnvironmentErrorHandler(); - xr_->xrEnvironmentProviderPtr()->RequestHitTest( + xr_->xrEnvironmentProviderRemote()->RequestHitTest( std::move(ray_mojo), WTF::Bind(&XRSession::OnHitTestResults, WrapPersistent(this), WrapPersistent(resolver))); @@ -446,11 +567,68 @@ ScriptPromise XRSession::requestHitTest(ScriptState* script_state, return promise; } -ScriptPromise XRSession::requestHitTestSource(ScriptState* script_state, - XRHitTestOptionsInit* options) { - return ScriptPromise::RejectWithDOMException( - script_state, - MakeGarbageCollected<DOMException>(DOMExceptionCode::kInvalidStateError)); +ScriptPromise XRSession::requestHitTestSource( + ScriptState* script_state, + XRHitTestOptionsInit* options_init, + ExceptionState& exception_state) { + DVLOG(2) << __func__; + + DCHECK(options_init); // is this enforced by generated bindings? + + XRHitTestOptions* options = + MakeGarbageCollected<XRHitTestOptions>(options_init); + + // 1. Grab the native origin from the passed in XRSpace. + base::Optional<XRNativeOriginInformation> maybe_native_origin = + options->space()->NativeOrigin(); + + if (!maybe_native_origin) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kUnableToRetrieveNativeOrigin); + return {}; + } + + // 2. Convert the XRRay to be expressed in terms of passed in XRSpace. This + // should only matter for spaces whose transforms are not fully known on the + // device (for example any space containing origin-offset). + TransformationMatrix origin_from_space = + options->space()->OriginOffsetMatrix(); + + DVLOG(3) << __func__ + << ": origin_from_space = " << origin_from_space.ToString(true); + + // Transformation from passed in pose to |space|. + auto space_from_ray = options->offsetRay()->RawMatrix(); + auto origin_from_ray = origin_from_space * space_from_ray; + + DVLOG(3) << __func__ + << ": space_from_ray = " << space_from_ray.ToString(true); + + DVLOG(3) << __func__ + << ": origin_from_ray = " << origin_from_ray.ToString(true); + + device::mojom::blink::XRRayPtr ray_mojo = device::mojom::blink::XRRay::New(); + + ray_mojo->origin = WebFloatPoint3D(origin_from_ray.MapPoint({0, 0, 0})); + + // Zero out the translation of origin_from_ray matrix to correctly map a 3D + // vector. + origin_from_ray.Translate3d(-origin_from_ray.M41(), -origin_from_ray.M42(), + -origin_from_ray.M43()); + + auto direction = origin_from_ray.MapPoint({0, 0, -1}); + ray_mojo->direction = {direction.X(), direction.Y(), direction.Z()}; + + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + + xr_->xrEnvironmentProviderRemote()->SubscribeToHitTest( + maybe_native_origin->ToMojo(), std::move(ray_mojo), + WTF::Bind(&XRSession::OnSubscribeToHitTestResult, WrapPersistent(this), + WrapPersistent(resolver), WrapPersistent(options))); + request_hit_test_source_promises_.insert(resolver); + + return promise; } void XRSession::OnHitTestResults( @@ -473,9 +651,54 @@ void XRSession::OnHitTestResults( resolver->Resolve(hit_results); } +void XRSession::OnSubscribeToHitTestResult( + ScriptPromiseResolver* resolver, + XRHitTestOptions* options, + device::mojom::SubscribeToHitTestResult result, + uint32_t subscription_id) { + DVLOG(2) << __func__ << ": result=" << result + << ", subscription_id=" << subscription_id; + + DCHECK(request_hit_test_source_promises_.Contains(resolver)); + request_hit_test_source_promises_.erase(resolver); + + if (result != device::mojom::SubscribeToHitTestResult::SUCCESS) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kOperationError, kHitTestSubscriptionFailed)); + return; + } + + XRHitTestSource* hit_test_source = + MakeGarbageCollected<XRHitTestSource>(subscription_id, options); + + hit_test_source_ids_to_hit_test_sources_.insert(subscription_id, + hit_test_source); + + resolver->Resolve(hit_test_source); +} + +void XRSession::OnCreateAnchorResult(ScriptPromiseResolver* resolver, + device::mojom::CreateAnchorResult result, + uint32_t id) { + DCHECK(create_anchor_promises_.Contains(resolver)); + create_anchor_promises_.erase(resolver); + + XRAnchor* anchor = MakeGarbageCollected<XRAnchor>(id, this); + + anchor_ids_to_anchors_.insert(id, anchor); + + resolver->Resolve(anchor); +} + +void XRSession::OnEnvironmentProviderCreated() { + EnsureEnvironmentErrorHandler(); +} + void XRSession::EnsureEnvironmentErrorHandler() { + // Install error handler on environment provider to ensure that we get + // notified so that we can clean up all relevant pending promises. if (!environment_error_handler_subscribed_ && - xr_->xrEnvironmentProviderPtr()) { + xr_->xrEnvironmentProviderRemote()) { environment_error_handler_subscribed_ = true; xr_->AddEnvironmentProviderErrorHandler(WTF::Bind( &XRSession::OnEnvironmentProviderError, WrapWeakPersistent(this))); @@ -489,14 +712,137 @@ void XRSession::OnEnvironmentProviderError() { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, kDeviceDisconnected)); } + + HeapHashSet<Member<ScriptPromiseResolver>> create_anchor_promises; + create_anchor_promises_.swap(create_anchor_promises); + for (ScriptPromiseResolver* resolver : create_anchor_promises) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, kDeviceDisconnected)); + } + + HeapHashSet<Member<ScriptPromiseResolver>> request_hit_test_source_promises; + request_hit_test_source_promises_.swap(request_hit_test_source_promises); + for (ScriptPromiseResolver* resolver : request_hit_test_source_promises) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, kDeviceDisconnected)); + } +} + +void XRSession::ProcessAnchorsData( + const device::mojom::blink::XRAnchorsDataPtr& tracked_anchors_data, + double timestamp) { + TRACE_EVENT0("xr", __func__); + + if (!tracked_anchors_data) { + DVLOG(3) << __func__ << ": tracked_anchors_data is null"; + + // We have received a null ptr. Mark tracked_anchors as null & clear stored + // anchors. + is_tracked_anchors_null_ = true; + anchor_ids_to_anchors_.clear(); + return; + } + + TRACE_COUNTER2("xr", "Anchor statistics", "All anchors", + tracked_anchors_data->all_anchors_ids.size(), + "Updated anchors", + tracked_anchors_data->updated_anchors_data.size()); + + DVLOG(3) << __func__ << ": updated anchors size=" + << tracked_anchors_data->updated_anchors_data.size() + << ", all anchors size=" + << tracked_anchors_data->all_anchors_ids.size(); + + is_tracked_anchors_null_ = false; + + HeapHashMap<uint32_t, Member<XRAnchor>> updated_anchors; + + // First, process all planes that had their information updated (new planes + // are also processed here). + for (const auto& anchor : tracked_anchors_data->updated_anchors_data) { + auto it = anchor_ids_to_anchors_.find(anchor->id); + if (it != anchor_ids_to_anchors_.end()) { + updated_anchors.insert(anchor->id, it->value); + it->value->Update(anchor, timestamp); + } else { + updated_anchors.insert( + anchor->id, + MakeGarbageCollected<XRAnchor>(anchor->id, this, anchor, timestamp)); + } + } + + // Then, copy over the planes that were not updated but are still present. + for (const auto& anchor_id : tracked_anchors_data->all_anchors_ids) { + auto it_updated = updated_anchors.find(anchor_id); + + // If the plane was already updated, there is nothing to do as it was + // already moved to |updated_anchors|. Otherwise just copy it over as-is. + if (it_updated == updated_anchors.end()) { + auto it = anchor_ids_to_anchors_.find(anchor_id); + DCHECK(it != anchor_ids_to_anchors_.end()); + updated_anchors.insert(anchor_id, it->value); + } + } + + anchor_ids_to_anchors_.swap(updated_anchors); +} + +void XRSession::CleanUpUnusedHitTestSources() { + // Gather all IDs of unused hit test sources. + HashSet<uint32_t> unused_hit_test_source_ids; + for (auto& subscription_id_and_hit_test_source : + hit_test_source_ids_to_hit_test_sources_) { + if (!subscription_id_and_hit_test_source.value) { + unused_hit_test_source_ids.insert( + subscription_id_and_hit_test_source.key); + } + } + + // Remove all of the unused hit test sources. + hit_test_source_ids_to_hit_test_sources_.RemoveAll( + unused_hit_test_source_ids); + + DVLOG(3) << __func__ << ": removed unused hit test sources, amount: " + << unused_hit_test_source_ids.size(); +} + +void XRSession::ProcessHitTestData( + const device::mojom::blink::XRHitTestSubscriptionResultsDataPtr& + hit_test_subscriptions_data) { + DVLOG(2) << __func__; + + CleanUpUnusedHitTestSources(); + + if (hit_test_subscriptions_data) { + // We have received hit test results for hit test subscriptions - process + // each result and notify its corresponding hit test source about new + // results for the current frame. + for (auto& hit_test_subscription_data : + hit_test_subscriptions_data->results) { + auto it = hit_test_source_ids_to_hit_test_sources_.find( + hit_test_subscription_data->subscription_id); + if (it != hit_test_source_ids_to_hit_test_sources_.end()) { + it->value->Update(hit_test_subscription_data->hit_test_results); + } + } + } else { + // We have not received hit test results for any of the hit test + // subscriptions in the current frame - clean up the results on all hit test + // source objects. + for (auto& subscription_id_and_hit_test_source : + hit_test_source_ids_to_hit_test_sources_) { + subscription_id_and_hit_test_source.value->Update({}); + } + } } -ScriptPromise XRSession::end(ScriptState* script_state) { +ScriptPromise XRSession::end(ScriptState* script_state, + ExceptionState& exception_state) { // Don't allow a session to end twice. if (ended_) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, kSessionEnded)); + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kSessionEnded); + return ScriptPromise(); } ForceEnd(); @@ -534,11 +880,8 @@ void XRSession::ForceEnd() { canvas_input_provider_ = nullptr; } - // If this session is the active immersive session, notify the frameProvider - // that it's ended. - if (xr_->frameProvider()->immersive_session() == this) { - xr_->frameProvider()->OnImmersiveSessionEnded(); - } + // Notify the frame provider that we've ended + xr_->frameProvider()->OnSessionEnded(this); DispatchEvent(*XRSessionEvent::Create(event_type_names::kEnd, this)); } @@ -581,38 +924,101 @@ DoubleSize XRSession::OutputCanvasSize() const { return DoubleSize(output_width_, output_height_); } -void XRSession::OnFocus() { - if (!blurred_) - return; +void XRSession::OnFocusChanged() { + UpdateVisibilityState(); +} + +void XRSession::OnVisibilityStateChanged(XRVisibilityState visibility_state) { + // TODO(crbug.com/1002742): Until some ambiguities in the spec are cleared up, + // force "visible-blurred" states from the device to report as "hidden" + if (visibility_state == XRVisibilityState::VISIBLE_BLURRED) { + visibility_state = XRVisibilityState::HIDDEN; + } - blurred_ = false; - visibility_state_string_ = "visible"; - DispatchEvent( - *XRSessionEvent::Create(event_type_names::kVisibilitychange, this)); + if (device_visibility_state_ != visibility_state) { + device_visibility_state_ = visibility_state; + UpdateVisibilityState(); + } } -void XRSession::OnBlur() { - if (blurred_) +// The ultimate visibility state of the session is a combination of the devices +// reported visibility state and, for inline sessions, the frame focus, which +// will override the device visibility to "hidden" if the frame is not currently +// focused. +void XRSession::UpdateVisibilityState() { + // Don't need to track the visibility state if the session has ended. + if (ended_) { return; + } - blurred_ = true; - visibility_state_string_ = "hidden"; - DispatchEvent( - *XRSessionEvent::Create(event_type_names::kVisibilitychange, this)); -} + XRVisibilityState state = device_visibility_state_; + + // The WebXR spec requires that if our document is not focused, that we don't + // hand out real poses. For immersive sessions, we have to rely on the device + // to tell us it's visibility state, as some runtimes (WMR) put focus in the + // headset, and thus we cannot rely on Document Focus state. This is fine + // because while the runtime reports us as focused the content owned by the + // session should be focued, which is owned by the document. For inline, we + // can and must rely on frame focus. + if (!immersive() && !xr_->IsFrameFocused()) { + state = XRVisibilityState::HIDDEN; + } + + if (visibility_state_ != state) { + visibility_state_ = state; + + // If the visibility state was changed to something other than hidden, we + // may be able to restart the frame loop. + MaybeRequestFrame(); -// Immersive sessions may still not be blurred in headset even if the page isn't -// focused. This prevents the in-headset experience from freezing on an -// external display headset when the user clicks on another tab. -bool XRSession::HasAppropriateFocus() { - return immersive() ? has_xr_focus_ : has_xr_focus_ && xr_->IsFrameFocused(); + DispatchEvent( + *XRSessionEvent::Create(event_type_names::kVisibilitychange, this)); + } } -void XRSession::OnFocusChanged() { - if (HasAppropriateFocus()) { - OnFocus(); - } else { - OnBlur(); +void XRSession::MaybeRequestFrame() { + bool will_have_base_layer = !!render_state_->baseLayer(); + for (const auto& init : pending_render_state_) { + if (init->hasBaseLayer()) { + will_have_base_layer = !!init->baseLayer(); + } + } + + // A page will not be allowed to get frames if its visibility state is hidden. + bool page_allowed_frames = visibility_state_ != XRVisibilityState::HIDDEN; + + // A page is configured properly if it will have a base layer when the frame + // callback gets resolved. + bool page_configured_properly = will_have_base_layer; + + // If we have an outstanding callback registered, then we know that the page + // actually wants frames. + bool page_wants_frame = !callback_collection_->IsEmpty(); + + // A page can process frames if it has its appropriate base layer set and has + // indicated that it actually wants frames. + bool page_can_process_frames = page_configured_properly && page_wants_frame; + + // We consider frames to be throttled if the page is not allowed frames, but + // otherwise would be able to receive them. Therefore, if the page isn't in a + // state to process frames, it doesn't matter if we are throttling it, any + // "stalls" should be attributed to the page being poorly behaved. + bool frames_throttled = page_can_process_frames && !page_allowed_frames; + + // If our throttled state has changed, notify anyone who may care + if (frames_throttled_ != frames_throttled) { + frames_throttled_ = frames_throttled; + xr_->SetFramesThrottled(this, frames_throttled_); + } + + // We can request a frame if we don't have one already pending, the page is + // allowed to request frames, and the page is set up to properly handle frames + // and wants one. + bool request_frame = + !pending_frame_ && page_allowed_frames && page_can_process_frames; + if (request_frame) { + xr_->frameProvider()->RequestFrame(this); + pending_frame_ = true; } } @@ -632,8 +1038,9 @@ void XRSession::DetachOutputCanvas(HTMLCanvasElement* canvas) { } void XRSession::ApplyPendingRenderState() { + DCHECK(!prev_base_layer_); if (pending_render_state_.size() > 0) { - XRWebGLLayer* prev_base_layer = render_state_->baseLayer(); + prev_base_layer_ = render_state_->baseLayer(); HTMLCanvasElement* prev_ouput_canvas = render_state_->output_canvas(); update_views_next_frame_ = true; @@ -646,7 +1053,7 @@ void XRSession::ApplyPendingRenderState() { // If this is an inline session and the base layer has changed, give it an // opportunity to update it's drawing buffer size. if (!immersive() && render_state_->baseLayer() && - render_state_->baseLayer() != prev_base_layer) { + render_state_->baseLayer() != prev_base_layer_) { render_state_->baseLayer()->OnResize(); } @@ -681,38 +1088,84 @@ void XRSession::ApplyPendingRenderState() { } } -void XRSession::OnFrame( +void XRSession::UpdatePresentationFrameState( double timestamp, - std::unique_ptr<TransformationMatrix> base_pose_matrix, - const base::Optional<gpu::MailboxHolder>& output_mailbox_holder, - const device::mojom::blink::XRPlaneDetectionDataPtr& detected_planes_data) { - TRACE_EVENT0("gpu", __FUNCTION__); - DVLOG(2) << __FUNCTION__; + std::unique_ptr<TransformationMatrix> mojo_from_viewer, + const device::mojom::blink::XRFrameDataPtr& frame_data, + bool emulated_position) { + TRACE_EVENT0("gpu", __func__); + DVLOG(2) << __func__ << " : frame_data valid? " + << (frame_data ? true : false); // Don't process any outstanding frames once the session is ended. if (ended_) return; - base_pose_matrix_ = std::move(base_pose_matrix); + mojo_from_viewer_ = std::move(mojo_from_viewer); + DVLOG(2) << __func__ << " : mojo_from_viewer_ valid? " + << (mojo_from_viewer_ ? true : false); + + emulated_position_ = emulated_position; + + // Update objects that might change on per-frame basis. + if (frame_data) { + world_information_->ProcessPlaneInformation( + frame_data->detected_planes_data, timestamp); + ProcessAnchorsData(frame_data->anchors_data, timestamp); + ProcessHitTestData(frame_data->hit_test_subscription_results); + } else { + world_information_->ProcessPlaneInformation(nullptr, timestamp); + ProcessAnchorsData(nullptr, timestamp); + ProcessHitTestData(nullptr); + } +} + +void XRSession::OnFrame( + double timestamp, + const base::Optional<gpu::MailboxHolder>& output_mailbox_holder) { + TRACE_EVENT0("gpu", __func__); + DVLOG(2) << __func__; + // Don't process any outstanding frames once the session is ended. + if (ended_) + return; // If there are pending render state changes, apply them now. + prev_base_layer_ = nullptr; ApplyPendingRenderState(); - world_information_->ProcessPlaneInformation(detected_planes_data, timestamp); - if (pending_frame_) { pending_frame_ = false; // Don't allow frames to be processed if there's no layers attached to the // session. That would allow tracking with no associated visuals. XRWebGLLayer* frame_base_layer = render_state_->baseLayer(); - if (!frame_base_layer) + if (!frame_base_layer) { + // If we previously had a frame base layer, we need to still attempt to + // submit a frame back to the runtime, as all "GetFrameData" calls need a + // matching submit. + if (prev_base_layer_) { + prev_base_layer_->OnFrameStart(output_mailbox_holder); + prev_base_layer_->OnFrameEnd(); + prev_base_layer_ = nullptr; + } return; + } // Don't allow frames to be processed if an inline session doesn't have an // output canvas. if (!immersive() && !render_state_->output_canvas()) return; + frame_base_layer->OnFrameStart(output_mailbox_holder); + + // Don't allow frames to be processed if the session's visibility state is + // "hidden". + if (visibility_state_ == XRVisibilityState::HIDDEN) { + // If the frame is skipped because of the visibility state, make sure we + // end the frame anyway. + frame_base_layer->OnFrameEnd(); + return; + } + XRFrame* presentation_frame = CreatePresentationFrame(); presentation_frame->SetAnimationFrame(true); @@ -722,8 +1175,6 @@ void XRSession::OnFrame( update_views_next_frame_ = false; } - frame_base_layer->OnFrameStart(output_mailbox_holder); - // Resolve the queued requestAnimationFrame callbacks. All XR rendering will // happen within these calls. resolving_frame_ will be true for the duration // of the callbacks. @@ -751,11 +1202,28 @@ void XRSession::LogGetPose() const { } } +bool XRSession::CanReportPoses() { + // The spec has a few requirements for if poses can be reported. + // If we have a session, then user intent is understood. Therefore, (due to + // the way visibility state is updatd), the rest of the steps really just + // boil down to whether or not the XRVisibilityState is Visible. + return visibility_state_ == XRVisibilityState::VISIBLE; +} + XRFrame* XRSession::CreatePresentationFrame() { + DVLOG(2) << __func__; + XRFrame* presentation_frame = MakeGarbageCollected<XRFrame>(this, world_information_); - if (base_pose_matrix_) { - presentation_frame->SetBasePoseMatrix(*base_pose_matrix_); + + // TODO(https://crbug.com/1004201): Determine if world_information_ should be + // treated similarly to mojo_from_viewer_. + if (mojo_from_viewer_ && visibility_state_ != XRVisibilityState::HIDDEN) { + DVLOG(2) << __func__ << " : mojo_from_viewer_ is set and not hidden," + << " updating presentation frame"; + + presentation_frame->SetMojoFromViewer(*mojo_from_viewer_, + EmulatedPosition()); } return presentation_frame; } @@ -781,7 +1249,7 @@ void XRSession::UpdateCanvasDimensions(Element* element) { if (orientation) { output_angle = orientation->angle(); - DVLOG(2) << __FUNCTION__ << ": got angle=" << output_angle; + DVLOG(2) << __func__ << ": got angle=" << output_angle; } if (render_state_->baseLayer()) { @@ -807,6 +1275,11 @@ void XRSession::OnInputStateChangeInternal( int16_t frame_id, base::span<const device::mojom::blink::XRInputSourceStatePtr> input_states, bool from_eventing) { + // If we're in any state other than visible, input should not be processed + if (visibility_state_ != XRVisibilityState::VISIBLE) { + return; + } + HeapVector<Member<XRInputSource>> added; HeapVector<Member<XRInputSource>> removed; last_frame_id_ = frame_id; @@ -921,6 +1394,21 @@ void XRSession::OnExitPresent() { } } +bool XRSession::ValidateHitTestSourceExists(XRHitTestSource* hit_test_source) { + auto it = + hit_test_source_ids_to_hit_test_sources_.find(hit_test_source->id()); + if (it == hit_test_source_ids_to_hit_test_sources_.end()) { + return false; + } + + if (!it->value) { + hit_test_source_ids_to_hit_test_sources_.erase(it); + return false; + } + + return true; +} + void XRSession::SetXRDisplayInfo( device::mojom::blink::VRDisplayInfoPtr display_info) { // We don't necessarily trust the backend to only send us display info changes @@ -1024,7 +1512,12 @@ void XRSession::Trace(blink::Visitor* visitor) { visitor->Trace(canvas_input_provider_); visitor->Trace(callback_collection_); visitor->Trace(hit_test_promises_); + visitor->Trace(create_anchor_promises_); + visitor->Trace(request_hit_test_source_promises_); visitor->Trace(reference_spaces_); + visitor->Trace(anchor_ids_to_anchors_); + visitor->Trace(prev_base_layer_); + visitor->Trace(hit_test_source_ids_to_hit_test_sources_); EventTargetWithInlineData::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session.h b/chromium/third_party/blink/renderer/modules/xr/xr_session.h index f7f1c9cfb69..30c9ca5b139 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_session.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.h @@ -7,8 +7,9 @@ #include "base/containers/span.h" #include "device/vr/public/mojom/vr_service.mojom-blink.h" -#include "mojo/public/cpp/bindings/associated_binding.h" -#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/associated_receiver.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h" @@ -33,9 +34,13 @@ class ResizeObserver; class ScriptPromiseResolver; class V8XRFrameRequestCallback; class XR; +class XRAnchor; class XRAnchorSet; class XRCanvasInputProvider; +class XRHitTestOptions; class XRHitTestOptionsInit; +class XRHitTestSource; +class XRPlane; class XRRay; class XRReferenceSpace; class XRRenderState; @@ -43,6 +48,7 @@ class XRRenderStateInit; class XRRigidTransform; class XRSpace; class XRViewData; +class XRWebGLLayer; class XRWorldInformation; class XRWorldTrackingState; class XRWorldTrackingStateInit; @@ -67,7 +73,8 @@ class XRSession final }; XRSession(XR* xr, - device::mojom::blink::XRSessionClientRequest client_request, + mojo::PendingReceiver<device::mojom::blink::XRSessionClient> + client_receiver, SessionMode mode, EnvironmentBlendMode environment_blend_mode, bool uses_input_eventing, @@ -77,11 +84,11 @@ class XRSession final XR* xr() const { return xr_; } const String& environmentBlendMode() const { return blend_mode_string_; } - const String& visibilityState() const { return visibility_state_string_; } + const String visibilityState() const; XRRenderState* renderState() const { return render_state_; } XRWorldTrackingState* worldTrackingState() { return world_tracking_state_; } XRSpace* viewerSpace() const; - XRAnchorSet* trackedAnchors() const { return nullptr; } + XRAnchorSet* trackedAnchors() const; bool immersive() const; @@ -98,11 +105,21 @@ class XRSession final XRWorldTrackingStateInit* world_tracking_state_init, ExceptionState& exception_state); ScriptPromise requestReferenceSpace(ScriptState* script_state, - const String& type); + const String& type, + ExceptionState&); + // IDL-exposed ScriptPromise createAnchor(ScriptState* script_state, XRRigidTransform* initial_pose, - XRSpace* space); + XRSpace* space, + ExceptionState& exception_state); + + // helper, not IDL-exposed + ScriptPromise CreateAnchor(ScriptState* script_state, + XRRigidTransform* pose, + XRSpace* space, + XRPlane* plane, + ExceptionState& exception_state); int requestAnimationFrame(V8XRFrameRequestCallback* callback); void cancelAnimationFrame(int id); @@ -110,14 +127,16 @@ class XRSession final XRInputSourceArray* inputSources() const; ScriptPromise requestHitTestSource(ScriptState* script_state, - XRHitTestOptionsInit* options); + XRHitTestOptionsInit* options, + ExceptionState& exception_state); ScriptPromise requestHitTest(ScriptState* script_state, XRRay* ray, - XRSpace* space); + XRSpace* space, + ExceptionState&); // Called by JavaScript to manually end the session. - ScriptPromise end(ScriptState* script_state); + ScriptPromise end(ScriptState* script_state, ExceptionState&); bool ended() const { return ended_; } @@ -146,10 +165,7 @@ class XRSession final void OnFocusChanged(); void OnFrame(double timestamp, - std::unique_ptr<TransformationMatrix> base_pose_matrix, - const base::Optional<gpu::MailboxHolder>& output_mailbox_holder, - const device::mojom::blink::XRPlaneDetectionDataPtr& - detected_planes_data); + const base::Optional<gpu::MailboxHolder>& output_mailbox_holder); void OnInputStateChange( int16_t frame_id, @@ -171,18 +187,18 @@ class XRSession final return display_info_; } - device::mojom::blink::XRInputSourceButtonListenerAssociatedPtrInfo + mojo::PendingAssociatedRemote< + device::mojom::blink::XRInputSourceButtonListener> GetInputClickListener(); - // TODO(crbug.com/969131): Update the mojom to deliver this per-frame. bool EmulatedPosition() const { - if (display_info_) { - return !display_info_->capabilities->has_position; - } - // If we don't have display info then we should be using the identity // reference space, which by definition will be emulating the position. - return true; + if (!display_info_) { + return true; + } + + return emulated_position_; } // Immersive sessions currently use two views for VR, and only a single view @@ -201,6 +217,10 @@ class XRSession final unsigned int DisplayInfoPtrId() const { return display_info_id_; } unsigned int StageParametersId() const { return stage_parameters_id_; } + // Returns true if the session recognizes passed in hit_test_source as still + // existing. + bool ValidateHitTestSourceExists(XRHitTestSource* hit_test_source); + void SetXRDisplayInfo(device::mojom::blink::VRDisplayInfoPtr display_info); bool UsesInputEventing() { return uses_input_eventing_; } @@ -210,14 +230,38 @@ class XRSession final // ScriptWrappable bool HasPendingActivity() const override; + bool CanReportPoses(); + + // Creates presentation frame based on current state of the session. + // State currently used in XRFrame creation is mojo_from_viewer_ and + // world_information_. The created XRFrame also stores a reference to this + // XRSession. XRFrame* CreatePresentationFrame(); + // Updates the internal XRSession state that is relevant to creating + // presentation frames. + void UpdatePresentationFrameState( + double timestamp, + std::unique_ptr<TransformationMatrix> mojo_from_viewer, + const device::mojom::blink::XRFrameDataPtr& frame_data, + bool emulated_position); + + // Notifies immersive session that the environment integration provider has + // been created by the session's XR instance, |xr_|. Gives a session an + // opportunity to register its own error handlers on environment integration + // provider endpoint. + void OnEnvironmentProviderCreated(); + private: class XRSessionResizeObserverDelegate; + using XRVisibilityState = device::mojom::blink::XRVisibilityState; + void UpdateCanvasDimensions(Element*); void ApplyPendingRenderState(); + void MaybeRequestFrame(); + void OnInputStateChangeInternal( int16_t frame_id, base::span<const device::mojom::blink::XRInputSourceStatePtr> @@ -227,23 +271,45 @@ class XRSession final // XRSessionClient void OnChanged(device::mojom::blink::VRDisplayInfoPtr display_info) override; void OnExitPresent() override; - void OnFocus() override; - void OnBlur() override; + void OnVisibilityStateChanged( + device::mojom::blink::XRVisibilityState visibility_state) override; - bool HasAppropriateFocus(); + void UpdateVisibilityState(); void OnHitTestResults( ScriptPromiseResolver* resolver, base::Optional<WTF::Vector<device::mojom::blink::XRHitResultPtr>> results); + void OnSubscribeToHitTestResult( + ScriptPromiseResolver* resolver, + XRHitTestOptions* options, + device::mojom::SubscribeToHitTestResult result, + uint32_t subscription_id); + + void OnCreateAnchorResult(ScriptPromiseResolver* resolver, + device::mojom::CreateAnchorResult result, + uint32_t id); + void EnsureEnvironmentErrorHandler(); void OnEnvironmentProviderError(); + void ProcessAnchorsData( + const device::mojom::blink::XRAnchorsDataPtr& tracked_anchors_data, + double timestamp); + + void CleanUpUnusedHitTestSources(); + + void ProcessHitTestData( + const device::mojom::blink::XRHitTestSubscriptionResultsDataPtr& + hit_test_data); + const Member<XR> xr_; const SessionMode mode_; const bool environment_integration_; String blend_mode_string_; + XRVisibilityState device_visibility_state_ = XRVisibilityState::VISIBLE; + XRVisibilityState visibility_state_ = XRVisibilityState::VISIBLE; String visibility_state_string_; Member<XRRenderState> render_state_; Member<XRWorldTrackingState> world_tracking_state_; @@ -251,34 +317,52 @@ class XRSession final HeapVector<Member<XRRenderStateInit>> pending_render_state_; XRSessionFeatureSet enabled_features_; + + bool is_tracked_anchors_null_ = true; + HeapHashMap<uint32_t, Member<XRAnchor>> anchor_ids_to_anchors_; + + // Mapping of hit test source ids (aka hit test subscription ids) to hit test + // sources. Hit test source has to be stored via weak member - JavaScript side + // will communicate that it's no longer interested in the subscription by + // dropping all its references to the hit test source & we need to make sure + // that we don't keep the XRHitTestSources alive. + HeapHashMap<uint32_t, WeakMember<XRHitTestSource>> + hit_test_source_ids_to_hit_test_sources_; + WTF::Vector<XRViewData> views_; Member<XRInputSourceArray> input_sources_; + Member<XRWebGLLayer> prev_base_layer_; Member<ResizeObserver> resize_observer_; Member<XRCanvasInputProvider> canvas_input_provider_; bool environment_error_handler_subscribed_ = false; HeapHashSet<Member<ScriptPromiseResolver>> hit_test_promises_; + // Set of promises returned from CreateAnchor that are still in-flight. + HeapHashSet<Member<ScriptPromiseResolver>> create_anchor_promises_; + // Set of promises returned from requestHitTestSource that are still + // in-flight. + HeapHashSet<Member<ScriptPromiseResolver>> request_hit_test_source_promises_; HeapVector<Member<XRReferenceSpace>> reference_spaces_; - bool has_xr_focus_ = true; bool is_external_ = false; unsigned int display_info_id_ = 0; unsigned int stage_parameters_id_ = 0; device::mojom::blink::VRDisplayInfoPtr display_info_; - mojo::Binding<device::mojom::blink::XRSessionClient> client_binding_; - mojo::AssociatedBinding<device::mojom::blink::XRInputSourceButtonListener> - input_binding_; + mojo::Receiver<device::mojom::blink::XRSessionClient> client_receiver_; + mojo::AssociatedReceiver<device::mojom::blink::XRInputSourceButtonListener> + input_receiver_{this}; Member<XRFrameRequestCallbackCollection> callback_collection_; - std::unique_ptr<TransformationMatrix> base_pose_matrix_; + // Viewer pose in mojo space. + std::unique_ptr<TransformationMatrix> mojo_from_viewer_; - bool blurred_; bool ended_ = false; bool pending_frame_ = false; bool resolving_frame_ = false; bool update_views_next_frame_ = false; bool views_dirty_ = true; + bool frames_throttled_ = false; // Indicates that we've already logged a metric, so don't need to log it // again. @@ -296,6 +380,8 @@ class XRSession final bool sensorless_session_ = false; int16_t last_frame_id_ = -1; + + bool emulated_position_ = false; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session.idl b/chromium/third_party/blink/renderer/modules/xr/xr_session.idl index 0266a596185..1afffcb72d3 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_session.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.idl @@ -42,21 +42,21 @@ enum XRVisibilityState { [RaisesException] void updateRenderState(optional XRRenderStateInit init); - [CallWith=ScriptState] Promise<XRReferenceSpace> requestReferenceSpace(XRReferenceSpaceType type); + [CallWith=ScriptState, RaisesException] Promise<XRReferenceSpace> requestReferenceSpace(XRReferenceSpaceType type); long requestAnimationFrame(XRFrameRequestCallback callback); void cancelAnimationFrame(long handle); - [RuntimeEnabled=WebXRHitTest, CallWith=ScriptState] Promise<FrozenArray<XRHitResult>> requestHitTest(XRRay ray, XRSpace space); + [RuntimeEnabled=WebXRHitTest, CallWith=ScriptState, RaisesException] Promise<FrozenArray<XRHitResult>> requestHitTest(XRRay ray, XRSpace space); // https://github.com/immersive-web/real-world-geometry/blob/master/plane-detection-explainer.md [RuntimeEnabled=WebXRPlaneDetection] readonly attribute XRWorldTrackingState worldTrackingState; [RuntimeEnabled=WebXRPlaneDetection, RaisesException] void updateWorldTrackingState(optional XRWorldTrackingStateInit state); [RuntimeEnabled=WebXRAnchors] readonly attribute XRAnchorSet trackedAnchors; - [RuntimeEnabled=WebXRAnchors, CallWith=ScriptState] Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose, XRSpace space); + [RuntimeEnabled=WebXRAnchors, CallWith=ScriptState, RaisesException] Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose, XRSpace space); - [CallWith=ScriptState, Measure] Promise<void> end(); + [CallWith=ScriptState, Measure, RaisesException] Promise<void> end(); - [RuntimeEnabled=WebXRHitTest, CallWith=ScriptState] Promise<XRHitTestSource> requestHitTestSource(XRHitTestOptionsInit options); + [RuntimeEnabled=WebXRHitTest, CallWith=ScriptState, RaisesException] Promise<XRHitTestSource> requestHitTestSource(XRHitTestOptionsInit options); }; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_space.cc b/chromium/third_party/blink/renderer/modules/xr/xr_space.cc index 252b8a09e9a..3908681c92d 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_space.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_space.cc @@ -16,24 +16,29 @@ XRSpace::XRSpace(XRSession* session) : session_(session) {} XRSpace::~XRSpace() = default; -std::unique_ptr<TransformationMatrix> XRSpace::GetTransformToMojoSpace() { +std::unique_ptr<TransformationMatrix> XRSpace::MojoFromSpace() { // The base XRSpace does not have any relevant information, so can't determine // a transform here. return nullptr; } -std::unique_ptr<TransformationMatrix> XRSpace::DefaultPose() { +std::unique_ptr<TransformationMatrix> XRSpace::DefaultViewerPose() { return nullptr; } -std::unique_ptr<TransformationMatrix> XRSpace::TransformBasePose( - const TransformationMatrix& base_pose) { +std::unique_ptr<TransformationMatrix> XRSpace::SpaceFromMojo( + const TransformationMatrix& mojo_from_viewer) { return nullptr; } -std::unique_ptr<TransformationMatrix> XRSpace::TransformBaseInputPose( - const TransformationMatrix& base_input_pose, - const TransformationMatrix& base_pose) { +std::unique_ptr<TransformationMatrix> XRSpace::SpaceFromViewer( + const TransformationMatrix& mojo_from_viewer) { + return nullptr; +} + +std::unique_ptr<TransformationMatrix> XRSpace::SpaceFromInputForViewer( + const TransformationMatrix& mojo_from_input, + const TransformationMatrix& mojo_from_viewer) { return nullptr; } @@ -49,18 +54,17 @@ TransformationMatrix XRSpace::InverseOriginOffsetMatrix() { XRPose* XRSpace::getPose(XRSpace* other_space, const TransformationMatrix* base_pose_matrix) { - std::unique_ptr<TransformationMatrix> mojo_from_this = - GetTransformToMojoSpace(); - if (!mojo_from_this) { + std::unique_ptr<TransformationMatrix> mojo_from_space = MojoFromSpace(); + if (!mojo_from_space) { return nullptr; } // Rigid transforms should always be invertible. - DCHECK(mojo_from_this->IsInvertible()); - TransformationMatrix this_from_mojo = mojo_from_this->Inverse(); + DCHECK(mojo_from_space->IsInvertible()); + TransformationMatrix space_from_mojo = mojo_from_space->Inverse(); std::unique_ptr<TransformationMatrix> mojo_from_other = - other_space->GetTransformToMojoSpace(); + other_space->MojoFromSpace(); if (!mojo_from_other) { return nullptr; } @@ -68,33 +72,38 @@ XRPose* XRSpace::getPose(XRSpace* other_space, // TODO(crbug.com/969133): Update how EmulatedPosition is determined here once // spec issue https://github.com/immersive-web/webxr/issues/534 has been // resolved. - TransformationMatrix this_from_other = - this_from_mojo.Multiply(*mojo_from_other); - return MakeGarbageCollected<XRPose>(this_from_other, + TransformationMatrix space_from_other = + space_from_mojo.Multiply(*mojo_from_other); + return MakeGarbageCollected<XRPose>(space_from_other, session()->EmulatedPosition()); } -std::unique_ptr<TransformationMatrix> XRSpace::GetViewerPoseMatrix( - const TransformationMatrix* base_pose_matrix) { - std::unique_ptr<TransformationMatrix> pose; +std::unique_ptr<TransformationMatrix> +XRSpace::SpaceFromViewerWithDefaultAndOffset( + const TransformationMatrix* mojo_from_viewer) { + std::unique_ptr<TransformationMatrix> space_from_viewer; // If we don't have a valid base pose, request the reference space's default - // pose. Most common when tracking is lost. - if (base_pose_matrix) { - pose = TransformBasePose(*base_pose_matrix); + // viewer pose. Most common when tracking is lost. + if (mojo_from_viewer) { + space_from_viewer = SpaceFromViewer(*mojo_from_viewer); } else { - pose = DefaultPose(); + space_from_viewer = DefaultViewerPose(); } // Can only update an XRViewerPose's views with an invertible matrix. - if (!pose || !pose->IsInvertible()) { + if (!space_from_viewer || !space_from_viewer->IsInvertible()) { return nullptr; } // Account for any changes made to the reference space's origin offset so that // things like teleportation works. + // + // This is offset_from_viewer = offset_from_space * space_from_viewer, + // where offset_from_viewer = inverse(viewer_from_offset). + // TODO(https://crbug.com/1008466): move originOffset to separate class? return std::make_unique<TransformationMatrix>( - InverseOriginOffsetMatrix().Multiply(*pose)); + InverseOriginOffsetMatrix().Multiply(*space_from_viewer)); } ExecutionContext* XRSpace::GetExecutionContext() const { @@ -105,6 +114,10 @@ const AtomicString& XRSpace::InterfaceName() const { return event_target_names::kXRSpace; } +base::Optional<XRNativeOriginInformation> XRSpace::NativeOrigin() const { + return base::nullopt; +} + void XRSpace::Trace(blink::Visitor* visitor) { visitor->Trace(session_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_space.h b/chromium/third_party/blink/renderer/modules/xr/xr_space.h index c2c832df04e..1ea887c709e 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_space.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_space.h @@ -9,6 +9,7 @@ #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" +#include "third_party/blink/renderer/modules/xr/xr_native_origin_information.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/transforms/transformation_matrix.h" @@ -24,26 +25,51 @@ class XRSession; class XRSpace : public EventTargetWithInlineData { DEFINE_WRAPPERTYPEINFO(); + protected: + explicit XRSpace(XRSession* session); + public: - explicit XRSpace(XRSession*); ~XRSpace() override; - // Get a transform that maps from this space to mojo space. - // Returns nullptr if computing a transform is not possible. - virtual std::unique_ptr<TransformationMatrix> GetTransformToMojoSpace(); - - virtual std::unique_ptr<TransformationMatrix> DefaultPose(); - virtual std::unique_ptr<TransformationMatrix> TransformBasePose( - const TransformationMatrix& base_pose); - virtual std::unique_ptr<TransformationMatrix> TransformBaseInputPose( - const TransformationMatrix& base_input_pose, - const TransformationMatrix& base_pose); + // Gets a default viewer pose appropriate for this space. This is an identity + // for viewer space, null for everything else. + virtual std::unique_ptr<TransformationMatrix> DefaultViewerPose(); + + // Gets the pose of this space's origin in mojo space. This is a transform + // that maps from this space to mojo space (aka device space). Unless noted + // otherwise, all data returned over vr_service.mojom interfaces is expressed + // in mojo space coordinates. Returns nullptr if computing a transform is not + // possible. + virtual std::unique_ptr<TransformationMatrix> MojoFromSpace(); + + // Gets the pose of the mojo origin in this reference space, corresponding + // to a transform from mojo coordinates to reference space coordinates. + virtual std::unique_ptr<TransformationMatrix> SpaceFromMojo( + const TransformationMatrix& mojo_from_viewer); + + // Gets the viewer pose in this space, corresponding to a transform from + // viewer coordinates to this space's coordinates. (The position elements of + // the transformation matrix are the viewer's location in this space's + // coordinates.) + virtual std::unique_ptr<TransformationMatrix> SpaceFromViewer( + const TransformationMatrix& mojo_from_viewer); + + // Gets an input pose in this space. This requires the viewer pose as + // an additional input since a "viewer" space needs to transform the + // input pose to headset-relative coordinates. + virtual std::unique_ptr<TransformationMatrix> SpaceFromInputForViewer( + const TransformationMatrix& mojo_from_input, + const TransformationMatrix& mojo_from_viewer); virtual XRPose* getPose(XRSpace* other_space, - const TransformationMatrix* base_pose_matrix); + const TransformationMatrix* mojo_from_viewer); - std::unique_ptr<TransformationMatrix> GetViewerPoseMatrix( - const TransformationMatrix* base_pose_matrix); + // Gets the viewer pose in this space, including using an appropriate + // default pose (i.e. if tracking is lost), and applying originOffset + // as applicable. TODO(https://crbug.com/1008466): consider moving + // the originOffset handling to a separate class? + std::unique_ptr<TransformationMatrix> SpaceFromViewerWithDefaultAndOffset( + const TransformationMatrix* mojo_from_viewer); XRSession* session() const { return session_; } @@ -51,10 +77,13 @@ class XRSpace : public EventTargetWithInlineData { ExecutionContext* GetExecutionContext() const override; const AtomicString& InterfaceName() const override; + // Return origin offset matrix, aka native_origin_from_offset_space. virtual TransformationMatrix OriginOffsetMatrix(); virtual TransformationMatrix InverseOriginOffsetMatrix(); - void Trace(blink::Visitor*) override; + virtual base::Optional<XRNativeOriginInformation> NativeOrigin() const = 0; + + void Trace(blink::Visitor* visitor) override; private: const Member<XRSession> session_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc b/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc index c023be67e18..90eedcfd54b 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.cc @@ -14,92 +14,104 @@ namespace blink { XRTargetRaySpace::XRTargetRaySpace(XRSession* session, XRInputSource* source) : XRSpace(session), input_source_(source) {} -std::unique_ptr<TransformationMatrix> XRTargetRaySpace::GetPointerPoseForScreen( +std::unique_ptr<TransformationMatrix> XRTargetRaySpace::OtherSpaceFromScreenTap( XRSpace* other_space, - const TransformationMatrix& base_pose_matrix) { - // If the pointer origin is the screen we need the head's base pose and - // the pointer transform matrix to continue. The pointer transform will - // represent the point the canvas was clicked as an offset from the view. - if (!input_source_->PointerTransform()) { + const TransformationMatrix& mojo_from_viewer) { + // If the pointer origin is the screen, the input space is viewer space, and + // we need the head's viewer pose and the pointer pose in continue. The + // pointer transform will represent the point the canvas was clicked as an + // offset from the view. + if (!input_source_->InputFromPointer()) { return nullptr; } - // Multiply the head pose and pointer transform to get the final pointer. - std::unique_ptr<TransformationMatrix> pointer_pose = - other_space->TransformBasePose(base_pose_matrix); - if (!pointer_pose) { + // other_from_pointer = other_from_input * input_from_pointer, + // where input space is equivalent to viewer space for screen taps. + std::unique_ptr<TransformationMatrix> other_from_pointer = + other_space->SpaceFromViewer(mojo_from_viewer); + if (!other_from_pointer) { return nullptr; } - - pointer_pose->Multiply(*(input_source_->PointerTransform())); - return pointer_pose; + other_from_pointer->Multiply(*(input_source_->InputFromPointer())); + return other_from_pointer; } -std::unique_ptr<TransformationMatrix> XRTargetRaySpace::GetTrackedPointerPose( +std::unique_ptr<TransformationMatrix> +XRTargetRaySpace::OtherSpaceFromTrackedPointer( XRSpace* other_space, - const TransformationMatrix& base_pose_matrix) { - if (!input_source_->BasePose()) { + const TransformationMatrix& mojo_from_viewer) { + if (!input_source_->MojoFromInput()) { return nullptr; } - std::unique_ptr<TransformationMatrix> grip_pose = - other_space->TransformBaseInputPose(*(input_source_->BasePose()), - base_pose_matrix); + // Calculate other_from_pointer = other_from_input * input_from_pointer + std::unique_ptr<TransformationMatrix> other_from_pointer = + other_space->SpaceFromInputForViewer(*(input_source_->MojoFromInput()), + mojo_from_viewer); - if (!grip_pose) { + if (!other_from_pointer) { return nullptr; } - - if (input_source_->PointerTransform()) { - grip_pose->Multiply(*(input_source_->PointerTransform())); + if (input_source_->InputFromPointer()) { + other_from_pointer->Multiply(*(input_source_->InputFromPointer())); } - - return grip_pose; + return other_from_pointer; } XRPose* XRTargetRaySpace::getPose( XRSpace* other_space, - const TransformationMatrix* base_pose_matrix) { + const TransformationMatrix* mojo_from_viewer) { // If we don't have a valid base pose (most common when tracking is lost), // we can't get a target ray pose regardless of the mode. - if (!base_pose_matrix) { + if (!mojo_from_viewer) { + DVLOG(2) << __func__ << " : mojo_from_viewer is null, returning nullptr"; return nullptr; } - std::unique_ptr<TransformationMatrix> pointer_pose = nullptr; + std::unique_ptr<TransformationMatrix> other_from_ray = nullptr; switch (input_source_->TargetRayMode()) { case device::mojom::XRTargetRayMode::TAPPING: { - pointer_pose = GetPointerPoseForScreen(other_space, *base_pose_matrix); + other_from_ray = OtherSpaceFromScreenTap(other_space, *mojo_from_viewer); break; } case device::mojom::XRTargetRayMode::GAZING: { // If the pointer origin is the users head, this is a gaze cursor and the // returned pointer is based on the device pose. Just return the head pose // as the pointer pose. - pointer_pose = other_space->TransformBasePose(*base_pose_matrix); + other_from_ray = other_space->SpaceFromViewer(*mojo_from_viewer); break; } case device::mojom::XRTargetRayMode::POINTING: { - pointer_pose = GetTrackedPointerPose(other_space, *base_pose_matrix); + other_from_ray = + OtherSpaceFromTrackedPointer(other_space, *mojo_from_viewer); break; } - default: { - return nullptr; - } } - if (!pointer_pose) { + if (!other_from_ray) { + DVLOG(2) << __func__ << " : " + << "other_from_ray is null, input_source_->TargetRayMode() = " + << input_source_->TargetRayMode(); return nullptr; } // Account for any changes made to the reference space's origin offset so that // things like teleportation works. - TransformationMatrix adjusted_pose = - other_space->InverseOriginOffsetMatrix().Multiply(*pointer_pose); - return MakeGarbageCollected<XRPose>(adjusted_pose, + // + // otheroffset_from_ray = otheroffset_from_other * other_from_ray + // where otheroffset_from_other = inverse(other_from_otheroffset) + // TODO(https://crbug.com/1008466): move originOffset to separate class? + TransformationMatrix otheroffset_from_ray = + other_space->InverseOriginOffsetMatrix().Multiply(*other_from_ray); + return MakeGarbageCollected<XRPose>(otheroffset_from_ray, input_source_->emulatedPosition()); } +base::Optional<XRNativeOriginInformation> XRTargetRaySpace::NativeOrigin() + const { + return input_source_->nativeOrigin(); +} + void XRTargetRaySpace::Trace(blink::Visitor* visitor) { visitor->Trace(input_source_); XRSpace::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.h b/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.h index bf7c704ddf9..8df09c58c8a 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_target_ray_space.h @@ -13,19 +13,21 @@ namespace blink { class XRTargetRaySpace : public XRSpace { public: - XRTargetRaySpace(XRSession*, XRInputSource*); + XRTargetRaySpace(XRSession* session, XRInputSource* input_space); XRPose* getPose(XRSpace* other_space, const TransformationMatrix* base_pose_matrix) override; + base::Optional<XRNativeOriginInformation> NativeOrigin() const override; + void Trace(blink::Visitor*) override; private: - std::unique_ptr<TransformationMatrix> GetPointerPoseForScreen( + std::unique_ptr<TransformationMatrix> OtherSpaceFromScreenTap( XRSpace* other_space, - const TransformationMatrix& base_pose_matrix); - std::unique_ptr<TransformationMatrix> GetTrackedPointerPose( + const TransformationMatrix& mojo_from_viewer); + std::unique_ptr<TransformationMatrix> OtherSpaceFromTrackedPointer( XRSpace* other_space, - const TransformationMatrix& base_pose_matrix); + const TransformationMatrix& mojo_from_viewer); Member<XRInputSource> input_source_; }; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_information.cc b/chromium/third_party/blink/renderer/modules/xr/xr_world_information.cc index 0feed185dab..6af75714927 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_world_information.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_information.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/xr/xr_world_information.h" +#include "base/trace_event/trace_event.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" namespace blink { @@ -58,7 +59,7 @@ void XRWorldInformation::ProcessPlaneInformation( is_detected_planes_null_ = false; - HeapHashMap<int32_t, Member<XRPlane>> updated_planes; + HeapHashMap<uint32_t, Member<XRPlane>> updated_planes; // First, process all planes that had their information updated (new planes // are also processed here). diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_information.h b/chromium/third_party/blink/renderer/modules/xr/xr_world_information.h index 6f6e8167355..bd03a3a3f72 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_world_information.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_information.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_WORLD_INFORMATION_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_WORLD_INFORMATION_H_ -#include "device/vr/public/mojom/vr_service.mojom-blink.h" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" #include "third_party/blink/renderer/modules/xr/xr_plane.h" #include "third_party/blink/renderer/modules/xr/xr_plane_set.h" @@ -37,7 +37,7 @@ class XRWorldInformation : public ScriptWrappable { // This is the case if we have a freshly constructed instance, or if our // last `ProcessPlaneInformation()` was called with base::nullopt. bool is_detected_planes_null_ = true; - HeapHashMap<int32_t, Member<XRPlane>> plane_ids_to_planes_; + HeapHashMap<uint32_t, Member<XRPlane>> plane_ids_to_planes_; Member<XRSession> session_; }; |