diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/modules')
1591 files changed, 17402 insertions, 9581 deletions
diff --git a/chromium/third_party/blink/renderer/modules/BUILD.gn b/chromium/third_party/blink/renderer/modules/BUILD.gn index a7770de23ac..0f08d60394f 100644 --- a/chromium/third_party/blink/renderer/modules/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/BUILD.gn @@ -124,6 +124,7 @@ jumbo_component("modules") { "//third_party/blink/renderer/modules/nfc", "//third_party/blink/renderer/modules/notifications", "//third_party/blink/renderer/modules/payments", + "//third_party/blink/renderer/modules/payments/goods", "//third_party/blink/renderer/modules/peerconnection", "//third_party/blink/renderer/modules/permissions", "//third_party/blink/renderer/modules/picture_in_picture", @@ -214,6 +215,8 @@ jumbo_source_set("modules_testing") { "peerconnection/adapters/test/mock_p2p_quic_transport.h", "peerconnection/adapters/test/mock_p2p_quic_transport_delegate.h", "peerconnection/adapters/test/mock_p2p_quic_transport_factory.h", + "peerconnection/testing/fake_resource_listener.cc", + "peerconnection/testing/fake_resource_listener.h", "peerconnection/testing/internals_rtc_certificate.cc", "peerconnection/testing/internals_rtc_certificate.h", "peerconnection/testing/internals_rtc_peer_connection.cc", @@ -285,6 +288,7 @@ jumbo_source_set("unit_tests") { "csspaint/paint_worklet_global_scope_test.cc", "csspaint/paint_worklet_proxy_client_test.cc", "csspaint/paint_worklet_test.cc", + "delegated_ink/delegated_ink_trail_presenter_unittest.cc", "device_orientation/device_motion_event_pump_unittest.cc", "device_orientation/device_orientation_event_pump_unittest.cc", "document_metadata/document_metadata_extractor_test.cc", @@ -362,11 +366,13 @@ jumbo_source_set("unit_tests") { "payments/abort_test.cc", "payments/can_make_payment_test.cc", "payments/complete_test.cc", + "payments/goods/digital_goods_type_converters_unittest.cc", "payments/merchant_validation_event_test.cc", "payments/on_payment_response_test.cc", "payments/payment_address_test.cc", "payments/payment_event_data_conversion_test.cc", "payments/payment_request_details_test.cc", + "payments/payment_request_optional_total_test.cc", "payments/payment_request_test.cc", "payments/payment_request_update_event_test.cc", "payments/payment_response_test.cc", @@ -399,6 +405,8 @@ jumbo_source_set("unit_tests") { "peerconnection/rtc_rtp_sender_impl_test.cc", "peerconnection/rtc_rtp_transceiver_impl_test.cc", "peerconnection/rtc_sctp_transport_test.cc", + "peerconnection/thermal_resource_test.cc", + "peerconnection/thermal_uma_listener_test.cc", "peerconnection/transceiver_state_surfacer_test.cc", "peerconnection/webrtc_audio_renderer_test.cc", "peerconnection/webrtc_media_stream_track_adapter_map_test.cc", diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h index 8230d0ba787..559d483645f 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_enums.h @@ -100,6 +100,7 @@ enum AXTextFromNativeHTML { enum AXIgnoredReason { kAXActiveModalDialog, + kAXAriaModalDialog, kAXAncestorIsLeafNode, kAXAriaHiddenElement, kAXAriaHiddenSubtree, diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc index bd5132becee..6889176407f 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.cc @@ -126,7 +126,7 @@ bool AXImageMapLink::IsImageMapLink() const { return true; } -void AXImageMapLink::Trace(Visitor* visitor) { +void AXImageMapLink::Trace(Visitor* visitor) const { AXNodeObject::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h index 692d98752ab..b3775a45bad 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_image_map_link.h @@ -42,7 +42,7 @@ class AXImageMapLink final : public AXNodeObject { public: explicit AXImageMapLink(HTMLAreaElement*, AXObjectCacheImpl&); ~AXImageMapLink() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; HTMLAreaElement* AreaElement() const { return To<HTMLAreaElement>(GetNode()); 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 ddda0ab1c38..0c65443bcd6 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 @@ -32,7 +32,6 @@ #include <memory> #include <string> -#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h" #include "third_party/blink/renderer/core/aom/accessible_node.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/dom/element_traversal.h" @@ -44,7 +43,6 @@ #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" -#include "third_party/blink/renderer/core/html/canvas/image_data.h" #include "third_party/blink/renderer/core/html/forms/html_input_element.h" #include "third_party/blink/renderer/core/html/forms/html_label_element.h" #include "third_party/blink/renderer/core/html/forms/html_option_element.h" @@ -57,9 +55,7 @@ #include "third_party/blink/renderer/core/html/html_table_cell_element.h" #include "third_party/blink/renderer/core/html/html_table_col_element.h" #include "third_party/blink/renderer/core/html/html_table_element.h" -#include "third_party/blink/renderer/core/html/media/html_video_element.h" #include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h" -#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/blink/renderer/core/input_type_names.h" #include "third_party/blink/renderer/core/layout/api/line_layout_api_shim.h" #include "third_party/blink/renderer/core/layout/geometry/transform_state.h" @@ -78,8 +74,10 @@ #include "third_party/blink/renderer/core/layout/layout_text_control.h" #include "third_party/blink/renderer/core/layout/layout_text_fragment.h" #include "third_party/blink/renderer/core/layout/layout_view.h" +#include "third_party/blink/renderer/core/layout/list_marker.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h" +#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h" #include "third_party/blink/renderer/core/loader/progress_tracker.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" @@ -94,7 +92,6 @@ #include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h" #include "third_party/blink/renderer/modules/accessibility/ax_svg_root.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/graphics/image_data_buffer.h" #include "third_party/blink/renderer/platform/text/platform_locale.h" #include "third_party/blink/renderer/platform/text/text_direction.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" @@ -170,34 +167,28 @@ static bool IsImageOrAltText(LayoutBoxModelObject* box, Node* node) { return false; } -ax::mojom::Role AXLayoutObject::NativeRoleIgnoringAria() const { - // DOM role takes precedence over layout role. - // For example, <h4 style="display:table"> is a heading, not a table. - ax::mojom::Role dom_role = AXNodeObject::NativeRoleIgnoringAria(); - if (dom_role != ax::mojom::Role::kGenericContainer && - dom_role != ax::mojom::Role::kUnknown) - return dom_role; - +ax::mojom::blink::Role AXLayoutObject::RoleFromLayoutObject( + ax::mojom::blink::Role dom_role) const { // Markup did not provide a specific role, so attempt to determine one // from the computed style. Node* node = layout_object_->GetNode(); LayoutBoxModelObject* css_box = GetLayoutBoxModelObject(); if ((css_box && css_box->IsListItem()) || IsA<HTMLLIElement>(node)) - return ax::mojom::Role::kListItem; - if (layout_object_->IsListMarkerIncludingNGOutsideAndInside()) - return ax::mojom::Role::kListMarker; + return ax::mojom::blink::Role::kListItem; + if (layout_object_->IsListMarkerIncludingAll()) + return ax::mojom::blink::Role::kListMarker; if (layout_object_->IsBR()) - return ax::mojom::Role::kLineBreak; + return ax::mojom::blink::Role::kLineBreak; if (layout_object_->IsText()) - return ax::mojom::Role::kStaticText; + return ax::mojom::blink::Role::kStaticText; // Chrome exposes both table markup and table CSS as a tables, letting // the screen reader determine what to do for CSS tables. If this line // is reached, then it is not an HTML table, and therefore will only be // considered a data table if ARIA markup indicates it is a table. if (layout_object_->IsTable() && node) - return ax::mojom::Role::kLayoutTable; + return ax::mojom::blink::Role::kLayoutTable; if (layout_object_->IsTableSection()) return DetermineTableSectionRole(); if (layout_object_->IsTableRow() && node) @@ -207,58 +198,63 @@ ax::mojom::Role AXLayoutObject::NativeRoleIgnoringAria() const { if (css_box && IsImageOrAltText(css_box, node)) { if (node && node->IsLink()) - return ax::mojom::Role::kImageMap; + return ax::mojom::blink::Role::kImageMap; if (IsA<HTMLInputElement>(node)) return ButtonRoleType(); if (IsSVGImage()) - return ax::mojom::Role::kSvgRoot; + return ax::mojom::blink::Role::kSvgRoot; - return ax::mojom::Role::kImage; + return ax::mojom::blink::Role::kImage; } if (IsA<HTMLCanvasElement>(node)) - return ax::mojom::Role::kCanvas; + return ax::mojom::blink::Role::kCanvas; if (IsA<LayoutView>(css_box)) - return ax::mojom::Role::kRootWebArea; + return ax::mojom::blink::Role::kRootWebArea; if (layout_object_->IsSVGImage()) - return ax::mojom::Role::kImage; + return ax::mojom::blink::Role::kImage; if (layout_object_->IsSVGRoot()) - return ax::mojom::Role::kSvgRoot; + return ax::mojom::blink::Role::kSvgRoot; if (layout_object_->IsHR()) - return ax::mojom::Role::kSplitter; + return ax::mojom::blink::Role::kSplitter; + // TODO(accessibility): refactor this method to take no argument and instead + // default to returning kUnknownRole, the caller can then check for this and + // return a different value if they prefer. return dom_role; } -ax::mojom::Role AXLayoutObject::DetermineAccessibilityRole() { +ax::mojom::blink::Role AXLayoutObject::DetermineAccessibilityRole() { if (!layout_object_) - return ax::mojom::Role::kUnknown; + return ax::mojom::blink::Role::kUnknown; if (GetCSSAltText(GetNode())) { const ComputedStyle* style = GetNode()->GetComputedStyle(); ContentData* content_data = style->GetContentData(); // We just check the first item of the content list to determine the // appropriate role, should only ever be image or text. - ax::mojom::Role role = ax::mojom::Role::kStaticText; + ax::mojom::blink::Role role = ax::mojom::blink::Role::kStaticText; if (content_data->IsImage()) - role = ax::mojom::Role::kImage; + role = ax::mojom::blink::Role::kImage; return role; } native_role_ = NativeRoleIgnoringAria(); - if ((aria_role_ = DetermineAriaRoleAttribute()) != ax::mojom::Role::kUnknown) + if ((aria_role_ = DetermineAriaRoleAttribute()) != + ax::mojom::blink::Role::kUnknown) { return aria_role_; + } // Anything that needs to still be exposed but doesn't have a more specific // role should be considered a generic container. Examples are // layout blocks with no node, in-page link targets, and plain elements // such as a <span> with ARIA markup. - return native_role_ == ax::mojom::Role::kUnknown - ? ax::mojom::Role::kGenericContainer + return native_role_ == ax::mojom::blink::Role::kUnknown + ? ax::mojom::blink::Role::kGenericContainer : native_role_; } @@ -266,11 +262,20 @@ Node* AXLayoutObject::GetNodeOrContainingBlockNode() const { if (IsDetached()) return nullptr; + // For legacy layout, or editable list marker when disabling EditingNG. if (layout_object_->IsListMarker()) { // Return the originating list item node. return layout_object_->GetNode()->parentNode(); } + // For LayoutNG list marker. + // Note: When EditingNG is disabled, editable list items are laid out legacy + // layout even if LayoutNG enabled. + if (auto* list_marker = ListMarker::Get(layout_object_)) { + // Return the originating list item node. + return list_marker->ListItem(*layout_object_)->GetNode(); + } + if (layout_object_->IsAnonymous()) { if (LayoutBlock* layout_block = LayoutObject::FindNonAnonymousContainingBlock(layout_object_)) { @@ -320,21 +325,6 @@ static bool IsLinkable(const AXObject& object) { object.GetLayoutObject()->IsText(); } -bool AXLayoutObject::IsDefault() const { - if (IsDetached()) - return false; - - // Checks for any kind of disabled, including aria-disabled. - if (Restriction() == kRestrictionDisabled || - RoleValue() != ax::mojom::Role::kButton) { - return false; - } - - // Will only match :default pseudo class if it's the first default button in - // a form. - return GetElement()->MatchesDefaultPseudoClass(); -} - // Requires layoutObject to be present because it relies on style // user-modify. Don't move this logic to AXNodeObject. bool AXLayoutObject::IsEditable() const { @@ -429,10 +419,6 @@ bool AXLayoutObject::IsLinked() const { return false; } -bool AXLayoutObject::IsLoaded() const { - return !layout_object_->GetDocument().Parser(); -} - bool AXLayoutObject::IsOffScreen() const { DCHECK(layout_object_); IntRect content_rect = @@ -469,7 +455,7 @@ bool AXLayoutObject::IsFocused() const { // A web area is represented by the Document node in the DOM tree, which isn't // focusable. Check instead if the frame's selection controller is focused if (focused_object == this || - (RoleValue() == ax::mojom::Role::kRootWebArea && + (RoleValue() == ax::mojom::blink::Role::kRootWebArea && GetDocument()->GetFrame()->Selection().FrameIsFocusedAndActive())) return true; @@ -541,9 +527,9 @@ bool AXLayoutObject::IsSelectedFromFocus() const { // when the node is focused. This is true for only a subset of roles. bool AXLayoutObject::SelectionShouldFollowFocus() const { switch (RoleValue()) { - case ax::mojom::Role::kListBoxOption: - case ax::mojom::Role::kMenuListOption: - case ax::mojom::Role::kTab: + case ax::mojom::blink::Role::kListBoxOption: + case ax::mojom::blink::Role::kMenuListOption: + case ax::mojom::blink::Role::kTab: return true; default: break; @@ -618,7 +604,7 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored( // All nodes must have an unignored parent within their tree under // kRootWebArea, so force kRootWebArea to always be unignored. - if (role_ == ax::mojom::Role::kRootWebArea) + if (role_ == ax::mojom::blink::Role::kRootWebArea) return false; if (IsA<HTMLHtmlElement>(GetNode())) @@ -711,7 +697,7 @@ bool AXLayoutObject::ComputeAccessibilityIsIgnored( if (alt_text) return alt_text->IsEmpty(); - if (IsWebArea() || layout_object_->IsListMarkerIncludingNGOutsideAndInside()) + if (IsWebArea() || layout_object_->IsListMarkerIncludingAll()) return false; // Positioned elements and scrollable containers are important for @@ -761,10 +747,10 @@ bool AXLayoutObject::HasAriaCellRole(Element* elem) const { if (aria_role_str.IsEmpty()) return false; - ax::mojom::Role aria_role = AriaRoleToWebCoreRole(aria_role_str); - return aria_role == ax::mojom::Role::kCell || - aria_role == ax::mojom::Role::kColumnHeader || - aria_role == ax::mojom::Role::kRowHeader; + ax::mojom::blink::Role aria_role = AriaRoleToWebCoreRole(aria_role_str); + return aria_role == ax::mojom::blink::Role::kCell || + aria_role == ax::mojom::blink::Role::kColumnHeader || + aria_role == ax::mojom::blink::Role::kRowHeader; } // Return true if whitespace is not necessary to keep adjacent_node separate @@ -867,175 +853,7 @@ bool AXLayoutObject::CanIgnoreTextAsEmpty() const { // Properties of static elements. // -const AtomicString& AXLayoutObject::AccessKey() const { - auto* element = DynamicTo<Element>(layout_object_->GetNode()); - if (!element) - return g_null_atom; - return element->FastGetAttribute(html_names::kAccesskeyAttr); -} - -RGBA32 AXLayoutObject::ComputeBackgroundColor() const { - if (!GetLayoutObject()) - return AXNodeObject::BackgroundColor(); - - Color blended_color = Color::kTransparent; - // Color::blend should be called like this: background.blend(foreground). - for (LayoutObject* layout_object = GetLayoutObject(); layout_object; - layout_object = layout_object->Parent()) { - const AXObject* ax_parent = AXObjectCache().GetOrCreate(layout_object); - if (ax_parent && ax_parent != this) { - Color parent_color = ax_parent->BackgroundColor(); - blended_color = parent_color.Blend(blended_color); - return blended_color.Rgb(); - } - - const ComputedStyle* style = layout_object->Style(); - if (!style || !style->HasBackground()) - continue; - - Color current_color = - style->VisitedDependentColor(GetCSSPropertyBackgroundColor()); - blended_color = current_color.Blend(blended_color); - // Continue blending until we get no transparency. - if (!blended_color.HasAlpha()) - break; - } - - // If we still have some transparency, blend in the document base color. - if (blended_color.HasAlpha()) { - LocalFrameView* view = DocumentFrameView(); - if (view) { - Color document_base_color = view->BaseBackgroundColor(); - blended_color = document_base_color.Blend(blended_color); - } else { - // Default to a white background. - blended_color.BlendWithWhite(); - } - } - - return blended_color.Rgb(); -} - -RGBA32 AXLayoutObject::GetColor() const { - if (!GetLayoutObject() || IsColorWell()) - return AXNodeObject::GetColor(); - - const ComputedStyle* style = GetLayoutObject()->Style(); - if (!style) - return AXNodeObject::GetColor(); - - Color color = style->VisitedDependentColor(GetCSSPropertyColor()); - return color.Rgb(); -} - -String AXLayoutObject::FontFamily() const { - if (!GetLayoutObject()) - return AXNodeObject::FontFamily(); - - const ComputedStyle* style = GetLayoutObject()->Style(); - if (!style) - return AXNodeObject::FontFamily(); - - const SimpleFontData* primary_font = style->GetFont().PrimaryFont(); - if (!primary_font) - return AXNodeObject::FontFamily(); - - return primary_font->PlatformData().FontFamilyName(); -} - -// Font size is in pixels. -float AXLayoutObject::FontSize() const { - if (!GetLayoutObject()) - return AXNodeObject::FontSize(); - - const ComputedStyle* style = GetLayoutObject()->Style(); - if (!style) - return AXNodeObject::FontSize(); - - return style->ComputedFontSize(); -} - -float AXLayoutObject::FontWeight() const { - if (!GetLayoutObject()) - return AXNodeObject::FontWeight(); - - const ComputedStyle* style = GetLayoutObject()->Style(); - if (!style) - return AXNodeObject::FontWeight(); - - return style->GetFontWeight(); -} - -String AXLayoutObject::ImageDataUrl(const IntSize& max_size) const { - Node* node = GetNode(); - if (!node) - return String(); - - ImageBitmapOptions* options = ImageBitmapOptions::Create(); - ImageBitmap* image_bitmap = nullptr; - if (auto* image = DynamicTo<HTMLImageElement>(node)) { - image_bitmap = MakeGarbageCollected<ImageBitmap>( - image, base::Optional<IntRect>(), options); - } else if (auto* canvas = DynamicTo<HTMLCanvasElement>(node)) { - image_bitmap = MakeGarbageCollected<ImageBitmap>( - canvas, base::Optional<IntRect>(), options); - } else if (auto* video = DynamicTo<HTMLVideoElement>(node)) { - image_bitmap = MakeGarbageCollected<ImageBitmap>( - video, base::Optional<IntRect>(), options); - } - if (!image_bitmap) - return String(); - - scoped_refptr<StaticBitmapImage> bitmap_image = image_bitmap->BitmapImage(); - if (!bitmap_image) - return String(); - - sk_sp<SkImage> image = bitmap_image->PaintImageForCurrentFrame().GetSkImage(); - if (!image || image->width() <= 0 || image->height() <= 0) - return String(); - - // Determine the width and height of the output image, using a proportional - // scale factor such that it's no larger than |maxSize|, if |maxSize| is not - // empty. It only resizes the image to be smaller (if necessary), not - // larger. - float x_scale = - max_size.Width() ? max_size.Width() * 1.0 / image->width() : 1.0; - float y_scale = - max_size.Height() ? max_size.Height() * 1.0 / image->height() : 1.0; - float scale = std::min(x_scale, y_scale); - if (scale >= 1.0) - scale = 1.0; - int width = std::round(image->width() * scale); - int height = std::round(image->height() * scale); - - // Draw the scaled image into a bitmap in native format. - SkBitmap bitmap; - bitmap.allocPixels(SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType)); - SkCanvas canvas(bitmap); - canvas.clear(SK_ColorTRANSPARENT); - canvas.drawImageRect(image, SkRect::MakeIWH(width, height), nullptr); - - // Copy the bits into a buffer in RGBA_8888 unpremultiplied format - // for encoding. - SkImageInfo info = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType, - kUnpremul_SkAlphaType); - size_t row_bytes = info.minRowBytes(); - Vector<char> pixel_storage( - SafeCast<wtf_size_t>(info.computeByteSize(row_bytes))); - SkPixmap pixmap(info, pixel_storage.data(), row_bytes); - if (!SkImage::MakeFromBitmap(bitmap)->readPixels(pixmap, 0, 0)) - return String(); - - // Encode as a PNG and return as a data url. - std::unique_ptr<ImageDataBuffer> buffer = ImageDataBuffer::Create(pixmap); - - if (!buffer) - return String(); - - return buffer->ToDataURL(kMimeTypePng, 1.0); -} - -ax::mojom::ListStyle AXLayoutObject::GetListStyle() const { +ax::mojom::blink::ListStyle AXLayoutObject::GetListStyle() const { const LayoutObject* layout_object = GetLayoutObject(); if (!layout_object) return AXNodeObject::GetListStyle(); @@ -1046,22 +864,22 @@ ax::mojom::ListStyle AXLayoutObject::GetListStyle() const { const StyleImage* style_image = computed_style->ListStyleImage(); if (style_image && !style_image->ErrorOccurred()) - return ax::mojom::ListStyle::kImage; + return ax::mojom::blink::ListStyle::kImage; switch (computed_style->ListStyleType()) { case EListStyleType::kNone: - return ax::mojom::ListStyle::kNone; + return ax::mojom::blink::ListStyle::kNone; case EListStyleType::kDisc: - return ax::mojom::ListStyle::kDisc; + return ax::mojom::blink::ListStyle::kDisc; case EListStyleType::kCircle: - return ax::mojom::ListStyle::kCircle; + return ax::mojom::blink::ListStyle::kCircle; case EListStyleType::kSquare: - return ax::mojom::ListStyle::kSquare; + return ax::mojom::blink::ListStyle::kSquare; case EListStyleType::kDecimal: case EListStyleType::kDecimalLeadingZero: - return ax::mojom::ListStyle::kNumeric; + return ax::mojom::blink::ListStyle::kNumeric; default: - return ax::mojom::ListStyle::kOther; + return ax::mojom::blink::ListStyle::kOther; } } @@ -1104,7 +922,7 @@ String AXLayoutObject::GetText() const { return AXNodeObject::GetText(); } -ax::mojom::TextDirection AXLayoutObject::GetTextDirection() const { +ax::mojom::blink::TextDirection AXLayoutObject::GetTextDirection() const { if (!GetLayoutObject()) return AXNodeObject::GetTextDirection(); @@ -1115,23 +933,23 @@ ax::mojom::TextDirection AXLayoutObject::GetTextDirection() const { if (style->IsHorizontalWritingMode()) { switch (style->Direction()) { case TextDirection::kLtr: - return ax::mojom::TextDirection::kLtr; + return ax::mojom::blink::TextDirection::kLtr; case TextDirection::kRtl: - return ax::mojom::TextDirection::kRtl; + return ax::mojom::blink::TextDirection::kRtl; } } else { switch (style->Direction()) { case TextDirection::kLtr: - return ax::mojom::TextDirection::kTtb; + return ax::mojom::blink::TextDirection::kTtb; case TextDirection::kRtl: - return ax::mojom::TextDirection::kBtt; + return ax::mojom::blink::TextDirection::kBtt; } } return AXNodeObject::GetTextDirection(); } -ax::mojom::TextPosition AXLayoutObject::GetTextPosition() const { +ax::mojom::blink::TextPosition AXLayoutObject::GetTextPosition() const { if (!GetLayoutObject()) return AXNodeObject::GetTextPosition(); @@ -1150,28 +968,21 @@ ax::mojom::TextPosition AXLayoutObject::GetTextPosition() const { case EVerticalAlign::kLength: return AXNodeObject::GetTextPosition(); case EVerticalAlign::kSub: - return ax::mojom::TextPosition::kSubscript; + return ax::mojom::blink::TextPosition::kSubscript; case EVerticalAlign::kSuper: - return ax::mojom::TextPosition::kSuperscript; + return ax::mojom::blink::TextPosition::kSuperscript; } } -int AXLayoutObject::TextLength() const { - if (!IsTextControl()) - return -1; - - return GetText().length(); -} - -static unsigned TextStyleFlag(ax::mojom::TextStyle text_style_enum) { +static unsigned TextStyleFlag(ax::mojom::blink::TextStyle text_style_enum) { return static_cast<unsigned>(1 << static_cast<int>(text_style_enum)); } void AXLayoutObject::GetTextStyleAndTextDecorationStyle( int32_t* text_style, - ax::mojom::TextDecorationStyle* text_overline_style, - ax::mojom::TextDecorationStyle* text_strikethrough_style, - ax::mojom::TextDecorationStyle* text_underline_style) const { + ax::mojom::blink::TextDecorationStyle* text_overline_style, + ax::mojom::blink::TextDecorationStyle* text_strikethrough_style, + ax::mojom::blink::TextDecorationStyle* text_underline_style) const { if (!GetLayoutObject()) { AXNodeObject::GetTextStyleAndTextDecorationStyle( text_style, text_overline_style, text_strikethrough_style, @@ -1187,52 +998,52 @@ void AXLayoutObject::GetTextStyleAndTextDecorationStyle( } *text_style = 0; - *text_overline_style = ax::mojom::TextDecorationStyle::kNone; - *text_strikethrough_style = ax::mojom::TextDecorationStyle::kNone; - *text_underline_style = ax::mojom::TextDecorationStyle::kNone; + *text_overline_style = ax::mojom::blink::TextDecorationStyle::kNone; + *text_strikethrough_style = ax::mojom::blink::TextDecorationStyle::kNone; + *text_underline_style = ax::mojom::blink::TextDecorationStyle::kNone; if (style->GetFontWeight() == BoldWeightValue()) - *text_style |= TextStyleFlag(ax::mojom::TextStyle::kBold); + *text_style |= TextStyleFlag(ax::mojom::blink::TextStyle::kBold); if (style->GetFontDescription().Style() == ItalicSlopeValue()) - *text_style |= TextStyleFlag(ax::mojom::TextStyle::kItalic); + *text_style |= TextStyleFlag(ax::mojom::blink::TextStyle::kItalic); for (const auto& decoration : style->AppliedTextDecorations()) { if (EnumHasFlags(decoration.Lines(), TextDecoration::kOverline)) { - *text_style |= TextStyleFlag(ax::mojom::TextStyle::kOverline); + *text_style |= TextStyleFlag(ax::mojom::blink::TextStyle::kOverline); *text_overline_style = TextDecorationStyleToAXTextDecorationStyle(decoration.Style()); } if (EnumHasFlags(decoration.Lines(), TextDecoration::kLineThrough)) { - *text_style |= TextStyleFlag(ax::mojom::TextStyle::kLineThrough); + *text_style |= TextStyleFlag(ax::mojom::blink::TextStyle::kLineThrough); *text_strikethrough_style = TextDecorationStyleToAXTextDecorationStyle(decoration.Style()); } if (EnumHasFlags(decoration.Lines(), TextDecoration::kUnderline)) { - *text_style |= TextStyleFlag(ax::mojom::TextStyle::kUnderline); + *text_style |= TextStyleFlag(ax::mojom::blink::TextStyle::kUnderline); *text_underline_style = TextDecorationStyleToAXTextDecorationStyle(decoration.Style()); } } } -ax::mojom::TextDecorationStyle +ax::mojom::blink::TextDecorationStyle AXLayoutObject::TextDecorationStyleToAXTextDecorationStyle( const blink::ETextDecorationStyle text_decoration_style) { switch (text_decoration_style) { case ETextDecorationStyle::kDashed: - return ax::mojom::TextDecorationStyle::kDashed; + return ax::mojom::blink::TextDecorationStyle::kDashed; case ETextDecorationStyle::kSolid: - return ax::mojom::TextDecorationStyle::kSolid; + return ax::mojom::blink::TextDecorationStyle::kSolid; case ETextDecorationStyle::kDotted: - return ax::mojom::TextDecorationStyle::kDotted; + return ax::mojom::blink::TextDecorationStyle::kDotted; case ETextDecorationStyle::kDouble: - return ax::mojom::TextDecorationStyle::kDouble; + return ax::mojom::blink::TextDecorationStyle::kDouble; case ETextDecorationStyle::kWavy: - return ax::mojom::TextDecorationStyle::kWavy; + return ax::mojom::blink::TextDecorationStyle::kWavy; } NOTREACHED(); - return ax::mojom::TextDecorationStyle::kNone; + return ax::mojom::blink::TextDecorationStyle::kNone; } static bool ShouldUseLayoutNG(const LayoutObject& layout_object) { @@ -1250,7 +1061,7 @@ static AXObject* NextOnLineInternalNG(const AXObject& ax_object) { DCHECK(!ax_object.IsDetached()); const LayoutObject& layout_object = *ax_object.GetLayoutObject(); DCHECK(ShouldUseLayoutNG(layout_object)) << layout_object; - if (layout_object.IsListMarkerIncludingNGOutside() || + if (layout_object.IsBoxListMarkerIncludingNG() || !layout_object.IsInLayoutNGInlineFormattingContext()) return nullptr; NGInlineCursor cursor; @@ -1282,7 +1093,7 @@ AXObject* AXLayoutObject::NextOnLine() const { return nullptr; AXObject* result = nullptr; - if (GetLayoutObject()->IsListMarkerIncludingNGOutside()) { + if (GetLayoutObject()->IsBoxListMarkerIncludingNG()) { // A list marker should be followed by a list item on the same line. The // list item might have no text children, so we don't eagerly descend to the // inline text box. @@ -1354,8 +1165,8 @@ AXObject* AXLayoutObject::NextOnLine() const { // For consistency between the forward and backward directions, try to always // return leaf nodes. - if (result && result->ChildCount()) - return result->DeepestFirstChild(); + if (result && result->ChildCountIncludingIgnored()) + return result->DeepestFirstChildIncludingIgnored(); return result; } @@ -1368,7 +1179,7 @@ static AXObject* PreviousOnLineInlineNG(const AXObject& ax_object) { DCHECK(!ax_object.IsDetached()); const LayoutObject& layout_object = *ax_object.GetLayoutObject(); DCHECK(ShouldUseLayoutNG(layout_object)) << layout_object; - if (layout_object.IsListMarkerIncludingNGOutside() || + if (layout_object.IsBoxListMarkerIncludingNG() || !layout_object.IsInLayoutNGInlineFormattingContext()) { return nullptr; } @@ -1469,8 +1280,8 @@ AXObject* AXLayoutObject::PreviousOnLine() const { // For consistency between the forward and backward directions, try to always // return leaf nodes. - if (result && result->ChildCount()) - return result->DeepestLastChild(); + if (result && result->ChildCountIncludingIgnored()) + return result->DeepestLastChildIncludingIgnored(); return result; } @@ -1538,7 +1349,7 @@ String AXLayoutObject::StringValue() const { } // ARIA combobox can get value from inner contents. - if (AriaRoleAttribute() == ax::mojom::Role::kComboBoxMenuButton) { + if (AriaRoleAttribute() == ax::mojom::blink::Role::kComboBoxMenuButton) { AXObjectSet visited; return TextFromDescendants(visited, false); } @@ -1554,7 +1365,7 @@ String AXLayoutObject::StringValue() const { String AXLayoutObject::TextAlternative(bool recursive, bool in_aria_labelled_by_traversal, AXObjectSet& visited, - ax::mojom::NameFrom& name_from, + ax::mojom::blink::NameFrom& name_from, AXRelatedObjectVector* related_objects, NameSources* name_sources) const { if (layout_object_) { @@ -1563,7 +1374,7 @@ String AXLayoutObject::TextAlternative(bool recursive, if (text_alternative) { if (name_sources) { name_sources->push_back(NameSource(false)); - name_sources->back().type = ax::mojom::NameFrom::kAttribute; + name_sources->back().type = ax::mojom::blink::NameFrom::kAttribute; name_sources->back().text = text_alternative.value(); } return text_alternative.value(); @@ -1592,7 +1403,7 @@ String AXLayoutObject::TextAlternative(bool recursive, text_alternative = visible_text; } found_text_alternative = true; - } else if (layout_object_->IsListMarker() && !recursive) { + } else if (layout_object_->IsListMarkerForNormalContent() && !recursive) { text_alternative = ToLayoutListMarker(layout_object_)->TextAlternative(); found_text_alternative = true; } else if (!recursive) { @@ -1603,7 +1414,7 @@ String AXLayoutObject::TextAlternative(bool recursive, } if (found_text_alternative) { - name_from = ax::mojom::NameFrom::kContents; + name_from = ax::mojom::blink::NameFrom::kContents; if (name_sources) { name_sources->push_back(NameSource(false)); name_sources->back().type = name_from; @@ -1619,152 +1430,6 @@ String AXLayoutObject::TextAlternative(bool recursive, } // -// ARIA attributes. -// - -void AXLayoutObject::AriaOwnsElements(AXObjectVector& owns) const { - AccessibilityChildrenFromAOMProperty(AOMRelationListProperty::kOwns, owns); -} - -void AXLayoutObject::AriaDescribedbyElements( - AXObjectVector& describedby) const { - AccessibilityChildrenFromAOMProperty(AOMRelationListProperty::kDescribedBy, - describedby); -} - -ax::mojom::HasPopup AXLayoutObject::HasPopup() const { - const AtomicString& has_popup = - GetAOMPropertyOrARIAAttribute(AOMStringProperty::kHasPopUp); - if (!has_popup.IsNull()) { - if (EqualIgnoringASCIICase(has_popup, "false")) - return ax::mojom::HasPopup::kFalse; - - if (EqualIgnoringASCIICase(has_popup, "listbox")) - return ax::mojom::HasPopup::kListbox; - - if (EqualIgnoringASCIICase(has_popup, "tree")) - return ax::mojom::HasPopup::kTree; - - if (EqualIgnoringASCIICase(has_popup, "grid")) - return ax::mojom::HasPopup::kGrid; - - if (EqualIgnoringASCIICase(has_popup, "dialog")) - return ax::mojom::HasPopup::kDialog; - - // To provide backward compatibility with ARIA 1.0 content, - // user agents MUST treat an aria-haspopup value of true - // as equivalent to a value of menu. - // And unknown value also return menu too. - if (EqualIgnoringASCIICase(has_popup, "true") || - EqualIgnoringASCIICase(has_popup, "menu") || !has_popup.IsEmpty()) - return ax::mojom::HasPopup::kMenu; - } - - // ARIA 1.1 default value of haspopup for combobox is "listbox". - if (RoleValue() == ax::mojom::Role::kComboBoxMenuButton || - RoleValue() == ax::mojom::Role::kTextFieldWithComboBox) - return ax::mojom::HasPopup::kListbox; - - return AXObject::HasPopup(); -} - -// TODO : Aria-dropeffect and aria-grabbed are deprecated in aria 1.1 -// Also those properties are expected to be replaced by a new feature in -// a future version of WAI-ARIA. After that we will re-implement them -// following new spec. -bool AXLayoutObject::SupportsARIADragging() const { - 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(html_names::kAriaDropeffectAttr)) - return; - - Vector<String> str_dropeffects; - TokenVectorFromAttribute(str_dropeffects, html_names::kAriaDropeffectAttr); - - if (str_dropeffects.IsEmpty()) { - dropeffects.push_back(ax::mojom::Dropeffect::kNone); - return; - } - - for (auto&& str : str_dropeffects) { - dropeffects.push_back(ParseDropeffect(str)); - } -} - -ax::mojom::Dropeffect AXLayoutObject::ParseDropeffect( - String& dropeffect) const { - if (EqualIgnoringASCIICase(dropeffect, "copy")) - return ax::mojom::Dropeffect::kCopy; - if (EqualIgnoringASCIICase(dropeffect, "execute")) - return ax::mojom::Dropeffect::kExecute; - if (EqualIgnoringASCIICase(dropeffect, "link")) - return ax::mojom::Dropeffect::kLink; - if (EqualIgnoringASCIICase(dropeffect, "move")) - return ax::mojom::Dropeffect::kMove; - if (EqualIgnoringASCIICase(dropeffect, "popup")) - return ax::mojom::Dropeffect::kPopup; - return ax::mojom::Dropeffect::kNone; -} - -bool AXLayoutObject::SupportsARIAOwns() const { - if (!layout_object_) - return false; - const AtomicString& aria_owns = GetAttribute(html_names::kAriaOwnsAttr); - - return !aria_owns.IsEmpty(); -} - -// -// ARIA live-region features. -// - -const AtomicString& AXLayoutObject::LiveRegionStatus() const { - DEFINE_STATIC_LOCAL(const AtomicString, live_region_status_assertive, - ("assertive")); - DEFINE_STATIC_LOCAL(const AtomicString, live_region_status_polite, - ("polite")); - DEFINE_STATIC_LOCAL(const AtomicString, live_region_status_off, ("off")); - - const AtomicString& live_region_status = - GetAOMPropertyOrARIAAttribute(AOMStringProperty::kLive); - // These roles have implicit live region status. - if (live_region_status.IsEmpty()) { - switch (RoleValue()) { - case ax::mojom::Role::kAlert: - return live_region_status_assertive; - case ax::mojom::Role::kLog: - case ax::mojom::Role::kStatus: - return live_region_status_polite; - case ax::mojom::Role::kTimer: - case ax::mojom::Role::kMarquee: - return live_region_status_off; - default: - break; - } - } - - return live_region_status; -} - -const AtomicString& AXLayoutObject::LiveRegionRelevant() const { - DEFINE_STATIC_LOCAL(const AtomicString, default_live_region_relevant, - ("additions text")); - const AtomicString& relevant = - GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRelevant); - - // Default aria-relevant = "additions text". - if (relevant.IsEmpty()) - return default_live_region_relevant; - - return relevant; -} - -// // Hit testing. // @@ -2081,12 +1746,12 @@ AXObject* AXLayoutObject::ComputeParent() const { if (!layout_object_) return nullptr; - if (AriaRoleAttribute() == ax::mojom::Role::kMenuBar) + if (AriaRoleAttribute() == ax::mojom::blink::Role::kMenuBar) return AXObjectCache().GetOrCreate(layout_object_->Parent()); // menuButton and its corresponding menu are DOM siblings, but Accessibility // needs them to be parent/child. - if (AriaRoleAttribute() == ax::mojom::Role::kMenu) { + if (AriaRoleAttribute() == ax::mojom::blink::Role::kMenu) { AXObject* parent = MenuButtonForMenu(); if (parent) return parent; @@ -2112,12 +1777,12 @@ AXObject* AXLayoutObject::ComputeParentIfExists() const { if (!layout_object_) return nullptr; - if (AriaRoleAttribute() == ax::mojom::Role::kMenuBar) + if (AriaRoleAttribute() == ax::mojom::blink::Role::kMenuBar) return AXObjectCache().Get(layout_object_->Parent()); // menuButton and its corresponding menu are DOM siblings, but Accessibility // needs them to be parent/child. - if (AriaRoleAttribute() == ax::mojom::Role::kMenu) { + if (AriaRoleAttribute() == ax::mojom::blink::Role::kMenu) { AXObject* parent = MenuButtonForMenuIfExists(); if (parent) return parent; @@ -2144,28 +1809,12 @@ bool AXLayoutObject::CanHaveChildren() const { return false; if (GetCSSAltText(GetNode())) return false; - if (layout_object_->IsListMarker()) + if (layout_object_->IsListMarkerForNormalContent()) return false; return AXNodeObject::CanHaveChildren(); } // -// Properties of the object's owning document or page. -// - -double AXLayoutObject::EstimatedLoadingProgress() const { - if (!layout_object_) - return 0; - - if (IsLoaded()) - return 1.0; - - if (LocalFrame* frame = layout_object_->GetDocument().GetFrame()) - return frame->Loader().Progress().EstimatedProgress(); - return 0; -} - -// // DOM and layout tree access. // @@ -2230,27 +1879,6 @@ Element* AXLayoutObject::AnchorElement() const { return nullptr; } -AtomicString AXLayoutObject::Language() const { - // Uses the style engine to figure out the object's language. - // The style engine relies on, for example, the "lang" attribute of the - // current node and its ancestors, and the document's "content-language" - // header. See the Language of a Node Spec at - // https://html.spec.whatwg.org/C/#language - - if (!GetLayoutObject()) - return AXNodeObject::Language(); - - const ComputedStyle* style = GetLayoutObject()->Style(); - if (!style || !style->Locale()) - return AXNodeObject::Language(); - - Vector<String> languages; - String(style->Locale()).Split(',', languages); - if (languages.IsEmpty()) - return AXNodeObject::Language(); - return AtomicString(languages[0].StripWhiteSpace()); -} - // // Modify or take an action on an object. // @@ -2324,11 +1952,11 @@ void AXLayoutObject::HandleAriaExpandedChanged() { bool found_parent = false; switch (container_parent->RoleValue()) { - case ax::mojom::Role::kLayoutTable: - case ax::mojom::Role::kTree: - case ax::mojom::Role::kTreeGrid: - case ax::mojom::Role::kGrid: - case ax::mojom::Role::kTable: + case ax::mojom::blink::Role::kLayoutTable: + case ax::mojom::blink::Role::kTree: + case ax::mojom::blink::Role::kTreeGrid: + case ax::mojom::blink::Role::kGrid: + case ax::mojom::blink::Role::kTable: found_parent = true; break; default: @@ -2344,7 +1972,7 @@ void AXLayoutObject::HandleAriaExpandedChanged() { // Post that the row count changed. if (container_parent) { AXObjectCache().PostNotification(container_parent, - ax::mojom::Event::kRowCountChanged); + ax::mojom::blink::Event::kRowCountChanged); } // Post that the specific row either collapsed or expanded. @@ -2352,15 +1980,17 @@ void AXLayoutObject::HandleAriaExpandedChanged() { if (!expanded) return; - if (RoleValue() == ax::mojom::Role::kRow || - RoleValue() == ax::mojom::Role::kTreeItem) { - ax::mojom::Event notification = ax::mojom::Event::kRowExpanded; + if (RoleValue() == ax::mojom::blink::Role::kRow || + RoleValue() == ax::mojom::blink::Role::kTreeItem) { + ax::mojom::blink::Event notification = + ax::mojom::blink::Event::kRowExpanded; if (expanded == kExpandedCollapsed) - notification = ax::mojom::Event::kRowCollapsed; + notification = ax::mojom::blink::Event::kRowCollapsed; AXObjectCache().PostNotification(this, notification); } else { - AXObjectCache().PostNotification(this, ax::mojom::Event::kExpandedChanged); + AXObjectCache().PostNotification(this, + ax::mojom::blink::Event::kExpandedChanged); } } @@ -2381,7 +2011,7 @@ void AXLayoutObject::TextChanged() { Settings* settings = GetDocument()->GetSettings(); if (settings && settings->GetInlineTextBoxAccessibilityEnabled() && - RoleValue() == ax::mojom::Role::kStaticText) + RoleValue() == ax::mojom::blink::Role::kStaticText) ChildrenChanged(); // Do this last - AXNodeObject::textChanged posts live region announcements, @@ -2389,25 +2019,9 @@ void AXLayoutObject::TextChanged() { AXNodeObject::TextChanged(); } -AXObject* AXLayoutObject::ErrorMessage() const { - // Check for aria-errormessage. - Element* existing_error_message = - GetAOMPropertyOrARIAAttribute(AOMRelationProperty::kErrorMessage); - if (existing_error_message) - return AXObjectCache().GetOrCreate(existing_error_message); - - // Check for visible validationMessage. This can only be visible for a focused - // control. Corollary: if there is a visible validationMessage alert box, then - // it is related to the current focus. - if (this != AXObjectCache().FocusedObject()) - return nullptr; - - return AXObjectCache().ValidationMessageObjectIfInvalid(); -} - // The following is a heuristic used to determine if a -// <table> should be with ax::mojom::Role::kTable or -// ax::mojom::Role::kLayoutTable. +// <table> should be with ax::mojom::blink::Role::kTable or +// ax::mojom::blink::Role::kLayoutTable. bool AXLayoutObject::IsDataTable() const { if (!layout_object_ || !GetNode()) return false; @@ -2610,7 +2224,7 @@ bool AXLayoutObject::IsDataTable() const { } unsigned AXLayoutObject::ColumnCount() const { - if (AriaRoleAttribute() != ax::mojom::Role::kUnknown) + if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown) return AXNodeObject::ColumnCount(); LayoutObject* layout_object = GetLayoutObject(); @@ -2628,7 +2242,7 @@ unsigned AXLayoutObject::ColumnCount() const { } unsigned AXLayoutObject::RowCount() const { - if (AriaRoleAttribute() != ax::mojom::Role::kUnknown) + if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown) return AXNodeObject::RowCount(); LayoutObject* layout_object = GetLayoutObject(); @@ -2735,25 +2349,26 @@ unsigned AXLayoutObject::RowSpan() const { return cell->ResolvedRowSpan(); } -ax::mojom::SortDirection AXLayoutObject::GetSortDirection() const { - if (RoleValue() != ax::mojom::Role::kRowHeader && - RoleValue() != ax::mojom::Role::kColumnHeader) - return ax::mojom::SortDirection::kNone; +ax::mojom::blink::SortDirection AXLayoutObject::GetSortDirection() const { + if (RoleValue() != ax::mojom::blink::Role::kRowHeader && + RoleValue() != ax::mojom::blink::Role::kColumnHeader) { + return ax::mojom::blink::SortDirection::kNone; + } const AtomicString& aria_sort = GetAOMPropertyOrARIAAttribute(AOMStringProperty::kSort); if (aria_sort.IsEmpty()) - return ax::mojom::SortDirection::kNone; + return ax::mojom::blink::SortDirection::kNone; if (EqualIgnoringASCIICase(aria_sort, "none")) - return ax::mojom::SortDirection::kNone; + return ax::mojom::blink::SortDirection::kNone; if (EqualIgnoringASCIICase(aria_sort, "ascending")) - return ax::mojom::SortDirection::kAscending; + return ax::mojom::blink::SortDirection::kAscending; if (EqualIgnoringASCIICase(aria_sort, "descending")) - return ax::mojom::SortDirection::kDescending; + return ax::mojom::blink::SortDirection::kDescending; // Technically, illegal values should be exposed as is, but this does // not seem to be worth the implementation effort at this time. - return ax::mojom::SortDirection::kOther; + return ax::mojom::blink::SortDirection::kOther; } AXObject* AXLayoutObject::CellForColumnAndRow(unsigned target_column_index, @@ -2809,7 +2424,7 @@ AXObject* AXLayoutObject::CellForColumnAndRow(unsigned target_column_index, return nullptr; } -bool AXLayoutObject::FindAllTableCellsWithRole(ax::mojom::Role role, +bool AXLayoutObject::FindAllTableCellsWithRole(ax::mojom::blink::Role role, AXObjectVector& cells) const { LayoutObject* layout_object = GetLayoutObject(); if (!layout_object || !layout_object->IsTable()) @@ -2843,12 +2458,14 @@ bool AXLayoutObject::FindAllTableCellsWithRole(ax::mojom::Role role, } void AXLayoutObject::ColumnHeaders(AXObjectVector& headers) const { - if (!FindAllTableCellsWithRole(ax::mojom::Role::kColumnHeader, headers)) + if (!FindAllTableCellsWithRole(ax::mojom::blink::Role::kColumnHeader, + headers)) { AXNodeObject::ColumnHeaders(headers); + } } void AXLayoutObject::RowHeaders(AXObjectVector& headers) const { - if (!FindAllTableCellsWithRole(ax::mojom::Role::kRowHeader, headers)) + if (!FindAllTableCellsWithRole(ax::mojom::blink::Role::kRowHeader, headers)) AXNodeObject::RowHeaders(headers); } @@ -2864,7 +2481,7 @@ AXObject* AXLayoutObject::HeaderObject() const { AXObject* ax_cell = cell ? AXObjectCache().GetOrCreate(cell->ToMutableLayoutObject()) : nullptr; - if (ax_cell && ax_cell->RoleValue() == ax::mojom::Role::kRowHeader) + if (ax_cell && ax_cell->RoleValue() == ax::mojom::blink::Role::kRowHeader) return ax_cell; } @@ -2899,8 +2516,10 @@ bool AXLayoutObject::IsTabItemSelected() const { AXObject* tab_panel = AXObjectCache().GetOrCreate(element); // A tab item should only control tab panels. - if (!tab_panel || tab_panel->RoleValue() != ax::mojom::Role::kTabPanel) + if (!tab_panel || + tab_panel->RoleValue() != ax::mojom::blink::Role::kTabPanel) { continue; + } AXObject* check_focus_element = focused_element; // Check if the focused element is a descendant of the element controlled by @@ -2925,7 +2544,7 @@ AXObject* AXLayoutObject::AccessibilityImageMapHitTest( if (!parent) return nullptr; - for (const auto& child : parent->Children()) { + for (const auto& child : parent->ChildrenIncludingIgnored()) { if (child->GetBoundsInFrameCoordinates().Contains(point)) return child.Get(); } 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 ba42cb91d96..b3836195234 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 @@ -51,8 +51,7 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { // Public, overridden from AXObject. LayoutObject* GetLayoutObject() const final { return layout_object_; } ScrollableArea* GetScrollableAreaIfScrollable() const final; - ax::mojom::Role DetermineAccessibilityRole() override; - ax::mojom::Role NativeRoleIgnoringAria() const override; + ax::mojom::blink::Role DetermineAccessibilityRole() override; // If this is an anonymous node, returns the node of its containing layout // block, otherwise returns the node of this layout object. @@ -63,7 +62,6 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { Document* GetDocument() const override; LocalFrameView* DocumentFrameView() const override; Element* AnchorElement() const override; - AtomicString Language() const override; protected: LayoutObject* layout_object_; @@ -85,12 +83,10 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { // Check object role or purpose. bool IsAutofillAvailable() const override; - bool IsDefault() const final; bool IsEditable() const override; bool IsRichlyEditable() const override; bool IsLineBreakingObject() const override; bool IsLinked() const override; - bool IsLoaded() const override; bool IsOffScreen() const override; bool IsVisited() const override; @@ -107,24 +103,15 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const override; // Properties of static elements. - const AtomicString& AccessKey() const override; - RGBA32 ComputeBackgroundColor() const final; - RGBA32 GetColor() const final; - String FontFamily() const final; - // Font size is in pixels. - float FontSize() const final; - float FontWeight() const final; - String ImageDataUrl(const IntSize& max_size) const final; - ax::mojom::ListStyle GetListStyle() const final; + ax::mojom::blink::ListStyle GetListStyle() const final; String GetText() const override; - ax::mojom::TextDirection GetTextDirection() const final; - ax::mojom::TextPosition GetTextPosition() const final; - int TextLength() const override; + ax::mojom::blink::TextDirection GetTextDirection() const final; + ax::mojom::blink::TextPosition GetTextPosition() const final; void GetTextStyleAndTextDecorationStyle( int32_t* text_style, - ax::mojom::TextDecorationStyle* text_overline_style, - ax::mojom::TextDecorationStyle* text_strikethrough_style, - ax::mojom::TextDecorationStyle* text_underline_style) const final; + ax::mojom::blink::TextDecorationStyle* text_overline_style, + ax::mojom::blink::TextDecorationStyle* text_strikethrough_style, + ax::mojom::blink::TextDecorationStyle* text_underline_style) const final; // Inline text boxes. AXObject* NextOnLine() const override; @@ -133,24 +120,11 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { // Properties of interactive elements. String StringValue() const override; - // ARIA attributes. - void AriaDescribedbyElements(AXObjectVector&) const override; - void AriaOwnsElements(AXObjectVector&) const override; - - ax::mojom::HasPopup HasPopup() const override; - bool SupportsARIADragging() const override; - void Dropeffects(Vector<ax::mojom::Dropeffect>& dropeffects) const override; - bool SupportsARIAOwns() const override; - - // ARIA live-region features. - const AtomicString& LiveRegionStatus() const override; - const AtomicString& LiveRegionRelevant() const override; - // AX name calc. String TextAlternative(bool recursive, bool in_aria_labelled_by_traversal, AXObjectSet& visited, - ax::mojom::NameFrom&, + ax::mojom::blink::NameFrom&, AXRelatedObjectVector*, NameSources*) const override; @@ -172,9 +146,6 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { AXObject* RawNextSibling() const override; bool CanHaveChildren() const override; - // Properties of the object's owning document or page. - double EstimatedLoadingProgress() const override; - // Notifications that this object may have changed. void HandleActiveDescendantChanged() override; void HandleAriaExpandedChanged() override; @@ -195,14 +166,21 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { unsigned RowIndex() const override; // Also for a table row. unsigned ColumnSpan() const override; unsigned RowSpan() const override; - ax::mojom::SortDirection GetSortDirection() const override; + ax::mojom::blink::SortDirection GetSortDirection() const override; // For a table row or column. AXObject* HeaderObject() const override; - // The aria-errormessage object or native object from a validationMessage - // alert. - AXObject* ErrorMessage() const override; + // + // Layout object specific methods. + // + // These methods may eventually migrate over to AXNodeObject. + // + + // If we can't determine a useful role from the DOM node, attempt to determine + // a role from the layout object. + ax::mojom::blink::Role RoleFromLayoutObject( + ax::mojom::blink::Role dom_role) const override; private: bool IsTabItemSelected() const; @@ -211,17 +189,16 @@ class MODULES_EXPORT AXLayoutObject : public AXNodeObject { void DetachRemoteSVGRoot(); AXObject* RemoteSVGElementHitTest(const IntPoint&) const; void OffsetBoundingBoxForRemoteSVGElement(LayoutRect&) const; - bool FindAllTableCellsWithRole(ax::mojom::Role, AXObjectVector&) const; + bool FindAllTableCellsWithRole(ax::mojom::blink::Role, AXObjectVector&) const; LayoutRect ComputeElementRect() const; bool CanIgnoreTextAsEmpty() const; bool CanIgnoreSpaceNextTo(LayoutObject*, bool is_after) const; bool HasAriaCellRole(Element*) const; bool IsPlaceholder() const; - ax::mojom::Dropeffect ParseDropeffect(String& dropeffect) const; bool SelectionShouldFollowFocus() const; - static ax::mojom::TextDecorationStyle + static ax::mojom::blink::TextDecorationStyle TextDecorationStyleToAXTextDecorationStyle( const ETextDecorationStyle text_decoration_style); diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object_test.cc index 045b6a62742..34393bda73b 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object_test.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_layout_object_test.cc @@ -4,11 +4,75 @@ #include "third_party/blink/renderer/modules/accessibility/ax_layout_object.h" +#include "third_party/blink/renderer/core/layout/layout_list_item.h" +#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h" #include "third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h" namespace blink { -class AXLayoutObjectTest : public test::AccessibilityTest {}; +class AXLayoutObjectTest : public AccessibilityTest { + protected: + static LayoutObject* GetListMarker(const LayoutObject& list_item) { + if (list_item.IsListItem()) + return ToLayoutListItem(list_item).Marker(); + if (list_item.IsLayoutNGListItem()) + return ToLayoutNGListItem(list_item).Marker(); + NOTREACHED(); + return nullptr; + } +}; + +TEST_F(AXLayoutObjectTest, IsEditableInsideListmarker) { + SetBodyInnerHTML("<div contenteditable><li id=t>ab"); + // The layout tree is: + // LayoutNGBlockFlow {DIV} at (0,0) size 784x20 + // LayoutNGListItem {LI} at (0,0) size 784x20 + // LayoutNGInsideListMarker {::marker} at (-1,0) size 7x19 + // LayoutText (anonymous) at (-1,0) size 7x19 + // text run at (-1,0) width 7: "\x{2022} " + // LayoutText {#text} at (22,0) size 15x19 + // text run at (22,0) width 15: "ab" + LayoutObject& list_item = *GetElementById("t")->GetLayoutObject(); + LayoutObject& list_marker = *GetListMarker(list_item); + + const AXObject* ax_list_item = GetAXObject(&list_item); + ASSERT_NE(nullptr, ax_list_item); + EXPECT_TRUE(IsA<AXLayoutObject>(ax_list_item)); + EXPECT_TRUE(ax_list_item->IsEditable()); + EXPECT_TRUE(ax_list_item->IsRichlyEditable()); + + const AXObject* ax_list_marker = GetAXObject(&list_marker); + ASSERT_NE(nullptr, ax_list_marker); + EXPECT_TRUE(IsA<AXLayoutObject>(ax_list_item)); + EXPECT_TRUE(ax_list_marker->IsEditable()); + EXPECT_TRUE(ax_list_marker->IsRichlyEditable()); +} + +TEST_F(AXLayoutObjectTest, IsEditableOutsideListmarker) { + SetBodyInnerHTML("<ol contenteditable><li id=t>ab"); + // THe layout tree is: + // LayoutNGBlockFlow {OL} at (0,0) size 784x20 + // LayoutNGListItem {LI} at (40,0) size 744x20 + // LayoutNGOutsideListMarker {::marker} at (-16,0) size 16x20 + // LayoutText (anonymous) at (0,0) size 16x19 + // text run at (0,0) width 16: "1. " + // LayoutText {#text} at (0,0) size 15x19 + // text run at (0,0) width 15: "ab" + LayoutObject& list_item = *GetElementById("t")->GetLayoutObject(); + LayoutObject& list_marker = *GetListMarker(list_item); + + const AXObject* ax_list_item = GetAXObject(&list_item); + ASSERT_NE(nullptr, ax_list_item); + EXPECT_TRUE(IsA<AXLayoutObject>(ax_list_item)); + EXPECT_TRUE(ax_list_item->IsEditable()); + EXPECT_TRUE(ax_list_item->IsRichlyEditable()); + + const AXObject* ax_list_marker = GetAXObject(&list_marker); + ASSERT_NE(nullptr, ax_list_marker); + EXPECT_TRUE(IsA<AXLayoutObject>(ax_list_item)); + EXPECT_TRUE(ax_list_marker->IsEditable()); + EXPECT_TRUE(ax_list_marker->IsRichlyEditable()); +} TEST_F(AXLayoutObjectTest, StringValueTextTransform) { SetBodyInnerHTML( diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc index 1f2409fe475..82a5489b3e9 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list.cc @@ -65,7 +65,7 @@ void AXMenuList::ClearChildren() { // There's no reason to clear our AXMenuListPopup child. If we get a // call to clearChildren, it's because the options might have changed, // so call it on our popup. - DCHECK(children_.size() == 1); + DCHECK_EQ(ChildCountIncludingIgnored(), 1); children_[0]->ClearChildren(); } @@ -111,7 +111,7 @@ void AXMenuList::DidUpdateActiveOption(int option_index) { (GetNode() && !GetNode()->IsFinishedParsingChildren()); if (HasChildren()) { - const auto& child_objects = Children(); + const auto& child_objects = ChildrenIncludingIgnored(); if (!child_objects.IsEmpty()) { DCHECK_EQ(child_objects.size(), 1ul); DCHECK(IsA<AXMenuListPopup>(child_objects[0].Get())); @@ -126,18 +126,18 @@ void AXMenuList::DidUpdateActiveOption(int option_index) { } void AXMenuList::DidShowPopup() { - if (Children().size() != 1) + if (ChildCountIncludingIgnored() != 1) return; - auto* popup = To<AXMenuListPopup>(Children()[0].Get()); + auto* popup = To<AXMenuListPopup>(ChildAtIncludingIgnored(0)); popup->DidShow(); } void AXMenuList::DidHidePopup() { - if (Children().size() != 1) + if (ChildCountIncludingIgnored() != 1) return; - auto* popup = To<AXMenuListPopup>(Children()[0].Get()); + auto* popup = To<AXMenuListPopup>(ChildAtIncludingIgnored(0)); popup->DidHide(); if (GetNode() && GetNode()->IsFocused()) 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 9489ed52acf..1cb622903be 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 @@ -86,7 +86,7 @@ AXObject* AXMenuListOption::ComputeParent() const { return select_ax_object; if (menu_list->HasChildren()) { - const auto& child_objects = menu_list->Children(); + const auto& child_objects = menu_list->ChildrenIncludingIgnored(); if (child_objects.IsEmpty()) return nullptr; DCHECK_EQ(child_objects.size(), 1UL); @@ -234,7 +234,7 @@ HTMLSelectElement* AXMenuListOption::ParentSelectNode() const { return nullptr; } -void AXMenuListOption::Trace(Visitor* visitor) { +void AXMenuListOption::Trace(Visitor* visitor) const { visitor->Trace(element_); AXNodeObject::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h index 14f0d76bb17..953c61f9cd2 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_menu_list_option.h @@ -43,7 +43,7 @@ class AXMenuListOption final : public AXNodeObject { int SetSize() const override; private: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool IsMenuListOption() const override { return true; } 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 5598635a495..c8e5fe81f3c 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 @@ -176,7 +176,7 @@ AXObject* AXMenuListPopup::ActiveDescendant() { if (parent_ && !parent_->IsFocused()) return nullptr; - if (active_index_ < 0 || active_index_ >= static_cast<int>(Children().size())) + if (active_index_ < 0 || active_index_ >= ChildCountIncludingIgnored()) return nullptr; return children_[active_index_].Get(); 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 10a8708d339..5d1f7c7895a 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 @@ -33,6 +33,7 @@ #include <algorithm> #include "third_party/blink/public/strings/grit/blink_strings.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.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" @@ -49,6 +50,7 @@ #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" +#include "third_party/blink/renderer/core/html/canvas/image_data.h" #include "third_party/blink/renderer/core/html/custom/element_internals.h" #include "third_party/blink/renderer/core/html/forms/html_field_set_element.h" #include "third_party/blink/renderer/core/html/forms/html_input_element.h" @@ -72,8 +74,10 @@ #include "third_party/blink/renderer/core/html/html_table_row_element.h" #include "third_party/blink/renderer/core/html/html_table_section_element.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/parser/html_parser_idioms.h" #include "third_party/blink/renderer/core/html/portal/html_portal_element.h" +#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/blink/renderer/core/input_type_names.h" #include "third_party/blink/renderer/core/layout/layout_block_flow.h" #include "third_party/blink/renderer/core/layout/layout_box_model_object.h" @@ -81,6 +85,7 @@ #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_table.h" #include "third_party/blink/renderer/core/layout/layout_view.h" +#include "third_party/blink/renderer/core/loader/progress_tracker.h" #include "third_party/blink/renderer/core/mathml_names.h" #include "third_party/blink/renderer/core/page/focus_controller.h" #include "third_party/blink/renderer/core/page/page.h" @@ -94,6 +99,7 @@ #include "third_party/blink/renderer/modules/accessibility/ax_range.h" #include "third_party/blink/renderer/modules/accessibility/ax_svg_root.h" #include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h" +#include "third_party/blink/renderer/platform/graphics/image_data_buffer.h" #include "third_party/blink/renderer/platform/text/platform_locale.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -102,11 +108,11 @@ namespace { bool IsNeutralWithinTable(blink::AXObject* obj) { if (!obj) return false; - ax::mojom::Role role = obj->RoleValue(); - return role == ax::mojom::Role::kGroup || - role == ax::mojom::Role::kGenericContainer || - role == ax::mojom::Role::kIgnored || - role == ax::mojom::Role::kRowGroup; + ax::mojom::blink::Role role = obj->RoleValue(); + return role == ax::mojom::blink::Role::kGroup || + role == ax::mojom::blink::Role::kGenericContainer || + role == ax::mojom::blink::Role::kIgnored || + role == ax::mojom::blink::Role::kRowGroup; } } // namespace @@ -123,7 +129,7 @@ const int kDefaultHeadingLevel = 2; AXNodeObject::AXNodeObject(Node* node, AXObjectCacheImpl& ax_object_cache) : AXObject(ax_object_cache), children_dirty_(false), - native_role_(ax::mojom::Role::kUnknown), + native_role_(ax::mojom::blink::Role::kUnknown), node_(node) {} AXNodeObject::~AXNodeObject() { @@ -145,7 +151,14 @@ void AXNodeObject::AlterSliderOrSpinButtonValue(bool increase) { value += increase ? step : -step; OnNativeSetValueAction(String::Number(value)); - AXObjectCache().PostNotification(GetNode(), ax::mojom::Event::kValueChanged); + + // Dispatching an event could result in changes to the document, like + // this AXObject becoming detached. + if (IsDetached()) + return; + + AXObjectCache().PostNotification(GetNode(), + ax::mojom::blink::Event::kValueChanged); } AXObject* AXNodeObject::ActiveDescendant() { @@ -159,7 +172,7 @@ AXObject* AXNodeObject::ActiveDescendant() { return nullptr; AXObject* ax_descendant = AXObjectCache().GetOrCreate(descendant); - return ax_descendant; + return ax_descendant && ax_descendant->IsVisible() ? ax_descendant : nullptr; } AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics( @@ -173,7 +186,7 @@ AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics( return kIgnoreObject; } - if (RoleValue() == ax::mojom::Role::kIgnored) { + if (RoleValue() == ax::mojom::blink::Role::kIgnored) { if (ignored_reasons) ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); return kIgnoreObject; @@ -234,8 +247,8 @@ AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics( // A click handler might be placed on an otherwise ignored non-empty block // element, e.g. a div. We shouldn't ignore such elements because if an AT - // sees the |ax::mojom::DefaultActionVerb::kClickAncestor|, it will look for - // the clickable ancestor and it expects to find one. + // sees the |ax::mojom::blink::DefaultActionVerb::kClickAncestor|, it will + // look for the clickable ancestor and it expects to find one. if (IsClickable()) return kIncludeObject; @@ -253,7 +266,7 @@ AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics( return kIncludeObject; // Anything with an explicit ARIA role should be included. - if (AriaRoleAttribute() != ax::mojom::Role::kUnknown) + if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown) return kIncludeObject; // Anything with CSS alt should be included. @@ -275,25 +288,26 @@ AXObjectInclusion AXNodeObject::ShouldIncludeBasedOnSemantics( if (HasContentEditableAttributeSet()) return kIncludeObject; - static const HashSet<ax::mojom::Role> always_included_computed_roles = { - ax::mojom::Role::kAbbr, - ax::mojom::Role::kBlockquote, - ax::mojom::Role::kContentDeletion, - ax::mojom::Role::kContentInsertion, - ax::mojom::Role::kDetails, - ax::mojom::Role::kDialog, - ax::mojom::Role::kFigcaption, - ax::mojom::Role::kFigure, - ax::mojom::Role::kListItem, - ax::mojom::Role::kMark, - ax::mojom::Role::kMath, - ax::mojom::Role::kMeter, - ax::mojom::Role::kPluginObject, - ax::mojom::Role::kProgressIndicator, - ax::mojom::Role::kRuby, - ax::mojom::Role::kSplitter, - ax::mojom::Role::kTime, - }; + static const HashSet<ax::mojom::blink::Role> always_included_computed_roles = + { + ax::mojom::blink::Role::kAbbr, + ax::mojom::blink::Role::kBlockquote, + ax::mojom::blink::Role::kContentDeletion, + ax::mojom::blink::Role::kContentInsertion, + ax::mojom::blink::Role::kDetails, + ax::mojom::blink::Role::kDialog, + ax::mojom::blink::Role::kFigcaption, + ax::mojom::blink::Role::kFigure, + ax::mojom::blink::Role::kListItem, + ax::mojom::blink::Role::kMark, + ax::mojom::blink::Role::kMath, + ax::mojom::blink::Role::kMeter, + ax::mojom::blink::Role::kPluginObject, + ax::mojom::blink::Role::kProgressIndicator, + ax::mojom::blink::Role::kRuby, + ax::mojom::blink::Role::kSplitter, + ax::mojom::blink::Role::kTime, + }; if (always_included_computed_roles.find(RoleValue()) != always_included_computed_roles.end()) @@ -373,11 +387,11 @@ bool AXNodeObject::ComputeAccessibilityIsIgnored( // All nodes must have an unignored parent within their tree under // kRootWebArea, so force kRootWebArea to always be unignored. - if (role_ == ax::mojom::Role::kRootWebArea) + if (role_ == ax::mojom::blink::Role::kRootWebArea) return false; if (GetLayoutObject()) { - if (role_ == ax::mojom::Role::kUnknown) { + if (role_ == ax::mojom::blink::Role::kUnknown) { if (ignored_reasons) ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); return true; @@ -424,20 +438,20 @@ static bool IsListElement(Node* node) { } static bool IsRequiredOwnedElement(AXObject* parent, - ax::mojom::Role current_role, + ax::mojom::blink::Role current_role, HTMLElement* current_element) { Node* parent_node = parent->GetNode(); auto* parent_html_element = DynamicTo<HTMLElement>(parent_node); if (!parent_html_element) return false; - if (current_role == ax::mojom::Role::kListItem) + if (current_role == ax::mojom::blink::Role::kListItem) return IsListElement(parent_node); - if (current_role == ax::mojom::Role::kListMarker) + if (current_role == ax::mojom::blink::Role::kListMarker) return IsA<HTMLLIElement>(*parent_node); - if (current_role == ax::mojom::Role::kMenuItemCheckBox || - current_role == ax::mojom::Role::kMenuItem || - current_role == ax::mojom::Role::kMenuItemRadio) + if (current_role == ax::mojom::blink::Role::kMenuItemCheckBox || + current_role == ax::mojom::blink::Role::kMenuItem || + current_role == ax::mojom::blink::Role::kMenuItemRadio) return IsA<HTMLMenuElement>(*parent_node); if (!current_element) @@ -467,7 +481,7 @@ const AXObject* AXNodeObject::InheritsPresentationalRoleFrom() const { // ARIA spec says that the user agent MUST apply an inherited role of // presentation // to any owned elements that do not have an explicit role defined. - if (AriaRoleAttribute() != ax::mojom::Role::kUnknown) + if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown) return nullptr; AXObject* parent = ParentObject(); @@ -528,7 +542,7 @@ static bool IsHeaderCell(const Node* cell) { return cell && cell->HasTagName(html_names::kThTag); } -static ax::mojom::Role DecideRoleFromSiblings(Element* cell) { +static ax::mojom::blink::Role DecideRoleFromSiblings(Element* cell) { // If this header is only cell in its row, it is a column header. // It is also a column header if it has a header on either side of it. // If instead it has a non-empty td element next to it, it is a row header. @@ -537,16 +551,16 @@ static ax::mojom::Role DecideRoleFromSiblings(Element* cell) { const Node* previous_cell = LayoutTreeBuilderTraversal::PreviousSibling(*cell); if (!next_cell && !previous_cell) - return ax::mojom::Role::kColumnHeader; + return ax::mojom::blink::Role::kColumnHeader; if (IsHeaderCell(next_cell) && IsHeaderCell(previous_cell)) - return ax::mojom::Role::kColumnHeader; + return ax::mojom::blink::Role::kColumnHeader; if (IsNonEmptyNonHeaderCell(next_cell) || IsNonEmptyNonHeaderCell(previous_cell)) - return ax::mojom::Role::kRowHeader; + return ax::mojom::blink::Role::kRowHeader; const auto* row = To<Element>(cell->parentNode()); if (!row || !row->HasTagName(html_names::kTrTag)) - return ax::mojom::Role::kColumnHeader; + return ax::mojom::blink::Role::kColumnHeader; // If this row's first or last cell is a non-empty td, this is a row header. // Do the same check for the second and second-to-last cells because tables @@ -558,72 +572,72 @@ static ax::mojom::Role DecideRoleFromSiblings(Element* cell) { DCHECK(last_cell); if (IsNonEmptyNonHeaderCell(first_cell) || IsNonEmptyNonHeaderCell(last_cell)) - return ax::mojom::Role::kRowHeader; + return ax::mojom::blink::Role::kRowHeader; if (IsNonEmptyNonHeaderCell(ElementTraversal::NextSibling(*first_cell)) || IsNonEmptyNonHeaderCell(ElementTraversal::PreviousSibling(*last_cell))) - return ax::mojom::Role::kRowHeader; + return ax::mojom::blink::Role::kRowHeader; // We have no evidence that this is not a column header. - return ax::mojom::Role::kColumnHeader; + return ax::mojom::blink::Role::kColumnHeader; } -ax::mojom::Role AXNodeObject::DetermineTableSectionRole() const { +ax::mojom::blink::Role AXNodeObject::DetermineTableSectionRole() const { if (!GetElement()) - return ax::mojom::Role::kUnknown; + return ax::mojom::blink::Role::kUnknown; AXObject* parent = ParentObject(); if (!parent || !parent->IsTableLikeRole()) - return ax::mojom::Role::kGenericContainer; + return ax::mojom::blink::Role::kGenericContainer; - if (parent->RoleValue() == ax::mojom::Role::kLayoutTable) - return ax::mojom::Role::kIgnored; + if (parent->RoleValue() == ax::mojom::blink::Role::kLayoutTable) + return ax::mojom::blink::Role::kIgnored; - return ax::mojom::Role::kRowGroup; + return ax::mojom::blink::Role::kRowGroup; } -ax::mojom::Role AXNodeObject::DetermineTableRowRole() const { +ax::mojom::blink::Role AXNodeObject::DetermineTableRowRole() const { AXObject* parent = ParentObject(); while (IsNeutralWithinTable(parent)) parent = parent->ParentObject(); if (!parent || !parent->IsTableLikeRole()) - return ax::mojom::Role::kGenericContainer; + return ax::mojom::blink::Role::kGenericContainer; - if (parent->RoleValue() == ax::mojom::Role::kLayoutTable) - return ax::mojom::Role::kLayoutTableRow; + if (parent->RoleValue() == ax::mojom::blink::Role::kLayoutTable) + return ax::mojom::blink::Role::kLayoutTableRow; if (parent->IsTableLikeRole()) - return ax::mojom::Role::kRow; + return ax::mojom::blink::Role::kRow; - return ax::mojom::Role::kGenericContainer; + return ax::mojom::blink::Role::kGenericContainer; } -ax::mojom::Role AXNodeObject::DetermineTableCellRole() const { +ax::mojom::blink::Role AXNodeObject::DetermineTableCellRole() const { AXObject* parent = ParentObject(); if (!parent || !parent->IsTableRowLikeRole()) - return ax::mojom::Role::kGenericContainer; + return ax::mojom::blink::Role::kGenericContainer; // Ensure table container. AXObject* grandparent = parent->ParentObject(); while (IsNeutralWithinTable(grandparent)) grandparent = grandparent->ParentObject(); if (!grandparent || !grandparent->IsTableLikeRole()) - return ax::mojom::Role::kGenericContainer; + return ax::mojom::blink::Role::kGenericContainer; - if (parent->RoleValue() == ax::mojom::Role::kLayoutTableRow) - return ax::mojom::Role::kLayoutTableCell; + if (parent->RoleValue() == ax::mojom::blink::Role::kLayoutTableRow) + return ax::mojom::blink::Role::kLayoutTableCell; if (!GetElement() || !GetNode()->HasTagName(html_names::kThTag)) - return ax::mojom::Role::kCell; + return ax::mojom::blink::Role::kCell; const AtomicString& scope = GetAttribute(html_names::kScopeAttr); if (EqualIgnoringASCIICase(scope, "row") || EqualIgnoringASCIICase(scope, "rowgroup")) - return ax::mojom::Role::kRowHeader; + return ax::mojom::blink::Role::kRowHeader; if (EqualIgnoringASCIICase(scope, "col") || EqualIgnoringASCIICase(scope, "colgroup")) - return ax::mojom::Role::kColumnHeader; + return ax::mojom::blink::Role::kColumnHeader; return DecideRoleFromSiblings(GetElement()); } @@ -634,48 +648,52 @@ ax::mojom::Role AXNodeObject::DetermineTableCellRole() const { // TODO(accessibility) This value is cached in native_role_ so it needs to // be recached if anything it depends on change, such as IsClickable(), // DataList(), aria-pressed, the parent's tag, role on an iframe, etc. -ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const { +ax::mojom::blink::Role AXNodeObject::NativeRoleIgnoringAria() const { if (!GetNode()) - return ax::mojom::Role::kUnknown; + return RoleFromLayoutObject(ax::mojom::blink::Role::kUnknown); // |HTMLAnchorElement| sets isLink only when it has kHrefAttr. if (GetNode()->IsLink()) { - return IsA<HTMLImageElement>(GetNode()) ? ax::mojom::Role::kImageMap - : ax::mojom::Role::kLink; + if (IsA<HTMLImageElement>(GetNode())) + return ax::mojom::blink::Role::kImageMap; + else + return ax::mojom::blink::Role::kLink; } if (IsA<HTMLPortalElement>(*GetNode())) { - return ax::mojom::Role::kPortal; + return ax::mojom::blink::Role::kPortal; } if (IsA<HTMLAnchorElement>(*GetNode())) { // We assume that an anchor element is LinkRole if it has event listeners // even though it doesn't have kHrefAttr. if (IsClickable()) - return ax::mojom::Role::kLink; - return ax::mojom::Role::kAnchor; + return ax::mojom::blink::Role::kLink; + return ax::mojom::blink::Role::kAnchor; } if (IsA<HTMLButtonElement>(*GetNode())) return ButtonRoleType(); if (IsA<HTMLDetailsElement>(*GetNode())) - return ax::mojom::Role::kDetails; + return ax::mojom::blink::Role::kDetails; if (IsA<HTMLSummaryElement>(*GetNode())) { ContainerNode* parent = LayoutTreeBuilderTraversal::Parent(*GetNode()); if (IsA<HTMLSlotElement>(parent)) parent = LayoutTreeBuilderTraversal::Parent(*parent); if (parent && IsA<HTMLDetailsElement>(parent)) - return ax::mojom::Role::kDisclosureTriangle; - return ax::mojom::Role::kUnknown; + return ax::mojom::blink::Role::kDisclosureTriangle; + return RoleFromLayoutObject(ax::mojom::blink::Role::kUnknown); } // Chrome exposes both table markup and table CSS as a tables, letting // the screen reader determine what to do for CSS tables. if (IsA<HTMLTableElement>(*GetNode())) { - return IsDataTable() ? ax::mojom::Role::kTable - : ax::mojom::Role::kLayoutTable; + if (IsDataTable()) + return ax::mojom::blink::Role::kTable; + else + return ax::mojom::blink::Role::kLayoutTable; } if (IsA<HTMLTableRowElement>(*GetNode())) return DetermineTableRowRole(); @@ -687,180 +705,183 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const { if (const auto* input = DynamicTo<HTMLInputElement>(*GetNode())) { const AtomicString& type = input->type(); if (input->DataList() && type != input_type_names::kColor) - return ax::mojom::Role::kTextFieldWithComboBox; + return ax::mojom::blink::Role::kTextFieldWithComboBox; if (type == input_type_names::kButton) { if ((GetNode()->parentNode() && IsA<HTMLMenuElement>(GetNode()->parentNode())) || (ParentObject() && - ParentObject()->RoleValue() == ax::mojom::Role::kMenu)) - return ax::mojom::Role::kMenuItem; + ParentObject()->RoleValue() == ax::mojom::blink::Role::kMenu)) + return ax::mojom::blink::Role::kMenuItem; return ButtonRoleType(); } if (type == input_type_names::kCheckbox) { if ((GetNode()->parentNode() && IsA<HTMLMenuElement>(GetNode()->parentNode())) || (ParentObject() && - ParentObject()->RoleValue() == ax::mojom::Role::kMenu)) - return ax::mojom::Role::kMenuItemCheckBox; - return ax::mojom::Role::kCheckBox; + ParentObject()->RoleValue() == ax::mojom::blink::Role::kMenu)) + return ax::mojom::blink::Role::kMenuItemCheckBox; + return ax::mojom::blink::Role::kCheckBox; } if (type == input_type_names::kDate) - return ax::mojom::Role::kDate; + return ax::mojom::blink::Role::kDate; if (type == input_type_names::kDatetime || type == input_type_names::kDatetimeLocal || type == input_type_names::kMonth || type == input_type_names::kWeek) - return ax::mojom::Role::kDateTime; + return ax::mojom::blink::Role::kDateTime; if (type == input_type_names::kFile) - return ax::mojom::Role::kButton; + return ax::mojom::blink::Role::kButton; if (type == input_type_names::kRadio) { if ((GetNode()->parentNode() && IsA<HTMLMenuElement>(GetNode()->parentNode())) || (ParentObject() && - ParentObject()->RoleValue() == ax::mojom::Role::kMenu)) - return ax::mojom::Role::kMenuItemRadio; - return ax::mojom::Role::kRadioButton; + ParentObject()->RoleValue() == ax::mojom::blink::Role::kMenu)) + return ax::mojom::blink::Role::kMenuItemRadio; + return ax::mojom::blink::Role::kRadioButton; } if (type == input_type_names::kNumber) - return ax::mojom::Role::kSpinButton; + return ax::mojom::blink::Role::kSpinButton; if (input->IsTextButton()) return ButtonRoleType(); if (type == input_type_names::kRange) - return ax::mojom::Role::kSlider; + return ax::mojom::blink::Role::kSlider; if (type == input_type_names::kSearch) - return ax::mojom::Role::kSearchBox; + return ax::mojom::blink::Role::kSearchBox; if (type == input_type_names::kColor) - return ax::mojom::Role::kColorWell; + return ax::mojom::blink::Role::kColorWell; if (type == input_type_names::kTime) - return ax::mojom::Role::kInputTime; + return ax::mojom::blink::Role::kInputTime; if (type == input_type_names::kButton || type == input_type_names::kImage || type == input_type_names::kReset || type == input_type_names::kSubmit) { - return ax::mojom::Role::kButton; + return ax::mojom::blink::Role::kButton; } - return ax::mojom::Role::kTextField; + return ax::mojom::blink::Role::kTextField; } if (auto* select_element = DynamicTo<HTMLSelectElement>(*GetNode())) { - return select_element->IsMultiple() ? ax::mojom::Role::kListBox - : ax::mojom::Role::kPopUpButton; + if (select_element->IsMultiple()) + return ax::mojom::blink::Role::kListBox; + else + return ax::mojom::blink::Role::kPopUpButton; } if (auto* option = DynamicTo<HTMLOptionElement>(*GetNode())) { HTMLSelectElement* select_element = option->OwnerSelectElement(); - return !select_element || select_element->IsMultiple() - ? ax::mojom::Role::kListBoxOption - : ax::mojom::Role::kMenuListOption; + if (!select_element || select_element->IsMultiple()) + return ax::mojom::blink::Role::kListBoxOption; + else + return ax::mojom::blink::Role::kMenuListOption; } if (IsA<HTMLTextAreaElement>(*GetNode())) - return ax::mojom::Role::kTextField; + return ax::mojom::blink::Role::kTextField; if (HeadingLevel()) - return ax::mojom::Role::kHeading; + return ax::mojom::blink::Role::kHeading; if (IsA<HTMLDivElement>(*GetNode())) - return ax::mojom::Role::kGenericContainer; + return RoleFromLayoutObject(ax::mojom::blink::Role::kGenericContainer); if (IsA<HTMLMeterElement>(*GetNode())) - return ax::mojom::Role::kMeter; + return ax::mojom::blink::Role::kMeter; if (IsA<HTMLProgressElement>(*GetNode())) - return ax::mojom::Role::kProgressIndicator; + return ax::mojom::blink::Role::kProgressIndicator; if (IsA<HTMLOutputElement>(*GetNode())) - return ax::mojom::Role::kStatus; + return ax::mojom::blink::Role::kStatus; if (IsA<HTMLParagraphElement>(*GetNode())) - return ax::mojom::Role::kParagraph; + return ax::mojom::blink::Role::kParagraph; if (IsA<HTMLLabelElement>(*GetNode())) - return ax::mojom::Role::kLabelText; + return ax::mojom::blink::Role::kLabelText; if (IsA<HTMLLegendElement>(*GetNode())) - return ax::mojom::Role::kLegend; + return ax::mojom::blink::Role::kLegend; if (IsA<HTMLRubyElement>(*GetNode())) - return ax::mojom::Role::kRuby; + return ax::mojom::blink::Role::kRuby; if (IsA<HTMLDListElement>(*GetNode())) - return ax::mojom::Role::kDescriptionList; + return ax::mojom::blink::Role::kDescriptionList; if (IsA<HTMLAudioElement>(*GetNode())) - return ax::mojom::Role::kAudio; + return ax::mojom::blink::Role::kAudio; if (IsA<HTMLVideoElement>(*GetNode())) - return ax::mojom::Role::kVideo; + return ax::mojom::blink::Role::kVideo; if (GetNode()->HasTagName(html_names::kDdTag)) - return ax::mojom::Role::kDescriptionListDetail; + return ax::mojom::blink::Role::kDescriptionListDetail; if (GetNode()->HasTagName(html_names::kDtTag)) - return ax::mojom::Role::kDescriptionListTerm; + return ax::mojom::blink::Role::kDescriptionListTerm; if (GetNode()->nodeName() == mathml_names::kMathTag.LocalName()) - return ax::mojom::Role::kMath; + return ax::mojom::blink::Role::kMath; if (GetNode()->HasTagName(html_names::kRpTag) || GetNode()->HasTagName(html_names::kRtTag)) - return ax::mojom::Role::kRubyAnnotation; + return ax::mojom::blink::Role::kRubyAnnotation; if (IsA<HTMLFormElement>(*GetNode())) - return ax::mojom::Role::kForm; + return ax::mojom::blink::Role::kForm; if (GetNode()->HasTagName(html_names::kAbbrTag)) - return ax::mojom::Role::kAbbr; + return ax::mojom::blink::Role::kAbbr; if (GetNode()->HasTagName(html_names::kArticleTag)) - return ax::mojom::Role::kArticle; + return ax::mojom::blink::Role::kArticle; if (GetNode()->HasTagName(html_names::kCodeTag)) - return ax::mojom::Role::kCode; + return ax::mojom::blink::Role::kCode; if (GetNode()->HasTagName(html_names::kEmTag)) - return ax::mojom::Role::kEmphasis; + return ax::mojom::blink::Role::kEmphasis; if (GetNode()->HasTagName(html_names::kStrongTag)) - return ax::mojom::Role::kStrong; + return ax::mojom::blink::Role::kStrong; if (GetNode()->HasTagName(html_names::kDelTag)) - return ax::mojom::Role::kContentDeletion; + return ax::mojom::blink::Role::kContentDeletion; if (GetNode()->HasTagName(html_names::kInsTag)) - return ax::mojom::Role::kContentInsertion; + return ax::mojom::blink::Role::kContentInsertion; if (GetNode()->HasTagName(html_names::kMainTag)) - return ax::mojom::Role::kMain; + return ax::mojom::blink::Role::kMain; if (GetNode()->HasTagName(html_names::kMarkTag)) - return ax::mojom::Role::kMark; + return ax::mojom::blink::Role::kMark; if (GetNode()->HasTagName(html_names::kNavTag)) - return ax::mojom::Role::kNavigation; + return ax::mojom::blink::Role::kNavigation; if (GetNode()->HasTagName(html_names::kAsideTag)) - return ax::mojom::Role::kComplementary; + return ax::mojom::blink::Role::kComplementary; if (GetNode()->HasTagName(html_names::kPreTag)) - return ax::mojom::Role::kPre; + return ax::mojom::blink::Role::kPre; if (GetNode()->HasTagName(html_names::kSectionTag)) - return ax::mojom::Role::kSection; + return ax::mojom::blink::Role::kSection; if (GetNode()->HasTagName(html_names::kAddressTag)) - return ax::mojom::Role::kGenericContainer; + return RoleFromLayoutObject(ax::mojom::blink::Role::kGenericContainer); if (IsA<HTMLDialogElement>(*GetNode())) - return ax::mojom::Role::kDialog; + return ax::mojom::blink::Role::kDialog; // The HTML element. if (IsA<HTMLHtmlElement>(GetNode())) - return ax::mojom::Role::kGenericContainer; + return RoleFromLayoutObject(ax::mojom::blink::Role::kGenericContainer); // Treat <iframe> and <frame> the same. if (IsA<HTMLIFrameElement>(*GetNode()) || IsA<HTMLFrameElement>(*GetNode())) { const AtomicString& aria_role = GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRole); if (aria_role == "none" || aria_role == "presentation") - return ax::mojom::Role::kIframePresentational; - return ax::mojom::Role::kIframe; + return ax::mojom::blink::Role::kIframePresentational; + return ax::mojom::blink::Role::kIframe; } // There should only be one banner/contentInfo per page. If header/footer are @@ -868,59 +889,60 @@ ax::mojom::Role AXNodeObject::NativeRoleIgnoringAria() const { // whole page's banner/contentInfo but as a generic container role. if (GetNode()->HasTagName(html_names::kHeaderTag)) { if (IsDescendantOfElementType(GetLandmarkRolesNotAllowed())) - return ax::mojom::Role::kHeaderAsNonLandmark; - return ax::mojom::Role::kHeader; + return ax::mojom::blink::Role::kHeaderAsNonLandmark; + return ax::mojom::blink::Role::kHeader; } if (GetNode()->HasTagName(html_names::kFooterTag)) { if (IsDescendantOfElementType(GetLandmarkRolesNotAllowed())) - return ax::mojom::Role::kFooterAsNonLandmark; - return ax::mojom::Role::kFooter; + return ax::mojom::blink::Role::kFooterAsNonLandmark; + return ax::mojom::blink::Role::kFooter; } if (GetNode()->HasTagName(html_names::kBlockquoteTag)) - return ax::mojom::Role::kBlockquote; + return ax::mojom::blink::Role::kBlockquote; if (GetNode()->HasTagName(html_names::kCaptionTag)) - return ax::mojom::Role::kCaption; + return ax::mojom::blink::Role::kCaption; if (GetNode()->HasTagName(html_names::kFigcaptionTag)) - return ax::mojom::Role::kFigcaption; + return ax::mojom::blink::Role::kFigcaption; if (GetNode()->HasTagName(html_names::kFigureTag)) - return ax::mojom::Role::kFigure; + return ax::mojom::blink::Role::kFigure; if (GetNode()->HasTagName(html_names::kTimeTag)) - return ax::mojom::Role::kTime; + return ax::mojom::blink::Role::kTime; if (IsA<HTMLPlugInElement>(GetNode())) { if (IsA<HTMLEmbedElement>(GetNode())) - return ax::mojom::Role::kEmbeddedObject; - return ax::mojom::Role::kPluginObject; + return ax::mojom::blink::Role::kEmbeddedObject; + return ax::mojom::blink::Role::kPluginObject; } if (IsA<HTMLHRElement>(*GetNode())) - return ax::mojom::Role::kSplitter; + return ax::mojom::blink::Role::kSplitter; if (IsFieldset()) - return ax::mojom::Role::kGroup; + return ax::mojom::blink::Role::kGroup; - return ax::mojom::Role::kUnknown; + return RoleFromLayoutObject(ax::mojom::blink::Role::kUnknown); } -ax::mojom::Role AXNodeObject::DetermineAccessibilityRole() { +ax::mojom::blink::Role AXNodeObject::DetermineAccessibilityRole() { if (!GetNode()) - return ax::mojom::Role::kUnknown; + return ax::mojom::blink::Role::kUnknown; native_role_ = NativeRoleIgnoringAria(); - if ((aria_role_ = DetermineAriaRoleAttribute()) != ax::mojom::Role::kUnknown) + if ((aria_role_ = DetermineAriaRoleAttribute()) != + ax::mojom::blink::Role::kUnknown) return aria_role_; if (GetNode()->IsTextNode()) - return ax::mojom::Role::kStaticText; + return ax::mojom::blink::Role::kStaticText; - return native_role_ == ax::mojom::Role::kUnknown - ? ax::mojom::Role::kGenericContainer + return native_role_ == ax::mojom::blink::Role::kUnknown + ? ax::mojom::blink::Role::kGenericContainer : native_role_; } @@ -949,9 +971,9 @@ bool AXNodeObject::IsMultiline() const { if (!node) return false; - const ax::mojom::Role role = RoleValue(); - const bool is_edit_box = role == ax::mojom::Role::kSearchBox || - role == ax::mojom::Role::kTextField; + const ax::mojom::blink::Role role = RoleValue(); + const bool is_edit_box = role == ax::mojom::blink::Role::kSearchBox || + role == ax::mojom::blink::Role::kTextField; if (!IsEditable() && !is_edit_box) return false; // Doesn't support multiline. @@ -1047,7 +1069,7 @@ static Element* SiblingWithAriaRole(String role, Node* node) { } Element* AXNodeObject::MenuItemElementForMenu() const { - if (AriaRoleAttribute() != ax::mojom::Role::kMenu) + if (AriaRoleAttribute() != ax::mojom::blink::Role::kMenu) return nullptr; return SiblingWithAriaRole("menuitem", GetNode()); @@ -1117,6 +1139,21 @@ bool AXNodeObject::IsControllingVideoElement() const { MediaControlElementsHelper::ToParentMediaElement(node)); } +bool AXNodeObject::IsDefault() const { + if (IsDetached()) + return false; + + // Checks for any kind of disabled, including aria-disabled. + if (Restriction() == kRestrictionDisabled || + RoleValue() != ax::mojom::blink::Role::kButton) { + return false; + } + + // Will only match :default pseudo class if it's the first default button in + // a form. + return GetElement()->MatchesDefaultPseudoClass(); +} + bool AXNodeObject::ComputeIsEditableRoot() const { Node* node = GetNode(); if (!node) @@ -1148,7 +1185,7 @@ bool AXNodeObject::IsImageButton() const { bool AXNodeObject::IsInputImage() const { auto* html_input_element = DynamicTo<HTMLInputElement>(this->GetNode()); - if (html_input_element && RoleValue() == ax::mojom::Role::kButton) + if (html_input_element && RoleValue() == ax::mojom::blink::Role::kButton) return html_input_element->type() == input_type_names::kImage; return false; @@ -1178,13 +1215,19 @@ bool AXNodeObject::IsInPageLinkTarget() const { return false; } +bool AXNodeObject::IsLoaded() const { + if (!GetDocument()) + return false; + return !GetDocument()->Parser(); +} + bool AXNodeObject::IsMultiSelectable() const { switch (RoleValue()) { - case ax::mojom::Role::kGrid: - case ax::mojom::Role::kTreeGrid: - case ax::mojom::Role::kTree: - case ax::mojom::Role::kListBox: - case ax::mojom::Role::kTabList: { + case ax::mojom::blink::Role::kGrid: + case ax::mojom::blink::Role::kTreeGrid: + case ax::mojom::blink::Role::kTree: + case ax::mojom::blink::Role::kListBox: + case ax::mojom::blink::Role::kTabList: { bool multiselectable = false; if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kMultiselectable, multiselectable)) { @@ -1258,16 +1301,16 @@ bool AXNodeObject::IsPasswordField() const { if (!html_input_element) return false; - ax::mojom::Role aria_role = AriaRoleAttribute(); - if (aria_role != ax::mojom::Role::kTextField && - aria_role != ax::mojom::Role::kUnknown) + ax::mojom::blink::Role aria_role = AriaRoleAttribute(); + if (aria_role != ax::mojom::blink::Role::kTextField && + aria_role != ax::mojom::blink::Role::kUnknown) return false; return html_input_element->type() == input_type_names::kPassword; } bool AXNodeObject::IsProgressIndicator() const { - return RoleValue() == ax::mojom::Role::kProgressIndicator; + return RoleValue() == ax::mojom::blink::Role::kProgressIndicator; } bool AXNodeObject::IsRichlyEditable() const { @@ -1275,11 +1318,11 @@ bool AXNodeObject::IsRichlyEditable() const { } bool AXNodeObject::IsSlider() const { - return RoleValue() == ax::mojom::Role::kSlider; + return RoleValue() == ax::mojom::blink::Role::kSlider; } bool AXNodeObject::IsSpinButton() const { - return RoleValue() == ax::mojom::Role::kSpinButton; + return RoleValue() == ax::mojom::blink::Role::kSpinButton; } bool AXNodeObject::IsNativeSlider() const { @@ -1365,8 +1408,8 @@ AXRestriction AXNodeObject::Restriction() const { if (row && row->IsTableRowLikeRole()) { AXObject* table = row->ParentObjectUnignored(); if (table && table->IsTableLikeRole() && - (table->RoleValue() == ax::mojom::Role::kGrid || - table->RoleValue() == ax::mojom::Role::kTreeGrid)) { + (table->RoleValue() == ax::mojom::blink::Role::kGrid || + table->RoleValue() == ax::mojom::blink::Role::kTreeGrid)) { if (table->Restriction() == kRestrictionReadOnly) return kRestrictionReadOnly; } @@ -1399,8 +1442,8 @@ AccessibilityExpanded AXNodeObject::IsExpanded() const { } bool AXNodeObject::IsModal() const { - if (RoleValue() != ax::mojom::Role::kDialog && - RoleValue() != ax::mojom::Role::kAlertDialog) + if (RoleValue() != ax::mojom::blink::Role::kDialog && + RoleValue() != ax::mojom::blink::Role::kAlertDialog) return false; bool modal = false; @@ -1437,7 +1480,7 @@ int AXNodeObject::HeadingLevel() const { if (!node) return 0; - if (RoleValue() == ax::mojom::Role::kHeading) { + if (RoleValue() == ax::mojom::blink::Role::kHeading) { uint32_t level; if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kLevel, level)) { if (level >= 1 && level <= 9) @@ -1467,7 +1510,7 @@ int AXNodeObject::HeadingLevel() const { if (element->HasTagName(html_names::kH6Tag)) return 6; - if (RoleValue() == ax::mojom::Role::kHeading) + if (RoleValue() == ax::mojom::blink::Role::kHeading) return kDefaultHeadingLevel; return 0; @@ -1486,7 +1529,8 @@ unsigned AXNodeObject::HierarchicalLevel() const { // Helper lambda for calculating hierarchical levels by counting ancestor // nodes that match a target role. - auto accumulateLevel = [&](int initial_level, ax::mojom::Role target_role) { + auto accumulateLevel = [&](int initial_level, + ax::mojom::blink::Role target_role) { int level = initial_level; for (AXObject* parent = ParentObject(); parent; parent = parent->ParentObject()) { @@ -1497,28 +1541,28 @@ unsigned AXNodeObject::HierarchicalLevel() const { }; switch (RoleValue()) { - case ax::mojom::Role::kComment: + case ax::mojom::blink::Role::kComment: // Comment: level is based on counting comment ancestors until the root. - return accumulateLevel(1, ax::mojom::Role::kComment); - case ax::mojom::Role::kListItem: - level = accumulateLevel(0, ax::mojom::Role::kList); + return accumulateLevel(1, ax::mojom::blink::Role::kComment); + case ax::mojom::blink::Role::kListItem: + level = accumulateLevel(0, ax::mojom::blink::Role::kList); // When level count is 0 due to this list item not having an ancestor of // Role::kList, not nested in list groups, this list item has a level // of 1. return level == 0 ? 1 : level; - case ax::mojom::Role::kTabList: - return accumulateLevel(1, ax::mojom::Role::kTabList); - case ax::mojom::Role::kTreeItem: { + case ax::mojom::blink::Role::kTabList: + return accumulateLevel(1, ax::mojom::blink::Role::kTabList); + case ax::mojom::blink::Role::kTreeItem: { // Hierarchy leveling starts at 1, to match the aria-level spec. // We measure tree hierarchy by the number of groups that the item is // within. level = 1; for (AXObject* parent = ParentObject(); parent; parent = parent->ParentObject()) { - ax::mojom::Role parent_role = parent->RoleValue(); - if (parent_role == ax::mojom::Role::kGroup) + ax::mojom::blink::Role parent_role = parent->RoleValue(); + if (parent_role == ax::mojom::blink::Role::kGroup) level++; - else if (parent_role == ax::mojom::Role::kTree) + else if (parent_role == ax::mojom::blink::Role::kTree) break; } return level; @@ -1671,27 +1715,27 @@ AccessibilityOrientation AXNodeObject::Orientation() const { orientation = kAccessibilityOrientationVertical; switch (RoleValue()) { - case ax::mojom::Role::kListBox: - case ax::mojom::Role::kMenu: - case ax::mojom::Role::kScrollBar: - case ax::mojom::Role::kTree: + case ax::mojom::blink::Role::kListBox: + case ax::mojom::blink::Role::kMenu: + case ax::mojom::blink::Role::kScrollBar: + case ax::mojom::blink::Role::kTree: if (orientation == kAccessibilityOrientationUndefined) orientation = kAccessibilityOrientationVertical; return orientation; - case ax::mojom::Role::kMenuBar: - case ax::mojom::Role::kSlider: - case ax::mojom::Role::kSplitter: - case ax::mojom::Role::kTabList: - case ax::mojom::Role::kToolbar: + case ax::mojom::blink::Role::kMenuBar: + case ax::mojom::blink::Role::kSlider: + case ax::mojom::blink::Role::kSplitter: + case ax::mojom::blink::Role::kTabList: + case ax::mojom::blink::Role::kToolbar: if (orientation == kAccessibilityOrientationUndefined) orientation = kAccessibilityOrientationHorizontal; return orientation; - case ax::mojom::Role::kComboBoxGrouping: - case ax::mojom::Role::kComboBoxMenuButton: - case ax::mojom::Role::kRadioGroup: - case ax::mojom::Role::kTreeGrid: + case ax::mojom::blink::Role::kComboBoxGrouping: + case ax::mojom::blink::Role::kComboBoxMenuButton: + case ax::mojom::blink::Role::kRadioGroup: + case ax::mojom::blink::Role::kTreeGrid: return orientation; default: return AXObject::Orientation(); @@ -1700,7 +1744,7 @@ AccessibilityOrientation AXNodeObject::Orientation() const { AXObject::AXObjectVector AXNodeObject::RadioButtonsInGroup() const { AXObjectVector radio_buttons; - if (!node_ || RoleValue() != ax::mojom::Role::kRadioButton) + if (!node_ || RoleValue() != ax::mojom::blink::Role::kRadioButton) return radio_buttons; if (auto* node_radio_button = DynamicTo<HTMLInputElement>(node_.Get())) { @@ -1717,10 +1761,10 @@ AXObject::AXObjectVector AXNodeObject::RadioButtonsInGroup() const { // If the immediate parent is a radio group, return all its children that are // radio buttons. AXObject* parent = ParentObject(); - if (parent && parent->RoleValue() == ax::mojom::Role::kRadioGroup) { - for (AXObject* child : parent->Children()) { + if (parent && parent->RoleValue() == ax::mojom::blink::Role::kRadioGroup) { + for (AXObject* child : parent->ChildrenIncludingIgnored()) { DCHECK(child); - if (child->RoleValue() == ax::mojom::Role::kRadioButton && + if (child->RoleValue() == ax::mojom::blink::Role::kRadioButton && child->AccessibilityIsIncludedInTree()) { radio_buttons.push_back(child); } @@ -1777,6 +1821,89 @@ String AXNodeObject::GetText() const { return element ? element->innerText() : String(); } +String AXNodeObject::ImageDataUrl(const IntSize& max_size) const { + Node* node = GetNode(); + if (!node) + return String(); + + ImageBitmapOptions* options = ImageBitmapOptions::Create(); + ImageBitmap* image_bitmap = nullptr; + if (auto* image = DynamicTo<HTMLImageElement>(node)) { + image_bitmap = MakeGarbageCollected<ImageBitmap>( + image, base::Optional<IntRect>(), options); + } else if (auto* canvas = DynamicTo<HTMLCanvasElement>(node)) { + image_bitmap = MakeGarbageCollected<ImageBitmap>( + canvas, base::Optional<IntRect>(), options); + } else if (auto* video = DynamicTo<HTMLVideoElement>(node)) { + image_bitmap = MakeGarbageCollected<ImageBitmap>( + video, base::Optional<IntRect>(), options); + } + if (!image_bitmap) + return String(); + + scoped_refptr<StaticBitmapImage> bitmap_image = image_bitmap->BitmapImage(); + if (!bitmap_image) + return String(); + + sk_sp<SkImage> image = bitmap_image->PaintImageForCurrentFrame().GetSkImage(); + if (!image || image->width() <= 0 || image->height() <= 0) + return String(); + + // Determine the width and height of the output image, using a proportional + // scale factor such that it's no larger than |maxSize|, if |maxSize| is not + // empty. It only resizes the image to be smaller (if necessary), not + // larger. + float x_scale = + max_size.Width() ? max_size.Width() * 1.0 / image->width() : 1.0; + float y_scale = + max_size.Height() ? max_size.Height() * 1.0 / image->height() : 1.0; + float scale = std::min(x_scale, y_scale); + if (scale >= 1.0) + scale = 1.0; + int width = std::round(image->width() * scale); + int height = std::round(image->height() * scale); + + // Draw the scaled image into a bitmap in native format. + SkBitmap bitmap; + bitmap.allocPixels(SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType)); + SkCanvas canvas(bitmap); + canvas.clear(SK_ColorTRANSPARENT); + canvas.drawImageRect(image, SkRect::MakeIWH(width, height), nullptr); + + // Copy the bits into a buffer in RGBA_8888 unpremultiplied format + // for encoding. + SkImageInfo info = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType, + kUnpremul_SkAlphaType); + size_t row_bytes = info.minRowBytes(); + Vector<char> pixel_storage( + SafeCast<wtf_size_t>(info.computeByteSize(row_bytes))); + SkPixmap pixmap(info, pixel_storage.data(), row_bytes); + if (!SkImage::MakeFromBitmap(bitmap)->readPixels(pixmap, 0, 0)) + return String(); + + // Encode as a PNG and return as a data url. + std::unique_ptr<ImageDataBuffer> buffer = ImageDataBuffer::Create(pixmap); + + if (!buffer) + return String(); + + return buffer->ToDataURL(kMimeTypePng, 1.0); +} + +const AtomicString& AXNodeObject::AccessKey() const { + auto* element = DynamicTo<Element>(GetNode()); + if (!element) + return g_null_atom; + return element->FastGetAttribute(html_names::kAccesskeyAttr); +} + +int AXNodeObject::TextLength() const { + if (!IsTextControl()) + return -1; + + return GetText().length(); +} + RGBA32 AXNodeObject::ColorValue() const { auto* input = DynamicTo<HTMLInputElement>(GetNode()); if (!input || !IsColorWell()) @@ -1793,54 +1920,147 @@ RGBA32 AXNodeObject::ColorValue() const { return color.Rgb(); } -ax::mojom::AriaCurrentState AXNodeObject::GetAriaCurrentState() const { +RGBA32 AXNodeObject::ComputeBackgroundColor() const { + if (!GetLayoutObject()) + return AXObject::BackgroundColor(); + + Color blended_color = Color::kTransparent; + // Color::blend should be called like this: background.blend(foreground). + for (LayoutObject* layout_object = GetLayoutObject(); layout_object; + layout_object = layout_object->Parent()) { + const AXObject* ax_parent = AXObjectCache().GetOrCreate(layout_object); + if (ax_parent && ax_parent != this) { + Color parent_color = ax_parent->BackgroundColor(); + blended_color = parent_color.Blend(blended_color); + return blended_color.Rgb(); + } + + const ComputedStyle* style = layout_object->Style(); + if (!style || !style->HasBackground()) + continue; + + Color current_color = + style->VisitedDependentColor(GetCSSPropertyBackgroundColor()); + blended_color = current_color.Blend(blended_color); + // Continue blending until we get no transparency. + if (!blended_color.HasAlpha()) + break; + } + + // If we still have some transparency, blend in the document base color. + if (blended_color.HasAlpha()) { + LocalFrameView* view = DocumentFrameView(); + if (view) { + Color document_base_color = view->BaseBackgroundColor(); + blended_color = document_base_color.Blend(blended_color); + } else { + // Default to a white background. + blended_color.BlendWithWhite(); + } + } + + return blended_color.Rgb(); +} + +RGBA32 AXNodeObject::GetColor() const { + if (!GetLayoutObject() || IsColorWell()) + return AXObject::GetColor(); + + const ComputedStyle* style = GetLayoutObject()->Style(); + if (!style) + return AXObject::GetColor(); + + Color color = style->VisitedDependentColor(GetCSSPropertyColor()); + return color.Rgb(); +} + +String AXNodeObject::FontFamily() const { + if (!GetLayoutObject()) + return AXObject::FontFamily(); + + const ComputedStyle* style = GetLayoutObject()->Style(); + if (!style) + return AXObject::FontFamily(); + + const SimpleFontData* primary_font = style->GetFont().PrimaryFont(); + if (!primary_font) + return AXObject::FontFamily(); + + return primary_font->PlatformData().FontFamilyName(); +} + +// Font size is in pixels. +float AXNodeObject::FontSize() const { + if (!GetLayoutObject()) + return AXObject::FontSize(); + + const ComputedStyle* style = GetLayoutObject()->Style(); + if (!style) + return AXObject::FontSize(); + + return style->ComputedFontSize(); +} + +float AXNodeObject::FontWeight() const { + if (!GetLayoutObject()) + return AXObject::FontWeight(); + + const ComputedStyle* style = GetLayoutObject()->Style(); + if (!style) + return AXObject::FontWeight(); + + return style->GetFontWeight(); +} + +ax::mojom::blink::AriaCurrentState AXNodeObject::GetAriaCurrentState() const { const AtomicString& attribute_value = GetAOMPropertyOrARIAAttribute(AOMStringProperty::kCurrent); if (attribute_value.IsNull()) - return ax::mojom::AriaCurrentState::kNone; + return ax::mojom::blink::AriaCurrentState::kNone; if (attribute_value.IsEmpty() || EqualIgnoringASCIICase(attribute_value, "false")) - return ax::mojom::AriaCurrentState::kFalse; + return ax::mojom::blink::AriaCurrentState::kFalse; if (EqualIgnoringASCIICase(attribute_value, "true")) - return ax::mojom::AriaCurrentState::kTrue; + return ax::mojom::blink::AriaCurrentState::kTrue; if (EqualIgnoringASCIICase(attribute_value, "page")) - return ax::mojom::AriaCurrentState::kPage; + return ax::mojom::blink::AriaCurrentState::kPage; if (EqualIgnoringASCIICase(attribute_value, "step")) - return ax::mojom::AriaCurrentState::kStep; + return ax::mojom::blink::AriaCurrentState::kStep; if (EqualIgnoringASCIICase(attribute_value, "location")) - return ax::mojom::AriaCurrentState::kLocation; + return ax::mojom::blink::AriaCurrentState::kLocation; if (EqualIgnoringASCIICase(attribute_value, "date")) - return ax::mojom::AriaCurrentState::kDate; + return ax::mojom::blink::AriaCurrentState::kDate; if (EqualIgnoringASCIICase(attribute_value, "time")) - return ax::mojom::AriaCurrentState::kTime; + return ax::mojom::blink::AriaCurrentState::kTime; // An unknown value should return true. if (!attribute_value.IsEmpty()) - return ax::mojom::AriaCurrentState::kTrue; + return ax::mojom::blink::AriaCurrentState::kTrue; return AXObject::GetAriaCurrentState(); } -ax::mojom::InvalidState AXNodeObject::GetInvalidState() const { +ax::mojom::blink::InvalidState AXNodeObject::GetInvalidState() const { const AtomicString& attribute_value = GetAOMPropertyOrARIAAttribute(AOMStringProperty::kInvalid); if (EqualIgnoringASCIICase(attribute_value, "false")) - return ax::mojom::InvalidState::kFalse; + return ax::mojom::blink::InvalidState::kFalse; if (EqualIgnoringASCIICase(attribute_value, "true")) - return ax::mojom::InvalidState::kTrue; + return ax::mojom::blink::InvalidState::kTrue; // "spelling" and "grammar" are also invalid values: they are exposed via // Markers() as if they are native errors, but also use the invalid entry // state on the node itself, therefore they are treated like "true". // in terms of the node's invalid state // A yet unknown value. if (!attribute_value.IsEmpty()) - return ax::mojom::InvalidState::kOther; + return ax::mojom::blink::InvalidState::kOther; if (GetElement()) { ListedElement* form_control = ListedElement::From(*GetElement()); if (form_control) { - return form_control->IsNotCandidateOrValid() - ? ax::mojom::InvalidState::kFalse - : ax::mojom::InvalidState::kTrue; + if (form_control->IsNotCandidateOrValid()) + return ax::mojom::blink::InvalidState::kFalse; + else + return ax::mojom::blink::InvalidState::kTrue; } } return AXObject::GetInvalidState(); @@ -1865,7 +2085,7 @@ int AXNodeObject::SetSize() const { } String AXNodeObject::AriaInvalidValue() const { - if (GetInvalidState() == ax::mojom::InvalidState::kOther) + if (GetInvalidState() == ax::mojom::blink::InvalidState::kOther) return GetAOMPropertyOrARIAAttribute(AOMStringProperty::kInvalid); return String(); @@ -1901,8 +2121,8 @@ bool AXNodeObject::ValueForRange(float* out_value) const { // - separator : 50 // - spinbutton : 0 switch (AriaRoleAttribute()) { - case ax::mojom::Role::kScrollBar: - case ax::mojom::Role::kSlider: { + case ax::mojom::blink::Role::kScrollBar: + case ax::mojom::blink::Role::kSlider: { float min_value, max_value; if (MinValueForRange(&min_value) && MaxValueForRange(&max_value)) { *out_value = (min_value + max_value) / 2.0f; @@ -1910,11 +2130,11 @@ bool AXNodeObject::ValueForRange(float* out_value) const { } FALLTHROUGH; } - case ax::mojom::Role::kSplitter: { + case ax::mojom::blink::Role::kSplitter: { *out_value = 50.0f; return true; } - case ax::mojom::Role::kSpinButton: { + case ax::mojom::blink::Role::kSpinButton: { *out_value = 0.0f; return true; } @@ -1945,9 +2165,9 @@ bool AXNodeObject::MaxValueForRange(float* out_value) const { // In ARIA 1.1, default value of scrollbar, separator and slider // for aria-valuemax were changed to 100. switch (AriaRoleAttribute()) { - case ax::mojom::Role::kScrollBar: - case ax::mojom::Role::kSplitter: - case ax::mojom::Role::kSlider: { + case ax::mojom::blink::Role::kScrollBar: + case ax::mojom::blink::Role::kSplitter: + case ax::mojom::blink::Role::kSlider: { *out_value = 100.0f; return true; } @@ -1978,9 +2198,9 @@ bool AXNodeObject::MinValueForRange(float* out_value) const { // In ARIA 1.1, default value of scrollbar, separator and slider // for aria-valuemin were changed to 0. switch (AriaRoleAttribute()) { - case ax::mojom::Role::kScrollBar: - case ax::mojom::Role::kSplitter: - case ax::mojom::Role::kSlider: { + case ax::mojom::blink::Role::kScrollBar: + case ax::mojom::blink::Role::kSplitter: + case ax::mojom::blink::Role::kSlider: { *out_value = 0.0f; return true; } @@ -2000,9 +2220,9 @@ bool AXNodeObject::StepValueForRange(float* out_value) const { } switch (AriaRoleAttribute()) { - case ax::mojom::Role::kScrollBar: - case ax::mojom::Role::kSplitter: - case ax::mojom::Role::kSlider: { + case ax::mojom::blink::Role::kScrollBar: + case ax::mojom::blink::Role::kSplitter: + case ax::mojom::blink::Role::kSlider: { *out_value = 0.0f; return true; } @@ -2050,9 +2270,9 @@ AXObject* AXNodeObject::ChooserPopup() const { // When color & date chooser popups are visible, they can be found in the tree // as a WebArea child of the <input> control itself. switch (native_role_) { - case ax::mojom::Role::kColorWell: - case ax::mojom::Role::kDate: - case ax::mojom::Role::kDateTime: { + case ax::mojom::blink::Role::kColorWell: + case ax::mojom::blink::Role::kDate: + case ax::mojom::blink::Role::kDateTime: { for (const auto& child : children_) { if (child->IsWebArea()) return child; @@ -2106,7 +2326,7 @@ String AXNodeObject::StringValue() const { } // ARIA combobox can get value from inner contents. - if (AriaRoleAttribute() == ax::mojom::Role::kComboBoxMenuButton) { + if (AriaRoleAttribute() == ax::mojom::blink::Role::kComboBoxMenuButton) { AXObjectSet visited; return TextFromDescendants(visited, false); } @@ -2114,7 +2334,7 @@ String AXNodeObject::StringValue() const { return String(); } -ax::mojom::Role AXNodeObject::AriaRoleAttribute() const { +ax::mojom::blink::Role AXNodeObject::AriaRoleAttribute() const { return aria_role_; } @@ -2124,7 +2344,7 @@ bool AXNodeObject::HasAriaAttribute() const { return false; // Explicit ARIA role should be considered an aria attribute. - if (AriaRoleAttribute() != ax::mojom::Role::kUnknown) + if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown) return true; AttributeCollection attributes = element->AttributesWithoutUpdate(); @@ -2137,6 +2357,147 @@ bool AXNodeObject::HasAriaAttribute() const { return false; } +void AXNodeObject::AriaDescribedbyElements(AXObjectVector& describedby) const { + AccessibilityChildrenFromAOMProperty(AOMRelationListProperty::kDescribedBy, + describedby); +} + +void AXNodeObject::AriaOwnsElements(AXObjectVector& owns) const { + AccessibilityChildrenFromAOMProperty(AOMRelationListProperty::kOwns, owns); +} + +bool AXNodeObject::SupportsARIAOwns() const { + if (!GetLayoutObject()) + return false; + const AtomicString& aria_owns = GetAttribute(html_names::kAriaOwnsAttr); + + return !aria_owns.IsEmpty(); +} + +// TODO : Aria-dropeffect and aria-grabbed are deprecated in aria 1.1 +// Also those properties are expected to be replaced by a new feature in +// a future version of WAI-ARIA. After that we will re-implement them +// following new spec. +bool AXNodeObject::SupportsARIADragging() const { + const AtomicString& grabbed = GetAttribute(html_names::kAriaGrabbedAttr); + return EqualIgnoringASCIICase(grabbed, "true") || + EqualIgnoringASCIICase(grabbed, "false"); +} + +ax::mojom::blink::Dropeffect AXNodeObject::ParseDropeffect( + String& dropeffect) const { + if (EqualIgnoringASCIICase(dropeffect, "copy")) + return ax::mojom::blink::Dropeffect::kCopy; + if (EqualIgnoringASCIICase(dropeffect, "execute")) + return ax::mojom::blink::Dropeffect::kExecute; + if (EqualIgnoringASCIICase(dropeffect, "link")) + return ax::mojom::blink::Dropeffect::kLink; + if (EqualIgnoringASCIICase(dropeffect, "move")) + return ax::mojom::blink::Dropeffect::kMove; + if (EqualIgnoringASCIICase(dropeffect, "popup")) + return ax::mojom::blink::Dropeffect::kPopup; + return ax::mojom::blink::Dropeffect::kNone; +} + +void AXNodeObject::Dropeffects( + Vector<ax::mojom::blink::Dropeffect>& dropeffects) const { + if (!HasAttribute(html_names::kAriaDropeffectAttr)) + return; + + Vector<String> str_dropeffects; + TokenVectorFromAttribute(str_dropeffects, html_names::kAriaDropeffectAttr); + + if (str_dropeffects.IsEmpty()) { + dropeffects.push_back(ax::mojom::blink::Dropeffect::kNone); + return; + } + + for (auto&& str : str_dropeffects) { + dropeffects.push_back(ParseDropeffect(str)); + } +} + +// +// ARIA live-region features. +// + +const AtomicString& AXNodeObject::LiveRegionStatus() const { + DEFINE_STATIC_LOCAL(const AtomicString, live_region_status_assertive, + ("assertive")); + DEFINE_STATIC_LOCAL(const AtomicString, live_region_status_polite, + ("polite")); + DEFINE_STATIC_LOCAL(const AtomicString, live_region_status_off, ("off")); + + const AtomicString& live_region_status = + GetAOMPropertyOrARIAAttribute(AOMStringProperty::kLive); + // These roles have implicit live region status. + if (live_region_status.IsEmpty()) { + switch (RoleValue()) { + case ax::mojom::blink::Role::kAlert: + return live_region_status_assertive; + case ax::mojom::blink::Role::kLog: + case ax::mojom::blink::Role::kStatus: + return live_region_status_polite; + case ax::mojom::blink::Role::kTimer: + case ax::mojom::blink::Role::kMarquee: + return live_region_status_off; + default: + break; + } + } + + return live_region_status; +} + +const AtomicString& AXNodeObject::LiveRegionRelevant() const { + DEFINE_STATIC_LOCAL(const AtomicString, default_live_region_relevant, + ("additions text")); + const AtomicString& relevant = + GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRelevant); + + // Default aria-relevant = "additions text". + if (relevant.IsEmpty()) + return default_live_region_relevant; + + return relevant; +} + +ax::mojom::blink::HasPopup AXNodeObject::HasPopup() const { + const AtomicString& has_popup = + GetAOMPropertyOrARIAAttribute(AOMStringProperty::kHasPopUp); + if (!has_popup.IsNull()) { + if (EqualIgnoringASCIICase(has_popup, "false")) + return ax::mojom::blink::HasPopup::kFalse; + + if (EqualIgnoringASCIICase(has_popup, "listbox")) + return ax::mojom::blink::HasPopup::kListbox; + + if (EqualIgnoringASCIICase(has_popup, "tree")) + return ax::mojom::blink::HasPopup::kTree; + + if (EqualIgnoringASCIICase(has_popup, "grid")) + return ax::mojom::blink::HasPopup::kGrid; + + if (EqualIgnoringASCIICase(has_popup, "dialog")) + return ax::mojom::blink::HasPopup::kDialog; + + // To provide backward compatibility with ARIA 1.0 content, + // user agents MUST treat an aria-haspopup value of true + // as equivalent to a value of menu. + // And unknown value also return menu too. + if (EqualIgnoringASCIICase(has_popup, "true") || + EqualIgnoringASCIICase(has_popup, "menu") || !has_popup.IsEmpty()) + return ax::mojom::blink::HasPopup::kMenu; + } + + // ARIA 1.1 default value of haspopup for combobox is "listbox". + if (RoleValue() == ax::mojom::blink::Role::kComboBoxMenuButton || + RoleValue() == ax::mojom::blink::Role::kTextFieldWithComboBox) + return ax::mojom::blink::HasPopup::kListbox; + + return AXObject::HasPopup(); +} + // Returns the nearest block-level LayoutBlockFlow ancestor static LayoutBlockFlow* NonInlineBlockFlow(LayoutObject* object) { LayoutObject* current = object; @@ -2167,10 +2528,11 @@ static bool IsInSameNonInlineBlockFlow(LayoutObject* r1, LayoutObject* r2) { // New AX name calculation. // -String AXNodeObject::GetName(ax::mojom::NameFrom& name_from, +String AXNodeObject::GetName(ax::mojom::blink::NameFrom& name_from, AXObjectVector* name_objects) const { String name = AXObject::GetName(name_from, name_objects); - if (RoleValue() == ax::mojom::Role::kSpinButton && DatetimeAncestor()) { + if (RoleValue() == ax::mojom::blink::Role::kSpinButton && + DatetimeAncestor()) { // Fields inside a datetime control need to merge the field name with // the name of the <input> element. name_objects->clear(); @@ -2185,7 +2547,7 @@ String AXNodeObject::GetName(ax::mojom::NameFrom& name_from, String AXNodeObject::TextAlternative(bool recursive, bool in_aria_labelled_by_traversal, AXObjectSet& visited, - ax::mojom::NameFrom& name_from, + ax::mojom::blink::NameFrom& name_from, AXRelatedObjectVector* related_objects, NameSources* name_sources) const { // If nameSources is non-null, relatedObjects is used in filling it in, so it @@ -2257,7 +2619,7 @@ String AXNodeObject::TextAlternative(bool recursive, &found_text_alternative); const bool has_text_alternative = !text_alternative.IsEmpty() || - name_from == ax::mojom::NameFrom::kAttributeExplicitlyEmpty; + name_from == ax::mojom::blink::NameFrom::kAttributeExplicitlyEmpty; if (has_text_alternative && !name_sources) return text_alternative; @@ -2265,7 +2627,7 @@ String AXNodeObject::TextAlternative(bool recursive, if (in_aria_labelled_by_traversal || NameFromContents(recursive)) { Node* node = GetNode(); if (!IsA<HTMLSelectElement>(node)) { // Avoid option descendant text - name_from = ax::mojom::NameFrom::kContents; + name_from = ax::mojom::blink::NameFrom::kContents; if (name_sources) { name_sources->push_back(NameSource(found_text_alternative)); name_sources->back().type = name_from; @@ -2290,7 +2652,7 @@ String AXNodeObject::TextAlternative(bool recursive, } // Step 2H from: http://www.w3.org/TR/accname-aam-1.1 - name_from = ax::mojom::NameFrom::kTitle; + name_from = ax::mojom::blink::NameFrom::kTitle; if (name_sources) { name_sources->push_back(NameSource(found_text_alternative, kTitleAttr)); name_sources->back().type = name_from; @@ -2298,7 +2660,7 @@ String AXNodeObject::TextAlternative(bool recursive, const AtomicString& title = GetAttribute(kTitleAttr); if (!title.IsEmpty()) { text_alternative = title; - name_from = ax::mojom::NameFrom::kTitle; + name_from = ax::mojom::blink::NameFrom::kTitle; if (name_sources) { found_text_alternative = true; name_sources->back().text = text_alternative; @@ -2307,7 +2669,7 @@ String AXNodeObject::TextAlternative(bool recursive, } } - name_from = ax::mojom::NameFrom::kUninitialized; + name_from = ax::mojom::blink::NameFrom::kUninitialized; if (name_sources && found_text_alternative) { for (NameSource& name_source : *name_sources) { @@ -2326,8 +2688,8 @@ String AXNodeObject::TextAlternative(bool recursive, static bool ShouldInsertSpaceBetweenObjectsIfNeeded( AXObject* previous, AXObject* next, - ax::mojom::NameFrom last_used_name_from, - ax::mojom::NameFrom name_from) { + ax::mojom::blink::NameFrom last_used_name_from, + ax::mojom::blink::NameFrom name_from) { // If we're going between two layoutObjects that are in separate // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if // you have <span>Hello</span><span>World</span>, those are part of the same @@ -2343,31 +2705,31 @@ static bool ShouldInsertSpaceBetweenObjectsIfNeeded( // the strings. Doing so is consistent with what is stated in the AccName // spec and with what is done in other user agents. switch (last_used_name_from) { - case ax::mojom::NameFrom::kNone: - case ax::mojom::NameFrom::kUninitialized: - case ax::mojom::NameFrom::kAttributeExplicitlyEmpty: - case ax::mojom::NameFrom::kContents: + case ax::mojom::blink::NameFrom::kNone: + case ax::mojom::blink::NameFrom::kUninitialized: + case ax::mojom::blink::NameFrom::kAttributeExplicitlyEmpty: + case ax::mojom::blink::NameFrom::kContents: break; - case ax::mojom::NameFrom::kAttribute: - case ax::mojom::NameFrom::kCaption: - case ax::mojom::NameFrom::kPlaceholder: - case ax::mojom::NameFrom::kRelatedElement: - case ax::mojom::NameFrom::kTitle: - case ax::mojom::NameFrom::kValue: + case ax::mojom::blink::NameFrom::kAttribute: + case ax::mojom::blink::NameFrom::kCaption: + case ax::mojom::blink::NameFrom::kPlaceholder: + case ax::mojom::blink::NameFrom::kRelatedElement: + case ax::mojom::blink::NameFrom::kTitle: + case ax::mojom::blink::NameFrom::kValue: return true; } switch (name_from) { - case ax::mojom::NameFrom::kNone: - case ax::mojom::NameFrom::kUninitialized: - case ax::mojom::NameFrom::kAttributeExplicitlyEmpty: - case ax::mojom::NameFrom::kContents: + case ax::mojom::blink::NameFrom::kNone: + case ax::mojom::blink::NameFrom::kUninitialized: + case ax::mojom::blink::NameFrom::kAttributeExplicitlyEmpty: + case ax::mojom::blink::NameFrom::kContents: break; - case ax::mojom::NameFrom::kAttribute: - case ax::mojom::NameFrom::kCaption: - case ax::mojom::NameFrom::kPlaceholder: - case ax::mojom::NameFrom::kRelatedElement: - case ax::mojom::NameFrom::kTitle: - case ax::mojom::NameFrom::kValue: + case ax::mojom::blink::NameFrom::kAttribute: + case ax::mojom::blink::NameFrom::kCaption: + case ax::mojom::blink::NameFrom::kPlaceholder: + case ax::mojom::blink::NameFrom::kRelatedElement: + case ax::mojom::blink::NameFrom::kTitle: + case ax::mojom::blink::NameFrom::kValue: return true; } @@ -2383,7 +2745,8 @@ String AXNodeObject::TextFromDescendants(AXObjectSet& visited, StringBuilder accumulated_text; AXObject* previous = nullptr; - ax::mojom::NameFrom last_used_name_from = ax::mojom::NameFrom::kUninitialized; + ax::mojom::blink::NameFrom last_used_name_from = + ax::mojom::blink::NameFrom::kUninitialized; AXObjectVector children; @@ -2424,7 +2787,8 @@ String AXNodeObject::TextFromDescendants(AXObjectSet& visited, child->AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kHidden)) continue; - ax::mojom::NameFrom child_name_from = ax::mojom::NameFrom::kUninitialized; + ax::mojom::blink::NameFrom child_name_from = + ax::mojom::blink::NameFrom::kUninitialized; String result; if (!is_continuation && child->IsPresentational()) { if (child->IsVisible()) @@ -2733,7 +3097,7 @@ void AXNodeObject::AddHiddenChildren() { if (AXObject* child_object = AXObjectCache().Get(child.GetLayoutObject())) { if (!child_object->AccessibilityIsIncludedInTree()) { - const auto& children = child_object->Children(); + const auto& children = child_object->ChildrenIncludingIgnored(); child_object = children.size() ? children.back().Get() : nullptr; } if (child_object) @@ -2802,7 +3166,7 @@ void AXNodeObject::AddRemoteSVGChildren() { root->SetParent(this); if (!root->AccessibilityIsIncludedInTree()) { - for (const auto& child : root->Children()) + for (const auto& child : root->ChildrenIncludingIgnored()) children_.push_back(child); } else { children_.push_back(root); @@ -2910,7 +3274,7 @@ void AXNodeObject::InsertChild(AXObject* child, unsigned index) { child->ClearChildren(); if (!child->AccessibilityIsIncludedInTree()) { - const auto& children = child->Children(); + const auto& children = child->ChildrenIncludingIgnored(); wtf_size_t length = children.size(); for (wtf_size_t i = 0; i < length; ++i) children_.insert(index + i, children[i]); @@ -2936,53 +3300,53 @@ bool AXNodeObject::CanHaveChildren() const { return false; // Does not have a role, so check here switch (native_role_) { - case ax::mojom::Role::kCheckBox: - case ax::mojom::Role::kImage: - case ax::mojom::Role::kListBoxOption: - case ax::mojom::Role::kMenuButton: - case ax::mojom::Role::kMenuListOption: - case ax::mojom::Role::kMenuItem: - case ax::mojom::Role::kMenuItemCheckBox: - case ax::mojom::Role::kMenuItemRadio: - case ax::mojom::Role::kProgressIndicator: - case ax::mojom::Role::kRadioButton: - case ax::mojom::Role::kScrollBar: - // case ax::mojom::Role::kSearchBox: - case ax::mojom::Role::kSlider: - case ax::mojom::Role::kSplitter: - case ax::mojom::Role::kSwitch: - case ax::mojom::Role::kTab: - // case ax::mojom::Role::kTextField: - case ax::mojom::Role::kToggleButton: + case ax::mojom::blink::Role::kCheckBox: + case ax::mojom::blink::Role::kImage: + case ax::mojom::blink::Role::kListBoxOption: + case ax::mojom::blink::Role::kMenuButton: + case ax::mojom::blink::Role::kMenuListOption: + case ax::mojom::blink::Role::kMenuItem: + case ax::mojom::blink::Role::kMenuItemCheckBox: + case ax::mojom::blink::Role::kMenuItemRadio: + case ax::mojom::blink::Role::kProgressIndicator: + case ax::mojom::blink::Role::kRadioButton: + case ax::mojom::blink::Role::kScrollBar: + // case ax::mojom::blink::Role::kSearchBox: + case ax::mojom::blink::Role::kSlider: + case ax::mojom::blink::Role::kSplitter: + case ax::mojom::blink::Role::kSwitch: + case ax::mojom::blink::Role::kTab: + // case ax::mojom::blink::Role::kTextField: + case ax::mojom::blink::Role::kToggleButton: return false; - case ax::mojom::Role::kPopUpButton: + case ax::mojom::blink::Role::kPopUpButton: return true; - case ax::mojom::Role::kStaticText: + case ax::mojom::blink::Role::kStaticText: return AXObjectCache().InlineTextBoxAccessibilityEnabled(); default: break; } switch (AriaRoleAttribute()) { - case ax::mojom::Role::kImage: + case ax::mojom::blink::Role::kImage: return false; - case ax::mojom::Role::kCheckBox: - case ax::mojom::Role::kListBoxOption: - case ax::mojom::Role::kMath: // role="math" is flat, unlike <math> - case ax::mojom::Role::kMenuButton: - case ax::mojom::Role::kMenuListOption: - case ax::mojom::Role::kMenuItem: - case ax::mojom::Role::kMenuItemCheckBox: - case ax::mojom::Role::kMenuItemRadio: - case ax::mojom::Role::kPopUpButton: - case ax::mojom::Role::kProgressIndicator: - case ax::mojom::Role::kRadioButton: - case ax::mojom::Role::kScrollBar: - case ax::mojom::Role::kSlider: - case ax::mojom::Role::kSplitter: - case ax::mojom::Role::kSwitch: - case ax::mojom::Role::kTab: - case ax::mojom::Role::kToggleButton: { + case ax::mojom::blink::Role::kCheckBox: + case ax::mojom::blink::Role::kListBoxOption: + case ax::mojom::blink::Role::kMath: // role="math" is flat, unlike <math> + case ax::mojom::blink::Role::kMenuButton: + case ax::mojom::blink::Role::kMenuListOption: + case ax::mojom::blink::Role::kMenuItem: + case ax::mojom::blink::Role::kMenuItemCheckBox: + case ax::mojom::blink::Role::kMenuItemRadio: + case ax::mojom::blink::Role::kPopUpButton: + case ax::mojom::blink::Role::kProgressIndicator: + case ax::mojom::blink::Role::kRadioButton: + case ax::mojom::blink::Role::kScrollBar: + case ax::mojom::blink::Role::kSlider: + case ax::mojom::blink::Role::kSplitter: + case ax::mojom::blink::Role::kSwitch: + case ax::mojom::blink::Role::kTab: + case ax::mojom::blink::Role::kToggleButton: { // These roles have ChildrenPresentational: true in the ARIA spec. // We used to remove/prune all descendants of them, but that removed // useful content if the author didn't follow the spec perfectly, for @@ -3000,6 +3364,26 @@ bool AXNodeObject::CanHaveChildren() const { return true; } +// +// Properties of the object's owning document or page. +// + +double AXNodeObject::EstimatedLoadingProgress() const { + if (!GetDocument()) + return 0; + + if (IsLoaded()) + return 1.0; + + if (LocalFrame* frame = GetDocument()->GetFrame()) + return frame->Loader().Progress().EstimatedProgress(); + return 0; +} + +// +// DOM and Render tree access. +// + Element* AXNodeObject::ActionElement() const { Node* node = this->GetNode(); if (!node) @@ -3046,6 +3430,39 @@ Document* AXNodeObject::GetDocument() const { return &GetNode()->GetDocument(); } +AtomicString AXNodeObject::Language() const { + if (!GetNode()) + return AXObject::Language(); + + // If it's the root, get the computed language for the document element, + // because the root LayoutObject doesn't have the right value. + if (RoleValue() == ax::mojom::blink::Role::kRootWebArea) { + Element* document_element = GetDocument()->documentElement(); + if (!document_element) + return g_empty_atom; + + AtomicString lang = document_element->ComputeInheritedLanguage(); + if (!lang.IsEmpty()) + return lang; + } + + // Uses the style engine to figure out the object's language. + // The style engine relies on, for example, the "lang" attribute of the + // current node and its ancestors, and the document's "content-language" + // header. See the Language of a Node Spec at + // https://html.spec.whatwg.org/C/#language + const ComputedStyle* style = GetNode()->GetComputedStyle(); + if (!style || !style->Locale()) + return AXObject::Language(); + + Vector<String> languages; + String(style->Locale()).Split(',', languages); + if (languages.IsEmpty()) + return AXObject::Language(); + + return AtomicString(languages[0].StripWhiteSpace()); +} + void AXNodeObject::SetNode(Node* node) { node_ = node; } @@ -3134,9 +3551,15 @@ bool AXNodeObject::OnNativeFocusAction() { // focus() won't do anything. That is a problem when focus is removed // from the webpage to chrome, and then returns. In these cases, we need // to do what keyboard and mouse focus do, which is reset focus first. - if (document->FocusedElement() == element) + if (document->FocusedElement() == element) { document->ClearFocusedElement(); + // Calling ClearFocusedElement could result in changes to the document, + // like this AXObject becoming detached. + if (IsDetached()) + return false; + } + // If the object is not natively focusable but can be focused using an ARIA // active descendant, perform a native click instead. This will enable Web // apps that set accessibility focus using an active descendant to capture and @@ -3208,7 +3631,8 @@ void AXNodeObject::ChildrenChanged() { if (IsDetached()) return; - AXObjectCache().PostNotification(this, ax::mojom::Event::kChildrenChanged); + AXObjectCache().PostNotification(this, + ax::mojom::blink::Event::kChildrenChanged); // Go up the accessibility parent chain, but only if the element already // exists. This method is called during layout, minimal work should be done. @@ -3226,8 +3650,8 @@ void AXNodeObject::ChildrenChanged() { // changes. Do not fire live region changed events if aria-live="off". if (parent->IsLiveRegionRoot()) { if (parent->IsActiveLiveRegionRoot()) { - AXObjectCache().PostNotification(parent, - ax::mojom::Event::kLiveRegionChanged); + AXObjectCache().PostNotification( + parent, ax::mojom::blink::Event::kLiveRegionChanged); } break; } @@ -3239,7 +3663,8 @@ void AXNodeObject::ChildrenChanged() { // changed" notification on it so that it behaves just like a native input // element or textarea. if (IsNonNativeTextControl()) { - AXObjectCache().PostNotification(parent, ax::mojom::Event::kValueChanged); + AXObjectCache().PostNotification(parent, + ax::mojom::blink::Event::kValueChanged); break; } } @@ -3267,10 +3692,10 @@ void AXNodeObject::SelectedOptions(AXObjectVector& options) const { // As a result, we need to use RawFirstChild and RawNextSibling to iterate // over the children in search of the selected option(s). - if (RoleValue() == ax::mojom::Role::kComboBoxGrouping || - RoleValue() == ax::mojom::Role::kComboBoxMenuButton) { + if (RoleValue() == ax::mojom::blink::Role::kComboBoxGrouping || + RoleValue() == ax::mojom::blink::Role::kComboBoxMenuButton) { for (AXObject* obj = RawFirstChild(); obj; obj = obj->RawNextSibling()) { - if (obj->RoleValue() == ax::mojom::Role::kListBox) { + if (obj->RoleValue() == ax::mojom::blink::Role::kListBox) { obj->SelectedOptions(options); return; } @@ -3288,12 +3713,12 @@ void AXNodeObject::SelectionChanged() { // focused (to handle form controls, ARIA text boxes and contentEditable), // or the web area if the selection is just in the document somewhere. if (IsFocused() || IsWebArea()) { - AXObjectCache().PostNotification(this, - ax::mojom::Event::kTextSelectionChanged); + AXObjectCache().PostNotification( + this, ax::mojom::blink::Event::kTextSelectionChanged); if (GetDocument()) { AXObject* document_object = AXObjectCache().GetOrCreate(GetDocument()); AXObjectCache().PostNotification( - document_object, ax::mojom::Event::kDocumentSelectionChanged); + document_object, ax::mojom::blink::Event::kDocumentSelectionChanged); } } else { AXObject::SelectionChanged(); // Calls selectionChanged on parent. @@ -3313,7 +3738,7 @@ void AXNodeObject::TextChanged() { if (parent->IsLiveRegionRoot()) { if (parent->IsActiveLiveRegionRoot()) { cache.PostNotification(parent_node, - ax::mojom::Event::kLiveRegionChanged); + ax::mojom::blink::Event::kLiveRegionChanged); } break; } @@ -3328,12 +3753,29 @@ void AXNodeObject::TextChanged() { if (!parent) continue; if (parent->IsNonNativeTextControl()) { - cache.PostNotification(parent_node, ax::mojom::Event::kValueChanged); + cache.PostNotification(parent_node, + ax::mojom::blink::Event::kValueChanged); break; } } } +AXObject* AXNodeObject::ErrorMessage() const { + // Check for aria-errormessage. + Element* existing_error_message = + GetAOMPropertyOrARIAAttribute(AOMRelationProperty::kErrorMessage); + if (existing_error_message) + return AXObjectCache().GetOrCreate(existing_error_message); + + // Check for visible validationMessage. This can only be visible for a focused + // control. Corollary: if there is a visible validationMessage alert box, then + // it is related to the current focus. + if (this != AXObjectCache().FocusedObject()) + return nullptr; + + return AXObjectCache().ValidationMessageObjectIfInvalid(); +} + void AXNodeObject::ComputeAriaOwnsChildren( HeapVector<Member<AXObject>>& owned_children) const { Vector<String> id_vector; @@ -3384,7 +3826,7 @@ static Element* GetChildFigcaption(const Node& node) { // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and-description-calculation String AXNodeObject::NativeTextAlternative( AXObjectSet& visited, - ax::mojom::NameFrom& name_from, + ax::mojom::blink::NameFrom& name_from, AXRelatedObjectVector* related_objects, NameSources* name_sources, bool* found_text_alternative) const { @@ -3405,7 +3847,7 @@ String AXNodeObject::NativeTextAlternative( // If you change this logic, update AXNodeObject::nameFromLabelElement, too. auto* html_element = DynamicTo<HTMLElement>(GetNode()); if (html_element && html_element->IsLabelable()) { - name_from = ax::mojom::NameFrom::kRelatedElement; + name_from = ax::mojom::blink::NameFrom::kRelatedElement; if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative)); name_sources->back().type = name_from; @@ -3453,7 +3895,7 @@ String AXNodeObject::NativeTextAlternative( // 5.2 input type="button", input type="submit" and input type="reset" if (input_element && input_element->IsTextButton()) { // value attribute. - name_from = ax::mojom::NameFrom::kValue; + name_from = ax::mojom::blink::NameFrom::kValue; if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative, kValueAttr)); name_sources->back().type = name_from; @@ -3476,7 +3918,7 @@ String AXNodeObject::NativeTextAlternative( String default_label = input_element->ValueOrDefaultLabel(); if (value.IsNull() && !default_label.IsNull()) { // default label - name_from = ax::mojom::NameFrom::kContents; + name_from = ax::mojom::blink::NameFrom::kContents; if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative)); name_sources->back().type = name_from; @@ -3500,8 +3942,8 @@ String AXNodeObject::NativeTextAlternative( // alt attr const AtomicString& alt = input_element->getAttribute(kAltAttr); const bool is_empty = alt.IsEmpty() && !alt.IsNull(); - name_from = is_empty ? ax::mojom::NameFrom::kAttributeExplicitlyEmpty - : ax::mojom::NameFrom::kAttribute; + name_from = is_empty ? ax::mojom::blink::NameFrom::kAttributeExplicitlyEmpty + : ax::mojom::blink::NameFrom::kAttribute; if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative, kAltAttr)); name_sources->back().type = name_from; @@ -3523,7 +3965,7 @@ String AXNodeObject::NativeTextAlternative( name_sources->push_back(NameSource(*found_text_alternative, kValueAttr)); name_sources->back().type = name_from; } - name_from = ax::mojom::NameFrom::kAttribute; + name_from = ax::mojom::blink::NameFrom::kAttribute; String value = input_element->value(); if (!value.IsNull()) { text_alternative = value; @@ -3541,7 +3983,7 @@ String AXNodeObject::NativeTextAlternative( name_sources->push_back(NameSource(*found_text_alternative, kTitleAttr)); name_sources->back().type = name_from; } - name_from = ax::mojom::NameFrom::kTitle; + name_from = ax::mojom::blink::NameFrom::kTitle; const AtomicString& title = input_element->getAttribute(kTitleAttr); if (!title.IsNull()) { text_alternative = title; @@ -3556,7 +3998,7 @@ String AXNodeObject::NativeTextAlternative( } // localised default value ("Submit") - name_from = ax::mojom::NameFrom::kValue; + name_from = ax::mojom::blink::NameFrom::kValue; text_alternative = input_element->GetLocale().QueryString(IDS_FORM_SUBMIT_LABEL); if (name_sources) { @@ -3574,7 +4016,7 @@ String AXNodeObject::NativeTextAlternative( // 5.1 Text inputs - step 3 (placeholder attribute) if (html_element && html_element->IsTextControl()) { - name_from = ax::mojom::NameFrom::kPlaceholder; + name_from = ax::mojom::blink::NameFrom::kPlaceholder; if (name_sources) { name_sources->push_back( NameSource(*found_text_alternative, html_names::kPlaceholderAttr)); @@ -3598,7 +4040,7 @@ String AXNodeObject::NativeTextAlternative( // Also check for aria-placeholder. if (IsTextControl()) { - name_from = ax::mojom::NameFrom::kPlaceholder; + name_from = ax::mojom::blink::NameFrom::kPlaceholder; if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative, html_names::kAriaPlaceholderAttr)); @@ -3625,7 +4067,7 @@ String AXNodeObject::NativeTextAlternative( // 5.7 figure and figcaption Elements if (GetNode()->HasTagName(html_names::kFigureTag)) { // figcaption - name_from = ax::mojom::NameFrom::kRelatedElement; + name_from = ax::mojom::blink::NameFrom::kRelatedElement; if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative)); name_sources->back().type = name_from; @@ -3665,8 +4107,8 @@ String AXNodeObject::NativeTextAlternative( // alt const AtomicString& alt = GetAttribute(kAltAttr); const bool is_empty = alt.IsEmpty() && !alt.IsNull(); - name_from = is_empty ? ax::mojom::NameFrom::kAttributeExplicitlyEmpty - : ax::mojom::NameFrom::kAttribute; + name_from = is_empty ? ax::mojom::blink::NameFrom::kAttributeExplicitlyEmpty + : ax::mojom::blink::NameFrom::kAttribute; if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative, kAltAttr)); name_sources->back().type = name_from; @@ -3688,7 +4130,7 @@ String AXNodeObject::NativeTextAlternative( // 5.9 table Element if (auto* table_element = DynamicTo<HTMLTableElement>(GetNode())) { // caption - name_from = ax::mojom::NameFrom::kCaption; + name_from = ax::mojom::blink::NameFrom::kCaption; if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative)); name_sources->back().type = name_from; @@ -3720,7 +4162,7 @@ String AXNodeObject::NativeTextAlternative( } // summary - name_from = ax::mojom::NameFrom::kAttribute; + name_from = ax::mojom::blink::NameFrom::kAttribute; if (name_sources) { name_sources->push_back( NameSource(*found_text_alternative, html_names::kSummaryAttr)); @@ -3744,7 +4186,7 @@ String AXNodeObject::NativeTextAlternative( // Per SVG AAM 1.0's modifications to 2D of this algorithm. if (GetNode()->IsSVGElement()) { - name_from = ax::mojom::NameFrom::kRelatedElement; + name_from = ax::mojom::blink::NameFrom::kRelatedElement; if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative)); name_sources->back().type = name_from; @@ -3781,7 +4223,7 @@ String AXNodeObject::NativeTextAlternative( // Fieldset / legend. if (auto* html_field_set_element = DynamicTo<HTMLFieldSetElement>(GetNode())) { - name_from = ax::mojom::NameFrom::kRelatedElement; + name_from = ax::mojom::blink::NameFrom::kRelatedElement; if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative)); name_sources->back().type = name_from; @@ -3819,7 +4261,7 @@ String AXNodeObject::NativeTextAlternative( if (IsWebArea()) { Document* document = this->GetDocument(); if (document) { - name_from = ax::mojom::NameFrom::kAttribute; + name_from = ax::mojom::blink::NameFrom::kAttribute; if (name_sources) { name_sources->push_back( NameSource(found_text_alternative, html_names::kAriaLabelAttr)); @@ -3843,7 +4285,7 @@ String AXNodeObject::NativeTextAlternative( } } - name_from = ax::mojom::NameFrom::kRelatedElement; + name_from = ax::mojom::blink::NameFrom::kRelatedElement; if (name_sources) { name_sources->push_back(NameSource(*found_text_alternative)); name_sources->back().type = name_from; @@ -3878,9 +4320,10 @@ String AXNodeObject::NativeTextAlternative( return text_alternative; } -String AXNodeObject::Description(ax::mojom::NameFrom name_from, - ax::mojom::DescriptionFrom& description_from, - AXObjectVector* description_objects) const { +String AXNodeObject::Description( + ax::mojom::blink::NameFrom name_from, + ax::mojom::blink::DescriptionFrom& description_from, + AXObjectVector* description_objects) const { AXRelatedObjectVector related_objects; String result = Description(name_from, description_from, nullptr, &related_objects); @@ -3892,11 +4335,12 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from, result = CollapseWhitespace(result); - if (RoleValue() == ax::mojom::Role::kSpinButton && DatetimeAncestor()) { + if (RoleValue() == ax::mojom::blink::Role::kSpinButton && + DatetimeAncestor()) { // Fields inside a datetime control need to merge the field description // with the description of the <input> element. const AXObject* datetime_ancestor = DatetimeAncestor(); - ax::mojom::NameFrom datetime_ancestor_name_from; + ax::mojom::blink::NameFrom datetime_ancestor_name_from; datetime_ancestor->GetName(datetime_ancestor_name_from, nullptr); description_objects->clear(); String ancestor_description = DatetimeAncestor()->Description( @@ -3912,10 +4356,11 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from, // Based on // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html#accessible-name-and-description-calculation -String AXNodeObject::Description(ax::mojom::NameFrom name_from, - ax::mojom::DescriptionFrom& description_from, - DescriptionSources* description_sources, - AXRelatedObjectVector* related_objects) const { +String AXNodeObject::Description( + ax::mojom::blink::NameFrom name_from, + ax::mojom::blink::DescriptionFrom& description_from, + DescriptionSources* description_sources, + AXRelatedObjectVector* related_objects) const { // If descriptionSources is non-null, relatedObjects is used in filling it in, // so it must be non-null as well. if (description_sources) @@ -3927,7 +4372,7 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from, String description; bool found_description = false; - description_from = ax::mojom::DescriptionFrom::kRelatedElement; + description_from = ax::mojom::blink::DescriptionFrom::kRelatedElement; if (description_sources) { description_sources->push_back( DescriptionSource(found_description, html_names::kAriaDescribedbyAttr)); @@ -3980,11 +4425,11 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from, // aria-description overrides any HTML-based accessible description, // but not aria-describedby. if (RuntimeEnabledFeatures::AccessibilityExposeARIAAnnotationsEnabled( - GetDocument())) { + element->GetExecutionContext())) { const AtomicString& aria_desc = GetAOMPropertyOrARIAAttribute(AOMStringProperty::kDescription); if (!aria_desc.IsNull()) { - description_from = ax::mojom::DescriptionFrom::kAttribute; + description_from = ax::mojom::blink::DescriptionFrom::kAttribute; description = aria_desc; if (description_sources) { found_description = true; @@ -3998,9 +4443,9 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from, const auto* input_element = DynamicTo<HTMLInputElement>(GetNode()); // value, 5.2.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam.html - if (name_from != ax::mojom::NameFrom::kValue && input_element && + if (name_from != ax::mojom::blink::NameFrom::kValue && input_element && input_element->IsTextButton()) { - description_from = ax::mojom::DescriptionFrom::kAttribute; + description_from = ax::mojom::blink::DescriptionFrom::kAttribute; if (description_sources) { description_sources->push_back( DescriptionSource(found_description, kValueAttr)); @@ -4022,8 +4467,8 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from, // table caption, 5.9.2 from: // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html auto* table_element = DynamicTo<HTMLTableElement>(element); - if (name_from != ax::mojom::NameFrom::kCaption && table_element) { - description_from = ax::mojom::DescriptionFrom::kRelatedElement; + if (name_from != ax::mojom::blink::NameFrom::kCaption && table_element) { + description_from = ax::mojom::blink::DescriptionFrom::kRelatedElement; if (description_sources) { description_sources->push_back(DescriptionSource(found_description)); description_sources->back().type = description_from; @@ -4057,9 +4502,9 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from, // summary, 5.6.2 from: // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html - if (name_from != ax::mojom::NameFrom::kContents && + if (name_from != ax::mojom::blink::NameFrom::kContents && IsA<HTMLSummaryElement>(GetNode())) { - description_from = ax::mojom::DescriptionFrom::kContents; + description_from = ax::mojom::blink::DescriptionFrom::kContents; if (description_sources) { description_sources->push_back(DescriptionSource(found_description)); description_sources->back().type = description_from; @@ -4080,8 +4525,8 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from, // title attribute, from: // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html - if (name_from != ax::mojom::NameFrom::kTitle) { - description_from = ax::mojom::DescriptionFrom::kTitle; + if (name_from != ax::mojom::blink::NameFrom::kTitle) { + description_from = ax::mojom::blink::DescriptionFrom::kTitle; if (description_sources) { description_sources->push_back( DescriptionSource(found_description, kTitleAttr)); @@ -4099,7 +4544,7 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from, } } - description_from = ax::mojom::DescriptionFrom::kUninitialized; + description_from = ax::mojom::blink::DescriptionFrom::kUninitialized; if (found_description) { for (DescriptionSource& description_source : *description_sources) { @@ -4115,8 +4560,8 @@ String AXNodeObject::Description(ax::mojom::NameFrom name_from, return String(); } -String AXNodeObject::Placeholder(ax::mojom::NameFrom name_from) const { - if (name_from == ax::mojom::NameFrom::kPlaceholder) +String AXNodeObject::Placeholder(ax::mojom::blink::NameFrom name_from) const { + if (name_from == ax::mojom::blink::NameFrom::kPlaceholder) return String(); Node* node = GetNode(); @@ -4135,8 +4580,8 @@ String AXNodeObject::Placeholder(ax::mojom::NameFrom name_from) const { return String(); } -String AXNodeObject::Title(ax::mojom::NameFrom name_from) const { - if (name_from == ax::mojom::NameFrom::kTitle) +String AXNodeObject::Title(ax::mojom::blink::NameFrom name_from) const { + if (name_from == ax::mojom::blink::NameFrom::kTitle) return String(); if (const auto* element = GetElement()) { @@ -4155,7 +4600,7 @@ String AXNodeObject::PlaceholderFromNativeAttribute() const { return ToTextControl(node)->StrippedPlaceholder(); } -void AXNodeObject::Trace(Visitor* visitor) { +void AXNodeObject::Trace(Visitor* visitor) const { visitor->Trace(node_); AXObject::Trace(visitor); } 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 56fb4f990b1..0ae6c2172b2 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 @@ -45,7 +45,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject { public: AXNodeObject(Node*, AXObjectCacheImpl&); ~AXNodeObject() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: bool children_dirty_; @@ -53,18 +53,18 @@ class MODULES_EXPORT AXNodeObject : public AXObject { bool initialized_ = false; #endif // The accessibility role, not taking ARIA into account. - ax::mojom::Role native_role_; + ax::mojom::blink::Role native_role_; static base::Optional<String> GetCSSAltText(Node*); AXObjectInclusion ShouldIncludeBasedOnSemantics( IgnoredReasons* = nullptr) const; bool ComputeAccessibilityIsIgnored(IgnoredReasons* = nullptr) const override; const AXObject* InheritsPresentationalRoleFrom() const override; - ax::mojom::Role DetermineTableSectionRole() const; - ax::mojom::Role DetermineTableCellRole() const; - ax::mojom::Role DetermineTableRowRole() const; - ax::mojom::Role DetermineAccessibilityRole() override; - virtual ax::mojom::Role NativeRoleIgnoringAria() const; + ax::mojom::blink::Role DetermineTableSectionRole() const; + ax::mojom::blink::Role DetermineTableCellRole() const; + ax::mojom::blink::Role DetermineTableRowRole() const; + ax::mojom::blink::Role DetermineAccessibilityRole() override; + virtual ax::mojom::blink::Role NativeRoleIgnoringAria() const; void AlterSliderOrSpinButtonValue(bool increase); AXObject* ActiveDescendant() override; String AriaAccessibilityDescription() const; @@ -95,6 +95,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject { // Check object role or purpose. bool IsControllingVideoElement() const; + bool IsDefault() const final; bool IsMultiline() const override; bool IsEditable() const override { return IsNativeTextControl(); } bool ComputeIsEditableRoot() const override; @@ -103,6 +104,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject { bool IsImageButton() const; bool IsInputImage() const final; bool IsInPageLinkTarget() const override; + bool IsLoaded() const override; bool IsMultiSelectable() const override; bool IsNativeImage() const final; bool IsNativeTextControl() const final; @@ -125,7 +127,14 @@ class MODULES_EXPORT AXNodeObject : public AXObject { AXRestriction Restriction() const override; // Properties of static elements. + const AtomicString& AccessKey() const override; RGBA32 ColorValue() const final; + RGBA32 ComputeBackgroundColor() const final; + RGBA32 GetColor() const final; + String FontFamily() const final; + // Font size is in pixels. + float FontSize() const final; + float FontWeight() const final; bool CanvasHasFallbackContent() const final; int HeadingLevel() const final; unsigned HierarchicalLevel() const final; @@ -137,10 +146,12 @@ class MODULES_EXPORT AXNodeObject : public AXObject { static HeapVector<Member<HTMLInputElement>> FindAllRadioButtonsWithSameName( HTMLInputElement* radio_button); String GetText() const override; + String ImageDataUrl(const IntSize& max_size) const final; + int TextLength() const override; // Properties of interactive elements. - ax::mojom::AriaCurrentState GetAriaCurrentState() const final; - ax::mojom::InvalidState GetInvalidState() const final; + ax::mojom::blink::AriaCurrentState GetAriaCurrentState() const final; + ax::mojom::blink::InvalidState GetInvalidState() const final; // Only used when invalidState() returns InvalidStateOther. String AriaInvalidValue() const final; String ValueDescription() const override; @@ -155,27 +166,39 @@ class MODULES_EXPORT AXNodeObject : public AXObject { bool recursive) const override; // ARIA attributes. - ax::mojom::Role AriaRoleAttribute() const final; + ax::mojom::blink::Role AriaRoleAttribute() const final; bool HasAriaAttribute() const override; + void AriaDescribedbyElements(AXObjectVector&) const override; + void AriaOwnsElements(AXObjectVector&) const override; + bool SupportsARIAOwns() const override; + bool SupportsARIADragging() const override; + void Dropeffects( + Vector<ax::mojom::blink::Dropeffect>& dropeffects) const override; + + // ARIA live-region features. + const AtomicString& LiveRegionStatus() const override; + const AtomicString& LiveRegionRelevant() const override; + + ax::mojom::blink::HasPopup HasPopup() const override; // AX name calculation. - String GetName(ax::mojom::NameFrom&, + String GetName(ax::mojom::blink::NameFrom&, AXObjectVector* name_objects) const override; String TextAlternative(bool recursive, bool in_aria_labelled_by_traversal, AXObjectSet& visited, - ax::mojom::NameFrom&, + ax::mojom::blink::NameFrom&, AXRelatedObjectVector*, NameSources*) const override; - String Description(ax::mojom::NameFrom, - ax::mojom::DescriptionFrom&, + String Description(ax::mojom::blink::NameFrom, + ax::mojom::blink::DescriptionFrom&, AXObjectVector* description_objects) const override; - String Description(ax::mojom::NameFrom, - ax::mojom::DescriptionFrom&, + String Description(ax::mojom::blink::NameFrom, + ax::mojom::blink::DescriptionFrom&, DescriptionSources*, AXRelatedObjectVector*) const override; - String Placeholder(ax::mojom::NameFrom) const override; - String Title(ax::mojom::NameFrom) const override; + String Placeholder(ax::mojom::blink::NameFrom) const override; + String Title(ax::mojom::blink::NameFrom) const override; bool NameFromLabelElement() const override; // Location @@ -202,12 +225,18 @@ class MODULES_EXPORT AXNodeObject : public AXObject { void UpdateChildrenIfNecessary() override; void SelectedOptions(AXObjectVector&) const override; + // Properties of the object's owning document or page. + double EstimatedLoadingProgress() const override; + // DOM and Render tree access. Element* ActionElement() const override; Element* AnchorElement() const override; Document* GetDocument() const override; Node* GetNode() const override { return node_; } + // DOM and layout tree access. + AtomicString Language() const override; + // Modify or take an action on an object. bool OnNativeFocusAction() final; bool OnNativeIncrementAction() final; @@ -219,6 +248,10 @@ class MODULES_EXPORT AXNodeObject : public AXObject { void SelectionChanged() final; void TextChanged() override; + // The aria-errormessage object or native object from a validationMessage + // alert. + AXObject* ErrorMessage() const override; + // Position in set and Size of set int PosInSet() const override; int SetSize() const override; @@ -238,6 +271,17 @@ class MODULES_EXPORT AXNodeObject : public AXObject { return nullptr; } + // + // Layout object specific methods. + // + + // If we can't determine a useful role from the DOM node, attempt to determine + // a role from the layout object. + virtual ax::mojom::blink::Role RoleFromLayoutObject( + ax::mojom::blink::Role dom_role) const { + return dom_role; + } + FRIEND_TEST_ALL_PREFIXES(AccessibilityTest, SetNeedsToUpdateChildren); FRIEND_TEST_ALL_PREFIXES(AccessibilityTest, UpdateChildrenIfNecessary); @@ -246,7 +290,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject { bool IsNativeCheckboxInMixedState() const; String NativeTextAlternative(AXObjectSet& visited, - ax::mojom::NameFrom&, + ax::mojom::blink::NameFrom&, AXRelatedObjectVector*, NameSources*, bool* found_text_alternative) const; @@ -262,6 +306,7 @@ class MODULES_EXPORT AXNodeObject : public AXObject { void AddValidationMessageChild(); // For some nodes, only LayoutBuilderTraversal visits the necessary children. bool ShouldUseLayoutBuilderTraversal() const; + ax::mojom::blink::Dropeffect ParseDropeffect(String& dropeffect) const; DISALLOW_COPY_AND_ASSIGN(AXNodeObject); }; 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 b13abcb657b..01e1d32c062 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.cc @@ -80,386 +80,388 @@ namespace blink { namespace { -struct RoleHashTraits : HashTraits<ax::mojom::Role> { +struct RoleHashTraits : HashTraits<ax::mojom::blink::Role> { static const bool kEmptyValueIsZero = true; - static ax::mojom::Role EmptyValue() { return ax::mojom::Role::kUnknown; } + static ax::mojom::blink::Role EmptyValue() { + return ax::mojom::blink::Role::kUnknown; + } }; using ARIARoleMap = HashMap<String, - ax::mojom::Role, + ax::mojom::blink::Role, CaseFoldingHash, HashTraits<String>, RoleHashTraits>; struct RoleEntry { const char* aria_role; - ax::mojom::Role webcore_role; + ax::mojom::blink::Role webcore_role; }; // Mapping of ARIA role name to internal role name. const RoleEntry kRoles[] = { - {"alert", ax::mojom::Role::kAlert}, - {"alertdialog", ax::mojom::Role::kAlertDialog}, - {"application", ax::mojom::Role::kApplication}, - {"article", ax::mojom::Role::kArticle}, - {"banner", ax::mojom::Role::kBanner}, - {"blockquote", ax::mojom::Role::kBlockquote}, - {"button", ax::mojom::Role::kButton}, - {"caption", ax::mojom::Role::kCaption}, - {"cell", ax::mojom::Role::kCell}, - {"code", ax::mojom::Role::kCode}, - {"checkbox", ax::mojom::Role::kCheckBox}, - {"columnheader", ax::mojom::Role::kColumnHeader}, - {"combobox", ax::mojom::Role::kComboBoxGrouping}, - {"comment", ax::mojom::Role::kComment}, - {"complementary", ax::mojom::Role::kComplementary}, - {"contentinfo", ax::mojom::Role::kContentInfo}, - {"definition", ax::mojom::Role::kDefinition}, - {"deletion", ax::mojom::Role::kContentDeletion}, - {"dialog", ax::mojom::Role::kDialog}, - {"directory", ax::mojom::Role::kDirectory}, + {"alert", ax::mojom::blink::Role::kAlert}, + {"alertdialog", ax::mojom::blink::Role::kAlertDialog}, + {"application", ax::mojom::blink::Role::kApplication}, + {"article", ax::mojom::blink::Role::kArticle}, + {"banner", ax::mojom::blink::Role::kBanner}, + {"blockquote", ax::mojom::blink::Role::kBlockquote}, + {"button", ax::mojom::blink::Role::kButton}, + {"caption", ax::mojom::blink::Role::kCaption}, + {"cell", ax::mojom::blink::Role::kCell}, + {"code", ax::mojom::blink::Role::kCode}, + {"checkbox", ax::mojom::blink::Role::kCheckBox}, + {"columnheader", ax::mojom::blink::Role::kColumnHeader}, + {"combobox", ax::mojom::blink::Role::kComboBoxGrouping}, + {"comment", ax::mojom::blink::Role::kComment}, + {"complementary", ax::mojom::blink::Role::kComplementary}, + {"contentinfo", ax::mojom::blink::Role::kContentInfo}, + {"definition", ax::mojom::blink::Role::kDefinition}, + {"deletion", ax::mojom::blink::Role::kContentDeletion}, + {"dialog", ax::mojom::blink::Role::kDialog}, + {"directory", ax::mojom::blink::Role::kDirectory}, // ------------------------------------------------- // DPub Roles: // www.w3.org/TR/dpub-aam-1.0/#mapping_role_table - {"doc-abstract", ax::mojom::Role::kDocAbstract}, - {"doc-acknowledgments", ax::mojom::Role::kDocAcknowledgments}, - {"doc-afterword", ax::mojom::Role::kDocAfterword}, - {"doc-appendix", ax::mojom::Role::kDocAppendix}, - {"doc-backlink", ax::mojom::Role::kDocBackLink}, - {"doc-biblioentry", ax::mojom::Role::kDocBiblioEntry}, - {"doc-bibliography", ax::mojom::Role::kDocBibliography}, - {"doc-biblioref", ax::mojom::Role::kDocBiblioRef}, - {"doc-chapter", ax::mojom::Role::kDocChapter}, - {"doc-colophon", ax::mojom::Role::kDocColophon}, - {"doc-conclusion", ax::mojom::Role::kDocConclusion}, - {"doc-cover", ax::mojom::Role::kDocCover}, - {"doc-credit", ax::mojom::Role::kDocCredit}, - {"doc-credits", ax::mojom::Role::kDocCredits}, - {"doc-dedication", ax::mojom::Role::kDocDedication}, - {"doc-endnote", ax::mojom::Role::kDocEndnote}, - {"doc-endnotes", ax::mojom::Role::kDocEndnotes}, - {"doc-epigraph", ax::mojom::Role::kDocEpigraph}, - {"doc-epilogue", ax::mojom::Role::kDocEpilogue}, - {"doc-errata", ax::mojom::Role::kDocErrata}, - {"doc-example", ax::mojom::Role::kDocExample}, - {"doc-footnote", ax::mojom::Role::kDocFootnote}, - {"doc-foreword", ax::mojom::Role::kDocForeword}, - {"doc-glossary", ax::mojom::Role::kDocGlossary}, - {"doc-glossref", ax::mojom::Role::kDocGlossRef}, - {"doc-index", ax::mojom::Role::kDocIndex}, - {"doc-introduction", ax::mojom::Role::kDocIntroduction}, - {"doc-noteref", ax::mojom::Role::kDocNoteRef}, - {"doc-notice", ax::mojom::Role::kDocNotice}, - {"doc-pagebreak", ax::mojom::Role::kDocPageBreak}, - {"doc-pagelist", ax::mojom::Role::kDocPageList}, - {"doc-part", ax::mojom::Role::kDocPart}, - {"doc-preface", ax::mojom::Role::kDocPreface}, - {"doc-prologue", ax::mojom::Role::kDocPrologue}, - {"doc-pullquote", ax::mojom::Role::kDocPullquote}, - {"doc-qna", ax::mojom::Role::kDocQna}, - {"doc-subtitle", ax::mojom::Role::kDocSubtitle}, - {"doc-tip", ax::mojom::Role::kDocTip}, - {"doc-toc", ax::mojom::Role::kDocToc}, + {"doc-abstract", ax::mojom::blink::Role::kDocAbstract}, + {"doc-acknowledgments", ax::mojom::blink::Role::kDocAcknowledgments}, + {"doc-afterword", ax::mojom::blink::Role::kDocAfterword}, + {"doc-appendix", ax::mojom::blink::Role::kDocAppendix}, + {"doc-backlink", ax::mojom::blink::Role::kDocBackLink}, + {"doc-biblioentry", ax::mojom::blink::Role::kDocBiblioEntry}, + {"doc-bibliography", ax::mojom::blink::Role::kDocBibliography}, + {"doc-biblioref", ax::mojom::blink::Role::kDocBiblioRef}, + {"doc-chapter", ax::mojom::blink::Role::kDocChapter}, + {"doc-colophon", ax::mojom::blink::Role::kDocColophon}, + {"doc-conclusion", ax::mojom::blink::Role::kDocConclusion}, + {"doc-cover", ax::mojom::blink::Role::kDocCover}, + {"doc-credit", ax::mojom::blink::Role::kDocCredit}, + {"doc-credits", ax::mojom::blink::Role::kDocCredits}, + {"doc-dedication", ax::mojom::blink::Role::kDocDedication}, + {"doc-endnote", ax::mojom::blink::Role::kDocEndnote}, + {"doc-endnotes", ax::mojom::blink::Role::kDocEndnotes}, + {"doc-epigraph", ax::mojom::blink::Role::kDocEpigraph}, + {"doc-epilogue", ax::mojom::blink::Role::kDocEpilogue}, + {"doc-errata", ax::mojom::blink::Role::kDocErrata}, + {"doc-example", ax::mojom::blink::Role::kDocExample}, + {"doc-footnote", ax::mojom::blink::Role::kDocFootnote}, + {"doc-foreword", ax::mojom::blink::Role::kDocForeword}, + {"doc-glossary", ax::mojom::blink::Role::kDocGlossary}, + {"doc-glossref", ax::mojom::blink::Role::kDocGlossRef}, + {"doc-index", ax::mojom::blink::Role::kDocIndex}, + {"doc-introduction", ax::mojom::blink::Role::kDocIntroduction}, + {"doc-noteref", ax::mojom::blink::Role::kDocNoteRef}, + {"doc-notice", ax::mojom::blink::Role::kDocNotice}, + {"doc-pagebreak", ax::mojom::blink::Role::kDocPageBreak}, + {"doc-pagelist", ax::mojom::blink::Role::kDocPageList}, + {"doc-part", ax::mojom::blink::Role::kDocPart}, + {"doc-preface", ax::mojom::blink::Role::kDocPreface}, + {"doc-prologue", ax::mojom::blink::Role::kDocPrologue}, + {"doc-pullquote", ax::mojom::blink::Role::kDocPullquote}, + {"doc-qna", ax::mojom::blink::Role::kDocQna}, + {"doc-subtitle", ax::mojom::blink::Role::kDocSubtitle}, + {"doc-tip", ax::mojom::blink::Role::kDocTip}, + {"doc-toc", ax::mojom::blink::Role::kDocToc}, // End DPub roles. // ------------------------------------------------- - {"document", ax::mojom::Role::kDocument}, - {"emphasis", ax::mojom::Role::kEmphasis}, - {"feed", ax::mojom::Role::kFeed}, - {"figure", ax::mojom::Role::kFigure}, - {"form", ax::mojom::Role::kForm}, - {"generic", ax::mojom::Role::kGenericContainer}, + {"document", ax::mojom::blink::Role::kDocument}, + {"emphasis", ax::mojom::blink::Role::kEmphasis}, + {"feed", ax::mojom::blink::Role::kFeed}, + {"figure", ax::mojom::blink::Role::kFigure}, + {"form", ax::mojom::blink::Role::kForm}, + {"generic", ax::mojom::blink::Role::kGenericContainer}, // ------------------------------------------------- // ARIA Graphics module roles: // https://rawgit.com/w3c/graphics-aam/master/ - {"graphics-document", ax::mojom::Role::kGraphicsDocument}, - {"graphics-object", ax::mojom::Role::kGraphicsObject}, - {"graphics-symbol", ax::mojom::Role::kGraphicsSymbol}, + {"graphics-document", ax::mojom::blink::Role::kGraphicsDocument}, + {"graphics-object", ax::mojom::blink::Role::kGraphicsObject}, + {"graphics-symbol", ax::mojom::blink::Role::kGraphicsSymbol}, // End ARIA Graphics module roles. // ------------------------------------------------- - {"grid", ax::mojom::Role::kGrid}, - {"gridcell", ax::mojom::Role::kCell}, - {"group", ax::mojom::Role::kGroup}, - {"heading", ax::mojom::Role::kHeading}, - {"img", ax::mojom::Role::kImage}, - {"insertion", ax::mojom::Role::kContentInsertion}, - {"link", ax::mojom::Role::kLink}, - {"list", ax::mojom::Role::kList}, - {"listbox", ax::mojom::Role::kListBox}, - {"listitem", ax::mojom::Role::kListItem}, - {"log", ax::mojom::Role::kLog}, - {"main", ax::mojom::Role::kMain}, - {"marquee", ax::mojom::Role::kMarquee}, - {"math", ax::mojom::Role::kMath}, - {"menu", ax::mojom::Role::kMenu}, - {"menubar", ax::mojom::Role::kMenuBar}, - {"menuitem", ax::mojom::Role::kMenuItem}, - {"menuitemcheckbox", ax::mojom::Role::kMenuItemCheckBox}, - {"menuitemradio", ax::mojom::Role::kMenuItemRadio}, - {"mark", ax::mojom::Role::kMark}, - {"meter", ax::mojom::Role::kMeter}, - {"navigation", ax::mojom::Role::kNavigation}, - {"none", ax::mojom::Role::kNone}, - {"note", ax::mojom::Role::kNote}, - {"option", ax::mojom::Role::kListBoxOption}, - {"paragraph", ax::mojom::Role::kParagraph}, - {"presentation", ax::mojom::Role::kPresentational}, - {"progressbar", ax::mojom::Role::kProgressIndicator}, - {"radio", ax::mojom::Role::kRadioButton}, - {"radiogroup", ax::mojom::Role::kRadioGroup}, + {"grid", ax::mojom::blink::Role::kGrid}, + {"gridcell", ax::mojom::blink::Role::kCell}, + {"group", ax::mojom::blink::Role::kGroup}, + {"heading", ax::mojom::blink::Role::kHeading}, + {"img", ax::mojom::blink::Role::kImage}, + {"insertion", ax::mojom::blink::Role::kContentInsertion}, + {"link", ax::mojom::blink::Role::kLink}, + {"list", ax::mojom::blink::Role::kList}, + {"listbox", ax::mojom::blink::Role::kListBox}, + {"listitem", ax::mojom::blink::Role::kListItem}, + {"log", ax::mojom::blink::Role::kLog}, + {"main", ax::mojom::blink::Role::kMain}, + {"marquee", ax::mojom::blink::Role::kMarquee}, + {"math", ax::mojom::blink::Role::kMath}, + {"menu", ax::mojom::blink::Role::kMenu}, + {"menubar", ax::mojom::blink::Role::kMenuBar}, + {"menuitem", ax::mojom::blink::Role::kMenuItem}, + {"menuitemcheckbox", ax::mojom::blink::Role::kMenuItemCheckBox}, + {"menuitemradio", ax::mojom::blink::Role::kMenuItemRadio}, + {"mark", ax::mojom::blink::Role::kMark}, + {"meter", ax::mojom::blink::Role::kMeter}, + {"navigation", ax::mojom::blink::Role::kNavigation}, + {"none", ax::mojom::blink::Role::kNone}, + {"note", ax::mojom::blink::Role::kNote}, + {"option", ax::mojom::blink::Role::kListBoxOption}, + {"paragraph", ax::mojom::blink::Role::kParagraph}, + {"presentation", ax::mojom::blink::Role::kPresentational}, + {"progressbar", ax::mojom::blink::Role::kProgressIndicator}, + {"radio", ax::mojom::blink::Role::kRadioButton}, + {"radiogroup", ax::mojom::blink::Role::kRadioGroup}, // TODO(accessibility) region should only be mapped // if name present. See http://crbug.com/840819. - {"region", ax::mojom::Role::kRegion}, - {"row", ax::mojom::Role::kRow}, - {"rowgroup", ax::mojom::Role::kRowGroup}, - {"rowheader", ax::mojom::Role::kRowHeader}, - {"scrollbar", ax::mojom::Role::kScrollBar}, - {"search", ax::mojom::Role::kSearch}, - {"searchbox", ax::mojom::Role::kSearchBox}, - {"separator", ax::mojom::Role::kSplitter}, - {"slider", ax::mojom::Role::kSlider}, - {"spinbutton", ax::mojom::Role::kSpinButton}, - {"status", ax::mojom::Role::kStatus}, - {"strong", ax::mojom::Role::kStrong}, - {"suggestion", ax::mojom::Role::kSuggestion}, - {"switch", ax::mojom::Role::kSwitch}, - {"tab", ax::mojom::Role::kTab}, - {"table", ax::mojom::Role::kTable}, - {"tablist", ax::mojom::Role::kTabList}, - {"tabpanel", ax::mojom::Role::kTabPanel}, - {"term", ax::mojom::Role::kTerm}, - {"text", ax::mojom::Role::kStaticText}, - {"textbox", ax::mojom::Role::kTextField}, - {"time", ax::mojom::Role::kTime}, - {"timer", ax::mojom::Role::kTimer}, - {"toolbar", ax::mojom::Role::kToolbar}, - {"tooltip", ax::mojom::Role::kTooltip}, - {"tree", ax::mojom::Role::kTree}, - {"treegrid", ax::mojom::Role::kTreeGrid}, - {"treeitem", ax::mojom::Role::kTreeItem}}; + {"region", ax::mojom::blink::Role::kRegion}, + {"row", ax::mojom::blink::Role::kRow}, + {"rowgroup", ax::mojom::blink::Role::kRowGroup}, + {"rowheader", ax::mojom::blink::Role::kRowHeader}, + {"scrollbar", ax::mojom::blink::Role::kScrollBar}, + {"search", ax::mojom::blink::Role::kSearch}, + {"searchbox", ax::mojom::blink::Role::kSearchBox}, + {"separator", ax::mojom::blink::Role::kSplitter}, + {"slider", ax::mojom::blink::Role::kSlider}, + {"spinbutton", ax::mojom::blink::Role::kSpinButton}, + {"status", ax::mojom::blink::Role::kStatus}, + {"strong", ax::mojom::blink::Role::kStrong}, + {"suggestion", ax::mojom::blink::Role::kSuggestion}, + {"switch", ax::mojom::blink::Role::kSwitch}, + {"tab", ax::mojom::blink::Role::kTab}, + {"table", ax::mojom::blink::Role::kTable}, + {"tablist", ax::mojom::blink::Role::kTabList}, + {"tabpanel", ax::mojom::blink::Role::kTabPanel}, + {"term", ax::mojom::blink::Role::kTerm}, + {"text", ax::mojom::blink::Role::kStaticText}, + {"textbox", ax::mojom::blink::Role::kTextField}, + {"time", ax::mojom::blink::Role::kTime}, + {"timer", ax::mojom::blink::Role::kTimer}, + {"toolbar", ax::mojom::blink::Role::kToolbar}, + {"tooltip", ax::mojom::blink::Role::kTooltip}, + {"tree", ax::mojom::blink::Role::kTree}, + {"treegrid", ax::mojom::blink::Role::kTreeGrid}, + {"treeitem", ax::mojom::blink::Role::kTreeItem}}; struct InternalRoleEntry { - ax::mojom::Role webcore_role; + ax::mojom::blink::Role webcore_role; const char* internal_role_name; }; const InternalRoleEntry kInternalRoles[] = { - {ax::mojom::Role::kNone, "None"}, - {ax::mojom::Role::kAbbr, "Abbr"}, - {ax::mojom::Role::kAlertDialog, "AlertDialog"}, - {ax::mojom::Role::kAlert, "Alert"}, - {ax::mojom::Role::kAnchor, "Anchor"}, - {ax::mojom::Role::kComment, "Comment"}, - {ax::mojom::Role::kApplication, "Application"}, - {ax::mojom::Role::kArticle, "Article"}, - {ax::mojom::Role::kAudio, "Audio"}, - {ax::mojom::Role::kBanner, "Banner"}, - {ax::mojom::Role::kBlockquote, "Blockquote"}, - {ax::mojom::Role::kButton, "Button"}, - {ax::mojom::Role::kCanvas, "Canvas"}, - {ax::mojom::Role::kCaption, "Caption"}, - {ax::mojom::Role::kCaret, "Caret"}, - {ax::mojom::Role::kCell, "Cell"}, - {ax::mojom::Role::kCheckBox, "CheckBox"}, - {ax::mojom::Role::kClient, "Client"}, - {ax::mojom::Role::kCode, "Code"}, - {ax::mojom::Role::kColorWell, "ColorWell"}, - {ax::mojom::Role::kColumnHeader, "ColumnHeader"}, - {ax::mojom::Role::kColumn, "Column"}, - {ax::mojom::Role::kComboBoxGrouping, "ComboBox"}, - {ax::mojom::Role::kComboBoxMenuButton, "ComboBox"}, - {ax::mojom::Role::kComplementary, "Complementary"}, - {ax::mojom::Role::kContentDeletion, "ContentDeletion"}, - {ax::mojom::Role::kContentInsertion, "ContentInsertion"}, - {ax::mojom::Role::kContentInfo, "ContentInfo"}, - {ax::mojom::Role::kDate, "Date"}, - {ax::mojom::Role::kDateTime, "DateTime"}, - {ax::mojom::Role::kDefinition, "Definition"}, - {ax::mojom::Role::kDescriptionListDetail, "DescriptionListDetail"}, - {ax::mojom::Role::kDescriptionList, "DescriptionList"}, - {ax::mojom::Role::kDescriptionListTerm, "DescriptionListTerm"}, - {ax::mojom::Role::kDesktop, "Desktop"}, - {ax::mojom::Role::kDetails, "Details"}, - {ax::mojom::Role::kDialog, "Dialog"}, - {ax::mojom::Role::kDirectory, "Directory"}, - {ax::mojom::Role::kDisclosureTriangle, "DisclosureTriangle"}, + {ax::mojom::blink::Role::kNone, "None"}, + {ax::mojom::blink::Role::kAbbr, "Abbr"}, + {ax::mojom::blink::Role::kAlertDialog, "AlertDialog"}, + {ax::mojom::blink::Role::kAlert, "Alert"}, + {ax::mojom::blink::Role::kAnchor, "Anchor"}, + {ax::mojom::blink::Role::kComment, "Comment"}, + {ax::mojom::blink::Role::kApplication, "Application"}, + {ax::mojom::blink::Role::kArticle, "Article"}, + {ax::mojom::blink::Role::kAudio, "Audio"}, + {ax::mojom::blink::Role::kBanner, "Banner"}, + {ax::mojom::blink::Role::kBlockquote, "Blockquote"}, + {ax::mojom::blink::Role::kButton, "Button"}, + {ax::mojom::blink::Role::kCanvas, "Canvas"}, + {ax::mojom::blink::Role::kCaption, "Caption"}, + {ax::mojom::blink::Role::kCaret, "Caret"}, + {ax::mojom::blink::Role::kCell, "Cell"}, + {ax::mojom::blink::Role::kCheckBox, "CheckBox"}, + {ax::mojom::blink::Role::kClient, "Client"}, + {ax::mojom::blink::Role::kCode, "Code"}, + {ax::mojom::blink::Role::kColorWell, "ColorWell"}, + {ax::mojom::blink::Role::kColumnHeader, "ColumnHeader"}, + {ax::mojom::blink::Role::kColumn, "Column"}, + {ax::mojom::blink::Role::kComboBoxGrouping, "ComboBox"}, + {ax::mojom::blink::Role::kComboBoxMenuButton, "ComboBox"}, + {ax::mojom::blink::Role::kComplementary, "Complementary"}, + {ax::mojom::blink::Role::kContentDeletion, "ContentDeletion"}, + {ax::mojom::blink::Role::kContentInsertion, "ContentInsertion"}, + {ax::mojom::blink::Role::kContentInfo, "ContentInfo"}, + {ax::mojom::blink::Role::kDate, "Date"}, + {ax::mojom::blink::Role::kDateTime, "DateTime"}, + {ax::mojom::blink::Role::kDefinition, "Definition"}, + {ax::mojom::blink::Role::kDescriptionListDetail, "DescriptionListDetail"}, + {ax::mojom::blink::Role::kDescriptionList, "DescriptionList"}, + {ax::mojom::blink::Role::kDescriptionListTerm, "DescriptionListTerm"}, + {ax::mojom::blink::Role::kDesktop, "Desktop"}, + {ax::mojom::blink::Role::kDetails, "Details"}, + {ax::mojom::blink::Role::kDialog, "Dialog"}, + {ax::mojom::blink::Role::kDirectory, "Directory"}, + {ax::mojom::blink::Role::kDisclosureTriangle, "DisclosureTriangle"}, // -------------------------------------------------------------- // DPub Roles: // https://www.w3.org/TR/dpub-aam-1.0/#mapping_role_table - {ax::mojom::Role::kDocAbstract, "DocAbstract"}, - {ax::mojom::Role::kDocAcknowledgments, "DocAcknowledgments"}, - {ax::mojom::Role::kDocAfterword, "DocAfterword"}, - {ax::mojom::Role::kDocAppendix, "DocAppendix"}, - {ax::mojom::Role::kDocBackLink, "DocBackLink"}, - {ax::mojom::Role::kDocBiblioEntry, "DocBiblioentry"}, - {ax::mojom::Role::kDocBibliography, "DocBibliography"}, - {ax::mojom::Role::kDocBiblioRef, "DocBiblioref"}, - {ax::mojom::Role::kDocChapter, "DocChapter"}, - {ax::mojom::Role::kDocColophon, "DocColophon"}, - {ax::mojom::Role::kDocConclusion, "DocConclusion"}, - {ax::mojom::Role::kDocCover, "DocCover"}, - {ax::mojom::Role::kDocCredit, "DocCredit"}, - {ax::mojom::Role::kDocCredits, "DocCredits"}, - {ax::mojom::Role::kDocDedication, "DocDedication"}, - {ax::mojom::Role::kDocEndnote, "DocEndnote"}, - {ax::mojom::Role::kDocEndnotes, "DocEndnotes"}, - {ax::mojom::Role::kDocEpigraph, "DocEpigraph"}, - {ax::mojom::Role::kDocEpilogue, "DocEpilogue"}, - {ax::mojom::Role::kDocErrata, "DocErrata"}, - {ax::mojom::Role::kDocExample, "DocExample"}, - {ax::mojom::Role::kDocFootnote, "DocFootnote"}, - {ax::mojom::Role::kDocForeword, "DocForeword"}, - {ax::mojom::Role::kDocGlossary, "DocGlossary"}, - {ax::mojom::Role::kDocGlossRef, "DocGlossref"}, - {ax::mojom::Role::kDocIndex, "DocIndex"}, - {ax::mojom::Role::kDocIntroduction, "DocIntroduction"}, - {ax::mojom::Role::kDocNoteRef, "DocNoteref"}, - {ax::mojom::Role::kDocNotice, "DocNotice"}, - {ax::mojom::Role::kDocPageBreak, "DocPagebreak"}, - {ax::mojom::Role::kDocPageList, "DocPagelist"}, - {ax::mojom::Role::kDocPart, "DocPart"}, - {ax::mojom::Role::kDocPreface, "DocPreface"}, - {ax::mojom::Role::kDocPrologue, "DocPrologue"}, - {ax::mojom::Role::kDocPullquote, "DocPullquote"}, - {ax::mojom::Role::kDocQna, "DocQna"}, - {ax::mojom::Role::kDocSubtitle, "DocSubtitle"}, - {ax::mojom::Role::kDocTip, "DocTip"}, - {ax::mojom::Role::kDocToc, "DocToc"}, + {ax::mojom::blink::Role::kDocAbstract, "DocAbstract"}, + {ax::mojom::blink::Role::kDocAcknowledgments, "DocAcknowledgments"}, + {ax::mojom::blink::Role::kDocAfterword, "DocAfterword"}, + {ax::mojom::blink::Role::kDocAppendix, "DocAppendix"}, + {ax::mojom::blink::Role::kDocBackLink, "DocBackLink"}, + {ax::mojom::blink::Role::kDocBiblioEntry, "DocBiblioentry"}, + {ax::mojom::blink::Role::kDocBibliography, "DocBibliography"}, + {ax::mojom::blink::Role::kDocBiblioRef, "DocBiblioref"}, + {ax::mojom::blink::Role::kDocChapter, "DocChapter"}, + {ax::mojom::blink::Role::kDocColophon, "DocColophon"}, + {ax::mojom::blink::Role::kDocConclusion, "DocConclusion"}, + {ax::mojom::blink::Role::kDocCover, "DocCover"}, + {ax::mojom::blink::Role::kDocCredit, "DocCredit"}, + {ax::mojom::blink::Role::kDocCredits, "DocCredits"}, + {ax::mojom::blink::Role::kDocDedication, "DocDedication"}, + {ax::mojom::blink::Role::kDocEndnote, "DocEndnote"}, + {ax::mojom::blink::Role::kDocEndnotes, "DocEndnotes"}, + {ax::mojom::blink::Role::kDocEpigraph, "DocEpigraph"}, + {ax::mojom::blink::Role::kDocEpilogue, "DocEpilogue"}, + {ax::mojom::blink::Role::kDocErrata, "DocErrata"}, + {ax::mojom::blink::Role::kDocExample, "DocExample"}, + {ax::mojom::blink::Role::kDocFootnote, "DocFootnote"}, + {ax::mojom::blink::Role::kDocForeword, "DocForeword"}, + {ax::mojom::blink::Role::kDocGlossary, "DocGlossary"}, + {ax::mojom::blink::Role::kDocGlossRef, "DocGlossref"}, + {ax::mojom::blink::Role::kDocIndex, "DocIndex"}, + {ax::mojom::blink::Role::kDocIntroduction, "DocIntroduction"}, + {ax::mojom::blink::Role::kDocNoteRef, "DocNoteref"}, + {ax::mojom::blink::Role::kDocNotice, "DocNotice"}, + {ax::mojom::blink::Role::kDocPageBreak, "DocPagebreak"}, + {ax::mojom::blink::Role::kDocPageList, "DocPagelist"}, + {ax::mojom::blink::Role::kDocPart, "DocPart"}, + {ax::mojom::blink::Role::kDocPreface, "DocPreface"}, + {ax::mojom::blink::Role::kDocPrologue, "DocPrologue"}, + {ax::mojom::blink::Role::kDocPullquote, "DocPullquote"}, + {ax::mojom::blink::Role::kDocQna, "DocQna"}, + {ax::mojom::blink::Role::kDocSubtitle, "DocSubtitle"}, + {ax::mojom::blink::Role::kDocTip, "DocTip"}, + {ax::mojom::blink::Role::kDocToc, "DocToc"}, // End DPub roles. // -------------------------------------------------------------- - {ax::mojom::Role::kDocument, "Document"}, - {ax::mojom::Role::kEmbeddedObject, "EmbeddedObject"}, - {ax::mojom::Role::kEmphasis, "Emphasis"}, - {ax::mojom::Role::kFeed, "feed"}, - {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"}, + {ax::mojom::blink::Role::kDocument, "Document"}, + {ax::mojom::blink::Role::kEmbeddedObject, "EmbeddedObject"}, + {ax::mojom::blink::Role::kEmphasis, "Emphasis"}, + {ax::mojom::blink::Role::kFeed, "feed"}, + {ax::mojom::blink::Role::kFigcaption, "Figcaption"}, + {ax::mojom::blink::Role::kFigure, "Figure"}, + {ax::mojom::blink::Role::kFooter, "Footer"}, + {ax::mojom::blink::Role::kFooterAsNonLandmark, "FooterAsNonLandmark"}, + {ax::mojom::blink::Role::kForm, "Form"}, + {ax::mojom::blink::Role::kGenericContainer, "GenericContainer"}, // -------------------------------------------------------------- // ARIA Graphics module roles: // https://rawgit.com/w3c/graphics-aam/master/#mapping_role_table - {ax::mojom::Role::kGraphicsDocument, "GraphicsDocument"}, - {ax::mojom::Role::kGraphicsObject, "GraphicsObject"}, - {ax::mojom::Role::kGraphicsSymbol, "GraphicsSymbol"}, + {ax::mojom::blink::Role::kGraphicsDocument, "GraphicsDocument"}, + {ax::mojom::blink::Role::kGraphicsObject, "GraphicsObject"}, + {ax::mojom::blink::Role::kGraphicsSymbol, "GraphicsSymbol"}, // End ARIA Graphics module roles. // -------------------------------------------------------------- - {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"}, - {ax::mojom::Role::kIgnored, "Ignored"}, - {ax::mojom::Role::kImageMap, "ImageMap"}, - {ax::mojom::Role::kImage, "Image"}, - {ax::mojom::Role::kImeCandidate, "ImeCandidate"}, - {ax::mojom::Role::kInlineTextBox, "InlineTextBox"}, - {ax::mojom::Role::kInputTime, "InputTime"}, - {ax::mojom::Role::kKeyboard, "Keyboard"}, - {ax::mojom::Role::kLabelText, "Label"}, - {ax::mojom::Role::kLayoutTable, "LayoutTable"}, - {ax::mojom::Role::kLayoutTableCell, "LayoutCellTable"}, - {ax::mojom::Role::kLayoutTableRow, "LayoutRowTable"}, - {ax::mojom::Role::kLegend, "Legend"}, - {ax::mojom::Role::kLink, "Link"}, - {ax::mojom::Role::kLineBreak, "LineBreak"}, - {ax::mojom::Role::kListBox, "ListBox"}, - {ax::mojom::Role::kListBoxOption, "ListBoxOption"}, - {ax::mojom::Role::kListGrid, "ListGrid"}, - {ax::mojom::Role::kListItem, "ListItem"}, - {ax::mojom::Role::kListMarker, "ListMarker"}, - {ax::mojom::Role::kList, "List"}, - {ax::mojom::Role::kLog, "Log"}, - {ax::mojom::Role::kMain, "Main"}, - {ax::mojom::Role::kMark, "Mark"}, - {ax::mojom::Role::kMarquee, "Marquee"}, - {ax::mojom::Role::kMath, "Math"}, - {ax::mojom::Role::kMenuBar, "MenuBar"}, - {ax::mojom::Role::kMenuButton, "MenuButton"}, - {ax::mojom::Role::kMenuItem, "MenuItem"}, - {ax::mojom::Role::kMenuItemCheckBox, "MenuItemCheckBox"}, - {ax::mojom::Role::kMenuItemRadio, "MenuItemRadio"}, - {ax::mojom::Role::kMenuListOption, "MenuListOption"}, - {ax::mojom::Role::kMenuListPopup, "MenuListPopup"}, - {ax::mojom::Role::kMenu, "Menu"}, - {ax::mojom::Role::kMeter, "Meter"}, - {ax::mojom::Role::kNavigation, "Navigation"}, - {ax::mojom::Role::kNote, "Note"}, - {ax::mojom::Role::kPane, "Pane"}, - {ax::mojom::Role::kParagraph, "Paragraph"}, - {ax::mojom::Role::kPdfActionableHighlight, "PdfActionableHighlight"}, - {ax::mojom::Role::kPluginObject, "PluginObject"}, - {ax::mojom::Role::kPopUpButton, "PopUpButton"}, - {ax::mojom::Role::kPortal, "Portal"}, - {ax::mojom::Role::kPre, "Pre"}, - {ax::mojom::Role::kPresentational, "Presentational"}, - {ax::mojom::Role::kProgressIndicator, "ProgressIndicator"}, - {ax::mojom::Role::kRadioButton, "RadioButton"}, - {ax::mojom::Role::kRadioGroup, "RadioGroup"}, - {ax::mojom::Role::kRegion, "Region"}, - {ax::mojom::Role::kRootWebArea, "WebArea"}, - {ax::mojom::Role::kRow, "Row"}, - {ax::mojom::Role::kRowGroup, "RowGroup"}, - {ax::mojom::Role::kRowHeader, "RowHeader"}, - {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"}, - {ax::mojom::Role::kSearch, "Search"}, - {ax::mojom::Role::kSearchBox, "SearchBox"}, - {ax::mojom::Role::kSlider, "Slider"}, - {ax::mojom::Role::kSliderThumb, "SliderThumb"}, - {ax::mojom::Role::kSpinButton, "SpinButton"}, - {ax::mojom::Role::kSplitter, "Splitter"}, - {ax::mojom::Role::kStaticText, "StaticText"}, - {ax::mojom::Role::kStatus, "Status"}, - {ax::mojom::Role::kStrong, "Strong"}, - {ax::mojom::Role::kSuggestion, "Suggestion"}, - {ax::mojom::Role::kSwitch, "Switch"}, - {ax::mojom::Role::kTab, "Tab"}, - {ax::mojom::Role::kTabList, "TabList"}, - {ax::mojom::Role::kTabPanel, "TabPanel"}, - {ax::mojom::Role::kTable, "Table"}, - {ax::mojom::Role::kTableHeaderContainer, "TableHeaderContainer"}, - {ax::mojom::Role::kTerm, "Term"}, - {ax::mojom::Role::kTextField, "TextField"}, - {ax::mojom::Role::kTextFieldWithComboBox, "ComboBox"}, - {ax::mojom::Role::kTime, "Time"}, - {ax::mojom::Role::kTimer, "Timer"}, - {ax::mojom::Role::kTitleBar, "TitleBar"}, - {ax::mojom::Role::kToggleButton, "ToggleButton"}, - {ax::mojom::Role::kToolbar, "Toolbar"}, - {ax::mojom::Role::kTreeGrid, "TreeGrid"}, - {ax::mojom::Role::kTreeItem, "TreeItem"}, - {ax::mojom::Role::kTree, "Tree"}, - {ax::mojom::Role::kTooltip, "UserInterfaceTooltip"}, - {ax::mojom::Role::kUnknown, "Unknown"}, - {ax::mojom::Role::kVideo, "Video"}, - {ax::mojom::Role::kWebArea, "WebArea"}, - {ax::mojom::Role::kWebView, "WebView"}, - {ax::mojom::Role::kWindow, "Window"}}; + {ax::mojom::blink::Role::kGrid, "Grid"}, + {ax::mojom::blink::Role::kGroup, "Group"}, + {ax::mojom::blink::Role::kHeader, "Header"}, + {ax::mojom::blink::Role::kHeaderAsNonLandmark, "HeaderAsNonLandmark"}, + {ax::mojom::blink::Role::kHeading, "Heading"}, + {ax::mojom::blink::Role::kIframePresentational, "IframePresentational"}, + {ax::mojom::blink::Role::kIframe, "Iframe"}, + {ax::mojom::blink::Role::kIgnored, "Ignored"}, + {ax::mojom::blink::Role::kImageMap, "ImageMap"}, + {ax::mojom::blink::Role::kImage, "Image"}, + {ax::mojom::blink::Role::kImeCandidate, "ImeCandidate"}, + {ax::mojom::blink::Role::kInlineTextBox, "InlineTextBox"}, + {ax::mojom::blink::Role::kInputTime, "InputTime"}, + {ax::mojom::blink::Role::kKeyboard, "Keyboard"}, + {ax::mojom::blink::Role::kLabelText, "Label"}, + {ax::mojom::blink::Role::kLayoutTable, "LayoutTable"}, + {ax::mojom::blink::Role::kLayoutTableCell, "LayoutCellTable"}, + {ax::mojom::blink::Role::kLayoutTableRow, "LayoutRowTable"}, + {ax::mojom::blink::Role::kLegend, "Legend"}, + {ax::mojom::blink::Role::kLink, "Link"}, + {ax::mojom::blink::Role::kLineBreak, "LineBreak"}, + {ax::mojom::blink::Role::kListBox, "ListBox"}, + {ax::mojom::blink::Role::kListBoxOption, "ListBoxOption"}, + {ax::mojom::blink::Role::kListGrid, "ListGrid"}, + {ax::mojom::blink::Role::kListItem, "ListItem"}, + {ax::mojom::blink::Role::kListMarker, "ListMarker"}, + {ax::mojom::blink::Role::kList, "List"}, + {ax::mojom::blink::Role::kLog, "Log"}, + {ax::mojom::blink::Role::kMain, "Main"}, + {ax::mojom::blink::Role::kMark, "Mark"}, + {ax::mojom::blink::Role::kMarquee, "Marquee"}, + {ax::mojom::blink::Role::kMath, "Math"}, + {ax::mojom::blink::Role::kMenuBar, "MenuBar"}, + {ax::mojom::blink::Role::kMenuButton, "MenuButton"}, + {ax::mojom::blink::Role::kMenuItem, "MenuItem"}, + {ax::mojom::blink::Role::kMenuItemCheckBox, "MenuItemCheckBox"}, + {ax::mojom::blink::Role::kMenuItemRadio, "MenuItemRadio"}, + {ax::mojom::blink::Role::kMenuListOption, "MenuListOption"}, + {ax::mojom::blink::Role::kMenuListPopup, "MenuListPopup"}, + {ax::mojom::blink::Role::kMenu, "Menu"}, + {ax::mojom::blink::Role::kMeter, "Meter"}, + {ax::mojom::blink::Role::kNavigation, "Navigation"}, + {ax::mojom::blink::Role::kNote, "Note"}, + {ax::mojom::blink::Role::kPane, "Pane"}, + {ax::mojom::blink::Role::kParagraph, "Paragraph"}, + {ax::mojom::blink::Role::kPdfActionableHighlight, "PdfActionableHighlight"}, + {ax::mojom::blink::Role::kPluginObject, "PluginObject"}, + {ax::mojom::blink::Role::kPopUpButton, "PopUpButton"}, + {ax::mojom::blink::Role::kPortal, "Portal"}, + {ax::mojom::blink::Role::kPre, "Pre"}, + {ax::mojom::blink::Role::kPresentational, "Presentational"}, + {ax::mojom::blink::Role::kProgressIndicator, "ProgressIndicator"}, + {ax::mojom::blink::Role::kRadioButton, "RadioButton"}, + {ax::mojom::blink::Role::kRadioGroup, "RadioGroup"}, + {ax::mojom::blink::Role::kRegion, "Region"}, + {ax::mojom::blink::Role::kRootWebArea, "WebArea"}, + {ax::mojom::blink::Role::kRow, "Row"}, + {ax::mojom::blink::Role::kRowGroup, "RowGroup"}, + {ax::mojom::blink::Role::kRowHeader, "RowHeader"}, + {ax::mojom::blink::Role::kRuby, "Ruby"}, + {ax::mojom::blink::Role::kRubyAnnotation, "RubyAnnotation"}, + {ax::mojom::blink::Role::kSection, "Section"}, + {ax::mojom::blink::Role::kSvgRoot, "SVGRoot"}, + {ax::mojom::blink::Role::kScrollBar, "ScrollBar"}, + {ax::mojom::blink::Role::kScrollView, "ScrollView"}, + {ax::mojom::blink::Role::kSearch, "Search"}, + {ax::mojom::blink::Role::kSearchBox, "SearchBox"}, + {ax::mojom::blink::Role::kSlider, "Slider"}, + {ax::mojom::blink::Role::kSliderThumb, "SliderThumb"}, + {ax::mojom::blink::Role::kSpinButton, "SpinButton"}, + {ax::mojom::blink::Role::kSplitter, "Splitter"}, + {ax::mojom::blink::Role::kStaticText, "StaticText"}, + {ax::mojom::blink::Role::kStatus, "Status"}, + {ax::mojom::blink::Role::kStrong, "Strong"}, + {ax::mojom::blink::Role::kSuggestion, "Suggestion"}, + {ax::mojom::blink::Role::kSwitch, "Switch"}, + {ax::mojom::blink::Role::kTab, "Tab"}, + {ax::mojom::blink::Role::kTabList, "TabList"}, + {ax::mojom::blink::Role::kTabPanel, "TabPanel"}, + {ax::mojom::blink::Role::kTable, "Table"}, + {ax::mojom::blink::Role::kTableHeaderContainer, "TableHeaderContainer"}, + {ax::mojom::blink::Role::kTerm, "Term"}, + {ax::mojom::blink::Role::kTextField, "TextField"}, + {ax::mojom::blink::Role::kTextFieldWithComboBox, "ComboBox"}, + {ax::mojom::blink::Role::kTime, "Time"}, + {ax::mojom::blink::Role::kTimer, "Timer"}, + {ax::mojom::blink::Role::kTitleBar, "TitleBar"}, + {ax::mojom::blink::Role::kToggleButton, "ToggleButton"}, + {ax::mojom::blink::Role::kToolbar, "Toolbar"}, + {ax::mojom::blink::Role::kTreeGrid, "TreeGrid"}, + {ax::mojom::blink::Role::kTreeItem, "TreeItem"}, + {ax::mojom::blink::Role::kTree, "Tree"}, + {ax::mojom::blink::Role::kTooltip, "UserInterfaceTooltip"}, + {ax::mojom::blink::Role::kUnknown, "Unknown"}, + {ax::mojom::blink::Role::kVideo, "Video"}, + {ax::mojom::blink::Role::kWebArea, "WebArea"}, + {ax::mojom::blink::Role::kWebView, "WebView"}, + {ax::mojom::blink::Role::kWindow, "Window"}}; static_assert(base::size(kInternalRoles) == - static_cast<size_t>(ax::mojom::Role::kMaxValue) + 1, + static_cast<size_t>(ax::mojom::blink::Role::kMaxValue) + 1, "Not all internal roles have an entry in internalRoles array"); // 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}}; + {"banner", ax::mojom::blink::Role::kHeader}, + {"button", ax::mojom::blink::Role::kToggleButton}, + {"combobox", ax::mojom::blink::Role::kPopUpButton}, + {"contentinfo", ax::mojom::blink::Role::kFooter}, + {"menuitem", ax::mojom::blink::Role::kMenuButton}, + {"menuitem", ax::mojom::blink::Role::kMenuListOption}, + {"progressbar", ax::mojom::blink::Role::kMeter}, + {"region", ax::mojom::blink::Role::kSection}, + {"textbox", ax::mojom::blink::Role::kTextField}, + {"combobox", ax::mojom::blink::Role::kComboBoxMenuButton}, + {"combobox", ax::mojom::blink::Role::kTextFieldWithComboBox}}; static ARIARoleMap* CreateARIARoleMap() { ARIARoleMap* role_map = new ARIARoleMap; @@ -513,8 +515,8 @@ unsigned AXObject::number_of_live_ax_objects_ = 0; AXObject::AXObject(AXObjectCacheImpl& ax_object_cache) : id_(0), have_children_(false), - role_(ax::mojom::Role::kUnknown), - aria_role_(ax::mojom::Role::kUnknown), + role_(ax::mojom::blink::Role::kUnknown), + aria_role_(ax::mojom::blink::Role::kUnknown), last_known_is_ignored_value_(kDefaultBehavior), last_known_is_ignored_but_included_in_tree_value_(kDefaultBehavior), explicit_container_id_(0), @@ -775,6 +777,9 @@ void AXObject::Serialize(ui::AXNodeData* node_data) { if (IsSelected() != blink::kSelectedStateUndefined) { node_data->AddBoolAttribute(ax::mojom::blink::BoolAttribute::kSelected, IsSelected() == blink::kSelectedStateTrue); + node_data->AddBoolAttribute( + ax::mojom::blink::BoolAttribute::kSelectedFromFocus, + IsSelectedFromFocus()); } if (IsRichlyEditable()) @@ -856,14 +861,14 @@ bool AXObject::IsVirtualObject() const { return false; } -ax::mojom::Role AXObject::RoleValue() const { +ax::mojom::blink::Role AXObject::RoleValue() const { return role_; } bool AXObject::IsARIATextControl() const { - return AriaRoleAttribute() == ax::mojom::Role::kTextField || - AriaRoleAttribute() == ax::mojom::Role::kSearchBox || - AriaRoleAttribute() == ax::mojom::Role::kTextFieldWithComboBox; + return AriaRoleAttribute() == ax::mojom::blink::Role::kTextField || + AriaRoleAttribute() == ax::mojom::blink::Role::kSearchBox || + AriaRoleAttribute() == ax::mojom::blink::Role::kTextFieldWithComboBox; } bool AXObject::IsAnchor() const { @@ -875,11 +880,11 @@ bool AXObject::IsButton() const { } bool AXObject::IsCanvas() const { - return RoleValue() == ax::mojom::Role::kCanvas; + return RoleValue() == ax::mojom::blink::Role::kCanvas; } bool AXObject::IsCheckbox() const { - return RoleValue() == ax::mojom::Role::kCheckBox; + return RoleValue() == ax::mojom::blink::Role::kCheckBox; } bool AXObject::IsCheckboxOrRadio() const { @@ -887,7 +892,7 @@ bool AXObject::IsCheckboxOrRadio() const { } bool AXObject::IsColorWell() const { - return RoleValue() == ax::mojom::Role::kColorWell; + return RoleValue() == ax::mojom::blink::Role::kColorWell; } bool AXObject::IsControl() const { @@ -910,7 +915,8 @@ bool AXObject::IsImage() const { // Canvas is not currently included so that it is not exposed unless there is // a label, fallback content or something to make it accessible. This decision // may be revisited at a later date. - return ui::IsImage(RoleValue()) && RoleValue() != ax::mojom::Role::kCanvas; + return ui::IsImage(RoleValue()) && + RoleValue() != ax::mojom::blink::Role::kCanvas; } bool AXObject::IsInputImage() const { @@ -930,25 +936,25 @@ bool AXObject::IsImageMapLink() const { } bool AXObject::IsMenu() const { - return RoleValue() == ax::mojom::Role::kMenu; + return RoleValue() == ax::mojom::blink::Role::kMenu; } bool AXObject::IsMenuButton() const { - return RoleValue() == ax::mojom::Role::kMenuButton; + return RoleValue() == ax::mojom::blink::Role::kMenuButton; } bool AXObject::IsCheckable() const { switch (RoleValue()) { - case ax::mojom::Role::kCheckBox: - case ax::mojom::Role::kMenuItemCheckBox: - case ax::mojom::Role::kMenuItemRadio: - case ax::mojom::Role::kRadioButton: - case ax::mojom::Role::kSwitch: - case ax::mojom::Role::kToggleButton: + case ax::mojom::blink::Role::kCheckBox: + case ax::mojom::blink::Role::kMenuItemCheckBox: + case ax::mojom::blink::Role::kMenuItemRadio: + case ax::mojom::blink::Role::kRadioButton: + case ax::mojom::blink::Role::kSwitch: + case ax::mojom::blink::Role::kToggleButton: return true; - case ax::mojom::Role::kTreeItem: - case ax::mojom::Role::kListBoxOption: - case ax::mojom::Role::kMenuListOption: + case ax::mojom::blink::Role::kTreeItem: + case ax::mojom::blink::Role::kListBoxOption: + case ax::mojom::blink::Role::kMenuListOption: return AriaCheckedIsPresent(); default: return false; @@ -959,34 +965,34 @@ bool AXObject::IsCheckable() const { // Because an AXMenuListOption (<option>) can // have an ARIA role of menuitemcheckbox/menuitemradio // yet does not inherit from AXNodeObject -ax::mojom::CheckedState AXObject::CheckedState() const { +ax::mojom::blink::CheckedState AXObject::CheckedState() const { if (!IsCheckable()) - return ax::mojom::CheckedState::kNone; + return ax::mojom::blink::CheckedState::kNone; // Try ARIA checked/pressed state - const ax::mojom::Role role = RoleValue(); - const auto prop = role == ax::mojom::Role::kToggleButton + const ax::mojom::blink::Role role = RoleValue(); + const auto prop = role == ax::mojom::blink::Role::kToggleButton ? AOMStringProperty::kPressed : AOMStringProperty::kChecked; const AtomicString& checked_attribute = GetAOMPropertyOrARIAAttribute(prop); if (checked_attribute) { if (EqualIgnoringASCIICase(checked_attribute, "mixed")) { // Only checkable role that doesn't support mixed is the switch. - if (role != ax::mojom::Role::kSwitch) - return ax::mojom::CheckedState::kMixed; + if (role != ax::mojom::blink::Role::kSwitch) + return ax::mojom::blink::CheckedState::kMixed; } // Anything other than "false" should be treated as "true". return EqualIgnoringASCIICase(checked_attribute, "false") - ? ax::mojom::CheckedState::kFalse - : ax::mojom::CheckedState::kTrue; + ? ax::mojom::blink::CheckedState::kFalse + : ax::mojom::blink::CheckedState::kTrue; } // Native checked state - if (role != ax::mojom::Role::kToggleButton) { + if (role != ax::mojom::blink::Role::kToggleButton) { const Node* node = this->GetNode(); if (!node) - return ax::mojom::CheckedState::kNone; + return ax::mojom::blink::CheckedState::kNone; // Expose native checkbox mixed state as accessibility mixed state. However, // do not expose native radio mixed state as accessibility mixed state. @@ -994,15 +1000,15 @@ ax::mojom::CheckedState AXObject::CheckedState() const { // both checked and partially checked, but a native mixed native radio // button sinply means no radio buttons have been checked in the group yet. if (IsNativeCheckboxInMixedState(node)) - return ax::mojom::CheckedState::kMixed; + return ax::mojom::blink::CheckedState::kMixed; auto* html_input_element = DynamicTo<HTMLInputElement>(node); if (html_input_element && html_input_element->ShouldAppearChecked()) { - return ax::mojom::CheckedState::kTrue; + return ax::mojom::blink::CheckedState::kTrue; } } - return ax::mojom::CheckedState::kFalse; + return ax::mojom::blink::CheckedState::kFalse; } bool AXObject::IsNativeCheckboxInMixedState(const Node* node) { @@ -1018,36 +1024,36 @@ bool AXObject::IsNativeCheckboxInMixedState(const Node* node) { bool AXObject::IsLandmarkRelated() const { switch (RoleValue()) { - case ax::mojom::Role::kApplication: - case ax::mojom::Role::kArticle: - case ax::mojom::Role::kBanner: - case ax::mojom::Role::kComplementary: - case ax::mojom::Role::kContentInfo: - case ax::mojom::Role::kDocAcknowledgments: - case ax::mojom::Role::kDocAfterword: - case ax::mojom::Role::kDocAppendix: - case ax::mojom::Role::kDocBibliography: - case ax::mojom::Role::kDocChapter: - case ax::mojom::Role::kDocConclusion: - case ax::mojom::Role::kDocCredits: - case ax::mojom::Role::kDocEndnotes: - case ax::mojom::Role::kDocEpilogue: - case ax::mojom::Role::kDocErrata: - case ax::mojom::Role::kDocForeword: - case ax::mojom::Role::kDocGlossary: - case ax::mojom::Role::kDocIntroduction: - case ax::mojom::Role::kDocPart: - case ax::mojom::Role::kDocPreface: - case ax::mojom::Role::kDocPrologue: - 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: + case ax::mojom::blink::Role::kApplication: + case ax::mojom::blink::Role::kArticle: + case ax::mojom::blink::Role::kBanner: + case ax::mojom::blink::Role::kComplementary: + case ax::mojom::blink::Role::kContentInfo: + case ax::mojom::blink::Role::kDocAcknowledgments: + case ax::mojom::blink::Role::kDocAfterword: + case ax::mojom::blink::Role::kDocAppendix: + case ax::mojom::blink::Role::kDocBibliography: + case ax::mojom::blink::Role::kDocChapter: + case ax::mojom::blink::Role::kDocConclusion: + case ax::mojom::blink::Role::kDocCredits: + case ax::mojom::blink::Role::kDocEndnotes: + case ax::mojom::blink::Role::kDocEpilogue: + case ax::mojom::blink::Role::kDocErrata: + case ax::mojom::blink::Role::kDocForeword: + case ax::mojom::blink::Role::kDocGlossary: + case ax::mojom::blink::Role::kDocIntroduction: + case ax::mojom::blink::Role::kDocPart: + case ax::mojom::blink::Role::kDocPreface: + case ax::mojom::blink::Role::kDocPrologue: + case ax::mojom::blink::Role::kDocToc: + case ax::mojom::blink::Role::kFooter: + case ax::mojom::blink::Role::kForm: + case ax::mojom::blink::Role::kHeader: + case ax::mojom::blink::Role::kMain: + case ax::mojom::blink::Role::kNavigation: + case ax::mojom::blink::Role::kRegion: + case ax::mojom::blink::Role::kSearch: + case ax::mojom::blink::Role::kSection: return true; default: return false; @@ -1059,7 +1065,7 @@ bool AXObject::IsMenuRelated() const { } bool AXObject::IsMeter() const { - return RoleValue() == ax::mojom::Role::kMeter; + return RoleValue() == ax::mojom::blink::Role::kMeter; } bool AXObject::IsNativeImage() const { @@ -1095,12 +1101,12 @@ bool AXObject::IsPresentational() const { } bool AXObject::IsTextObject() const { - // Objects with |ax::mojom::Role::kLineBreak| are HTML <br> elements and are - // not backed by DOM text nodes. We can't mark them as text objects for that - // reason. + // Objects with |ax::mojom::blink::Role::kLineBreak| are HTML <br> elements + // and are not backed by DOM text nodes. We can't mark them as text objects + // for that reason. switch (RoleValue()) { - case ax::mojom::Role::kInlineTextBox: - case ax::mojom::Role::kStaticText: + case ax::mojom::blink::Role::kInlineTextBox: + case ax::mojom::blink::Role::kStaticText: return true; default: return false; @@ -1108,7 +1114,7 @@ bool AXObject::IsTextObject() const { } bool AXObject::IsRangeValueSupported() const { - if (RoleValue() == ax::mojom::Role::kSplitter) { + if (RoleValue() == ax::mojom::blink::Role::kSplitter) { // According to the ARIA spec, role="separator" acts as a splitter only // when focusable, and supports a range only in that case. return CanSetFocusAttribute(); @@ -1254,6 +1260,8 @@ bool AXObject::ComputeIsInertOrAriaHidden( } } return true; + } else if (IsBlockedByAriaModalDialog(ignored_reasons)) { + return true; } } else { AXObject* parent = ParentObject(); @@ -1280,6 +1288,27 @@ bool AXObject::ComputeIsInertOrAriaHidden( return false; } +bool AXObject::IsBlockedByAriaModalDialog( + IgnoredReasons* ignored_reasons) const { + AXObject* active_aria_modal_dialog = + AXObjectCache().GetActiveAriaModalDialog(); + + // On platforms that don't require manual pruning of the accessibility tree, + // the active aria modal dialog should never be set, so has no effect. + if (!active_aria_modal_dialog) + return false; + + if (this == active_aria_modal_dialog || + IsDescendantOf(*active_aria_modal_dialog)) + return false; + + if (ignored_reasons) { + ignored_reasons->push_back( + IgnoredReason(kAXAriaModalDialog, active_aria_modal_dialog)); + } + return true; +} + bool AXObject::IsVisible() const { return !IsInertOrAriaHidden() && !IsHiddenViaStyle(); } @@ -1446,7 +1475,7 @@ bool AXObject::ComputeAccessibilityIsIgnoredButIncludedInTree() const { // 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. - if (RoleValue() == ax::mojom::Role::kIgnored || + if (RoleValue() == ax::mojom::blink::Role::kIgnored || GetNode()->IsInUserAgentShadowRoot()) { return false; } @@ -1484,10 +1513,10 @@ bool AXObject::ComputeAccessibilityIsIgnoredButIncludedInTree() const { const AXObject* AXObject::DatetimeAncestor(int max_levels_to_check) const { switch (RoleValue()) { - case ax::mojom::Role::kDateTime: - case ax::mojom::Role::kDate: - case ax::mojom::Role::kInputTime: - case ax::mojom::Role::kTime: + case ax::mojom::blink::Role::kDateTime: + case ax::mojom::blink::Role::kDate: + case ax::mojom::blink::Role::kInputTime: + case ax::mojom::blink::Role::kTime: return this; default: break; @@ -1538,16 +1567,17 @@ bool AXObject::HasInheritedPresentationalRole() const { bool AXObject::CanSetValueAttribute() const { switch (RoleValue()) { - case ax::mojom::Role::kColorWell: - case ax::mojom::Role::kDate: - case ax::mojom::Role::kDateTime: - case ax::mojom::Role::kScrollBar: - case ax::mojom::Role::kSlider: - case ax::mojom::Role::kSpinButton: - case ax::mojom::Role::kSplitter: - case ax::mojom::Role::kTextField: - case ax::mojom::Role::kTextFieldWithComboBox: - case ax::mojom::Role::kSearchBox: + case ax::mojom::blink::Role::kColorWell: + case ax::mojom::blink::Role::kDate: + case ax::mojom::blink::Role::kDateTime: + case ax::mojom::blink::Role::kInputTime: + case ax::mojom::blink::Role::kScrollBar: + case ax::mojom::blink::Role::kSearchBox: + case ax::mojom::blink::Role::kSlider: + case ax::mojom::blink::Role::kSpinButton: + case ax::mojom::blink::Role::kSplitter: + case ax::mojom::blink::Role::kTextField: + case ax::mojom::blink::Role::kTextFieldWithComboBox: return Restriction() == kRestrictionNone; default: return false; @@ -1640,7 +1670,7 @@ bool AXObject::CanSetFocusAttribute() const { // behaving like potential active descendants, and handling focus actions. // Menu list options are handled before visibility check, because they // are considered focusable even when part of collapsed drop down. - if (RoleValue() == ax::mojom::Role::kMenuListOption) + if (RoleValue() == ax::mojom::blink::Role::kMenuListOption) return true; // NOT focusable: hidden elements. @@ -1650,7 +1680,7 @@ bool AXObject::CanSetFocusAttribute() const { // Focusable: options in a combobox or listbox. // Similar to menu list option treatment above, but not focusable if hidden. - if (RoleValue() == ax::mojom::Role::kListBoxOption) + if (RoleValue() == ax::mojom::blink::Role::kListBoxOption) return true; // Focusable: element supports focus. @@ -1700,7 +1730,7 @@ bool AXObject::CanBeActiveDescendant() const { // Does not make sense to use aria-activedescendant to point to an HTML // element that requires real focus, therefore an ARIA role is necessary. - if (AriaRoleAttribute() == ax::mojom::Role::kUnknown) + if (AriaRoleAttribute() == ax::mojom::blink::Role::kUnknown) return false; return IsARIAControlledByTextboxWithActiveDescendant() || @@ -1782,7 +1812,7 @@ bool AXObject::AncestorExposesActiveDescendant() const { } bool AXObject::HasIndirectChildren() const { - return RoleValue() == ax::mojom::Role::kTableHeaderContainer; + return RoleValue() == ax::mojom::blink::Role::kTableHeaderContainer; } bool AXObject::CanSetSelectedAttribute() const { @@ -1792,11 +1822,11 @@ bool AXObject::CanSetSelectedAttribute() const { bool AXObject::IsSubWidget() const { switch (RoleValue()) { - case ax::mojom::Role::kCell: - case ax::mojom::Role::kColumnHeader: - case ax::mojom::Role::kRowHeader: - case ax::mojom::Role::kColumn: - case ax::mojom::Role::kRow: + case ax::mojom::blink::Role::kCell: + case ax::mojom::blink::Role::kColumnHeader: + case ax::mojom::blink::Role::kRowHeader: + case ax::mojom::blink::Role::kColumn: + case ax::mojom::blink::Role::kRow: // If it has an explicit ARIA role, it's a subwidget. // // Reasoning: @@ -1810,21 +1840,22 @@ bool AXObject::IsSubWidget() const { // an ARIA 1.1 role of "table", should not be selectable. We may // need to create separate role enums for grid cells vs table cells // to implement this. - if (AriaRoleAttribute() != ax::mojom::Role::kUnknown) + if (AriaRoleAttribute() != ax::mojom::blink::Role::kUnknown) return true; // Otherwise it's only a subwidget if it's in a grid or treegrid, // not in a table. return std::any_of( - AncestorsBegin(), AncestorsEnd(), [](const AXObject& ancestor) { - return ancestor.RoleValue() == ax::mojom::Role::kGrid || - ancestor.RoleValue() == ax::mojom::Role::kTreeGrid; + UnignoredAncestorsBegin(), UnignoredAncestorsEnd(), + [](const AXObject& ancestor) { + return ancestor.RoleValue() == ax::mojom::blink::Role::kGrid || + ancestor.RoleValue() == ax::mojom::blink::Role::kTreeGrid; }); - case ax::mojom::Role::kListBoxOption: - case ax::mojom::Role::kMenuListOption: - case ax::mojom::Role::kTab: - case ax::mojom::Role::kTreeItem: + case ax::mojom::blink::Role::kListBoxOption: + case ax::mojom::blink::Role::kMenuListOption: + case ax::mojom::blink::Role::kTab: + case ax::mojom::blink::Role::kTreeItem: return true; default: return false; @@ -1849,12 +1880,12 @@ String AXObject::CollapseWhitespace(const String& str) { } String AXObject::ComputedName() const { - ax::mojom::NameFrom name_from; - AXObject::AXObjectVector name_objects; + ax::mojom::blink::NameFrom name_from; + AXObjectVector name_objects; return GetName(name_from, &name_objects); } -String AXObject::GetName(ax::mojom::NameFrom& name_from, +String AXObject::GetName(ax::mojom::blink::NameFrom& name_from, AXObject::AXObjectVector* name_objects) const { HeapHashSet<Member<const AXObject>> visited; AXRelatedObjectVector related_objects; @@ -1867,14 +1898,14 @@ String AXObject::GetName(ax::mojom::NameFrom& name_from, AccessibilityIsIgnoredButIncludedInTree(); // Initialize |name_from|, as TextAlternative() might never set it in some // cases. - name_from = ax::mojom::NameFrom::kNone; + name_from = ax::mojom::blink::NameFrom::kNone; String text = TextAlternative(false, hidden_and_ignored_but_included_in_tree, visited, name_from, &related_objects, nullptr); - ax::mojom::Role role = RoleValue(); - if (!GetNode() || - (!IsA<HTMLBRElement>(GetNode()) && role != ax::mojom::Role::kStaticText && - role != ax::mojom::Role::kInlineTextBox)) + ax::mojom::blink::Role role = RoleValue(); + if (!GetNode() || (!IsA<HTMLBRElement>(GetNode()) && + role != ax::mojom::blink::Role::kStaticText && + role != ax::mojom::blink::Role::kInlineTextBox)) text = CollapseWhitespace(text); if (name_objects) { @@ -1888,7 +1919,7 @@ String AXObject::GetName(ax::mojom::NameFrom& name_from, String AXObject::GetName(NameSources* name_sources) const { AXObjectSet visited; - ax::mojom::NameFrom tmp_name_from; + ax::mojom::blink::NameFrom tmp_name_from; AXRelatedObjectVector tmp_related_objects; // For purposes of computing a text alternative, if an ignored node is // included in the tree, assume that it is the target of aria-labelledby or @@ -1907,15 +1938,16 @@ String AXObject::GetName(NameSources* name_sources) const { String AXObject::RecursiveTextAlternative(const AXObject& ax_obj, bool in_aria_labelled_by_traversal, AXObjectSet& visited) { - ax::mojom::NameFrom tmp_name_from; + ax::mojom::blink::NameFrom tmp_name_from; return RecursiveTextAlternative(ax_obj, in_aria_labelled_by_traversal, visited, tmp_name_from); } -String AXObject::RecursiveTextAlternative(const AXObject& ax_obj, - bool in_aria_labelled_by_traversal, - AXObjectSet& visited, - ax::mojom::NameFrom& name_from) { +String AXObject::RecursiveTextAlternative( + const AXObject& ax_obj, + bool in_aria_labelled_by_traversal, + AXObjectSet& visited, + ax::mojom::blink::NameFrom& name_from) { if (visited.Contains(&ax_obj) && !in_aria_labelled_by_traversal) return String(); @@ -1984,7 +2016,7 @@ bool AXObject::IsHiddenForTextAlternativeCalculation() const { String AXObject::AriaTextAlternative(bool recursive, bool in_aria_labelled_by_traversal, AXObjectSet& visited, - ax::mojom::NameFrom& name_from, + ax::mojom::blink::NameFrom& name_from, AXRelatedObjectVector* related_objects, NameSources* name_sources, bool* found_text_alternative) const { @@ -2003,7 +2035,7 @@ String AXObject::AriaTextAlternative(bool recursive, // Step 2B from: http://www.w3.org/TR/accname-aam-1.1 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. if (!in_aria_labelled_by_traversal && !already_visited) { - name_from = ax::mojom::NameFrom::kRelatedElement; + name_from = ax::mojom::blink::NameFrom::kRelatedElement; // Check ARIA attributes. const QualifiedName& attr = @@ -2057,7 +2089,7 @@ String AXObject::AriaTextAlternative(bool recursive, // Step 2C from: http://www.w3.org/TR/accname-aam-1.1 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. - name_from = ax::mojom::NameFrom::kAttribute; + name_from = ax::mojom::blink::NameFrom::kAttribute; if (name_sources) { name_sources->push_back( NameSource(*found_text_alternative, html_names::kAriaLabelAttr)); @@ -2192,19 +2224,19 @@ void AXObject::TextCharacterOffsets(Vector<int>&) const {} void AXObject::GetWordBoundaries(Vector<int>& word_starts, Vector<int>& word_ends) const {} -ax::mojom::DefaultActionVerb AXObject::Action() const { +ax::mojom::blink::DefaultActionVerb AXObject::Action() const { Element* action_element = ActionElement(); if (!action_element) - return ax::mojom::DefaultActionVerb::kNone; + return ax::mojom::blink::DefaultActionVerb::kNone; // TODO(dmazzoni): Ensure that combo box text field is handled here. if (IsTextControl()) - return ax::mojom::DefaultActionVerb::kActivate; + return ax::mojom::blink::DefaultActionVerb::kActivate; if (IsCheckable()) { - return CheckedState() != ax::mojom::CheckedState::kTrue - ? ax::mojom::DefaultActionVerb::kCheck - : ax::mojom::DefaultActionVerb::kUncheck; + return CheckedState() != ax::mojom::blink::CheckedState::kTrue + ? ax::mojom::blink::DefaultActionVerb::kCheck + : ax::mojom::blink::DefaultActionVerb::kUncheck; } // If this object cannot receive focus and has a button role, use click as @@ -2213,28 +2245,28 @@ ax::mojom::DefaultActionVerb AXObject::Action() const { // a click action means the user should trigger the action via a simulated // click. If this object cannot receive focus, it's impossible to trigger it // with a key press. - if (RoleValue() == ax::mojom::Role::kButton && !CanSetFocusAttribute()) - return ax::mojom::DefaultActionVerb::kClick; + if (RoleValue() == ax::mojom::blink::Role::kButton && !CanSetFocusAttribute()) + return ax::mojom::blink::DefaultActionVerb::kClick; switch (RoleValue()) { - case ax::mojom::Role::kButton: - case ax::mojom::Role::kDisclosureTriangle: - case ax::mojom::Role::kToggleButton: - return ax::mojom::DefaultActionVerb::kPress; - case ax::mojom::Role::kListBoxOption: - case ax::mojom::Role::kMenuItemRadio: - case ax::mojom::Role::kMenuItem: - case ax::mojom::Role::kMenuListOption: - return ax::mojom::DefaultActionVerb::kSelect; - case ax::mojom::Role::kLink: - return ax::mojom::DefaultActionVerb::kJump; - case ax::mojom::Role::kComboBoxMenuButton: - case ax::mojom::Role::kPopUpButton: - return ax::mojom::DefaultActionVerb::kOpen; + case ax::mojom::blink::Role::kButton: + case ax::mojom::blink::Role::kDisclosureTriangle: + case ax::mojom::blink::Role::kToggleButton: + return ax::mojom::blink::DefaultActionVerb::kPress; + case ax::mojom::blink::Role::kListBoxOption: + case ax::mojom::blink::Role::kMenuItemRadio: + case ax::mojom::blink::Role::kMenuItem: + case ax::mojom::blink::Role::kMenuListOption: + return ax::mojom::blink::DefaultActionVerb::kSelect; + case ax::mojom::blink::Role::kLink: + return ax::mojom::blink::DefaultActionVerb::kJump; + case ax::mojom::blink::Role::kComboBoxMenuButton: + case ax::mojom::blink::Role::kPopUpButton: + return ax::mojom::blink::DefaultActionVerb::kOpen; default: if (action_element == GetNode()) - return ax::mojom::DefaultActionVerb::kClick; - return ax::mojom::DefaultActionVerb::kClickAncestor; + return ax::mojom::blink::DefaultActionVerb::kClick; + return ax::mojom::blink::DefaultActionVerb::kClickAncestor; } } @@ -2250,28 +2282,28 @@ bool AXObject::AriaCheckedIsPresent() const { bool AXObject::SupportsARIAExpanded() const { switch (RoleValue()) { - case ax::mojom::Role::kApplication: - case ax::mojom::Role::kButton: - case ax::mojom::Role::kCheckBox: - case ax::mojom::Role::kColumnHeader: - case ax::mojom::Role::kComboBoxGrouping: - case ax::mojom::Role::kComboBoxMenuButton: - case ax::mojom::Role::kDisclosureTriangle: - case ax::mojom::Role::kListBox: - case ax::mojom::Role::kLink: - case ax::mojom::Role::kPopUpButton: - case ax::mojom::Role::kMenuButton: - case ax::mojom::Role::kMenuItem: - case ax::mojom::Role::kMenuItemCheckBox: - case ax::mojom::Role::kMenuItemRadio: - case ax::mojom::Role::kRow: - case ax::mojom::Role::kRowHeader: - case ax::mojom::Role::kSwitch: - case ax::mojom::Role::kTab: - case ax::mojom::Role::kTextFieldWithComboBox: - case ax::mojom::Role::kTreeItem: + case ax::mojom::blink::Role::kApplication: + case ax::mojom::blink::Role::kButton: + case ax::mojom::blink::Role::kCheckBox: + case ax::mojom::blink::Role::kColumnHeader: + case ax::mojom::blink::Role::kComboBoxGrouping: + case ax::mojom::blink::Role::kComboBoxMenuButton: + case ax::mojom::blink::Role::kDisclosureTriangle: + case ax::mojom::blink::Role::kListBox: + case ax::mojom::blink::Role::kLink: + case ax::mojom::blink::Role::kPopUpButton: + case ax::mojom::blink::Role::kMenuButton: + case ax::mojom::blink::Role::kMenuItem: + case ax::mojom::blink::Role::kMenuItemCheckBox: + case ax::mojom::blink::Role::kMenuItemRadio: + case ax::mojom::blink::Role::kRow: + case ax::mojom::blink::Role::kRowHeader: + case ax::mojom::blink::Role::kSwitch: + case ax::mojom::blink::Role::kTab: + case ax::mojom::blink::Role::kTextFieldWithComboBox: + case ax::mojom::blink::Role::kTreeItem: return true; - case ax::mojom::Role::kCell: + case ax::mojom::blink::Role::kCell: // TODO(Accessibility): aria-expanded is supported on grid cells but not // on cells inside a static table. Consider creating separate internal // roles so that we can easily distinguish these two types. See also @@ -2361,7 +2393,8 @@ int AXObject::IndexInParent() const { if (!ParentObjectIncludedInTree()) return 0; - const AXObjectVector& siblings = ParentObjectIncludedInTree()->Children(); + const AXObjectVector& siblings = + ParentObjectIncludedInTree()->ChildrenIncludingIgnored(); wtf_size_t index = siblings.Find(this); DCHECK(index != kNotFound); return (index == kNotFound) ? 0 : static_cast<int>(index); @@ -2405,31 +2438,32 @@ AXRestriction AXObject::Restriction() const { return kRestrictionNone; } -ax::mojom::Role AXObject::DetermineAccessibilityRole() { +ax::mojom::blink::Role AXObject::DetermineAccessibilityRole() { aria_role_ = DetermineAriaRoleAttribute(); return aria_role_; } -ax::mojom::Role AXObject::AriaRoleAttribute() const { +ax::mojom::blink::Role AXObject::AriaRoleAttribute() const { return aria_role_; } -ax::mojom::Role AXObject::DetermineAriaRoleAttribute() const { +ax::mojom::blink::Role AXObject::DetermineAriaRoleAttribute() const { const AtomicString& aria_role = GetAOMPropertyOrARIAAttribute(AOMStringProperty::kRole); if (aria_role.IsNull() || aria_role.IsEmpty()) - return ax::mojom::Role::kUnknown; + return ax::mojom::blink::Role::kUnknown; - ax::mojom::Role role = AriaRoleToWebCoreRole(aria_role); + ax::mojom::blink::Role role = AriaRoleToWebCoreRole(aria_role); switch (role) { - case ax::mojom::Role::kComment: - case ax::mojom::Role::kMark: - case ax::mojom::Role::kSuggestion: + case ax::mojom::blink::Role::kComment: + case ax::mojom::blink::Role::kMark: + case ax::mojom::blink::Role::kSuggestion: UseCounter::Count(GetDocument(), WebFeature::kARIAAnnotations); - if (!RuntimeEnabledFeatures::AccessibilityExposeARIAAnnotationsEnabled( - GetDocument())) { - role = ax::mojom::Role::kGenericContainer; + if (GetElement() && + !RuntimeEnabledFeatures::AccessibilityExposeARIAAnnotationsEnabled( + GetElement()->GetExecutionContext())) { + role = ax::mojom::blink::Role::kGenericContainer; } break; default: @@ -2439,38 +2473,39 @@ ax::mojom::Role AXObject::DetermineAriaRoleAttribute() const { // 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. - if ((role == ax::mojom::Role::kNone || - role == ax::mojom::Role::kPresentational) && + if ((role == ax::mojom::blink::Role::kNone || + role == ax::mojom::blink::Role::kPresentational) && (CanSetFocusAttribute() || HasGlobalARIAAttribute())) - return ax::mojom::Role::kUnknown; + return ax::mojom::blink::Role::kUnknown; - if (role == ax::mojom::Role::kButton) + if (role == ax::mojom::blink::Role::kButton) role = ButtonRoleType(); role = RemapAriaRoleDueToParent(role); // Distinguish between different uses of the "combobox" role: // - // ax::mojom::Role::kComboBoxGrouping: + // ax::mojom::blink::Role::kComboBoxGrouping: // <div role="combobox"><input></div> - // ax::mojom::Role::kTextFieldWithComboBox: + // ax::mojom::blink::Role::kTextFieldWithComboBox: // <input role="combobox"> - // ax::mojom::Role::kComboBoxMenuButton: + // ax::mojom::blink::Role::kComboBoxMenuButton: // <div tabindex=0 role="combobox">Select</div> - if (role == ax::mojom::Role::kComboBoxGrouping) { + if (role == ax::mojom::blink::Role::kComboBoxGrouping) { if (IsNativeTextControl()) - role = ax::mojom::Role::kTextFieldWithComboBox; + role = ax::mojom::blink::Role::kTextFieldWithComboBox; else if (GetElement() && GetElement()->SupportsFocus()) - role = ax::mojom::Role::kComboBoxMenuButton; + role = ax::mojom::blink::Role::kComboBoxMenuButton; } - if (role != ax::mojom::Role::kUnknown) + if (role != ax::mojom::blink::Role::kUnknown) return role; - return ax::mojom::Role::kUnknown; + return ax::mojom::blink::Role::kUnknown; } -ax::mojom::Role AXObject::RemapAriaRoleDueToParent(ax::mojom::Role role) const { +ax::mojom::blink::Role AXObject::RemapAriaRoleDueToParent( + ax::mojom::blink::Role role) const { // Some objects change their role based on their parent. // However, asking for the unignoredParent calls accessibilityIsIgnored(), // which can trigger a loop. While inside the call stack of creating an @@ -2479,48 +2514,49 @@ ax::mojom::Role AXObject::RemapAriaRoleDueToParent(ax::mojom::Role role) const { // Don't return table roles unless inside a table-like container. switch (role) { - case ax::mojom::Role::kRow: - case ax::mojom::Role::kRowGroup: - case ax::mojom::Role::kCell: - case ax::mojom::Role::kRowHeader: - case ax::mojom::Role::kColumnHeader: + case ax::mojom::blink::Role::kRow: + case ax::mojom::blink::Role::kRowGroup: + case ax::mojom::blink::Role::kCell: + case ax::mojom::blink::Role::kRowHeader: + case ax::mojom::blink::Role::kColumnHeader: for (AXObject* ancestor = ParentObjectUnignored(); ancestor; ancestor = ancestor->ParentObjectUnignored()) { - ax::mojom::Role ancestor_aria_role = ancestor->AriaRoleAttribute(); - if (ancestor_aria_role == ax::mojom::Role::kCell) - return ax::mojom::Role::kGenericContainer; // In another cell, - // illegal. + ax::mojom::blink::Role ancestor_aria_role = + ancestor->AriaRoleAttribute(); + if (ancestor_aria_role == ax::mojom::blink::Role::kCell) + return ax::mojom::blink::Role::kGenericContainer; // In another cell, + // illegal. if (ancestor->IsTableLikeRole()) return role; // Inside a table: ARIA role is legal. } - return ax::mojom::Role::kGenericContainer; // Not in a table. + return ax::mojom::blink::Role::kGenericContainer; // Not in a table. default: break; } - if (role != ax::mojom::Role::kListBoxOption && - role != ax::mojom::Role::kMenuItem) + if (role != ax::mojom::blink::Role::kListBoxOption && + role != ax::mojom::blink::Role::kMenuItem) return role; for (AXObject* parent = ParentObject(); parent && !parent->AccessibilityIsIgnored(); parent = parent->ParentObject()) { - ax::mojom::Role parent_aria_role = parent->AriaRoleAttribute(); + ax::mojom::blink::Role parent_aria_role = parent->AriaRoleAttribute(); // Selects and listboxes both have options as child roles, but they map to // different roles within WebCore. - if (role == ax::mojom::Role::kListBoxOption && - parent_aria_role == ax::mojom::Role::kMenu) - return ax::mojom::Role::kMenuItem; + if (role == ax::mojom::blink::Role::kListBoxOption && + parent_aria_role == ax::mojom::blink::Role::kMenu) + return ax::mojom::blink::Role::kMenuItem; // An aria "menuitem" may map to MenuButton or MenuItem depending on its // parent. - if (role == ax::mojom::Role::kMenuItem && - parent_aria_role == ax::mojom::Role::kGroup) - return ax::mojom::Role::kMenuButton; + if (role == ax::mojom::blink::Role::kMenuItem && + parent_aria_role == ax::mojom::blink::Role::kGroup) + return ax::mojom::blink::Role::kMenuButton; // If the parent had a different role, then we don't need to continue // searching up the chain. - if (parent_aria_role != ax::mojom::Role::kUnknown) + if (parent_aria_role != ax::mojom::blink::Role::kUnknown) break; } @@ -2544,8 +2580,8 @@ bool AXObject::LiveRegionAtomic() const { // ARIA roles "alert" and "status" should have an implicit aria-atomic value // of true. - return RoleValue() == ax::mojom::Role::kAlert || - RoleValue() == ax::mojom::Role::kStatus; + return RoleValue() == ax::mojom::blink::Role::kAlert || + RoleValue() == ax::mojom::blink::Role::kStatus; } const AtomicString& AXObject::ContainerLiveRegionStatus() const { @@ -2585,14 +2621,14 @@ AXObject* AXObject::ElementAccessibilityHitTest(const IntPoint& point) const { return const_cast<AXObject*>(this); } -AXObject::AncestorsIterator AXObject::AncestorsBegin() const { +AXObject::AncestorsIterator AXObject::UnignoredAncestorsBegin() const { AXObject* parent = ParentObjectUnignored(); if (parent) return AXObject::AncestorsIterator(*parent); - return AncestorsEnd(); + return UnignoredAncestorsEnd(); } -AXObject::AncestorsIterator AXObject::AncestorsEnd() const { +AXObject::AncestorsIterator AXObject::UnignoredAncestorsEnd() const { return AXObject::AncestorsIterator(); } @@ -2600,46 +2636,109 @@ AXObject::InOrderTraversalIterator AXObject::GetInOrderTraversalIterator() { return InOrderTraversalIterator(*this); } -int AXObject::ChildCount() const { - return HasIndirectChildren() ? 0 : static_cast<int>(Children().size()); +int AXObject::ChildCountIncludingIgnored() const { + return HasIndirectChildren() ? 0 : int{ChildrenIncludingIgnored().size()}; } -const AXObject::AXObjectVector& AXObject::Children() const { - return const_cast<AXObject*>(this)->Children(); +AXObject* AXObject::ChildAtIncludingIgnored(int index) const { + // We need to use "ChildCountIncludingIgnored()" and + // "ChildrenIncludingIgnored()" instead of using the "children_" member + // directly, because we might need to update children and check for the + // presence of indirect children. + if (index < 0 || index >= ChildCountIncludingIgnored()) + return nullptr; + return ChildrenIncludingIgnored()[index]; } -const AXObject::AXObjectVector& AXObject::Children() { - UpdateChildrenIfNecessary(); +const AXObject::AXObjectVector& AXObject::ChildrenIncludingIgnored() const { + return const_cast<AXObject*>(this)->ChildrenIncludingIgnored(); +} +const AXObject::AXObjectVector& AXObject::ChildrenIncludingIgnored() { + UpdateChildrenIfNecessary(); return children_; } -AXObject* AXObject::FirstChild() const { - return ChildCount() ? *Children().begin() : nullptr; +const AXObject::AXObjectVector AXObject::UnignoredChildren() const { + return const_cast<AXObject*>(this)->UnignoredChildren(); +} + +const AXObject::AXObjectVector AXObject::UnignoredChildren() { + if (!AccessibilityIsIncludedInTree()) { + NOTREACHED() << "We don't support finding the unignored children of " + "objects excluded from the accessibility tree."; + return {}; + } + + UpdateChildrenIfNecessary(); + + // Capture only descendants that are not accessibility ignored, and that are + // one level deeper than the current object after flattening any accessibility + // ignored descendants. + // + // For example : + // ++A + // ++++B + // ++++C IGNORED + // ++++++F + // ++++D + // ++++++G + // ++++E IGNORED + // ++++++H IGNORED + // ++++++++J + // ++++++I + // + // Objects [B, F, D, I, J] will be returned, since after flattening all + // ignored objects ,those are the ones that are one level deep. + + AXObjectVector unignored_children; + AXObject* child = FirstChildIncludingIgnored(); + while (child && child != this) { + if (child->AccessibilityIsIgnored()) { + child = child->NextInPreOrderIncludingIgnored(this); + continue; + } + + unignored_children.push_back(child); + for (; child != this; child = child->ParentObjectIncludedInTree()) { + if (AXObject* sibling = child->NextSiblingIncludingIgnored()) { + child = sibling; + break; + } + } + } + + return unignored_children; +} + +AXObject* AXObject::FirstChildIncludingIgnored() const { + return ChildCountIncludingIgnored() ? *ChildrenIncludingIgnored().begin() + : nullptr; } -AXObject* AXObject::LastChild() const { - return ChildCount() ? *(Children().end() - 1) : nullptr; +AXObject* AXObject::LastChildIncludingIgnored() const { + return ChildCountIncludingIgnored() ? *(ChildrenIncludingIgnored().end() - 1) + : nullptr; } -AXObject* AXObject::DeepestFirstChild() const { - if (!ChildCount()) +AXObject* AXObject::DeepestFirstChildIncludingIgnored() const { + if (!ChildCountIncludingIgnored()) return nullptr; - AXObject* deepest_child = FirstChild(); - while (deepest_child->ChildCount()) - deepest_child = deepest_child->FirstChild(); + AXObject* deepest_child = FirstChildIncludingIgnored(); + while (deepest_child->ChildCountIncludingIgnored()) + deepest_child = deepest_child->FirstChildIncludingIgnored(); return deepest_child; } -AXObject* AXObject::DeepestLastChild() const { - if (!ChildCount()) +AXObject* AXObject::DeepestLastChildIncludingIgnored() const { + if (!ChildCountIncludingIgnored()) return nullptr; - AXObject* deepest_child = LastChild(); - while (deepest_child->ChildCount()) - deepest_child = deepest_child->LastChild(); + AXObject* deepest_child = LastChildIncludingIgnored(); + while (deepest_child->ChildCountIncludingIgnored()) + deepest_child = deepest_child->LastChildIncludingIgnored(); return deepest_child; } @@ -2658,7 +2757,7 @@ bool AXObject::IsDescendantOf(const AXObject& ancestor) const { AXObject* AXObject::NextSiblingIncludingIgnored() const { if (!AccessibilityIsIncludedInTree()) { NOTREACHED() << "We don't support iterating over objects excluded " - "from the accessibility tree"; + "from the accessibility tree."; return nullptr; } @@ -2667,15 +2766,15 @@ AXObject* AXObject::NextSiblingIncludingIgnored() const { return nullptr; const int index_in_parent = IndexInParent(); - if (index_in_parent < parent_in_tree->ChildCount() - 1) - return *(parent_in_tree->Children().begin() + index_in_parent + 1); + if (index_in_parent < parent_in_tree->ChildCountIncludingIgnored() - 1) + return parent_in_tree->ChildAtIncludingIgnored(index_in_parent + 1); return nullptr; } AXObject* AXObject::PreviousSiblingIncludingIgnored() const { if (!AccessibilityIsIncludedInTree()) { NOTREACHED() << "We don't support iterating over objects excluded " - "from the accessibility tree"; + "from the accessibility tree."; return nullptr; } @@ -2685,7 +2784,7 @@ AXObject* AXObject::PreviousSiblingIncludingIgnored() const { const int index_in_parent = IndexInParent(); if (index_in_parent > 0) - return *(parent_in_tree->Children().begin() + index_in_parent - 1); + return parent_in_tree->ChildAtIncludingIgnored(index_in_parent - 1); return nullptr; } @@ -2693,12 +2792,12 @@ AXObject* AXObject::NextInPreOrderIncludingIgnored( const AXObject* within) const { if (!AccessibilityIsIncludedInTree()) { NOTREACHED() << "We don't support iterating over objects excluded " - "from the accessibility tree"; + "from the accessibility tree."; return nullptr; } - if (ChildCount()) - return FirstChild(); + if (ChildCountIncludingIgnored()) + return FirstChildIncludingIgnored(); if (within == this) return nullptr; @@ -2717,15 +2816,15 @@ AXObject* AXObject::PreviousInPreOrderIncludingIgnored( const AXObject* within) const { if (!AccessibilityIsIncludedInTree()) { NOTREACHED() << "We don't support iterating over objects excluded " - "from the accessibility tree"; + "from the accessibility tree."; return nullptr; } if (within == this) return nullptr; if (AXObject* sibling = PreviousSiblingIncludingIgnored()) { - if (sibling->ChildCount()) - return sibling->DeepestLastChild(); + if (sibling->ChildCountIncludingIgnored()) + return sibling->DeepestLastChildIncludingIgnored(); return sibling; } @@ -2736,12 +2835,12 @@ AXObject* AXObject::PreviousInPostOrderIncludingIgnored( const AXObject* within) const { if (!AccessibilityIsIncludedInTree()) { NOTREACHED() << "We don't support iterating over objects excluded " - "from the accessibility tree"; + "from the accessibility tree."; return nullptr; } - if (ChildCount()) - return LastChild(); + if (ChildCountIncludingIgnored()) + return LastChildIncludingIgnored(); if (within == this) return nullptr; @@ -2756,9 +2855,22 @@ AXObject* AXObject::PreviousInPostOrderIncludingIgnored( return previous; } -AXObject* AXObject::NextSibling() const { +int AXObject::UnignoredChildCount() const { + return int{UnignoredChildren().size()}; +} + +AXObject* AXObject::UnignoredChildAt(int index) const { + const AXObjectVector unignored_children = UnignoredChildren(); + if (index < 0 || index >= int{unignored_children.size()}) + return nullptr; + return unignored_children[index]; +} + +AXObject* AXObject::UnignoredNextSibling() const { if (AccessibilityIsIgnored()) { - NOTREACHED() << "We don't support finding siblings for ignored objects."; + NOTREACHED() << "We don't support finding unignored siblings for ignored " + "objects because it is not clear whether to search for the " + "sibling in the unignored tree or in the whole tree."; return nullptr; } @@ -2795,9 +2907,11 @@ AXObject* AXObject::NextSibling() const { return nullptr; } -AXObject* AXObject::PreviousSibling() const { +AXObject* AXObject::UnignoredPreviousSibling() const { if (AccessibilityIsIgnored()) { - NOTREACHED() << "We don't support finding siblings for ignored objects."; + NOTREACHED() << "We don't support finding unignored siblings for ignored " + "objects because it is not clear whether to search for the " + "sibling in the unignored tree or in the whole tree."; return nullptr; } @@ -2835,7 +2949,7 @@ AXObject* AXObject::PreviousSibling() const { return nullptr; } -AXObject* AXObject::NextInTreeObject() const { +AXObject* AXObject::UnignoredNextInPreOrder() const { AXObject* next = NextInPreOrderIncludingIgnored(); while (next && next->AccessibilityIsIgnored()) { next = next->NextInPreOrderIncludingIgnored(); @@ -2843,7 +2957,7 @@ AXObject* AXObject::NextInTreeObject() const { return next; } -AXObject* AXObject::PreviousInTreeObject() const { +AXObject* AXObject::UnignoredPreviousInPreOrder() const { AXObject* previous = PreviousInPreOrderIncludingIgnored(); while (previous && previous->AccessibilityIsIgnored()) { previous = previous->PreviousInPreOrderIncludingIgnored(); @@ -3121,17 +3235,17 @@ void AXObject::SetScrollOffset(const IntPoint& offset) const { bool AXObject::IsTableLikeRole() const { return ui::IsTableLike(RoleValue()) || - RoleValue() == ax::mojom::Role::kLayoutTable; + RoleValue() == ax::mojom::blink::Role::kLayoutTable; } bool AXObject::IsTableRowLikeRole() const { return ui::IsTableRow(RoleValue()) || - RoleValue() == ax::mojom::Role::kLayoutTableRow; + RoleValue() == ax::mojom::blink::Role::kLayoutTableRow; } bool AXObject::IsTableCellLikeRole() const { return ui::IsCellOrTableHeader(RoleValue()) || - RoleValue() == ax::mojom::Role::kLayoutTableCell; + RoleValue() == ax::mojom::blink::Role::kLayoutTableCell; } unsigned AXObject::ColumnCount() const { @@ -3160,7 +3274,7 @@ void AXObject::ColumnHeaders(AXObjectVector& headers) const { for (const auto& row : TableRowChildren()) { for (const auto& cell : row->TableCellChildren()) { - if (cell->RoleValue() == ax::mojom::Role::kColumnHeader) + if (cell->RoleValue() == ax::mojom::blink::Role::kColumnHeader) headers.push_back(cell); } } @@ -3172,7 +3286,7 @@ void AXObject::RowHeaders(AXObjectVector& headers) const { for (const auto& row : TableRowChildren()) { for (const auto& cell : row->TableCellChildren()) { - if (cell->RoleValue() == ax::mojom::Role::kRowHeader) + if (cell->RoleValue() == ax::mojom::blink::Role::kRowHeader) headers.push_back(cell); } } @@ -3289,10 +3403,10 @@ unsigned AXObject::ComputeAriaRowIndex() const { AXObject::AXObjectVector AXObject::TableRowChildren() const { AXObjectVector result; - for (const auto& child : Children()) { + for (const auto& child : ChildrenIncludingIgnored()) { if (child->IsTableRowLikeRole()) result.push_back(child); - else if (child->RoleValue() == ax::mojom::Role::kRowGroup) + else if (child->RoleValue() == ax::mojom::blink::Role::kRowGroup) result.AppendVector(child->TableRowChildren()); } return result; @@ -3300,10 +3414,10 @@ AXObject::AXObjectVector AXObject::TableRowChildren() const { AXObject::AXObjectVector AXObject::TableCellChildren() const { AXObjectVector result; - for (const auto& child : Children()) { + for (const auto& child : ChildrenIncludingIgnored()) { if (child->IsTableCellLikeRole()) result.push_back(child); - else if (child->RoleValue() == ax::mojom::Role::kGenericContainer) + else if (child->RoleValue() == ax::mojom::blink::Role::kGenericContainer) result.AppendVector(child->TableCellChildren()); } return result; @@ -3312,7 +3426,7 @@ AXObject::AXObjectVector AXObject::TableCellChildren() const { const AXObject* AXObject::TableRowParent() const { const AXObject* row = ParentObjectUnignored(); while (row && !row->IsTableRowLikeRole() && - row->RoleValue() == ax::mojom::Role::kGenericContainer) + row->RoleValue() == ax::mojom::blink::Role::kGenericContainer) row = row->ParentObjectUnignored(); return row; } @@ -3320,7 +3434,7 @@ const AXObject* AXObject::TableRowParent() const { const AXObject* AXObject::TableParent() const { const AXObject* table = ParentObjectUnignored(); while (table && !table->IsTableLikeRole() && - table->RoleValue() == ax::mojom::Role::kGenericContainer) + table->RoleValue() == ax::mojom::blink::Role::kGenericContainer) table = table->ParentObjectUnignored(); return table; } @@ -3627,7 +3741,7 @@ bool AXObject::OnNativeScrollToMakeVisibleAction() const { mojom::blink::ScrollBehavior::kAuto)); AXObjectCache().PostNotification( AXObjectCache().GetOrCreate(GetDocument()->GetLayoutView()), - ax::mojom::Event::kLocationChanged); + ax::mojom::blink::Event::kLocationChanged); return true; } @@ -3649,7 +3763,7 @@ bool AXObject::OnNativeScrollToMakeVisibleWithSubFocusAction( mojom::blink::ScrollBehavior::kAuto)); AXObjectCache().PostNotification( AXObjectCache().GetOrCreate(GetDocument()->GetLayoutView()), - ax::mojom::Event::kLocationChanged); + ax::mojom::blink::Event::kLocationChanged); return true; } @@ -3669,7 +3783,7 @@ bool AXObject::OnNativeScrollToGlobalPointAction( mojom::blink::ScrollBehavior::kAuto)); AXObjectCache().PostNotification( AXObjectCache().GetOrCreate(GetDocument()->GetLayoutView()), - ax::mojom::Event::kLocationChanged); + ax::mojom::blink::Event::kLocationChanged); return true; } @@ -3725,33 +3839,34 @@ void AXObject::SelectionChanged() { } // static -bool AXObject::IsARIAControl(ax::mojom::Role aria_role) { - return IsARIAInput(aria_role) || aria_role == ax::mojom::Role::kButton || - aria_role == ax::mojom::Role::kComboBoxMenuButton || - aria_role == ax::mojom::Role::kSlider; +bool AXObject::IsARIAControl(ax::mojom::blink::Role aria_role) { + return IsARIAInput(aria_role) || + aria_role == ax::mojom::blink::Role::kButton || + aria_role == ax::mojom::blink::Role::kComboBoxMenuButton || + aria_role == ax::mojom::blink::Role::kSlider; } // static -bool AXObject::IsARIAInput(ax::mojom::Role aria_role) { - return aria_role == ax::mojom::Role::kRadioButton || - aria_role == ax::mojom::Role::kCheckBox || - aria_role == ax::mojom::Role::kTextField || - aria_role == ax::mojom::Role::kSwitch || - aria_role == ax::mojom::Role::kSearchBox || - aria_role == ax::mojom::Role::kTextFieldWithComboBox; +bool AXObject::IsARIAInput(ax::mojom::blink::Role aria_role) { + return aria_role == ax::mojom::blink::Role::kRadioButton || + aria_role == ax::mojom::blink::Role::kCheckBox || + aria_role == ax::mojom::blink::Role::kTextField || + aria_role == ax::mojom::blink::Role::kSwitch || + aria_role == ax::mojom::blink::Role::kSearchBox || + aria_role == ax::mojom::blink::Role::kTextFieldWithComboBox; } -ax::mojom::Role AXObject::AriaRoleToWebCoreRole(const String& value) { +ax::mojom::blink::Role AXObject::AriaRoleToWebCoreRole(const String& value) { DCHECK(!value.IsEmpty()); static const ARIARoleMap* role_map = CreateARIARoleMap(); Vector<String> role_vector; value.Split(' ', role_vector); - ax::mojom::Role role = ax::mojom::Role::kUnknown; + ax::mojom::blink::Role role = ax::mojom::blink::Role::kUnknown; for (const auto& child : role_vector) { role = role_map->at(child); - if (role != ax::mojom::Role::kUnknown) + if (role != ax::mojom::blink::Role::kUnknown) return role; } @@ -3761,13 +3876,13 @@ ax::mojom::Role AXObject::AriaRoleToWebCoreRole(const String& value) { bool AXObject::NameFromSelectedOption(bool recursive) const { switch (RoleValue()) { // Step 2E from: http://www.w3.org/TR/accname-aam-1.1 - case ax::mojom::Role::kComboBoxGrouping: - case ax::mojom::Role::kComboBoxMenuButton: - case ax::mojom::Role::kListBox: + case ax::mojom::blink::Role::kComboBoxGrouping: + case ax::mojom::blink::Role::kComboBoxMenuButton: + case ax::mojom::blink::Role::kListBox: return recursive; // 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: + case ax::mojom::blink::Role::kPopUpButton: return DynamicTo<HTMLSelectElement>(*GetNode()) ? recursive : false; default: return false; @@ -3781,207 +3896,210 @@ bool AXObject::NameFromContents(bool recursive) const { switch (RoleValue()) { // ----- NameFrom: contents ------------------------- // Get their own name from contents, or contribute to ancestors - case ax::mojom::Role::kAnchor: - case ax::mojom::Role::kButton: - case ax::mojom::Role::kCell: - case ax::mojom::Role::kCheckBox: - case ax::mojom::Role::kColumnHeader: - case ax::mojom::Role::kDocBackLink: - case ax::mojom::Role::kDocBiblioRef: - case ax::mojom::Role::kDocNoteRef: - case ax::mojom::Role::kDocGlossRef: - case ax::mojom::Role::kDisclosureTriangle: - case ax::mojom::Role::kHeading: - case ax::mojom::Role::kLayoutTableCell: - case ax::mojom::Role::kLineBreak: - case ax::mojom::Role::kLink: - case ax::mojom::Role::kListBoxOption: - case ax::mojom::Role::kMenuItem: - case ax::mojom::Role::kMenuItemCheckBox: - case ax::mojom::Role::kMenuItemRadio: - case ax::mojom::Role::kMenuListOption: - case ax::mojom::Role::kPopUpButton: - case ax::mojom::Role::kPortal: - case ax::mojom::Role::kRadioButton: - case ax::mojom::Role::kRowHeader: - case ax::mojom::Role::kStaticText: - case ax::mojom::Role::kSwitch: - case ax::mojom::Role::kTab: - case ax::mojom::Role::kToggleButton: - case ax::mojom::Role::kTreeItem: - case ax::mojom::Role::kTooltip: + case ax::mojom::blink::Role::kAnchor: + case ax::mojom::blink::Role::kButton: + case ax::mojom::blink::Role::kCell: + case ax::mojom::blink::Role::kCheckBox: + case ax::mojom::blink::Role::kColumnHeader: + case ax::mojom::blink::Role::kDocBackLink: + case ax::mojom::blink::Role::kDocBiblioRef: + case ax::mojom::blink::Role::kDocNoteRef: + case ax::mojom::blink::Role::kDocGlossRef: + case ax::mojom::blink::Role::kDisclosureTriangle: + case ax::mojom::blink::Role::kHeading: + case ax::mojom::blink::Role::kLayoutTableCell: + case ax::mojom::blink::Role::kLineBreak: + case ax::mojom::blink::Role::kLink: + case ax::mojom::blink::Role::kListBoxOption: + case ax::mojom::blink::Role::kMenuItem: + case ax::mojom::blink::Role::kMenuItemCheckBox: + case ax::mojom::blink::Role::kMenuItemRadio: + case ax::mojom::blink::Role::kMenuListOption: + case ax::mojom::blink::Role::kPopUpButton: + case ax::mojom::blink::Role::kPortal: + case ax::mojom::blink::Role::kRadioButton: + case ax::mojom::blink::Role::kRowHeader: + case ax::mojom::blink::Role::kStaticText: + case ax::mojom::blink::Role::kSwitch: + case ax::mojom::blink::Role::kTab: + case ax::mojom::blink::Role::kToggleButton: + case ax::mojom::blink::Role::kTreeItem: + case ax::mojom::blink::Role::kTooltip: result = true; break; // ----- No name from contents ------------------------- // These never have or contribute a name from contents, as they are // containers for many subobjects. Superset of nameFrom:author ARIA roles. - case ax::mojom::Role::kAlert: - case ax::mojom::Role::kAlertDialog: - case ax::mojom::Role::kApplication: - case ax::mojom::Role::kAudio: - case ax::mojom::Role::kArticle: - case ax::mojom::Role::kBanner: - case ax::mojom::Role::kBlockquote: - case ax::mojom::Role::kCaret: - case ax::mojom::Role::kClient: - case ax::mojom::Role::kColorWell: - case ax::mojom::Role::kColumn: - case ax::mojom::Role::kComboBoxMenuButton: // Only value from content. - case ax::mojom::Role::kComboBoxGrouping: - case ax::mojom::Role::kComment: - case ax::mojom::Role::kComplementary: - case ax::mojom::Role::kContentInfo: - case ax::mojom::Role::kDate: - case ax::mojom::Role::kDateTime: - case ax::mojom::Role::kDesktop: - case ax::mojom::Role::kDialog: - case ax::mojom::Role::kDirectory: - case ax::mojom::Role::kDocCover: - case ax::mojom::Role::kDocBiblioEntry: - case ax::mojom::Role::kDocEndnote: - case ax::mojom::Role::kDocFootnote: - case ax::mojom::Role::kDocPageBreak: - case ax::mojom::Role::kDocAbstract: - case ax::mojom::Role::kDocAcknowledgments: - case ax::mojom::Role::kDocAfterword: - case ax::mojom::Role::kDocAppendix: - case ax::mojom::Role::kDocBibliography: - case ax::mojom::Role::kDocChapter: - case ax::mojom::Role::kDocColophon: - case ax::mojom::Role::kDocConclusion: - case ax::mojom::Role::kDocCredit: - case ax::mojom::Role::kDocCredits: - case ax::mojom::Role::kDocDedication: - case ax::mojom::Role::kDocEndnotes: - case ax::mojom::Role::kDocEpigraph: - case ax::mojom::Role::kDocEpilogue: - case ax::mojom::Role::kDocErrata: - case ax::mojom::Role::kDocExample: - case ax::mojom::Role::kDocForeword: - case ax::mojom::Role::kDocGlossary: - case ax::mojom::Role::kDocIndex: - case ax::mojom::Role::kDocIntroduction: - case ax::mojom::Role::kDocNotice: - case ax::mojom::Role::kDocPageList: - case ax::mojom::Role::kDocPart: - case ax::mojom::Role::kDocPreface: - case ax::mojom::Role::kDocPrologue: - case ax::mojom::Role::kDocPullquote: - case ax::mojom::Role::kDocQna: - case ax::mojom::Role::kDocSubtitle: - case ax::mojom::Role::kDocTip: - case ax::mojom::Role::kDocToc: - case ax::mojom::Role::kDocument: - case ax::mojom::Role::kEmbeddedObject: - case ax::mojom::Role::kFeed: - case ax::mojom::Role::kFigure: - case ax::mojom::Role::kForm: - case ax::mojom::Role::kGraphicsDocument: - case ax::mojom::Role::kGraphicsObject: - 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: - case ax::mojom::Role::kImeCandidate: // Internal role, not used on the web. - case ax::mojom::Role::kInputTime: - case ax::mojom::Role::kKeyboard: - case ax::mojom::Role::kListBox: - case ax::mojom::Role::kListGrid: - case ax::mojom::Role::kLog: - case ax::mojom::Role::kMain: - case ax::mojom::Role::kMarquee: - case ax::mojom::Role::kMath: - case ax::mojom::Role::kMenuListPopup: - case ax::mojom::Role::kMenu: - case ax::mojom::Role::kMenuBar: - case ax::mojom::Role::kMenuButton: // Only value from content, not name. - case ax::mojom::Role::kMeter: - case ax::mojom::Role::kNavigation: - case ax::mojom::Role::kNote: - case ax::mojom::Role::kPane: - case ax::mojom::Role::kPluginObject: - case ax::mojom::Role::kProgressIndicator: - case ax::mojom::Role::kRadioGroup: - case ax::mojom::Role::kRowGroup: - case ax::mojom::Role::kScrollBar: - case ax::mojom::Role::kScrollView: - case ax::mojom::Role::kSearch: - case ax::mojom::Role::kSearchBox: - case ax::mojom::Role::kSplitter: - case ax::mojom::Role::kSlider: - case ax::mojom::Role::kSpinButton: - case ax::mojom::Role::kStatus: - case ax::mojom::Role::kSliderThumb: - case ax::mojom::Role::kSuggestion: - case ax::mojom::Role::kSvgRoot: - case ax::mojom::Role::kTable: - case ax::mojom::Role::kTableHeaderContainer: - case ax::mojom::Role::kTabList: - case ax::mojom::Role::kTabPanel: - case ax::mojom::Role::kTerm: - case ax::mojom::Role::kTextField: - case ax::mojom::Role::kTextFieldWithComboBox: - case ax::mojom::Role::kTitleBar: - case ax::mojom::Role::kTimer: - case ax::mojom::Role::kToolbar: - case ax::mojom::Role::kTree: - case ax::mojom::Role::kTreeGrid: - case ax::mojom::Role::kVideo: - case ax::mojom::Role::kWebArea: - case ax::mojom::Role::kWebView: - case ax::mojom::Role::kWindow: + case ax::mojom::blink::Role::kAlert: + case ax::mojom::blink::Role::kAlertDialog: + case ax::mojom::blink::Role::kApplication: + case ax::mojom::blink::Role::kAudio: + case ax::mojom::blink::Role::kArticle: + case ax::mojom::blink::Role::kBanner: + case ax::mojom::blink::Role::kBlockquote: + case ax::mojom::blink::Role::kCaret: + case ax::mojom::blink::Role::kClient: + case ax::mojom::blink::Role::kColorWell: + case ax::mojom::blink::Role::kColumn: + case ax::mojom::blink::Role::kComboBoxMenuButton: // Only value from + // content. + case ax::mojom::blink::Role::kComboBoxGrouping: + case ax::mojom::blink::Role::kComment: + case ax::mojom::blink::Role::kComplementary: + case ax::mojom::blink::Role::kContentInfo: + case ax::mojom::blink::Role::kDate: + case ax::mojom::blink::Role::kDateTime: + case ax::mojom::blink::Role::kDesktop: + case ax::mojom::blink::Role::kDialog: + case ax::mojom::blink::Role::kDirectory: + case ax::mojom::blink::Role::kDocCover: + case ax::mojom::blink::Role::kDocBiblioEntry: + case ax::mojom::blink::Role::kDocEndnote: + case ax::mojom::blink::Role::kDocFootnote: + case ax::mojom::blink::Role::kDocPageBreak: + case ax::mojom::blink::Role::kDocAbstract: + case ax::mojom::blink::Role::kDocAcknowledgments: + case ax::mojom::blink::Role::kDocAfterword: + case ax::mojom::blink::Role::kDocAppendix: + case ax::mojom::blink::Role::kDocBibliography: + case ax::mojom::blink::Role::kDocChapter: + case ax::mojom::blink::Role::kDocColophon: + case ax::mojom::blink::Role::kDocConclusion: + case ax::mojom::blink::Role::kDocCredit: + case ax::mojom::blink::Role::kDocCredits: + case ax::mojom::blink::Role::kDocDedication: + case ax::mojom::blink::Role::kDocEndnotes: + case ax::mojom::blink::Role::kDocEpigraph: + case ax::mojom::blink::Role::kDocEpilogue: + case ax::mojom::blink::Role::kDocErrata: + case ax::mojom::blink::Role::kDocExample: + case ax::mojom::blink::Role::kDocForeword: + case ax::mojom::blink::Role::kDocGlossary: + case ax::mojom::blink::Role::kDocIndex: + case ax::mojom::blink::Role::kDocIntroduction: + case ax::mojom::blink::Role::kDocNotice: + case ax::mojom::blink::Role::kDocPageList: + case ax::mojom::blink::Role::kDocPart: + case ax::mojom::blink::Role::kDocPreface: + case ax::mojom::blink::Role::kDocPrologue: + case ax::mojom::blink::Role::kDocPullquote: + case ax::mojom::blink::Role::kDocQna: + case ax::mojom::blink::Role::kDocSubtitle: + case ax::mojom::blink::Role::kDocTip: + case ax::mojom::blink::Role::kDocToc: + case ax::mojom::blink::Role::kDocument: + case ax::mojom::blink::Role::kEmbeddedObject: + case ax::mojom::blink::Role::kFeed: + case ax::mojom::blink::Role::kFigure: + case ax::mojom::blink::Role::kForm: + case ax::mojom::blink::Role::kGraphicsDocument: + case ax::mojom::blink::Role::kGraphicsObject: + case ax::mojom::blink::Role::kGraphicsSymbol: + case ax::mojom::blink::Role::kGrid: + case ax::mojom::blink::Role::kGroup: + case ax::mojom::blink::Role::kHeader: + case ax::mojom::blink::Role::kIframePresentational: + case ax::mojom::blink::Role::kIframe: + case ax::mojom::blink::Role::kImage: + case ax::mojom::blink::Role::kImeCandidate: // Internal role, not used on + // the web. + case ax::mojom::blink::Role::kInputTime: + case ax::mojom::blink::Role::kKeyboard: + case ax::mojom::blink::Role::kListBox: + case ax::mojom::blink::Role::kListGrid: + case ax::mojom::blink::Role::kLog: + case ax::mojom::blink::Role::kMain: + case ax::mojom::blink::Role::kMarquee: + case ax::mojom::blink::Role::kMath: + case ax::mojom::blink::Role::kMenuListPopup: + case ax::mojom::blink::Role::kMenu: + case ax::mojom::blink::Role::kMenuBar: + case ax::mojom::blink::Role::kMenuButton: // Only value from content, not + // name. + case ax::mojom::blink::Role::kMeter: + case ax::mojom::blink::Role::kNavigation: + case ax::mojom::blink::Role::kNote: + case ax::mojom::blink::Role::kPane: + case ax::mojom::blink::Role::kPluginObject: + case ax::mojom::blink::Role::kProgressIndicator: + case ax::mojom::blink::Role::kRadioGroup: + case ax::mojom::blink::Role::kRowGroup: + case ax::mojom::blink::Role::kScrollBar: + case ax::mojom::blink::Role::kScrollView: + case ax::mojom::blink::Role::kSearch: + case ax::mojom::blink::Role::kSearchBox: + case ax::mojom::blink::Role::kSplitter: + case ax::mojom::blink::Role::kSlider: + case ax::mojom::blink::Role::kSpinButton: + case ax::mojom::blink::Role::kStatus: + case ax::mojom::blink::Role::kSliderThumb: + case ax::mojom::blink::Role::kSuggestion: + case ax::mojom::blink::Role::kSvgRoot: + case ax::mojom::blink::Role::kTable: + case ax::mojom::blink::Role::kTableHeaderContainer: + case ax::mojom::blink::Role::kTabList: + case ax::mojom::blink::Role::kTabPanel: + case ax::mojom::blink::Role::kTerm: + case ax::mojom::blink::Role::kTextField: + case ax::mojom::blink::Role::kTextFieldWithComboBox: + case ax::mojom::blink::Role::kTitleBar: + case ax::mojom::blink::Role::kTimer: + case ax::mojom::blink::Role::kToolbar: + case ax::mojom::blink::Role::kTree: + case ax::mojom::blink::Role::kTreeGrid: + case ax::mojom::blink::Role::kVideo: + case ax::mojom::blink::Role::kWebArea: + case ax::mojom::blink::Role::kWebView: + case ax::mojom::blink::Role::kWindow: result = false; break; // ----- Conditional: contribute to ancestor only, unless focusable ------- // 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::kCanvas: - case ax::mojom::Role::kCaption: - case ax::mojom::Role::kCode: - case ax::mojom::Role::kContentDeletion: - case ax::mojom::Role::kContentInsertion: - case ax::mojom::Role::kDefinition: - case ax::mojom::Role::kDescriptionListDetail: - case ax::mojom::Role::kDescriptionList: - case ax::mojom::Role::kDescriptionListTerm: - case ax::mojom::Role::kDetails: - case ax::mojom::Role::kEmphasis: - 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: - case ax::mojom::Role::kLabelText: - case ax::mojom::Role::kLayoutTable: - case ax::mojom::Role::kLayoutTableRow: - case ax::mojom::Role::kLegend: - case ax::mojom::Role::kList: - case ax::mojom::Role::kListItem: - case ax::mojom::Role::kListMarker: - case ax::mojom::Role::kMark: - case ax::mojom::Role::kNone: - case ax::mojom::Role::kParagraph: - case ax::mojom::Role::kPre: - case ax::mojom::Role::kPresentational: - case ax::mojom::Role::kRegion: + case ax::mojom::blink::Role::kAbbr: + case ax::mojom::blink::Role::kCanvas: + case ax::mojom::blink::Role::kCaption: + case ax::mojom::blink::Role::kCode: + case ax::mojom::blink::Role::kContentDeletion: + case ax::mojom::blink::Role::kContentInsertion: + case ax::mojom::blink::Role::kDefinition: + case ax::mojom::blink::Role::kDescriptionListDetail: + case ax::mojom::blink::Role::kDescriptionList: + case ax::mojom::blink::Role::kDescriptionListTerm: + case ax::mojom::blink::Role::kDetails: + case ax::mojom::blink::Role::kEmphasis: + case ax::mojom::blink::Role::kFigcaption: + case ax::mojom::blink::Role::kFooter: + case ax::mojom::blink::Role::kFooterAsNonLandmark: + case ax::mojom::blink::Role::kGenericContainer: + case ax::mojom::blink::Role::kHeaderAsNonLandmark: + case ax::mojom::blink::Role::kIgnored: + case ax::mojom::blink::Role::kImageMap: + case ax::mojom::blink::Role::kInlineTextBox: + case ax::mojom::blink::Role::kLabelText: + case ax::mojom::blink::Role::kLayoutTable: + case ax::mojom::blink::Role::kLayoutTableRow: + case ax::mojom::blink::Role::kLegend: + case ax::mojom::blink::Role::kList: + case ax::mojom::blink::Role::kListItem: + case ax::mojom::blink::Role::kListMarker: + case ax::mojom::blink::Role::kMark: + case ax::mojom::blink::Role::kNone: + case ax::mojom::blink::Role::kParagraph: + case ax::mojom::blink::Role::kPre: + case ax::mojom::blink::Role::kPresentational: + case ax::mojom::blink::Role::kRegion: // Spec says we should always expose the name on rows, // but for performance reasons we only do it // 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: - case ax::mojom::Role::kStrong: - case ax::mojom::Role::kTime: + case ax::mojom::blink::Role::kRow: + case ax::mojom::blink::Role::kRuby: + case ax::mojom::blink::Role::kRubyAnnotation: + case ax::mojom::blink::Role::kSection: + case ax::mojom::blink::Role::kStrong: + case ax::mojom::blink::Role::kTime: if (recursive) { // Use contents if part of a recursive name computation. result = true; @@ -3993,9 +4111,9 @@ bool AXObject::NameFromContents(bool recursive) const { // would cause them to be double-announced. // 2.Containers with aria-activedescendant, where the focus is being // forwarded somewhere else. - // TODO(accessibility) Scrollables are currently whitelisted here in - // order to keep the current behavior. In the future, this can be - // removed because this code will be handled in IsFocusable(), once + // TODO(accessibility) Scrollables are currently allowed here in order + // to keep the current behavior. In the future, this can be removed + // because this code will be handled in IsFocusable(), once // KeyboardFocusableScrollersEnabled is permanently enabled. // Note: this uses the same scrollable check that element.cc uses. bool is_focusable_scrollable = @@ -4008,7 +4126,7 @@ bool AXObject::NameFromContents(bool recursive) const { } break; - case ax::mojom::Role::kPdfActionableHighlight: + case ax::mojom::blink::Role::kPdfActionableHighlight: LOG(ERROR) << "PDF specific highlight role, Blink shouldn't generate " "this role type"; NOTREACHED(); @@ -4018,7 +4136,7 @@ bool AXObject::NameFromContents(bool recursive) const { // but a root web area inside a portal's main frame should compute its name // from its contents. This name is used by the portal element that hosts // this portal. - case ax::mojom::Role::kRootWebArea: { + case ax::mojom::blink::Role::kRootWebArea: { DCHECK(GetNode()); const Document& document = GetNode()->GetDocument(); bool is_main_frame = @@ -4028,8 +4146,8 @@ bool AXObject::NameFromContents(bool recursive) const { return is_inside_portal && is_main_frame; } - case ax::mojom::Role::kUnknown: - LOG(ERROR) << "ax::mojom::Role::kUnknown for " << GetNode(); + case ax::mojom::blink::Role::kUnknown: + LOG(ERROR) << "ax::mojom::blink::Role::kUnknown for " << GetNode(); NOTREACHED(); break; } @@ -4044,37 +4162,38 @@ bool AXObject::SupportsARIAReadOnly() const { if (ui::IsCellOrTableHeader(RoleValue())) { // For cells and row/column headers, readonly is supported within a grid. return std::any_of( - AncestorsBegin(), AncestorsEnd(), [](const AXObject& ancestor) { - return ancestor.RoleValue() == ax::mojom::Role::kGrid || - ancestor.RoleValue() == ax::mojom::Role::kTreeGrid; + UnignoredAncestorsBegin(), UnignoredAncestorsEnd(), + [](const AXObject& ancestor) { + return ancestor.RoleValue() == ax::mojom::blink::Role::kGrid || + ancestor.RoleValue() == ax::mojom::blink::Role::kTreeGrid; }); } return false; } -ax::mojom::Role AXObject::ButtonRoleType() const { +ax::mojom::blink::Role AXObject::ButtonRoleType() const { // If aria-pressed is present, then it should be exposed as a toggle button. // http://www.w3.org/TR/wai-aria/states_and_properties#aria-pressed if (AriaPressedIsPresent()) - return ax::mojom::Role::kToggleButton; - if (HasPopup() != ax::mojom::HasPopup::kFalse) - return ax::mojom::Role::kPopUpButton; + return ax::mojom::blink::Role::kToggleButton; + if (HasPopup() != ax::mojom::blink::HasPopup::kFalse) + return ax::mojom::blink::Role::kPopUpButton; // We don't contemplate RadioButtonRole, as it depends on the input // type. - return ax::mojom::Role::kButton; + return ax::mojom::blink::Role::kButton; } // static -const AtomicString& AXObject::RoleName(ax::mojom::Role role) { +const AtomicString& AXObject::RoleName(ax::mojom::blink::Role role) { static const Vector<AtomicString>* role_name_vector = CreateRoleNameVector(); return role_name_vector->at(static_cast<wtf_size_t>(role)); } // static -const AtomicString& AXObject::InternalRoleName(ax::mojom::Role role) { +const AtomicString& AXObject::InternalRoleName(ax::mojom::blink::Role role) { static const Vector<AtomicString>* internal_role_name_vector = CreateInternalRoleNameVector(); @@ -4210,7 +4329,7 @@ std::ostream& operator<<(std::ostream& stream, const AXObject& obj) { return stream << obj.ToString(true).Utf8(); } -void AXObject::Trace(Visitor* visitor) { +void AXObject::Trace(Visitor* visitor) const { visitor->Trace(children_); visitor->Trace(parent_); visitor->Trace(cached_live_region_root_); 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 3473c468584..96019107154 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object.h @@ -103,7 +103,7 @@ class IgnoredReason { IgnoredReason(AXIgnoredReason r, const AXObject* obj) : reason(r), related_object(obj) {} - void Trace(Visitor* visitor) { visitor->Trace(related_object); } + void Trace(Visitor* visitor) const { visitor->Trace(related_object); } }; class NameSourceRelatedObject final @@ -115,7 +115,7 @@ class NameSourceRelatedObject final NameSourceRelatedObject(AXObject* object, String text) : object(object), text(text) {} - void Trace(Visitor* visitor) { visitor->Trace(object); } + void Trace(Visitor* visitor) const { visitor->Trace(object); } DISALLOW_COPY_AND_ASSIGN(NameSourceRelatedObject); }; @@ -128,7 +128,7 @@ class NameSource { String text; bool superseded = false; bool invalid = false; - ax::mojom::NameFrom type = ax::mojom::NameFrom::kUninitialized; + ax::mojom::blink::NameFrom type = ax::mojom::blink::NameFrom::kUninitialized; const QualifiedName& attribute; AtomicString attribute_value; AXTextFromNativeHTML native_source = kAXTextFromNativeHTMLUninitialized; @@ -140,7 +140,7 @@ class NameSource { explicit NameSource(bool superseded) : superseded(superseded), attribute(QualifiedName::Null()) {} - void Trace(Visitor* visitor) { visitor->Trace(related_objects); } + void Trace(Visitor* visitor) const { visitor->Trace(related_objects); } }; class DescriptionSource { @@ -150,7 +150,8 @@ class DescriptionSource { String text; bool superseded = false; bool invalid = false; - ax::mojom::DescriptionFrom type = ax::mojom::DescriptionFrom::kUninitialized; + ax::mojom::blink::DescriptionFrom type = + ax::mojom::blink::DescriptionFrom::kUninitialized; const QualifiedName& attribute; AtomicString attribute_value; AXTextFromNativeHTML native_source = kAXTextFromNativeHTMLUninitialized; @@ -162,7 +163,7 @@ class DescriptionSource { explicit DescriptionSource(bool superseded) : superseded(superseded), attribute(QualifiedName::Null()) {} - void Trace(Visitor* visitor) { visitor->Trace(related_objects); } + void Trace(Visitor* visitor) const { visitor->Trace(related_objects); } }; } // namespace blink @@ -178,7 +179,9 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { typedef HeapVector<Member<AXObject>> AXObjectVector; // Iterator for doing an in-order traversal of the accessibility tree. - // Includes ignored objects in the traversal. + // + // Includes objects that are ignored but included in the accessibility tree in + // the traversal. class MODULES_EXPORT InOrderTraversalIterator final : public GarbageCollected<InOrderTraversalIterator> { public: @@ -196,7 +199,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { InOrderTraversalIterator& operator++() { previous_ = current_; current_ = (current_ && !current_->IsDetached()) - ? current_->NextInTreeObject() + ? current_->NextInPreOrderIncludingIgnored() : nullptr; return *this; } @@ -210,7 +213,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { InOrderTraversalIterator& operator--() { current_ = previous_; previous_ = (current_ && !current_->IsDetached()) - ? current_->PreviousInTreeObject() + ? current_->PreviousInPreOrderIncludingIgnored() : nullptr; return *this; } @@ -231,7 +234,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { return static_cast<AXObject*>(current_); } - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(current_); visitor->Trace(previous_); } @@ -273,6 +276,12 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { class MODULES_EXPORT AncestorsIterator final : public GarbageCollected<AncestorsIterator> { public: + using iterator_category = std::forward_iterator_tag; + using value_type = AXObject; + using difference_type = ptrdiff_t; + using pointer = value_type*; + using reference = value_type&; + ~AncestorsIterator() = default; AncestorsIterator(const AncestorsIterator& other) @@ -306,7 +315,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { return static_cast<AXObject*>(current_); } - void Trace(Visitor* visitor) { visitor->Trace(current_); } + void Trace(Visitor* visitor) const { visitor->Trace(current_); } MODULES_EXPORT friend void swap(AncestorsIterator& left, AncestorsIterator& right) { @@ -339,7 +348,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { public: virtual ~AXObject(); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; static unsigned NumberOfLiveAXObjects() { return number_of_live_ax_objects_; } @@ -417,7 +426,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { virtual bool IsVirtualObject() const; // Check object role or purpose. - virtual ax::mojom::Role RoleValue() const; + virtual ax::mojom::blink::Role RoleValue() const; bool IsARIATextControl() const; bool IsAnchor() const; bool IsButton() const; @@ -440,30 +449,31 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { bool IsMeter() const; virtual bool IsNativeImage() const; virtual bool IsNativeSpinButton() const; - // input or textarea. + // Returns true if this object is an input element of a text field type, such + // as type="text" or type="tel", or a textarea. virtual bool IsNativeTextControl() const; - // contenteditable or role=textbox. + // Returns true if this object is a contenteditable or has role=textbox. virtual bool IsNonNativeTextControl() const; virtual bool IsPasswordField() const; bool IsPasswordFieldAndShouldHideValue() const; bool IsPresentational() const; bool IsRadioButton() const { - return RoleValue() == ax::mojom::Role::kRadioButton; + return RoleValue() == ax::mojom::blink::Role::kRadioButton; } bool IsRangeValueSupported() const; bool IsScrollbar() const { - return RoleValue() == ax::mojom::Role::kScrollBar; + return RoleValue() == ax::mojom::blink::Role::kScrollBar; } virtual bool IsNativeSlider() const { return false; } virtual bool IsSpinButton() const { - return RoleValue() == ax::mojom::Role::kSpinButton; + return RoleValue() == ax::mojom::blink::Role::kSpinButton; } - bool IsTabItem() const { return RoleValue() == ax::mojom::Role::kTab; } + bool IsTabItem() const { return RoleValue() == ax::mojom::blink::Role::kTab; } virtual bool IsTextControl() const { return false; } bool IsTextObject() const; - bool IsTree() const { return RoleValue() == ax::mojom::Role::kTree; } + bool IsTree() const { return RoleValue() == ax::mojom::blink::Role::kTree; } bool IsWebArea() const { - return RoleValue() == ax::mojom::Role::kRootWebArea; + return RoleValue() == ax::mojom::blink::Role::kRootWebArea; } // Check object state. @@ -522,6 +532,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { bool IsInertOrAriaHidden() const; const AXObject* AriaHiddenRoot() const; bool ComputeIsInertOrAriaHidden(IgnoredReasons* = nullptr) const; + bool IsBlockedByAriaModalDialog(IgnoredReasons* = nullptr) const; bool IsDescendantOfLeafNode() const; AXObject* LeafNodeAncestor() const; bool IsDescendantOfDisabledNode() const; @@ -546,7 +557,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { // Retrieves the accessible name of the object, an enum indicating where the // name was derived from, and a list of objects that were used to derive the // name, if any. - virtual String GetName(ax::mojom::NameFrom&, + virtual String GetName(ax::mojom::blink::NameFrom&, AXObjectVector* name_objects) const; typedef HeapVector<NameSource> NameSources; @@ -559,16 +570,16 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { // accessible description of the object, which is secondary to |name|, an enum // indicating where the description was derived from, and a list of objects // that were used to derive the description, if any. - virtual String Description(ax::mojom::NameFrom, - ax::mojom::DescriptionFrom&, + virtual String Description(ax::mojom::blink::NameFrom, + ax::mojom::blink::DescriptionFrom&, AXObjectVector* description_objects) const { return String(); } // Same as above, but returns a list of all potential sources for the // description, indicating which were used. - virtual String Description(ax::mojom::NameFrom, - ax::mojom::DescriptionFrom&, + virtual String Description(ax::mojom::blink::NameFrom, + ax::mojom::blink::DescriptionFrom&, DescriptionSources*, AXRelatedObjectVector*) const { return String(); @@ -577,19 +588,21 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { // Takes the result of nameFrom and descriptionFrom from calling |name| and // |description|, above, and retrieves the placeholder of the object, if // present and if it wasn't already exposed by one of the two functions above. - virtual String Placeholder(ax::mojom::NameFrom) const { return String(); } + virtual String Placeholder(ax::mojom::blink::NameFrom) const { + return String(); + } // Takes the result of nameFrom and retrieves the HTML Title of the object, // if present and if it wasn't already exposed by |GetName| above. // HTML Title is typically used as a tooltip. - virtual String Title(ax::mojom::NameFrom) const { return String(); } + virtual String Title(ax::mojom::blink::NameFrom) const { return String(); } // Internal functions used by name and description, above. typedef HeapHashSet<Member<const AXObject>> AXObjectSet; virtual String TextAlternative(bool recursive, bool in_aria_labelled_by_traversal, AXObjectSet& visited, - ax::mojom::NameFrom& name_from, + ax::mojom::blink::NameFrom& name_from, AXRelatedObjectVector* related_objects, NameSources* name_sources) const { return String(); @@ -637,27 +650,27 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { } virtual AXObject* InPageLinkTarget() const { return nullptr; } virtual AccessibilityOrientation Orientation() const; - virtual ax::mojom::ListStyle GetListStyle() const { - return ax::mojom::ListStyle::kNone; + virtual ax::mojom::blink::ListStyle GetListStyle() const { + return ax::mojom::blink::ListStyle::kNone; } virtual String GetText() const { return String(); } - virtual ax::mojom::TextDirection GetTextDirection() const { - return ax::mojom::TextDirection::kLtr; + virtual ax::mojom::blink::TextDirection GetTextDirection() const { + return ax::mojom::blink::TextDirection::kLtr; } - virtual ax::mojom::TextPosition GetTextPosition() const { - return ax::mojom::TextPosition::kNone; + virtual ax::mojom::blink::TextPosition GetTextPosition() const { + return ax::mojom::blink::TextPosition::kNone; } virtual int TextLength() const { return 0; } virtual void GetTextStyleAndTextDecorationStyle( int32_t* text_style, - ax::mojom::TextDecorationStyle* text_overline_style, - ax::mojom::TextDecorationStyle* text_strikethrough_style, - ax::mojom::TextDecorationStyle* text_underline_style) const { + ax::mojom::blink::TextDecorationStyle* text_overline_style, + ax::mojom::blink::TextDecorationStyle* text_strikethrough_style, + ax::mojom::blink::TextDecorationStyle* text_underline_style) const { *text_style = 0; - *text_overline_style = ax::mojom::TextDecorationStyle::kNone; - *text_strikethrough_style = ax::mojom::TextDecorationStyle::kNone; - *text_underline_style = ax::mojom::TextDecorationStyle::kNone; + *text_overline_style = ax::mojom::blink::TextDecorationStyle::kNone; + *text_strikethrough_style = ax::mojom::blink::TextDecorationStyle::kNone; + *text_underline_style = ax::mojom::blink::TextDecorationStyle::kNone; } virtual AXObjectVector RadioButtonsInGroup() const { @@ -693,13 +706,13 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { } // Properties of interactive elements. - ax::mojom::DefaultActionVerb Action() const; - ax::mojom::CheckedState CheckedState() const; - virtual ax::mojom::AriaCurrentState GetAriaCurrentState() const { - return ax::mojom::AriaCurrentState::kNone; + ax::mojom::blink::DefaultActionVerb Action() const; + ax::mojom::blink::CheckedState CheckedState() const; + virtual ax::mojom::blink::AriaCurrentState GetAriaCurrentState() const { + return ax::mojom::blink::AriaCurrentState::kNone; } - virtual ax::mojom::InvalidState GetInvalidState() const { - return ax::mojom::InvalidState::kNone; + virtual ax::mojom::blink::InvalidState GetInvalidState() const { + return ax::mojom::blink::InvalidState::kNone; } // Only used when invalidState() returns InvalidStateOther. virtual String AriaInvalidValue() const { return String(); } @@ -712,17 +725,17 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { virtual AXRestriction Restriction() const; // ARIA attributes. - virtual ax::mojom::Role DetermineAccessibilityRole(); - ax::mojom::Role DetermineAriaRoleAttribute() const; - virtual ax::mojom::Role AriaRoleAttribute() const; + virtual ax::mojom::blink::Role DetermineAccessibilityRole(); + ax::mojom::blink::Role DetermineAriaRoleAttribute() const; + virtual ax::mojom::blink::Role AriaRoleAttribute() const; virtual bool HasAriaAttribute() const { return false; } virtual AXObject* ActiveDescendant() { return nullptr; } virtual String AutoComplete() const { return String(); } virtual void AriaOwnsElements(AXObjectVector& owns) const {} virtual void AriaDescribedbyElements(AXObjectVector&) const {} virtual AXObject* ErrorMessage() const { return nullptr; } - virtual ax::mojom::HasPopup HasPopup() const { - return ax::mojom::HasPopup::kFalse; + virtual ax::mojom::blink::HasPopup HasPopup() const { + return ax::mojom::blink::HasPopup::kFalse; } virtual bool IsEditable() const { return false; } bool IsEditableRoot() const; @@ -734,7 +747,8 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { bool HasGlobalARIAAttribute() const; bool SupportsARIAExpanded() const; virtual bool SupportsARIADragging() const { return false; } - virtual void Dropeffects(Vector<ax::mojom::Dropeffect>& dropeffects) const {} + virtual void Dropeffects( + Vector<ax::mojom::blink::Dropeffect>& dropeffects) const {} virtual bool SupportsARIAOwns() const { return false; } bool SupportsARIAReadOnly() const; @@ -794,89 +808,197 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { // AXLayoutObject. virtual AXObject* ElementAccessibilityHitTest(const IntPoint&) const; + // // High-level accessibility tree access. Other modules should only use these - // functions. - AncestorsIterator AncestorsBegin() const; - AncestorsIterator AncestorsEnd() const; + // methods. + // + // The following methods may support one or more kinds of objects. There are + // three kinds: Objects that are excluded from the accessibility tree by + // default, such as white space found in HTML, objects that are included in + // the tree but that are ignored, such as an empty div, and unignored objects. + + // Iterates through the node's unignored ancestors up to the root, starting + // from the node's unignored parent, i.e. does not include the node itself in + // the list of ancestors. + // + // Initially, it can be called on all nodes, including those that are + // accessibility ignored, but only traverses through the list of ancestors + // that are unignored and included in the accessibility tree. + AncestorsIterator UnignoredAncestorsBegin() const; + AncestorsIterator UnignoredAncestorsEnd() const; + + // Iterator for doing an in-order traversal of the accessibility tree. + // + // Includes nodes that are accessibility ignored but "included in tree" in the + // traversal. InOrderTraversalIterator GetInOrderTraversalIterator(); - int ChildCount() const; - const AXObjectVector& Children() const; - const AXObjectVector& Children(); + + // Returns the number of children, including children that are included in the + // accessibility tree but are accessibility ignored. + // + // Can be called on all nodes, even on nodes that are excluded from the + // accessibility tree. + int ChildCountIncludingIgnored() const; + + // Returns the child with the given index in the list of all children, + // including those that are accessibility ignored. + // + // Can be called on all nodes, even on nodes that are excluded from the + // accessibility tree. + AXObject* ChildAtIncludingIgnored(int index) const; + + // Returns the node's children, including any children that are included in + // the accessibility tree but are accessibility ignored. + // + // Can be called on all nodes, including nodes that are excluded from the + // accessibility tree. + const AXObjectVector& ChildrenIncludingIgnored() const; + const AXObjectVector& ChildrenIncludingIgnored(); + + // Returns the node's unignored descendants that are one level deeper than + // this node, after removing all accessibility ignored nodes from the tree. + // + // Flattens accessibility ignored nodes, so each unignored child will have the + // same unignored parent, but may have a different parent in tree. + // + // Can be called on all nodes that are included in the accessibility tree, + // including those that are accessibility ignored. + const AXObjectVector UnignoredChildren() const; + const AXObjectVector UnignoredChildren(); + // Returns the first child for this object. - // Works for all nodes, and may return nodes that are accessibility ignored. - AXObject* FirstChild() const; + // Works for all nodes that are included in the accessibility tree, and may + // return nodes that are accessibility ignored. + AXObject* FirstChildIncludingIgnored() const; + // Returns the last child for this object. - // Works for all nodes, and may return nodes that are accessibility ignored. - AXObject* LastChild() const; + // Works for all nodes that are included in the accessibility tree, and may + // return nodes that are accessibility ignored. + AXObject* LastChildIncludingIgnored() const; + // Returns the deepest first child for this object. - // Works for all nodes, and may return nodes that are accessibility ignored. - AXObject* DeepestFirstChild() const; + // Works for all nodes that are included in the accessibility tree, and may + // return nodes that are accessibility ignored. + AXObject* DeepestFirstChildIncludingIgnored() const; + // Returns the deepest last child for this object. - // Works for all nodes, and may return nodes that are accessibility ignored. - AXObject* DeepestLastChild() const; + // Works for all nodes that are included in the accessibility tree, and may + // return nodes that are accessibility ignored. + AXObject* DeepestLastChildIncludingIgnored() const; + + // Returns true if this node is strictly an ancestor of the given node, i.e. + // doesn't include the current node in the list of its ancestors. Works for + // all nodes that are included in the accessibility tree, including nodes that + // are accessibility ignored. bool IsAncestorOf(const AXObject&) const; + + // Returns true if this node is strictly a descendant of the given node, i.e. + // doesn't include the current node in the list of its descendants. Works for + // all nodes that are included in the accessibility tree, including nodes that + // are accessibility ignored. bool IsDescendantOf(const AXObject&) const; + // Next sibling for this object, where the sibling may be // an accessibility ignored object. // Works for all nodes that are included in the accessibility tree, // and may return nodes that are accessibility ignored. AXObject* NextSiblingIncludingIgnored() const; + // Previous sibling for this object, where the sibling may be // an accessibility ignored object. // Works for all nodes that are included in the accessibility tree, // and may return nodes that are accessibility ignored. AXObject* PreviousSiblingIncludingIgnored() const; + // Returns the next object in tree using depth-first pre-order traversal, // optionally staying within a specified AXObject. // Works for all nodes that are included in the accessibility tree, // and may return nodes that are accessibility ignored. AXObject* NextInPreOrderIncludingIgnored( const AXObject* within = nullptr) const; + // Returns the previous object in tree using depth-first pre-order traversal, // optionally staying within a specified AXObject. // Works for all nodes that are included in the accessibility tree, // and may return nodes that are accessibility ignored. AXObject* PreviousInPreOrderIncludingIgnored( const AXObject* within = nullptr) const; + // Returns the previous object in tree using depth-first post-order traversal, // optionally staying within a specified AXObject. // Works for all nodes that are included in the accessibility tree, // and may return nodes that are accessibility ignored. AXObject* PreviousInPostOrderIncludingIgnored( const AXObject* within = nullptr) const; + + // Returns the number of children that are not accessibility ignored. + // + // Unignored children are the objects that are one level deeper than the + // current object after all accessibility ignored descendants are removed. + // + // Can be called on all nodes that are included in the accessibility tree, + // including those that are accessibility ignored. + int UnignoredChildCount() const; + + // Returns the unignored child with the given index. + // + // Unignored children are the objects that are one level deeper than the + // current object after all accessibility ignored descendants are removed. + // + // Can be called on all nodes that are included in the accessibility tree, + // including those that are accessibility ignored. + AXObject* UnignoredChildAt(int index) const; + // Next sibling for this object that's not accessibility ignored. + // // Flattens accessibility ignored nodes, so the sibling will have the // same unignored parent, but may have a different parent in tree. + // // Doesn't work with nodes that are accessibility ignored. - AXObject* NextSibling() const; + AXObject* UnignoredNextSibling() const; + // Previous sibling for this object that's not accessibility ignored. + // // Flattens accessibility ignored nodes, so the sibling will have the // same unignored parent, but may have a different parent in tree. + // // Doesn't work with nodes that are accessibility ignored. - AXObject* PreviousSibling() const; + AXObject* UnignoredPreviousSibling() const; + // Next object in tree using depth-first pre-order traversal that's // not accessibility ignored. // Doesn't work with nodes that are accessibility ignored. - AXObject* NextInTreeObject() const; + AXObject* UnignoredNextInPreOrder() const; + // Previous object in tree using depth-first pre-order traversal that's // not accessibility ignored. // Doesn't work with nodes that are accessibility ignored. - AXObject* PreviousInTreeObject() const; + AXObject* UnignoredPreviousInPreOrder() const; + // Get or create the parent of this object. - // Works for all nodes, and may return nodes that are accessibility ignored. + // + // Works for all nodes, and may return nodes that are accessibility ignored, + // including nodes that might not be in the tree. AXObject* ParentObject() const; + // Get the parent of this object if it has already been created. - // Works for all nodes, and may return nodes that are accessibility ignored. + // + // Works for all nodes, and may return nodes that are accessibility ignored, + // including nodes that might not be in the tree. AXObject* ParentObjectIfExists() const; + virtual AXObject* ComputeParent() const = 0; virtual AXObject* ComputeParentIfExists() const { return nullptr; } AXObject* CachedParentObject() const { return parent_; } + // Get or create the first ancestor that's not accessibility ignored. // Works for all nodes. AXObject* ParentObjectUnignored() const; + // Get or create the first ancestor that's included in the accessibility tree. // Works for all nodes, and may return nodes that are accessibility ignored. AXObject* ParentObjectIncludedInTree() const; + AXObject* ContainerWidget() const; bool IsContainerWidget() const; @@ -941,8 +1063,8 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { unsigned AriaRowIndex() const; int AriaColumnCount() const; int AriaRowCount() const; - virtual ax::mojom::SortDirection GetSortDirection() const { - return ax::mojom::SortDirection::kNone; + virtual ax::mojom::blink::SortDirection GetSortDirection() const { + return ax::mojom::blink::SortDirection::kNone; } // For a row or column. @@ -1012,13 +1134,13 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { virtual void TextChanged() {} // Static helper functions. - static bool IsARIAControl(ax::mojom::Role); - static bool IsARIAInput(ax::mojom::Role); + static bool IsARIAControl(ax::mojom::blink::Role); + static bool IsARIAInput(ax::mojom::blink::Role); // Is this a widget that requires container widget. bool IsSubWidget() const; - static ax::mojom::Role AriaRoleToWebCoreRole(const String&); - static const AtomicString& RoleName(ax::mojom::Role); - static const AtomicString& InternalRoleName(ax::mojom::Role); + static ax::mojom::blink::Role AriaRoleToWebCoreRole(const String&); + static const AtomicString& RoleName(ax::mojom::blink::Role); + static const AtomicString& InternalRoleName(ax::mojom::blink::Role); static void AccessibleNodeListToElementVector(const AccessibleNodeList&, HeapVector<Member<Element>>&); @@ -1041,8 +1163,8 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { AXID id_; AXObjectVector children_; mutable bool have_children_; - ax::mojom::Role role_; - ax::mojom::Role aria_role_; + ax::mojom::blink::Role role_; + ax::mojom::blink::Role aria_role_; mutable AXObjectInclusion last_known_is_ignored_value_; mutable AXObjectInclusion last_known_is_ignored_but_included_in_tree_value_; LayoutRect explicit_element_rect_; @@ -1056,12 +1178,12 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { static String RecursiveTextAlternative(const AXObject&, bool in_aria_labelled_by_traversal, AXObjectSet& visited, - ax::mojom::NameFrom& name_from); + ax::mojom::blink::NameFrom& name_from); bool IsHiddenForTextAlternativeCalculation() const; String AriaTextAlternative(bool recursive, bool in_aria_labelled_by_traversal, AXObjectSet& visited, - ax::mojom::NameFrom&, + ax::mojom::blink::NameFrom&, AXRelatedObjectVector*, NameSources*, bool* found_text_alternative) const; @@ -1086,7 +1208,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { bool NameFromContents(bool recursive) const; bool NameFromSelectedOption(bool recursive) const; - ax::mojom::Role ButtonRoleType() const; + ax::mojom::blink::Role ButtonRoleType() const; virtual LayoutObject* LayoutObjectForRelativeBounds() const { return nullptr; @@ -1140,7 +1262,7 @@ class MODULES_EXPORT AXObject : public GarbageCollected<AXObject> { static bool IsNativeCheckboxInMixedState(const Node*); static bool IncludesARIAWidgetRole(const String&); static bool HasInteractiveARIAAttribute(const Element&); - ax::mojom::Role RemapAriaRoleDueToParent(ax::mojom::Role) const; + ax::mojom::blink::Role RemapAriaRoleDueToParent(ax::mojom::blink::Role) const; unsigned ComputeAriaColumnIndex() const; unsigned ComputeAriaRowIndex() const; bool HasInternalsAttribute(Element&, const QualifiedName&) const; 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 b97cd117085..422b7b03eae 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 @@ -32,6 +32,7 @@ #include "base/auto_reset.h" #include "base/memory/scoped_refptr.h" +#include "base/metrics/histogram_macros.h" #include "mojo/public/cpp/bindings/pending_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" @@ -91,9 +92,11 @@ #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/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "ui/accessibility/ax_enums.mojom-blink.h" #include "ui/accessibility/ax_event.h" +#include "ui/accessibility/ax_role_properties.h" // Prevent code that runs during the lifetime of the stack from altering the // document lifecycle. Usually doc is the same as document_, but it can be @@ -137,6 +140,7 @@ AXObjectCacheImpl::AXObjectCacheImpl(Document& document) : document_(document), modification_count_(0), validation_message_axid_(0), + active_aria_modal_dialog_(nullptr), relation_cache_(std::make_unique<AXRelationCache>(this)), accessibility_event_permission_(mojom::blink::PermissionStatus::ASK), permission_service_(document.GetExecutionContext()), @@ -239,7 +243,8 @@ AXObject* AXObjectCacheImpl::FocusedImageMapUIElement( if (!ax_layout_image) return nullptr; - const AXObject::AXObjectVector& image_children = ax_layout_image->Children(); + const AXObject::AXObjectVector& image_children = + ax_layout_image->ChildrenIncludingIgnored(); unsigned count = image_children.size(); for (unsigned k = 0; k < count; ++k) { AXObject* child = image_children[k]; @@ -496,7 +501,7 @@ AXObject* AXObjectCacheImpl::GetOrCreate(const Node* node) { } AXObject* AXObjectCacheImpl::GetOrCreate(Node* node) { - if (!node) + if (!node || !node->isConnected()) return nullptr; if (!node->IsElementNode() && !node->IsTextNode() && !node->IsDocumentNode()) @@ -775,6 +780,9 @@ void AXObjectCacheImpl::RemoveAXID(AXObject* object) { if (!object) return; + if (active_aria_modal_dialog_ == object) + active_aria_modal_dialog_ = nullptr; + AXID obj_id = object->AXObjectID(); if (!obj_id) return; @@ -809,21 +817,79 @@ AXObject::InOrderTraversalIterator AXObjectCacheImpl::InOrderTraversalEnd() { return AXObject::InOrderTraversalIterator(); } -void AXObjectCacheImpl::DeferTreeUpdateInternal(Node* node, - base::OnceClosure callback) { - // The node's document can be different from the main document_ when the node - // is inside a popup. Check to ensure both documents are in a good state. - if (!node || !IsActive(node->GetDocument()) || !IsActive(GetDocument())) +void AXObjectCacheImpl::UpdateNumTreeUpdatesQueuedBeforeLayoutHistogram() { + UMA_HISTOGRAM_COUNTS_100000( + "Blink.Accessibility.NumTreeUpdatesQueuedBeforeLayout", + tree_update_callback_queue_.size()); +} + +void AXObjectCacheImpl::DeferTreeUpdateInternal(base::OnceClosure callback, + AXObject* obj) { + // Called for updates that do not have a DOM node, e.g. a children or text + // changed event that occurs on an anonymous layout block flow. + DCHECK(obj); + + if (!IsActive(GetDocument()) || tree_updates_paused_) + return; + + Document& tree_update_document = *obj->GetDocument(); + + // Ensure the tree update document is in a good state. + if (!IsActive(tree_update_document)) return; - DCHECK(!node->GetDocument().GetPage()->Animator().IsServicingAnimations() || - (node->GetDocument().Lifecycle().GetState() < + if (tree_update_callback_queue_.size() >= max_pending_updates_) { + UpdateNumTreeUpdatesQueuedBeforeLayoutHistogram(); + + tree_updates_paused_ = true; + tree_update_callback_queue_.clear(); + return; + } + + DCHECK(!tree_update_document.GetPage()->Animator().IsServicingAnimations() || + (tree_update_document.Lifecycle().GetState() < DocumentLifecycle::kInAccessibility || - node->GetDocument().Lifecycle().StateAllowsDetach())) + tree_update_document.Lifecycle().StateAllowsDetach())) << "DeferTreeUpdateInternal should only be outside of the lifecycle or " "before the accessibility state."; tree_update_callback_queue_.push_back(MakeGarbageCollected<TreeUpdateParams>( - node, ComputeEventFrom(), ActiveEventIntents(), std::move(callback))); + obj->GetNode(), obj->AXObjectID(), ComputeEventFrom(), + ActiveEventIntents(), std::move(callback))); + + // These events are fired during DocumentLifecycle::kInAccessibility, + // ensure there is a document lifecycle update scheduled. + ScheduleVisualUpdate(); +} + +void AXObjectCacheImpl::DeferTreeUpdateInternal(base::OnceClosure callback, + Node* node) { + DCHECK(node); + + if (!IsActive(GetDocument()) || tree_updates_paused_) + return; + + Document& tree_update_document = node->GetDocument(); + + // Ensure the tree update document is in a good state. + if (!IsActive(tree_update_document)) + return; + + if (tree_update_callback_queue_.size() >= max_pending_updates_) { + UpdateNumTreeUpdatesQueuedBeforeLayoutHistogram(); + + tree_updates_paused_ = true; + tree_update_callback_queue_.clear(); + return; + } + + DCHECK(!tree_update_document.GetPage()->Animator().IsServicingAnimations() || + (tree_update_document.Lifecycle().GetState() < + DocumentLifecycle::kInAccessibility || + tree_update_document.Lifecycle().StateAllowsDetach())) + << "DeferTreeUpdateInternal should only be outside of the lifecycle or " + "before the accessibility state."; + tree_update_callback_queue_.push_back(MakeGarbageCollected<TreeUpdateParams>( + node, 0, ComputeEventFrom(), ActiveEventIntents(), std::move(callback))); // These events are fired during DocumentLifecycle::kInAccessibility, // ensure there is a document lifecycle update scheduled. @@ -835,7 +901,7 @@ void AXObjectCacheImpl::DeferTreeUpdate( Node* node) { base::OnceClosure callback = WTF::Bind(method, WrapWeakPersistent(this), WrapWeakPersistent(node)); - DeferTreeUpdateInternal(node, std::move(callback)); + DeferTreeUpdateInternal(std::move(callback), node); } void AXObjectCacheImpl::DeferTreeUpdate( @@ -844,7 +910,7 @@ void AXObjectCacheImpl::DeferTreeUpdate( Element* element) { base::OnceClosure callback = WTF::Bind( method, WrapWeakPersistent(this), attr_name, WrapWeakPersistent(element)); - DeferTreeUpdateInternal(element, std::move(callback)); + DeferTreeUpdateInternal(std::move(callback), element); } void AXObjectCacheImpl::DeferTreeUpdate( @@ -854,13 +920,22 @@ void AXObjectCacheImpl::DeferTreeUpdate( base::OnceClosure callback = WTF::Bind(method, WrapWeakPersistent(this), WrapWeakPersistent(node), WrapWeakPersistent(obj)); - DeferTreeUpdateInternal(node, std::move(callback)); + if (obj) { + DCHECK_EQ(node, obj->GetNode()); + DeferTreeUpdateInternal(std::move(callback), obj); + } else { + DeferTreeUpdateInternal(std::move(callback), node); + } } void AXObjectCacheImpl::SelectionChanged(Node* node) { if (!node) return; + Settings* settings = GetSettings(); + if (settings && settings->GetAriaModalPrunesAXTree()) + UpdateActiveAriaModalDialog(node); + DeferTreeUpdate(&AXObjectCacheImpl::SelectionChangedWithCleanLayout, node); } @@ -894,27 +969,40 @@ void AXObjectCacheImpl::TextChanged(LayoutObject* layout_object) { if (!layout_object) return; - // TODO(aboxhall): audit calls to this and figure out when this is called - // when node might be null + // The node may be null when the text changes on an anonymous layout object, + // such as a layout block flow that is inserted to parent an inline object + // when it has a block sibling. Node* node = GetClosestNodeForLayoutObject(layout_object); if (node) { DeferTreeUpdate(&AXObjectCacheImpl::TextChangedWithCleanLayout, node); return; } - TextChanged(Get(layout_object), layout_object->GetNode()); + if (layout_object->GetNode() || Get(layout_object)) { + DeferTreeUpdate(&AXObjectCacheImpl::TextChangedWithCleanLayout, + layout_object->GetNode(), Get(layout_object)); + } } -void AXObjectCacheImpl::TextChanged(AXObject* obj, - Node* node_for_relation_update) { - // TODO(aboxhall): Figure out when this may be called with dirty layout - if (obj) - obj->TextChanged(); +void AXObjectCacheImpl::TextChangedWithCleanLayout( + Node* optional_node_for_relation_update, + AXObject* obj) { + if (!obj && !optional_node_for_relation_update) + return; +#if DCHECK_IS_ON() + Document* document = obj ? obj->GetDocument() + : &optional_node_for_relation_update->GetDocument(); + DCHECK(document->Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean) + << "Unclean document at lifecycle " << document->Lifecycle().ToString(); +#endif // DCHECK_IS_ON() - if (node_for_relation_update) - relation_cache_->UpdateRelatedTree(node_for_relation_update); + if (obj) { + obj->TextChanged(); + PostNotification(obj, ax::mojom::Event::kTextChanged); + } - PostNotification(obj, ax::mojom::Event::kTextChanged); + if (optional_node_for_relation_update) + relation_cache_->UpdateRelatedTree(optional_node_for_relation_update); } void AXObjectCacheImpl::TextChangedWithCleanLayout(Node* node) { @@ -922,7 +1010,7 @@ void AXObjectCacheImpl::TextChangedWithCleanLayout(Node* node) { return; DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node)); - TextChanged(Get(node), node); + TextChangedWithCleanLayout(node, Get(node)); } void AXObjectCacheImpl::FocusableChangedWithCleanLayout(Element* element) { @@ -950,28 +1038,23 @@ void AXObjectCacheImpl::DocumentTitleChanged() { } void AXObjectCacheImpl::UpdateCacheAfterNodeIsAttached(Node* node) { + Element* element = DynamicTo<Element>(node); + if (!element) + return; + SCOPED_DISALLOW_LIFECYCLE_TRANSITION(node->GetDocument()); - // Calling get() will update the AX object if we had an AXNodeObject but now - // we need an AXLayoutObject, because it was reparented to a location outside - // of a canvas. - AXObject* obj = Get(node); // Process any relation attributes that can affect ax objects already created. // Force computation of aria-owns, so that original parents that already // computed their children get the aria-owned children removed. - Element* element = DynamicTo<Element>(node); - if (!element) - return; - if (element->FastHasAttribute(html_names::kAriaOwnsAttr) || element->HasExplicitlySetAttrAssociatedElements( html_names::kAriaOwnsAttr)) { HandleAttributeChanged(html_names::kAriaOwnsAttr, element); } - // Process cases where relationships are pointing to this node. - MaybeNewRelationTarget(node, obj); + MaybeNewRelationTarget(node, Get(node)); } void AXObjectCacheImpl::DidInsertChildrenOfNode(Node* node) { @@ -982,7 +1065,7 @@ void AXObjectCacheImpl::DidInsertChildrenOfNode(Node* node) { return; if (AXObject* obj = Get(node)) { - TextChanged(obj, node); + TextChanged(node); } else { DidInsertChildrenOfNode(NodeTraversal::Parent(*node)); } @@ -992,6 +1075,10 @@ void AXObjectCacheImpl::ChildrenChanged(Node* node) { if (!node) return; + // Don't enqueue a deferred event on the same node more than once. + if (!nodes_with_pending_children_changed_.insert(node).is_new_entry) + return; + DeferTreeUpdate(&AXObjectCacheImpl::ChildrenChangedWithCleanLayout, node); } @@ -1002,12 +1089,18 @@ void AXObjectCacheImpl::ChildrenChanged(LayoutObject* layout_object) { Node* node = GetClosestNodeForLayoutObject(layout_object); if (node) { + // Don't enqueue a deferred event on the same node more than once. + if (!nodes_with_pending_children_changed_.insert(node).is_new_entry) + return; + DeferTreeUpdate(&AXObjectCacheImpl::ChildrenChangedWithCleanLayout, node); return; } - AXObject* object = Get(layout_object); - ChildrenChanged(object, layout_object->GetNode()); + if (AXObject* obj = Get(layout_object)) { + DeferTreeUpdate(&AXObjectCacheImpl::ChildrenChangedWithCleanLayout, nullptr, + obj); + } } void AXObjectCacheImpl::ChildrenChanged(AccessibleNode* accessible_node) { @@ -1015,15 +1108,16 @@ void AXObjectCacheImpl::ChildrenChanged(AccessibleNode* accessible_node) { return; AXObject* object = Get(accessible_node); - ChildrenChanged(object, object ? object->GetNode() : nullptr); + if (!object) + return; + DeferTreeUpdate(&AXObjectCacheImpl::ChildrenChangedWithCleanLayout, + object->GetNode(), object); } void AXObjectCacheImpl::ChildrenChangedWithCleanLayout(Node* node) { if (!node) return; - DCHECK(node->GetDocument().Lifecycle().GetState() >= - DocumentLifecycle::kLayoutClean); #ifndef NDEBUG if (node->GetDocument().NeedsLayoutTreeUpdateForNode(*node)) { LOG(ERROR) << "Node needs layout tree update: " << node; @@ -1032,11 +1126,20 @@ void AXObjectCacheImpl::ChildrenChangedWithCleanLayout(Node* node) { #endif DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node)); - ChildrenChanged(Get(node), node); + ChildrenChangedWithCleanLayout(node, Get(node)); } -void AXObjectCacheImpl::ChildrenChanged(AXObject* obj, Node* optional_node) { - // TODO(aboxhall): Figure out when this may be called with dirty layout +void AXObjectCacheImpl::ChildrenChangedWithCleanLayout(Node* optional_node, + AXObject* obj) { + if (!obj && !optional_node) + return; + +#if DCHECK_IS_ON() + Document* document = obj ? obj->GetDocument() : &optional_node->GetDocument(); + DCHECK(document->Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean) + << "Unclean document at lifecycle " << document->Lifecycle().ToString(); +#endif // DCHECK_IS_ON() + if (obj) obj->ChildrenChanged(); @@ -1047,6 +1150,8 @@ void AXObjectCacheImpl::ChildrenChanged(AXObject* obj, Node* optional_node) { } void AXObjectCacheImpl::ProcessDeferredAccessibilityEvents(Document& document) { + TRACE_EVENT0("accessibility", "ProcessDeferredAccessibilityEvents"); + if (document.Lifecycle().GetState() != DocumentLifecycle::kInAccessibility) { DCHECK(false) << "Deferred events should only be processed during the " "accessibility document lifecycle"; @@ -1060,23 +1165,43 @@ void AXObjectCacheImpl::ProcessDeferredAccessibilityEvents(Document& document) { void AXObjectCacheImpl::ProcessUpdates(Document& document) { SCOPED_DISALLOW_LIFECYCLE_TRANSITION(document); + if (tree_updates_paused_) { + ChildrenChangedWithCleanLayout(nullptr, GetOrCreate(&document)); + tree_updates_paused_ = false; + return; + } + + UpdateNumTreeUpdatesQueuedBeforeLayoutHistogram(); + TreeUpdateCallbackQueue old_tree_update_callback_queue; tree_update_callback_queue_.swap(old_tree_update_callback_queue); + nodes_with_pending_children_changed_.clear(); + for (auto& tree_update : old_tree_update_callback_queue) { Node* node = tree_update->node; - if (!node) - continue; + AXID axid = tree_update->axid; + // Need either an DOM node or an AXObject to be a valid update. + // These may have been destroyed since the original update occurred. + if (!node) { + if (!axid || !ObjectFromAXID(axid)) + return; + } base::OnceClosure& callback = tree_update->callback; - if (node->GetDocument() != document) { + // Insure the update is for the correct document. + // If no node, this update must be from an AXObject with no DOM node, + // such as an AccessibleNode. In that case, ensure the update is in the + // main document. + Document& tree_update_document = node ? node->GetDocument() : GetDocument(); + if (document != tree_update_document) { tree_update_callback_queue_.push_back( - MakeGarbageCollected<TreeUpdateParams>(node, tree_update->event_from, - tree_update->event_intents, - std::move(callback))); + MakeGarbageCollected<TreeUpdateParams>( + node, axid, tree_update->event_from, tree_update->event_intents, + std::move(callback))); continue; } - FireTreeUpdatedEventImmediately(node, tree_update->event_from, + FireTreeUpdatedEventImmediately(document, tree_update->event_from, tree_update->event_intents, std::move(callback)); } @@ -1169,17 +1294,17 @@ void AXObjectCacheImpl::ScheduleVisualUpdate() { } void AXObjectCacheImpl::FireTreeUpdatedEventImmediately( - Node* node, + Document& document, ax::mojom::blink::EventFrom event_from, const BlinkAXEventIntentsSet& event_intents, base::OnceClosure callback) { - DCHECK_EQ(node->GetDocument().Lifecycle().GetState(), + DCHECK_EQ(document.Lifecycle().GetState(), DocumentLifecycle::kInAccessibility); base::AutoReset<ax::mojom::blink::EventFrom> event_from_resetter( &active_event_from_, event_from); ScopedBlinkAXEventIntent defered_event_intents(event_intents.AsVector(), - &node->GetDocument()); + &document); std::move(callback).Run(); } @@ -1216,7 +1341,7 @@ void AXObjectCacheImpl::FireAXEventImmediately( was_ignored_but_included_in_tree != obj->AccessibilityIsIgnoredButIncludedInTree(); if (is_ignored_changed) - ChildrenChanged(obj->CachedParentObject()); + ChildrenChangedWithCleanLayout(nullptr, obj->CachedParentObject()); } } @@ -1232,6 +1357,8 @@ void AXObjectCacheImpl::UpdateAriaOwns( const AXObject* owner, const Vector<String>& id_vector, HeapVector<Member<AXObject>>& owned_children) { + DCHECK(GetDocument().Lifecycle().GetState() >= + DocumentLifecycle::kLayoutClean); relation_cache_->UpdateAriaOwns(owner, id_vector, owned_children); } @@ -1239,6 +1366,8 @@ void AXObjectCacheImpl::UpdateAriaOwnsFromAttrAssociatedElements( const AXObject* owner, const HeapVector<Member<Element>>& attr_associated_elements, HeapVector<Member<AXObject>>& owned_children) { + DCHECK(GetDocument().Lifecycle().GetState() >= + DocumentLifecycle::kLayoutClean); relation_cache_->UpdateAriaOwnsFromAttrAssociatedElements( owner, attr_associated_elements, owned_children); } @@ -1359,9 +1488,9 @@ void AXObjectCacheImpl::HandleAriaExpandedChangeWithCleanLayout(Node* node) { } void AXObjectCacheImpl::HandleAriaSelectedChangedWithCleanLayout(Node* node) { + DCHECK(node); SCOPED_DISALLOW_LIFECYCLE_TRANSITION(node->GetDocument()); - DCHECK(node); DCHECK(!document_->NeedsLayoutTreeUpdateForNode(*node)); AXObject* obj = Get(node); if (!obj) @@ -1465,7 +1594,7 @@ void AXObjectCacheImpl::HandleRoleChangeWithCleanLayout(Node* node) { // Parent object changed children, as the previous AXObject for this node // was destroyed and a different one was created in its place. if (parent) - ChildrenChanged(parent, parent->GetNode()); + ChildrenChangedWithCleanLayout(parent->GetNode(), parent); modification_count_++; } } @@ -1804,8 +1933,10 @@ void AXObjectCacheImpl::HandleFocusedUIElementChanged( if (!new_focused_element) { // When focus is cleared, implicitly focus the document by sending a blur. - DeferTreeUpdate(&AXObjectCacheImpl::HandleNodeLostFocusWithCleanLayout, - GetDocument().documentElement()); + if (GetDocument().documentElement()) { + DeferTreeUpdate(&AXObjectCacheImpl::HandleNodeLostFocusWithCleanLayout, + GetDocument().documentElement()); + } return; } @@ -1818,10 +1949,53 @@ void AXObjectCacheImpl::HandleFocusedUIElementChanged( old_focused_element); } + Settings* settings = GetSettings(); + if (settings && settings->GetAriaModalPrunesAXTree()) + UpdateActiveAriaModalDialog(new_focused_element); + DeferTreeUpdate(&AXObjectCacheImpl::HandleNodeGainedFocusWithCleanLayout, this->FocusedElement()); } +// Check if the focused node is inside an active aria-modal dialog. If so, we +// should mark the cache as dirty to recompute the ignored status of each node. +void AXObjectCacheImpl::UpdateActiveAriaModalDialog(Node* node) { + AXObject* new_active_aria_modal = AncestorAriaModalDialog(node); + if (active_aria_modal_dialog_ == new_active_aria_modal) + return; + + active_aria_modal_dialog_ = new_active_aria_modal; + modification_count_++; + MarkAXObjectDirty(Root(), true); +} + +AXObject* AXObjectCacheImpl::AncestorAriaModalDialog(Node* node) { + for (Element* ancestor = Traversal<Element>::FirstAncestorOrSelf(*node); + ancestor; ancestor = Traversal<Element>::FirstAncestor(*ancestor)) { + if (!ancestor->FastHasAttribute(html_names::kAriaModalAttr)) + continue; + + AtomicString aria_modal = + ancestor->FastGetAttribute(html_names::kAriaModalAttr); + if (!EqualIgnoringASCIICase(aria_modal, "true")) { + continue; + } + + AXObject* ancestor_ax_object = GetOrCreate(ancestor); + ax::mojom::blink::Role ancestor_role = ancestor_ax_object->RoleValue(); + + if (!ui::IsDialog(ancestor_role)) + continue; + + return ancestor_ax_object; + } + return nullptr; +} + +AXObject* AXObjectCacheImpl::GetActiveAriaModalDialog() const { + return active_aria_modal_dialog_; +} + void AXObjectCacheImpl::HandleInitialFocus() { PostNotification(document_, ax::mojom::Event::kFocus); } @@ -1955,7 +2129,6 @@ const AtomicString& AXObjectCacheImpl::ComputedRoleForNode(Node* node) { String AXObjectCacheImpl::ComputedNameForNode(Node* node) { SCOPED_DISALLOW_LIFECYCLE_TRANSITION(node->GetDocument()); - AXObject* obj = GetOrCreate(node); if (!obj) return ""; @@ -2055,10 +2228,11 @@ void AXObjectCacheImpl::RequestAOMEventListenerPermission() { WrapPersistent(this))); } -void AXObjectCacheImpl::Trace(Visitor* visitor) { +void AXObjectCacheImpl::Trace(Visitor* visitor) const { visitor->Trace(document_); visitor->Trace(accessible_node_mapping_); visitor->Trace(node_object_mapping_); + visitor->Trace(active_aria_modal_dialog_); visitor->Trace(objects_); visitor->Trace(notifications_to_post_); @@ -2066,6 +2240,7 @@ void AXObjectCacheImpl::Trace(Visitor* visitor) { visitor->Trace(permission_observer_receiver_); visitor->Trace(documents_); visitor->Trace(tree_update_callback_queue_); + visitor->Trace(nodes_with_pending_children_changed_); AXObjectCache::Trace(visitor); } 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 afed1943527..7126c079f59 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 @@ -32,6 +32,7 @@ #include <memory> #include <utility> +#include "base/gtest_prod_util.h" #include "base/macros.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" @@ -67,7 +68,7 @@ class MODULES_EXPORT AXObjectCacheImpl explicit AXObjectCacheImpl(Document&); ~AXObjectCacheImpl() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; Document& GetDocument() { return *document_; } AXObject* FocusedObject(); @@ -109,7 +110,7 @@ class MODULES_EXPORT AXObjectCacheImpl // Called by a node when text or a text equivalent (e.g. alt) attribute is // changed. void TextChanged(LayoutObject*) override; - void TextChanged(AXObject*, Node* optional_node = nullptr); + void TextChangedWithCleanLayout(Node* optional_node, AXObject*); void FocusableChangedWithCleanLayout(Element* element); void DocumentTitleChanged() override; // Called when a node has just been attached, so we can make sure we have the @@ -186,7 +187,8 @@ class MODULES_EXPORT AXObjectCacheImpl void Remove(AXID); - void ChildrenChanged(AXObject*, Node* node_for_relation_update = nullptr); + void ChildrenChangedWithCleanLayout(Node* optional_node_for_relation_update, + AXObject*); void MaybeNewRelationTarget(Node* node, AXObject* obj); @@ -273,6 +275,8 @@ class MODULES_EXPORT AXObjectCacheImpl active_event_from_ = event_from; } + AXObject* GetActiveAriaModalDialog() const; + protected: void PostPlatformNotification( AXObject* obj, @@ -307,25 +311,30 @@ class MODULES_EXPORT AXObjectCacheImpl ax::mojom::blink::EventFrom event_from; BlinkAXEventIntentsSet event_intents; - void Trace(Visitor* visitor) { visitor->Trace(target); } + void Trace(Visitor* visitor) const { visitor->Trace(target); } }; struct TreeUpdateParams final : public GarbageCollected<TreeUpdateParams> { TreeUpdateParams(Node* node, + AXID axid, ax::mojom::blink::EventFrom event_from, const BlinkAXEventIntentsSet& intents, base::OnceClosure callback) - : node(node), event_from(event_from), callback(std::move(callback)) { + : node(node), + axid(axid), + event_from(event_from), + callback(std::move(callback)) { for (const auto& intent : intents) { event_intents.insert(intent.key, intent.value); } } WeakMember<Node> node; + AXID axid; ax::mojom::blink::EventFrom event_from; BlinkAXEventIntentsSet event_intents; base::OnceClosure callback; - void Trace(Visitor* visitor) { visitor->Trace(node); } + void Trace(Visitor* visitor) const { visitor->Trace(node); } }; ax::mojom::blink::EventFrom ComputeEventFrom(); @@ -348,6 +357,11 @@ class MODULES_EXPORT AXObjectCacheImpl // and it will always be related to the currently focused control. AXID validation_message_axid_; + // The currently active aria-modal dialog element, if one has been computed, + // null if otherwise. This is only ever computed on platforms that have the + // AriaModalPrunesAXTree setting enabled, such as Mac. + WeakMember<AXObject> active_aria_modal_dialog_; + std::unique_ptr<AXRelationCache> relation_cache_; #if DCHECK_IS_ON() @@ -402,11 +416,15 @@ class MODULES_EXPORT AXObjectCacheImpl Element* element), const QualifiedName& attr_name, Element* element); + // Provide either a DOM node or AXObject. If both are provided, then they must + // match, meaning that the AXObject's DOM node must equal the provided node. void DeferTreeUpdate(void (AXObjectCacheImpl::*method)(Node*, AXObject*), Node* node, AXObject* obj); - void DeferTreeUpdateInternal(Node* node, base::OnceClosure callback); + void DeferTreeUpdateInternal(base::OnceClosure callback, Node* node); + + void DeferTreeUpdateInternal(base::OnceClosure callback, AXObject* obj); void SelectionChangedWithCleanLayout(Node* node); void TextChangedWithCleanLayout(Node* node); @@ -414,9 +432,22 @@ class MODULES_EXPORT AXObjectCacheImpl void HandleAttributeChangedWithCleanLayout(const QualifiedName& attr_name, Element* element); + // + // aria-modal support + // + + // This function is only ever called on platforms where the + // AriaModalPrunesAXTree setting is enabled, and the accessibility tree must + // be manually pruned to remove background content. + void UpdateActiveAriaModalDialog(Node* element); + + // This will return null on platforms without the AriaModalPrunesAXTree + // setting enabled, or where there is no active ancestral aria-modal dialog. + AXObject* AncestorAriaModalDialog(Node* node); + void ScheduleVisualUpdate(); void FireTreeUpdatedEventImmediately( - Node* node, + Document& document, ax::mojom::blink::EventFrom event_from, const BlinkAXEventIntentsSet& event_intents, base::OnceClosure callback); @@ -425,6 +456,12 @@ class MODULES_EXPORT AXObjectCacheImpl ax::mojom::blink::EventFrom event_from, const BlinkAXEventIntentsSet& event_intents); + void SetMaxPendingUpdatesForTesting(wtf_size_t max_pending_updates) { + max_pending_updates_ = max_pending_updates; + } + + void UpdateNumTreeUpdatesQueuedBeforeLayoutHistogram(); + // Whether the user has granted permission for the user to install event // listeners for accessibility events using the AOM. mojom::PermissionStatus accessibility_event_permission_; @@ -436,8 +473,17 @@ class MODULES_EXPORT AXObjectCacheImpl // The main document, plus any page popups. HeapHashSet<WeakMember<Document>> documents_; + + // Queued callbacks. typedef HeapVector<Member<TreeUpdateParams>> TreeUpdateCallbackQueue; TreeUpdateCallbackQueue tree_update_callback_queue_; + HeapHashSet<WeakMember<Node>> nodes_with_pending_children_changed_; + + // If tree_update_callback_queue_ gets improbably large, stop + // enqueueing updates and fire a single ChildrenChanged event on the + // document once layout occurs. + wtf_size_t max_pending_updates_ = 1UL << 16; + bool tree_updates_paused_ = false; // Maps ids to their object's autofill state. HashMap<AXID, WebAXAutofillState> autofill_state_map_; @@ -450,6 +496,8 @@ class MODULES_EXPORT AXObjectCacheImpl BlinkAXEventIntentsSet active_event_intents_; DISALLOW_COPY_AND_ASSIGN(AXObjectCacheImpl); + + FRIEND_TEST_ALL_PREFIXES(AccessibilityTest, PauseUpdatesAfterMaxNumberQueued); }; // This is the only subclass of AXObjectCache. diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc index 669e007b415..d78827c6149 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_object_cache_test.cc @@ -7,10 +7,11 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/modules/accessibility/ax_object.h" +#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h" #include "third_party/blink/renderer/modules/accessibility/testing/accessibility_test.h" namespace blink { -namespace test { // TODO(nektar): Break test up into multiple tests. TEST_F(AccessibilityTest, IsARIAWidget) { @@ -56,5 +57,38 @@ TEST_F(AccessibilityTest, IsARIAWidget) { *root->getElementById("focusable-parent"))); } -} // namespace test +class MockAXObject : public AXObject { + public: + explicit MockAXObject(AXObjectCacheImpl& ax_object_cache) + : AXObject(ax_object_cache) {} + static unsigned num_children_changed_calls_; + + void ChildrenChanged() final { num_children_changed_calls_++; } + AXObject* ComputeParent() const final { return nullptr; } + Document* GetDocument() const final { return &AXObjectCache().GetDocument(); } +}; + +unsigned MockAXObject::num_children_changed_calls_ = 0; + +TEST_F(AccessibilityTest, PauseUpdatesAfterMaxNumberQueued) { + auto& document = GetDocument(); + auto* ax_object_cache = + To<AXObjectCacheImpl>(document.ExistingAXObjectCache()); + DCHECK(ax_object_cache); + + wtf_size_t max_updates = 10; + ax_object_cache->SetMaxPendingUpdatesForTesting(max_updates); + + MockAXObject* ax_obj = MakeGarbageCollected<MockAXObject>(*ax_object_cache); + ax_obj->SetAXObjectID(ax_object_cache->GetOrCreateAXID(ax_obj)); + for (unsigned i = 0; i < max_updates + 1; i++) { + ax_object_cache->DeferTreeUpdate( + &AXObjectCacheImpl::ChildrenChangedWithCleanLayout, nullptr, ax_obj); + } + document.Lifecycle().AdvanceTo(DocumentLifecycle::kInAccessibility); + ax_object_cache->ProcessUpdates(document); + + ASSERT_EQ(0u, MockAXObject::num_children_changed_calls_); +} + } // namespace blink 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 ad4aa1ca4d9..146c1968f98 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 @@ -56,14 +56,51 @@ TEST_F(AccessibilityTest, IsAncestorOf) { EXPECT_FALSE(button->IsAncestorOf(*root)); } +TEST_F(AccessibilityTest, UnignoredChildren) { + SetBodyInnerHTML(R"HTML(This is a test with + <p role="presentation"> + ignored objects + </p> + <p> + which are at multiple + </p> + <p role="presentation"> + <p role="presentation"> + depth levels + </p> + in the accessibility tree. + </p>)HTML"); + + const AXObject* ax_body = GetAXRootObject()->FirstChildIncludingIgnored(); + ASSERT_NE(nullptr, ax_body); + + ASSERT_EQ(5, ax_body->UnignoredChildCount()); + EXPECT_EQ(ax::mojom::blink::Role::kStaticText, + ax_body->UnignoredChildAt(0)->RoleValue()); + EXPECT_EQ("This is a test with", + ax_body->UnignoredChildAt(0)->ComputedName()); + EXPECT_EQ(ax::mojom::blink::Role::kStaticText, + ax_body->UnignoredChildAt(1)->RoleValue()); + EXPECT_EQ("ignored objects", ax_body->UnignoredChildAt(1)->ComputedName()); + EXPECT_EQ(ax::mojom::blink::Role::kParagraph, + ax_body->UnignoredChildAt(2)->RoleValue()); + EXPECT_EQ(ax::mojom::blink::Role::kStaticText, + ax_body->UnignoredChildAt(3)->RoleValue()); + EXPECT_EQ("depth levels", ax_body->UnignoredChildAt(3)->ComputedName()); + EXPECT_EQ(ax::mojom::blink::Role::kStaticText, + ax_body->UnignoredChildAt(4)->RoleValue()); + EXPECT_EQ("in the accessibility tree.", + ax_body->UnignoredChildAt(4)->ComputedName()); +} + TEST_F(AccessibilityTest, SimpleTreeNavigation) { SetBodyInnerHTML(R"HTML(<input id="input" type="text" value="value"> - <div id='ignored_a' aria-hidden='true'></div> + <div id="ignored_a" aria-hidden="true"></div> <p id="paragraph">hello<br id="br">there</p> - <span id='ignored_b' aria-hidden='true'></span> + <span id="ignored_b" aria-hidden="true"></span> <button id="button">button</button>)HTML"); - const AXObject* body = GetAXRootObject()->FirstChild(); + const AXObject* body = GetAXBodyObject(); ASSERT_NE(nullptr, body); const AXObject* input = GetAXObjectByElementId("input"); ASSERT_NE(nullptr, input); @@ -78,34 +115,51 @@ TEST_F(AccessibilityTest, SimpleTreeNavigation) { const AXObject* button = GetAXObjectByElementId("button"); ASSERT_NE(nullptr, button); - EXPECT_EQ(input, body->FirstChild()); - EXPECT_EQ(button, body->LastChild()); + EXPECT_EQ(input, body->FirstChildIncludingIgnored()); + EXPECT_EQ(button, body->LastChildIncludingIgnored()); - ASSERT_NE(nullptr, paragraph->FirstChild()); - EXPECT_EQ(ax::mojom::Role::kStaticText, paragraph->FirstChild()->RoleValue()); - ASSERT_NE(nullptr, paragraph->LastChild()); - EXPECT_EQ(ax::mojom::Role::kStaticText, paragraph->LastChild()->RoleValue()); - ASSERT_NE(nullptr, paragraph->DeepestFirstChild()); + ASSERT_NE(nullptr, paragraph->FirstChildIncludingIgnored()); + EXPECT_EQ(ax::mojom::Role::kStaticText, + paragraph->FirstChildIncludingIgnored()->RoleValue()); + ASSERT_NE(nullptr, paragraph->LastChildIncludingIgnored()); + EXPECT_EQ(ax::mojom::Role::kStaticText, + paragraph->LastChildIncludingIgnored()->RoleValue()); + ASSERT_NE(nullptr, paragraph->DeepestFirstChildIncludingIgnored()); + EXPECT_EQ(ax::mojom::Role::kStaticText, + paragraph->DeepestFirstChildIncludingIgnored()->RoleValue()); + ASSERT_NE(nullptr, paragraph->DeepestLastChildIncludingIgnored()); EXPECT_EQ(ax::mojom::Role::kStaticText, - paragraph->DeepestFirstChild()->RoleValue()); - ASSERT_NE(nullptr, paragraph->DeepestLastChild()); + paragraph->DeepestLastChildIncludingIgnored()->RoleValue()); + + EXPECT_EQ(paragraph->PreviousSiblingIncludingIgnored(), + GetAXObjectByElementId("ignored_a")); + EXPECT_EQ(GetAXObjectByElementId("ignored_a"), + input->NextSiblingIncludingIgnored()); + ASSERT_NE(nullptr, br->NextSiblingIncludingIgnored()); + EXPECT_EQ(ax::mojom::Role::kStaticText, + br->NextSiblingIncludingIgnored()->RoleValue()); + ASSERT_NE(nullptr, br->PreviousSiblingIncludingIgnored()); + EXPECT_EQ(ax::mojom::Role::kStaticText, + br->PreviousSiblingIncludingIgnored()->RoleValue()); + + EXPECT_EQ(paragraph->UnignoredPreviousSibling(), input); + EXPECT_EQ(paragraph, input->UnignoredNextSibling()); + ASSERT_NE(nullptr, br->UnignoredNextSibling()); EXPECT_EQ(ax::mojom::Role::kStaticText, - paragraph->DeepestLastChild()->RoleValue()); - - EXPECT_EQ(paragraph->PreviousSibling(), input); - EXPECT_EQ(paragraph, input->NextSibling()); - ASSERT_NE(nullptr, br->NextSibling()); - EXPECT_EQ(ax::mojom::Role::kStaticText, br->NextSibling()->RoleValue()); - ASSERT_NE(nullptr, br->PreviousSibling()); - EXPECT_EQ(ax::mojom::Role::kStaticText, br->PreviousSibling()->RoleValue()); - - ASSERT_NE(nullptr, button->FirstChild()); - EXPECT_EQ(ax::mojom::Role::kStaticText, button->FirstChild()->RoleValue()); - ASSERT_NE(nullptr, button->LastChild()); - EXPECT_EQ(ax::mojom::Role::kStaticText, button->LastChild()->RoleValue()); - ASSERT_NE(nullptr, button->DeepestFirstChild()); + br->UnignoredNextSibling()->RoleValue()); + ASSERT_NE(nullptr, br->UnignoredPreviousSibling()); EXPECT_EQ(ax::mojom::Role::kStaticText, - paragraph->DeepestFirstChild()->RoleValue()); + br->UnignoredPreviousSibling()->RoleValue()); + + ASSERT_NE(nullptr, button->FirstChildIncludingIgnored()); + EXPECT_EQ(ax::mojom::Role::kStaticText, + button->FirstChildIncludingIgnored()->RoleValue()); + ASSERT_NE(nullptr, button->LastChildIncludingIgnored()); + EXPECT_EQ(ax::mojom::Role::kStaticText, + button->LastChildIncludingIgnored()->RoleValue()); + ASSERT_NE(nullptr, button->DeepestFirstChildIncludingIgnored()); + EXPECT_EQ(ax::mojom::Role::kStaticText, + paragraph->DeepestFirstChildIncludingIgnored()->RoleValue()); } TEST_F(AccessibilityTest, TreeNavigationWithIgnoredContainer) { @@ -124,31 +178,31 @@ TEST_F(AccessibilityTest, TreeNavigationWithIgnoredContainer) { </body>)HTML"); const AXObject* root = GetAXRootObject(); - const AXObject* body = root->FirstChild(); - ASSERT_EQ(3, body->ChildCount()); - ASSERT_EQ(1, body->Children()[1]->ChildCount()); + const AXObject* body = GetAXBodyObject(); + ASSERT_EQ(3, body->ChildCountIncludingIgnored()); + ASSERT_EQ(1, body->ChildAtIncludingIgnored(1)->ChildCountIncludingIgnored()); ASSERT_FALSE(root->AccessibilityIsIgnored()); ASSERT_TRUE(body->AccessibilityIsIgnored()); const AXObject* obj_a = GetAXObjectByElementId("A"); ASSERT_NE(nullptr, obj_a); ASSERT_FALSE(obj_a->AccessibilityIsIgnored()); - const AXObject* obj_a_text = obj_a->FirstChild(); + const AXObject* obj_a_text = obj_a->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, obj_a_text); EXPECT_EQ(ax::mojom::Role::kStaticText, obj_a_text->RoleValue()); const AXObject* obj_b = GetAXObjectByElementId("B"); ASSERT_NE(nullptr, obj_b); ASSERT_FALSE(obj_b->AccessibilityIsIgnored()); - const AXObject* obj_b_text = obj_b->FirstChild(); + const AXObject* obj_b_text = obj_b->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, obj_b_text); EXPECT_EQ(ax::mojom::Role::kStaticText, obj_b_text->RoleValue()); const AXObject* obj_c = GetAXObjectByElementId("C"); ASSERT_NE(nullptr, obj_c); ASSERT_FALSE(obj_c->AccessibilityIsIgnored()); - const AXObject* obj_c_text = obj_c->FirstChild(); + const AXObject* obj_c_text = obj_c->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, obj_c_text); EXPECT_EQ(ax::mojom::Role::kStaticText, obj_c_text->RoleValue()); - const AXObject* obj_ignored = body->Children()[1]; + const AXObject* obj_ignored = body->ChildAtIncludingIgnored(1); ASSERT_NE(nullptr, obj_ignored); ASSERT_TRUE(obj_ignored->AccessibilityIsIgnored()); @@ -159,22 +213,37 @@ TEST_F(AccessibilityTest, TreeNavigationWithIgnoredContainer) { EXPECT_EQ(root, obj_c->ParentObjectUnignored()); EXPECT_EQ(body, obj_c->ParentObjectIncludedInTree()); - EXPECT_EQ(obj_b, obj_ignored->FirstChild()); - - EXPECT_EQ(nullptr, obj_a->PreviousSibling()); - EXPECT_EQ(obj_b, obj_a->NextSibling()); - EXPECT_EQ(root, obj_a->PreviousInTreeObject()); - EXPECT_EQ(obj_a_text, obj_a->NextInTreeObject()); - - EXPECT_EQ(obj_a, obj_b->PreviousSibling()); - EXPECT_EQ(obj_c, obj_b->NextSibling()); - EXPECT_EQ(obj_a_text, obj_b->PreviousInTreeObject()); - EXPECT_EQ(obj_b_text, obj_b->NextInTreeObject()); - - EXPECT_EQ(obj_b, obj_c->PreviousSibling()); - EXPECT_EQ(nullptr, obj_c->NextSibling()); - EXPECT_EQ(obj_b_text, obj_c->PreviousInTreeObject()); - EXPECT_EQ(obj_c_text, obj_c->NextInTreeObject()); + EXPECT_EQ(obj_b, obj_ignored->FirstChildIncludingIgnored()); + + EXPECT_EQ(nullptr, obj_a->PreviousSiblingIncludingIgnored()); + EXPECT_EQ(nullptr, obj_a->UnignoredPreviousSibling()); + EXPECT_EQ(obj_ignored, obj_a->NextSiblingIncludingIgnored()); + EXPECT_EQ(obj_b, obj_a->UnignoredNextSibling()); + + EXPECT_EQ(body, obj_a->PreviousInPreOrderIncludingIgnored()); + EXPECT_EQ(root, obj_a->UnignoredPreviousInPreOrder()); + EXPECT_EQ(obj_a_text, obj_a->NextInPreOrderIncludingIgnored()); + EXPECT_EQ(obj_a_text, obj_a->UnignoredNextInPreOrder()); + + EXPECT_EQ(nullptr, obj_b->PreviousSiblingIncludingIgnored()); + EXPECT_EQ(obj_a, obj_b->UnignoredPreviousSibling()); + EXPECT_EQ(nullptr, obj_b->NextSiblingIncludingIgnored()); + EXPECT_EQ(obj_c, obj_b->UnignoredNextSibling()); + + EXPECT_EQ(obj_ignored, obj_b->PreviousInPreOrderIncludingIgnored()); + EXPECT_EQ(obj_a_text, obj_b->UnignoredPreviousInPreOrder()); + EXPECT_EQ(obj_b_text, obj_b->NextInPreOrderIncludingIgnored()); + EXPECT_EQ(obj_b_text, obj_b->UnignoredNextInPreOrder()); + + EXPECT_EQ(obj_ignored, obj_c->PreviousSiblingIncludingIgnored()); + EXPECT_EQ(obj_b, obj_c->UnignoredPreviousSibling()); + EXPECT_EQ(nullptr, obj_c->NextSiblingIncludingIgnored()); + EXPECT_EQ(nullptr, obj_c->UnignoredNextSibling()); + + EXPECT_EQ(obj_b_text, obj_c->PreviousInPreOrderIncludingIgnored()); + EXPECT_EQ(obj_b_text, obj_c->UnignoredPreviousInPreOrder()); + EXPECT_EQ(obj_c_text, obj_c->NextInPreOrderIncludingIgnored()); + EXPECT_EQ(obj_c_text, obj_c->UnignoredNextInPreOrder()); } TEST_F(AccessibilityTest, AXObjectComparisonOperators) { @@ -219,7 +288,7 @@ TEST_F(AccessibilityTest, AXObjectComparisonOperators) { EXPECT_FALSE(*button > *button); } -TEST_F(AccessibilityTest, AXObjectAncestorsIterator) { +TEST_F(AccessibilityTest, AXObjectUnignoredAncestorsIterator) { SetBodyInnerHTML( R"HTML(<p id="paragraph"><b id="bold"><br id="br"></b></p>)HTML"); @@ -233,12 +302,12 @@ TEST_F(AccessibilityTest, AXObjectAncestorsIterator) { ASSERT_NE(nullptr, br); ASSERT_EQ(ax::mojom::Role::kLineBreak, br->RoleValue()); - AXObject::AncestorsIterator iter = br->AncestorsBegin(); + AXObject::AncestorsIterator iter = br->UnignoredAncestorsBegin(); EXPECT_EQ(*paragraph, *iter); EXPECT_EQ(ax::mojom::Role::kParagraph, iter->RoleValue()); EXPECT_EQ(*root, *++iter); EXPECT_EQ(*root, *iter++); - EXPECT_EQ(br->AncestorsEnd(), ++iter); + EXPECT_EQ(br->UnignoredAncestorsEnd(), ++iter); } TEST_F(AccessibilityTest, AXObjectInOrderTraversalIterator) { @@ -246,12 +315,13 @@ TEST_F(AccessibilityTest, AXObjectInOrderTraversalIterator) { AXObject* root = GetAXRootObject(); ASSERT_NE(nullptr, root); + AXObject* body = GetAXBodyObject(); + ASSERT_NE(nullptr, root); AXObject* checkbox = GetAXObjectByElementId("checkbox"); ASSERT_NE(nullptr, checkbox); - AXObject::InOrderTraversalIterator iter = root->GetInOrderTraversalIterator(); - EXPECT_EQ(*root, *iter); - ++iter; // Skip the generic container which is an ignored object. + AXObject::InOrderTraversalIterator iter = body->GetInOrderTraversalIterator(); + EXPECT_EQ(*body, *iter); EXPECT_NE(GetAXObjectCache().InOrderTraversalEnd(), iter); EXPECT_EQ(*checkbox, *++iter); EXPECT_EQ(ax::mojom::Role::kCheckBox, iter->RoleValue()); @@ -259,7 +329,8 @@ TEST_F(AccessibilityTest, AXObjectInOrderTraversalIterator) { EXPECT_EQ(GetAXObjectCache().InOrderTraversalEnd(), iter); EXPECT_EQ(*checkbox, *--iter); EXPECT_EQ(*checkbox, *iter--); - --iter; // Skip the generic container which is an ignored object. + --iter; // Skip the BODY element. + --iter; // Skip the HTML element. EXPECT_EQ(ax::mojom::Role::kRootWebArea, iter->RoleValue()); EXPECT_EQ(GetAXObjectCache().InOrderTraversalBegin(), iter); } @@ -343,7 +414,7 @@ TEST_P(AccessibilityLayoutTest, NextOnLine) { TEST_F(AccessibilityTest, AxObjectPreservedWhitespaceIsLineBreakingObjects) { SetBodyInnerHTML(R"HTML( - <span style='white-space: pre-line' id="preserved"> + <span style="white-space: pre-line" id="preserved"> First Paragraph Second Paragraph Third Paragraph @@ -355,10 +426,10 @@ TEST_F(AccessibilityTest, AxObjectPreservedWhitespaceIsLineBreakingObjects) { const AXObject* preserved_span = GetAXObjectByElementId("preserved"); ASSERT_NE(nullptr, preserved_span); ASSERT_EQ(ax::mojom::Role::kGenericContainer, preserved_span->RoleValue()); - ASSERT_EQ(1, preserved_span->ChildCount()); + ASSERT_EQ(1, preserved_span->ChildCountIncludingIgnored()); EXPECT_FALSE(preserved_span->IsLineBreakingObject()); - AXObject* preserved_text = preserved_span->FirstChild(); + AXObject* preserved_text = preserved_span->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, preserved_text); ASSERT_EQ(ax::mojom::Role::kStaticText, preserved_text->RoleValue()); EXPECT_FALSE(preserved_text->IsLineBreakingObject()); @@ -366,9 +437,9 @@ TEST_F(AccessibilityTest, AxObjectPreservedWhitespaceIsLineBreakingObjects) { // Expect 7 kInlineTextBox children // 3 lines of text, and 4 newlines preserved_text->LoadInlineTextBoxes(); - ASSERT_EQ(7, preserved_text->ChildCount()); + ASSERT_EQ(7, preserved_text->ChildCountIncludingIgnored()); bool all_children_are_inline_text_boxes = true; - for (const AXObject* child : preserved_text->Children()) { + for (const AXObject* child : preserved_text->ChildrenIncludingIgnored()) { if (child->RoleValue() != ax::mojom::Role::kInlineTextBox) { all_children_are_inline_text_boxes = false; break; @@ -376,20 +447,30 @@ TEST_F(AccessibilityTest, AxObjectPreservedWhitespaceIsLineBreakingObjects) { } ASSERT_TRUE(all_children_are_inline_text_boxes); - ASSERT_EQ(preserved_text->Children()[0]->ComputedName(), "\n"); - EXPECT_TRUE(preserved_text->Children()[0]->IsLineBreakingObject()); - ASSERT_EQ(preserved_text->Children()[1]->ComputedName(), "First Paragraph"); - EXPECT_FALSE(preserved_text->Children()[1]->IsLineBreakingObject()); - ASSERT_EQ(preserved_text->Children()[2]->ComputedName(), "\n"); - EXPECT_TRUE(preserved_text->Children()[2]->IsLineBreakingObject()); - ASSERT_EQ(preserved_text->Children()[3]->ComputedName(), "Second Paragraph"); - EXPECT_FALSE(preserved_text->Children()[3]->IsLineBreakingObject()); - ASSERT_EQ(preserved_text->Children()[4]->ComputedName(), "\n"); - EXPECT_TRUE(preserved_text->Children()[4]->IsLineBreakingObject()); - ASSERT_EQ(preserved_text->Children()[5]->ComputedName(), "Third Paragraph"); - EXPECT_FALSE(preserved_text->Children()[5]->IsLineBreakingObject()); - ASSERT_EQ(preserved_text->Children()[6]->ComputedName(), "\n"); - EXPECT_TRUE(preserved_text->Children()[6]->IsLineBreakingObject()); + ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(0)->ComputedName(), "\n"); + EXPECT_TRUE( + preserved_text->ChildAtIncludingIgnored(0)->IsLineBreakingObject()); + ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(1)->ComputedName(), + "First Paragraph"); + EXPECT_FALSE( + preserved_text->ChildAtIncludingIgnored(1)->IsLineBreakingObject()); + ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(2)->ComputedName(), "\n"); + EXPECT_TRUE( + preserved_text->ChildAtIncludingIgnored(2)->IsLineBreakingObject()); + ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(3)->ComputedName(), + "Second Paragraph"); + EXPECT_FALSE( + preserved_text->ChildAtIncludingIgnored(3)->IsLineBreakingObject()); + ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(4)->ComputedName(), "\n"); + EXPECT_TRUE( + preserved_text->ChildAtIncludingIgnored(4)->IsLineBreakingObject()); + ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(5)->ComputedName(), + "Third Paragraph"); + EXPECT_FALSE( + preserved_text->ChildAtIncludingIgnored(5)->IsLineBreakingObject()); + ASSERT_EQ(preserved_text->ChildAtIncludingIgnored(6)->ComputedName(), "\n"); + EXPECT_TRUE( + preserved_text->ChildAtIncludingIgnored(6)->IsLineBreakingObject()); } TEST_F(AccessibilityTest, CheckNoDuplicateChildren) { @@ -402,7 +483,8 @@ TEST_F(AccessibilityTest, CheckNoDuplicateChildren) { ax_select->SetNeedsToUpdateChildren(); ax_select->UpdateChildrenIfNecessary(); - ASSERT_EQ(ax_select->FirstChild()->ChildCount(), 1); + ASSERT_EQ( + ax_select->FirstChildIncludingIgnored()->ChildCountIncludingIgnored(), 1); } TEST_F(AccessibilityTest, InitRelationCache) { 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 f0b73cc3d6f..b88f12e4da0 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_position.cc @@ -98,8 +98,9 @@ const AXPosition AXPosition::CreateFirstPositionInObject( } // If the container is not a text object, creating a position inside an - // ignored container might result in an invalid position, because child count - // is inaccurate. + // object that is excluded from the accessibility tree will result in an + // invalid position, because child count is not always accurate for such + // objects. const AXObject* unignored_container = !container.AccessibilityIsIncludedInTree() ? container.ParentObjectIncludedInTree() @@ -132,15 +133,17 @@ const AXPosition AXPosition::CreateLastPositionInObject( } // If the container is not a text object, creating a position inside an - // ignored container might result in an invalid position, because child count - // is inaccurate. + // object that is excluded from the accessibility tree will result in an + // invalid position, because child count is not always accurate for such + // objects. const AXObject* unignored_container = !container.AccessibilityIsIncludedInTree() ? container.ParentObjectIncludedInTree() : &container; DCHECK(unignored_container); AXPosition position(*unignored_container); - position.text_offset_or_child_index_ = unignored_container->ChildCount(); + position.text_offset_or_child_index_ = + unignored_container->ChildCountIncludingIgnored(); #if DCHECK_IS_ON() String failure_reason; DCHECK(position.IsValid(&failure_reason)) << failure_reason; @@ -270,7 +273,8 @@ const AXPosition AXPosition::FromPosition( // positions. const Node* node_after_position = position.ComputeNodeAfterPosition(); if (!node_after_position) { - ax_position.text_offset_or_child_index_ = container->ChildCount(); + ax_position.text_offset_or_child_index_ = + container->ChildCountIncludingIgnored(); } else { const AXObject* ax_child = @@ -312,7 +316,7 @@ const AXPosition AXPosition::FromPosition( } } - if (!container->Children().Contains(ax_child)) { + if (!container->ChildrenIncludingIgnored().Contains(ax_child)) { // The |ax_child| is aria-owned by another object. return CreatePositionBeforeObject(*ax_child, adjustment_behavior); } @@ -365,9 +369,7 @@ AXPosition::AXPosition(const AXObject& container) const AXObject* AXPosition::ChildAfterTreePosition() const { if (!IsValid() || IsTextPosition()) return nullptr; - if (container_object_->ChildCount() <= ChildIndex()) - return nullptr; - return *(container_object_->Children().begin() + ChildIndex()); + return container_object_->ChildAtIncludingIgnored(ChildIndex()); } int AXPosition::ChildIndex() const { @@ -463,11 +465,13 @@ bool AXPosition::IsValid(String* failure_reason) const { return false; } } else { - if (text_offset_or_child_index_ > container_object_->ChildCount()) { + if (text_offset_or_child_index_ > + container_object_->ChildCountIncludingIgnored()) { if (failure_reason) { *failure_reason = String::Format( "\nPosition invalid: child index too large.\n%d vs. %d", - text_offset_or_child_index_, container_object_->ChildCount()); + text_offset_or_child_index_, + container_object_->ChildCountIncludingIgnored()); } return false; } @@ -509,9 +513,10 @@ const AXPosition AXPosition::CreateNextPosition() const { // text boxes when present, because we'll just be creating a text position // in the same piece of text. const AXObject* next_in_order = - container_object_->ChildCount() - ? container_object_->DeepestLastChild()->NextInTreeObject() - : container_object_->NextInTreeObject(); + container_object_->ChildCountIncludingIgnored() + ? container_object_->DeepestLastChildIncludingIgnored() + ->NextInPreOrderIncludingIgnored() + : container_object_->NextInPreOrderIncludingIgnored(); if (!next_in_order || !next_in_order->ParentObjectIncludedInTree()) return {}; @@ -544,8 +549,10 @@ const AXPosition AXPosition::CreatePreviousPosition() const { // If this is a static text object, we should not descend into its inline // text boxes when present, because we'll just be creating a text position // in the same piece of text. - if (!container_object_->IsTextObject() && container_object_->ChildCount()) { - const AXObject* last_child = container_object_->LastChild(); + if (!container_object_->IsTextObject() && + container_object_->ChildCountIncludingIgnored()) { + const AXObject* last_child = + container_object_->LastChildIncludingIgnored(); // Dont skip over any intervening text. if (last_child->IsTextObject() || last_child->IsNativeTextControl()) { return CreatePositionAfterObject( @@ -556,9 +563,10 @@ const AXPosition AXPosition::CreatePreviousPosition() const { *last_child, AXPositionAdjustmentBehavior::kMoveLeft); } - object_before_position = container_object_->PreviousInTreeObject(); + object_before_position = + container_object_->PreviousInPreOrderIncludingIgnored(); } else { - object_before_position = child->PreviousInTreeObject(); + object_before_position = child->PreviousInPreOrderIncludingIgnored(); } if (!object_before_position || @@ -695,7 +703,7 @@ const AXPosition AXPosition::AsValidDOMPosition( const AXObject* container = container_object_; DCHECK(container); const AXObject* child = ChildAfterTreePosition(); - const AXObject* last_child = container->LastChild(); + const AXObject* last_child = container->LastChildIncludingIgnored(); if ((IsTextPosition() && (!container->GetNode() || container->GetNode()->IsMarkerPseudoElement())) || container->IsMockObject() || container->IsVirtualObject() || @@ -737,7 +745,8 @@ const AXPosition AXPosition::AsValidDOMPosition( } else { switch (adjustment_behavior) { case AXPositionAdjustmentBehavior::kMoveRight: - position.text_offset_or_child_index_ = new_container->ChildCount(); + position.text_offset_or_child_index_ = + new_container->ChildCountIncludingIgnored(); break; case AXPositionAdjustmentBehavior::kMoveLeft: position.text_offset_or_child_index_ = 0; @@ -788,7 +797,7 @@ const PositionWithAffinity AXPosition::ToPositionWithAffinity( } // "After children" positions. - const AXObject* last_child = container_object_->LastChild(); + const AXObject* last_child = container_object_->LastChildIncludingIgnored(); if (last_child) { const Node* last_child_node = last_child->GetNode(); DCHECK(last_child_node) << "AX objects used in AX positions that are " @@ -865,8 +874,8 @@ const AXObject* AXPosition::FindNeighboringUnignoredObject( switch (adjustment_behavior) { case AXPositionAdjustmentBehavior::kMoveRight: { const Node* next_node = &child_node; - while ((next_node = NodeTraversal::NextSkippingChildren( - *next_node, container_node))) { + while ((next_node = NodeTraversal::NextIncludingPseudo(*next_node, + container_node))) { const AXObject* next_object = ax_object_cache_impl->GetOrCreate(next_node); if (next_object && next_object->AccessibilityIsIncludedInTree()) @@ -877,8 +886,14 @@ const AXObject* AXPosition::FindNeighboringUnignoredObject( case AXPositionAdjustmentBehavior::kMoveLeft: { const Node* previous_node = &child_node; - while ((previous_node = NodeTraversal::PreviousSkippingChildren( - *previous_node, container_node))) { + // Since this is a pre-order traversal, + // "NodeTraversal::PreviousIncludingPseudo" will eventually reach + // |container_node| if |container_node| is not nullptr. We should exclude + // this as we are strictly interested in |container_node|'s unignored + // descendantsin the accessibility tree. + while ((previous_node = NodeTraversal::PreviousIncludingPseudo( + *previous_node, container_node)) && + previous_node != container_node) { const AXObject* previous_object = ax_object_cache_impl->GetOrCreate(previous_node); if (previous_object && previous_object->AccessibilityIsIncludedInTree()) 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 5019ed02533..ef01b76b82d 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 @@ -95,7 +95,7 @@ TEST_F(AccessibilityTest, PositionInText) { ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); const AXObject* ax_static_text = - GetAXObjectByElementId("paragraph")->FirstChild(); + GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -118,7 +118,7 @@ TEST_F(AccessibilityTest, PositionBeforeText) { ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); const AXObject* ax_static_text = - GetAXObjectByElementId("paragraph")->FirstChild(); + GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -141,7 +141,7 @@ TEST_F(AccessibilityTest, PositionBeforeTextWithFirstLetterCSSRule) { ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); const AXObject* ax_static_text = - GetAXObjectByElementId("paragraph")->FirstChild(); + GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -165,7 +165,7 @@ TEST_F(AccessibilityTest, PositionAfterText) { ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); const AXObject* ax_static_text = - GetAXObjectByElementId("paragraph")->FirstChild(); + GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -208,7 +208,8 @@ TEST_F(AccessibilityTest, PositionAfterLineBreak) { const AXObject* ax_br = GetAXObjectByElementId("br"); ASSERT_NE(nullptr, ax_br); ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue()); - const AXObject* ax_static_text = GetAXRootObject()->DeepestLastChild(); + const AXObject* ax_static_text = + GetAXRootObject()->DeepestLastChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -233,7 +234,8 @@ TEST_F(AccessibilityTest, FirstPositionInDivContainer) { const AXObject* ax_div = GetAXObjectByElementId("div"); ASSERT_NE(nullptr, ax_div); ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_div->RoleValue()); - const AXObject* ax_static_text = GetAXRootObject()->DeepestFirstChild(); + const AXObject* ax_static_text = + GetAXRootObject()->DeepestFirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -278,7 +280,8 @@ TEST_F(AccessibilityTest, FirstPositionInTextContainer) { const Node* text = GetElementById("div")->firstChild(); ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); - const AXObject* ax_static_text = GetAXObjectByElementId("div")->FirstChild(); + const AXObject* ax_static_text = + GetAXObjectByElementId("div")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -298,7 +301,8 @@ TEST_F(AccessibilityTest, LastPositionInTextContainer) { const Node* text = GetElementById("div")->lastChild(); ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); - const AXObject* ax_static_text = GetAXObjectByElementId("div")->LastChild(); + const AXObject* ax_static_text = + GetAXObjectByElementId("div")->LastChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -322,7 +326,7 @@ TEST_F(AccessibilityTest, AXPositionComparisonOperators) { SetBodyInnerHTML(R"HTML(<input id="input" type="text" value="value"> <p id="paragraph">hello<br>there</p>)HTML"); - const AXObject* body = GetAXRootObject()->FirstChild(); + const AXObject* body = GetAXBodyObject(); ASSERT_NE(nullptr, body); const auto root_first = AXPosition::CreateFirstPositionInObject(*body); const auto root_last = AXPosition::CreateLastPositionInObject(*body); @@ -334,16 +338,16 @@ TEST_F(AccessibilityTest, AXPositionComparisonOperators) { const AXObject* paragraph = GetAXObjectByElementId("paragraph"); ASSERT_NE(nullptr, paragraph); - ASSERT_NE(nullptr, paragraph->FirstChild()); - ASSERT_NE(nullptr, paragraph->LastChild()); - const auto paragraph_before = - AXPosition::CreatePositionBeforeObject(*paragraph->FirstChild()); - const auto paragraph_after = - AXPosition::CreatePositionAfterObject(*paragraph->LastChild()); - const auto paragraph_start = - AXPosition::CreatePositionInTextObject(*paragraph->FirstChild(), 0); - const auto paragraph_end = - AXPosition::CreatePositionInTextObject(*paragraph->LastChild(), 5); + ASSERT_NE(nullptr, paragraph->FirstChildIncludingIgnored()); + ASSERT_NE(nullptr, paragraph->LastChildIncludingIgnored()); + const auto paragraph_before = AXPosition::CreatePositionBeforeObject( + *paragraph->FirstChildIncludingIgnored()); + const auto paragraph_after = AXPosition::CreatePositionAfterObject( + *paragraph->LastChildIncludingIgnored()); + const auto paragraph_start = AXPosition::CreatePositionInTextObject( + *paragraph->FirstChildIncludingIgnored(), 0); + const auto paragraph_end = AXPosition::CreatePositionInTextObject( + *paragraph->LastChildIncludingIgnored(), 5); EXPECT_TRUE(root_first == root_first); EXPECT_TRUE(root_last == root_last); @@ -394,7 +398,7 @@ TEST_F(AccessibilityTest, PositionInTextWithWhiteSpace) { ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); const AXObject* ax_static_text = - GetAXObjectByElementId("paragraph")->FirstChild(); + GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -415,7 +419,7 @@ TEST_F(AccessibilityTest, PositionBeforeTextWithWhiteSpace) { ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); const AXObject* ax_static_text = - GetAXObjectByElementId("paragraph")->FirstChild(); + GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -436,7 +440,7 @@ TEST_F(AccessibilityTest, PositionAfterTextWithWhiteSpace) { ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); const AXObject* ax_static_text = - GetAXObjectByElementId("paragraph")->LastChild(); + GetAXObjectByElementId("paragraph")->LastChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -479,7 +483,8 @@ TEST_F(AccessibilityTest, PositionAfterLineBreakWithWhiteSpace) { const AXObject* ax_br = GetAXObjectByElementId("br"); ASSERT_NE(nullptr, ax_br); ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue()); - const AXObject* ax_static_text = GetAXRootObject()->DeepestLastChild(); + const AXObject* ax_static_text = + GetAXRootObject()->DeepestLastChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -505,7 +510,8 @@ TEST_F(AccessibilityTest, FirstPositionInDivContainerWithWhiteSpace) { const AXObject* ax_div = GetAXObjectByElementId("div"); ASSERT_NE(nullptr, ax_div); ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_div->RoleValue()); - const AXObject* ax_static_text = GetAXRootObject()->DeepestFirstChild(); + const AXObject* ax_static_text = + GetAXRootObject()->DeepestFirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -551,7 +557,8 @@ TEST_F(AccessibilityTest, FirstPositionInTextContainerWithWhiteSpace) { const Node* text = GetElementById("div")->firstChild(); ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); - const AXObject* ax_static_text = GetAXObjectByElementId("div")->FirstChild(); + const AXObject* ax_static_text = + GetAXObjectByElementId("div")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -572,7 +579,8 @@ TEST_F(AccessibilityTest, LastPositionInTextContainerWithWhiteSpace) { const Node* text = GetElementById("div")->lastChild(); ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); - const AXObject* ax_static_text = GetAXObjectByElementId("div")->LastChild(); + const AXObject* ax_static_text = + GetAXObjectByElementId("div")->LastChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -595,7 +603,8 @@ TEST_F(AccessibilityTest, AXPositionFromDOMPositionWithWhiteSpace) { ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); ASSERT_EQ(15U, text->textContent().length()); - const AXObject* ax_static_text = GetAXObjectByElementId("div")->FirstChild(); + const AXObject* ax_static_text = + GetAXObjectByElementId("div")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -642,7 +651,7 @@ TEST_F(AccessibilityTest, PositionInTextWithAffinity) { ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); const AXObject* ax_static_text = - GetAXObjectByElementId("paragraph")->FirstChild(); + GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -680,7 +689,7 @@ TEST_F(AccessibilityTest, PositionInHTMLLabel) { const Node* paragraph = GetElementById("paragraph"); ASSERT_NE(nullptr, paragraph); - const AXObject* ax_body = GetAXRootObject()->FirstChild(); + const AXObject* ax_body = GetAXBodyObject(); ASSERT_NE(nullptr, ax_body); ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_body->RoleValue()); @@ -735,12 +744,17 @@ TEST_F(AccessibilityTest, PositionInIgnoredObject) { const AXObject* ax_root = GetAXRootObject(); ASSERT_NE(nullptr, ax_root); ASSERT_EQ(ax::mojom::Role::kRootWebArea, ax_root->RoleValue()); - ASSERT_EQ(1, ax_root->ChildCount()); + ASSERT_EQ(1, ax_root->ChildCountIncludingIgnored()); + + const AXObject* ax_html = ax_root->FirstChildIncludingIgnored(); + ASSERT_NE(nullptr, ax_html); + ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_html->RoleValue()); + ASSERT_EQ(1, ax_html->ChildCountIncludingIgnored()); - const AXObject* ax_body = ax_root->FirstChild(); + const AXObject* ax_body = GetAXBodyObject(); ASSERT_NE(nullptr, ax_body); ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_body->RoleValue()); - ASSERT_EQ(2, ax_body->ChildCount()); + ASSERT_EQ(2, ax_body->ChildCountIncludingIgnored()); const AXObject* ax_hidden = GetAXObjectByElementId("hidden"); ASSERT_NE(nullptr, ax_hidden); @@ -773,16 +787,17 @@ TEST_F(AccessibilityTest, PositionInIgnoredObject) { const auto ax_position_first = AXPosition::CreateFirstPositionInObject(*ax_root); const auto position_first = ax_position_first.ToPositionWithAffinity(); - EXPECT_EQ(GetDocument().body()->parentElement(), position_first.AnchorNode()); - EXPECT_FALSE(position_first.GetPosition().IsBeforeChildren()); - EXPECT_EQ(1, position_first.GetPosition().OffsetInContainerNode()); - EXPECT_EQ(GetDocument().body(), + EXPECT_EQ(GetDocument(), position_first.AnchorNode()); + EXPECT_TRUE(position_first.GetPosition().IsBeforeChildren()); + + EXPECT_EQ(GetDocument().documentElement(), position_first.GetPosition().ComputeNodeAfterPosition()); const auto ax_position_first_from_dom = AXPosition::FromPosition(position_first); EXPECT_EQ(ax_position_first, ax_position_first_from_dom); - EXPECT_EQ(ax_body, ax_position_first_from_dom.ChildAfterTreePosition()); + + EXPECT_EQ(ax_html, ax_position_first_from_dom.ChildAfterTreePosition()); // A DOM position before |hidden| should convert to an accessibility position // before |hidden| because the node is ignored but included in the tree. @@ -844,17 +859,17 @@ TEST_F(AccessibilityTest, BeforePositionInARIAHiddenShouldNotSkipARIAHidden) { EXPECT_EQ(ax_hidden, ax_position_from_dom.ChildAfterTreePosition()); } -TEST_F(AccessibilityTest, PreviousPositionAfterARIAHiddenShouldSkipARIAHidden) { +TEST_F(AccessibilityTest, + PreviousPositionAfterARIAHiddenShouldNotSkipARIAHidden) { SetBodyInnerHTML(R"HTML( <p id="before">Before aria-hidden.</p> <p id="ariaHidden" aria-hidden="true">Aria-hidden.</p> <p id="after">After aria-hidden.</p> )HTML"); - const Node* before = GetElementById("before"); - ASSERT_NE(nullptr, before); - ASSERT_NE(nullptr, before->firstChild()); - ASSERT_TRUE(before->firstChild()->IsTextNode()); + const Node* hidden = GetElementById("ariaHidden"); + ASSERT_NE(nullptr, hidden); + ASSERT_NE(nullptr, hidden->firstChild()); const Node* after = GetElementById("after"); ASSERT_NE(nullptr, after); @@ -876,8 +891,8 @@ TEST_F(AccessibilityTest, PreviousPositionAfterARIAHiddenShouldSkipARIAHidden) { const auto ax_position_previous = ax_position.CreatePreviousPosition(); const auto position_previous = ax_position_previous.ToPositionWithAffinity(); - EXPECT_EQ(before->firstChild(), position_previous.AnchorNode()); - EXPECT_EQ(19, position_previous.GetPosition().OffsetInContainerNode()); + EXPECT_EQ(hidden->firstChild(), position_previous.AnchorNode()); + EXPECT_EQ(12, position_previous.GetPosition().OffsetInContainerNode()); EXPECT_EQ(nullptr, position_previous.GetPosition().ComputeNodeAfterPosition()); @@ -902,36 +917,39 @@ TEST_F(AccessibilityTest, FromPositionInARIAHidden) { const AXObject* ax_container = GetAXObjectByElementId("container"); ASSERT_NE(nullptr, ax_container); ASSERT_EQ(ax::mojom::Role::kMain, ax_container->RoleValue()); - ASSERT_EQ(3, ax_container->ChildCount()); + ASSERT_EQ(3, ax_container->ChildCountIncludingIgnored()); const AXObject* ax_before = GetAXObjectByElementId("before"); ASSERT_NE(nullptr, ax_before); ASSERT_EQ(ax::mojom::Role::kParagraph, ax_before->RoleValue()); const AXObject* ax_after = GetAXObjectByElementId("after"); ASSERT_NE(nullptr, ax_after); ASSERT_EQ(ax::mojom::Role::kParagraph, ax_after->RoleValue()); - ASSERT_NE(nullptr, GetAXObjectByElementId("ariaHidden")); const AXObject* ax_hidden = GetAXObjectByElementId("ariaHidden"); + ASSERT_NE(nullptr, ax_hidden); ASSERT_TRUE(ax_hidden->AccessibilityIsIgnored()); const auto position_first = Position::FirstPositionInNode(*hidden); + // Since "ax_hidden" has a static text child, the AXPosition should move to an + // equivalent position on the static text child. auto ax_position_left = AXPosition::FromPosition(position_first, TextAffinity::kDownstream, AXPositionAdjustmentBehavior::kMoveLeft); EXPECT_TRUE(ax_position_left.IsValid()); EXPECT_TRUE(ax_position_left.IsTextPosition()); - EXPECT_EQ(ax_hidden->FirstChild(), ax_position_left.ContainerObject()); + EXPECT_EQ(ax_hidden->FirstChildIncludingIgnored(), + ax_position_left.ContainerObject()); EXPECT_EQ(0, ax_position_left.TextOffset()); - // This is an "after children" position. - EXPECT_EQ(nullptr, ax_position_left.ChildAfterTreePosition()); + // In this case, the adjustment behavior should not affect the outcome because + // there is an equivalent AXPosition in the static text child. auto ax_position_right = AXPosition::FromPosition(position_first, TextAffinity::kDownstream, AXPositionAdjustmentBehavior::kMoveRight); EXPECT_TRUE(ax_position_right.IsValid()); EXPECT_TRUE(ax_position_right.IsTextPosition()); - EXPECT_EQ(ax_hidden->FirstChild(), ax_position_right.ContainerObject()); + EXPECT_EQ(ax_hidden->FirstChildIncludingIgnored(), + ax_position_right.ContainerObject()); EXPECT_EQ(0, ax_position_right.TextOffset()); - EXPECT_EQ(nullptr, ax_position_right.ChildAfterTreePosition()); const auto position_before = Position::BeforeNode(*hidden); ax_position_left = @@ -941,9 +959,11 @@ TEST_F(AccessibilityTest, FromPositionInARIAHidden) { EXPECT_FALSE(ax_position_left.IsTextPosition()); EXPECT_EQ(ax_container, ax_position_left.ContainerObject()); EXPECT_EQ(1, ax_position_left.ChildIndex()); - // This is an "after children" position. EXPECT_EQ(ax_hidden, ax_position_left.ChildAfterTreePosition()); + // Since an AXPosition before "ax_hidden" is valid, i.e. it does not need to + // be adjusted, then adjustment behavior should not make a difference in the + // outcome. ax_position_right = AXPosition::FromPosition(position_before, TextAffinity::kDownstream, AXPositionAdjustmentBehavior::kMoveRight); @@ -953,16 +973,17 @@ TEST_F(AccessibilityTest, FromPositionInARIAHidden) { EXPECT_EQ(1, ax_position_right.ChildIndex()); EXPECT_EQ(ax_hidden, ax_position_right.ChildAfterTreePosition()); + // The DOM node right after "hidden" is accessibility ignored, so we should + // see an adjustment in the relevant direction. const auto position_after = Position::AfterNode(*hidden); ax_position_left = AXPosition::FromPosition(position_after, TextAffinity::kDownstream, AXPositionAdjustmentBehavior::kMoveLeft); EXPECT_TRUE(ax_position_left.IsValid()); - EXPECT_FALSE(ax_position_left.IsTextPosition()); - EXPECT_EQ(ax_hidden, ax_position_left.ContainerObject()); - EXPECT_EQ(1, ax_position_left.ChildIndex()); - // This is an "after children" position. - EXPECT_EQ(nullptr, ax_position_left.ChildAfterTreePosition()); + EXPECT_TRUE(ax_position_left.IsTextPosition()); + EXPECT_EQ(ax_hidden->FirstChildIncludingIgnored(), + ax_position_left.ContainerObject()); + EXPECT_EQ(12, ax_position_left.TextOffset()); ax_position_right = AXPosition::FromPosition(position_after, TextAffinity::kDownstream, @@ -1000,7 +1021,7 @@ TEST_F(AccessibilityTest, PositionInCanvas) { const AXObject* ax_canvas_1 = GetAXObjectByElementId("canvas1"); ASSERT_NE(nullptr, ax_canvas_1); ASSERT_EQ(ax::mojom::Role::kCanvas, ax_canvas_1->RoleValue()); - const AXObject* ax_text = ax_canvas_1->FirstChild(); + const AXObject* ax_text = ax_canvas_1->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text->RoleValue()); const AXObject* ax_canvas_2 = GetAXObjectByElementId("canvas2"); @@ -1093,8 +1114,8 @@ TEST_F(AccessibilityTest, PositionBeforeListMarker) { const AXObject* ax_item = GetAXObjectByElementId("listItem"); ASSERT_NE(nullptr, ax_item); ASSERT_EQ(ax::mojom::Role::kListItem, ax_item->RoleValue()); - ASSERT_EQ(2, ax_item->ChildCount()); - const AXObject* ax_marker = ax_item->FirstChild(); + ASSERT_EQ(2, ax_item->ChildCountIncludingIgnored()); + const AXObject* ax_marker = ax_item->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_marker); ASSERT_EQ(ax::mojom::Role::kListMarker, ax_marker->RoleValue()); @@ -1173,11 +1194,11 @@ TEST_F(AccessibilityTest, PositionAfterListMarker) { const AXObject* ax_item = GetAXObjectByElementId("listItem"); ASSERT_NE(nullptr, ax_item); ASSERT_EQ(ax::mojom::Role::kListItem, ax_item->RoleValue()); - ASSERT_EQ(2, ax_item->ChildCount()); - const AXObject* ax_marker = ax_item->FirstChild(); + ASSERT_EQ(2, ax_item->ChildCountIncludingIgnored()); + const AXObject* ax_marker = ax_item->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_marker); ASSERT_EQ(ax::mojom::Role::kListMarker, ax_marker->RoleValue()); - const AXObject* ax_text = ax_item->LastChild(); + const AXObject* ax_text = ax_item->LastChildIncludingIgnored(); ASSERT_NE(nullptr, ax_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text->RoleValue()); @@ -1207,15 +1228,17 @@ TEST_F(AccessibilityTest, PositionInCSSContent) { const AXObject* ax_quote = GetAXObjectByElementId("quote"); ASSERT_NE(nullptr, ax_quote); - ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_quote->RoleValue()); - ASSERT_EQ(3, ax_quote->ChildCount()); - const AXObject* ax_css_before = ax_quote->FirstChild(); + ASSERT_TRUE(ax_quote->AccessibilityIsIgnored()); + const AXObject* ax_quote_parent = ax_quote->ParentObjectUnignored(); + ASSERT_NE(nullptr, ax_quote_parent); + ASSERT_EQ(4, ax_quote_parent->UnignoredChildCount()); + const AXObject* ax_css_before = ax_quote_parent->UnignoredChildAt(0); ASSERT_NE(nullptr, ax_css_before); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_css_before->RoleValue()); - const AXObject* ax_text = *(ax_quote->Children().begin() + 1); + const AXObject* ax_text = ax_quote_parent->UnignoredChildAt(1); ASSERT_NE(nullptr, ax_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text->RoleValue()); - const AXObject* ax_css_after = ax_quote->LastChild(); + const AXObject* ax_css_after = ax_quote_parent->UnignoredChildAt(2); ASSERT_NE(nullptr, ax_css_after); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_css_after->RoleValue()); @@ -1256,9 +1279,9 @@ TEST_F(AccessibilityTest, PositionInCSSImageContent) { const AXObject* ax_heading = GetAXObjectByElementId("heading"); ASSERT_NE(nullptr, ax_heading); ASSERT_EQ(ax::mojom::Role::kHeading, ax_heading->RoleValue()); - ASSERT_EQ(2, ax_heading->ChildCount()); + ASSERT_EQ(2, ax_heading->ChildCountIncludingIgnored()); - const AXObject* ax_css_before = ax_heading->FirstChild(); + const AXObject* ax_css_before = ax_heading->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_css_before); ASSERT_EQ(ax::mojom::Role::kImage, ax_css_before->RoleValue()); @@ -1314,14 +1337,16 @@ TEST_F(AccessibilityTest, PositionInTableWithCSSContent) { ASSERT_NE(nullptr, ax_last_header_cell); ASSERT_EQ(ax::mojom::Role::kColumnHeader, ax_last_header_cell->RoleValue()); - ASSERT_EQ(3, ax_first_header_cell->ChildCount()); - AXObject* const ax_first_cell_css_before = ax_first_header_cell->FirstChild(); + ASSERT_EQ(3, ax_first_header_cell->ChildCountIncludingIgnored()); + AXObject* const ax_first_cell_css_before = + ax_first_header_cell->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_first_cell_css_before); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_first_cell_css_before->RoleValue()); - ASSERT_EQ(3, ax_last_header_cell->ChildCount()); - AXObject* const ax_last_cell_css_after = ax_last_header_cell->LastChild(); + ASSERT_EQ(3, ax_last_header_cell->ChildCountIncludingIgnored()); + AXObject* const ax_last_cell_css_after = + ax_last_header_cell->LastChildIncludingIgnored(); ASSERT_NE(nullptr, ax_last_cell_css_after); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_last_cell_css_after->RoleValue()); @@ -1352,9 +1377,9 @@ TEST_F(AccessibilityTest, PositionInTableWithCSSContent) { // Same situation as above, but now create a text position inside the inline // text box representing the CSS content after the last header cell. ax_first_cell_css_before->LoadInlineTextBoxes(); - ASSERT_NE(nullptr, ax_first_cell_css_before->FirstChild()); + ASSERT_NE(nullptr, ax_first_cell_css_before->FirstChildIncludingIgnored()); ax_position_before = AXPosition::CreateFirstPositionInObject( - *ax_first_cell_css_before->FirstChild()); + *ax_first_cell_css_before->FirstChildIncludingIgnored()); EXPECT_TRUE(ax_position_before.IsTextPosition()); EXPECT_EQ(0, ax_position_before.TextOffset()); position_before = ax_position_before.ToPositionWithAffinity( @@ -1388,9 +1413,9 @@ TEST_F(AccessibilityTest, PositionInTableWithCSSContent) { // Same situation as above, but now create a text position inside the inline // text box representing the CSS content after the last header cell. ax_last_cell_css_after->LoadInlineTextBoxes(); - ASSERT_NE(nullptr, ax_last_cell_css_after->FirstChild()); + ASSERT_NE(nullptr, ax_last_cell_css_after->FirstChildIncludingIgnored()); ax_position_after = AXPosition::CreateLastPositionInObject( - *ax_last_cell_css_after->FirstChild()); + *ax_last_cell_css_after->FirstChildIncludingIgnored()); EXPECT_TRUE(ax_position_after.IsTextPosition()); EXPECT_EQ(1, ax_position_after.TextOffset()); position_after = ax_position_after.ToPositionWithAffinity( @@ -1593,8 +1618,8 @@ TEST_F(AccessibilityTest, DISABLED_PositionInVirtualAOMNode) { const AXObject* ax_parent = GetAXObjectByElementId("aomParent"); ASSERT_NE(nullptr, ax_parent); ASSERT_EQ(ax::mojom::Role::kGenericContainer, ax_parent->RoleValue()); - ASSERT_EQ(1, ax_parent->ChildCount()); - const AXObject* ax_button = ax_parent->FirstChild(); + ASSERT_EQ(1, ax_parent->ChildCountIncludingIgnored()); + const AXObject* ax_button = ax_parent->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_button); ASSERT_EQ(ax::mojom::Role::kButton, ax_button->RoleValue()); const AXObject* ax_after = GetAXObjectByElementId("after"); @@ -1663,19 +1688,20 @@ TEST_P(ParameterizedAccessibilityTest, const Node* text = GetElementById("paragraph")->firstChild(); ASSERT_NE(nullptr, text); ASSERT_TRUE(text->IsTextNode()); - AXObject* ax_static_text = GetAXObjectByElementId("paragraph")->FirstChild(); + AXObject* ax_static_text = + GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); ax_static_text->LoadInlineTextBoxes(); - ASSERT_EQ(3, ax_static_text->ChildCount()); + ASSERT_EQ(3, ax_static_text->ChildCountIncludingIgnored()); // This test expects the starting offset of the last InlineTextBox object to // equates the sum of the previous inline text boxes length, without the // collapsed white-spaces. - const auto ax_position = - AXPosition::CreatePositionBeforeObject(*(ax_static_text->LastChild())); + const auto ax_position = AXPosition::CreatePositionBeforeObject( + *(ax_static_text->LastChildIncludingIgnored())); const auto position = ax_position.ToPositionWithAffinity(); EXPECT_EQ(LayoutNGEnabled() ? 7 : 6, position.GetPosition().OffsetInContainerNode()); diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc index a8a73f722b5..847fa7a73f9 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_range_test.cc @@ -19,18 +19,18 @@ TEST_F(AccessibilityTest, CommonAncestorContainerOfRange) { const AXObject* root = GetAXRootObject(); ASSERT_NE(nullptr, root); - const AXObject* body = root->FirstChild(); + const AXObject* body = GetAXBodyObject(); ASSERT_NE(nullptr, body); const AXObject* input = GetAXObjectByElementId("input"); ASSERT_NE(nullptr, input); const AXObject* paragraph = GetAXObjectByElementId("paragraph"); ASSERT_NE(nullptr, paragraph); - const AXObject* text1 = paragraph->FirstChild(); + const AXObject* text1 = paragraph->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, text1); ASSERT_EQ(ax::mojom::Role::kStaticText, text1->RoleValue()); const AXObject* br = GetAXObjectByElementId("br"); ASSERT_NE(nullptr, br); - const AXObject* text2 = paragraph->LastChild(); + const AXObject* text2 = paragraph->LastChildIncludingIgnored(); ASSERT_NE(nullptr, text2); ASSERT_EQ(ax::mojom::Role::kStaticText, text2->RoleValue()); const AXObject* button = GetAXObjectByElementId("button"); @@ -55,7 +55,7 @@ TEST_F(AccessibilityTest, IsCollapsedRange) { const AXObject* paragraph = GetAXObjectByElementId("paragraph"); ASSERT_NE(nullptr, paragraph); - const AXObject* text = paragraph->FirstChild(); + const AXObject* text = paragraph->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, text); ASSERT_EQ(ax::mojom::Role::kStaticText, text->RoleValue()); 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 9e78c2cdf4a..1897c42647e 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 @@ -318,11 +318,12 @@ AXObject* AXRelationCache::GetOrCreate(Node* node) { } void AXRelationCache::ChildrenChanged(AXObject* object) { - object_cache_->ChildrenChanged(object); + object->ChildrenChanged(); } void AXRelationCache::TextChanged(AXObject* object) { - object_cache_->TextChanged(object); + object->TextChanged(); + object_cache_->PostNotification(object, ax::mojom::Event::kTextChanged); } void AXRelationCache::LabelChanged(Node* node) { @@ -330,8 +331,10 @@ void AXRelationCache::LabelChanged(Node* node) { 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()) - TextChanged(Get(control)); + if (auto* control = To<HTMLLabelElement>(node)->control()) { + if (AXObject* obj = Get(control)) + TextChanged(obj); + } } } 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 02efbea750f..78b832591b2 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.cc @@ -191,7 +191,7 @@ AXSelection AXSelection::FromSelection( // in the accessibility tree. if (!selection.IsCaret()) { switch (selection_behavior) { - case AXSelectionBehavior::kShrinkToValidDOMRange: + case AXSelectionBehavior::kShrinkToValidRange: if (selection.IsBaseFirst()) { base_adjustment = AXPositionAdjustmentBehavior::kMoveRight; extent_adjustment = AXPositionAdjustmentBehavior::kMoveLeft; @@ -200,7 +200,7 @@ AXSelection AXSelection::FromSelection( extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight; } break; - case AXSelectionBehavior::kExtendToValidDOMRange: + case AXSelectionBehavior::kExtendToValidRange: if (selection.IsBaseFirst()) { base_adjustment = AXPositionAdjustmentBehavior::kMoveLeft; extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight; @@ -289,7 +289,7 @@ const SelectionInDOMTree AXSelection::AsSelection( AXPositionAdjustmentBehavior extent_adjustment = AXPositionAdjustmentBehavior::kMoveLeft; switch (selection_behavior) { - case AXSelectionBehavior::kShrinkToValidDOMRange: + case AXSelectionBehavior::kShrinkToValidRange: if (base_ < extent_) { base_adjustment = AXPositionAdjustmentBehavior::kMoveRight; extent_adjustment = AXPositionAdjustmentBehavior::kMoveLeft; @@ -298,7 +298,7 @@ const SelectionInDOMTree AXSelection::AsSelection( extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight; } break; - case AXSelectionBehavior::kExtendToValidDOMRange: + case AXSelectionBehavior::kExtendToValidRange: if (base_ < extent_) { base_adjustment = AXPositionAdjustmentBehavior::kMoveLeft; extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight; diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h index bca557a8459..8f3a5e4d344 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_selection.h @@ -26,14 +26,11 @@ namespace blink { // selection will shrink or extend the |AXSelection| to encompass endpoints that // are in the DOM. // Conversely, if a DOM selection is converted to an |AXSelection| via the -// |AsSelection| method, but the endpoints of the DOM selection are not present -// in the accessibility tree, e.g. they are aria-hidden, determines whether the -// conversion will shrink or extend the DOM selection to encompass endpoints -// that are in the accessibility tree. -enum class AXSelectionBehavior { - kShrinkToValidDOMRange, - kExtendToValidDOMRange -}; +// |FromSelection| method, but the endpoints of the DOM selection are not +// present in the accessibility tree, e.g. they are aria-hidden, determines +// whether the conversion will shrink or extend the DOM selection to encompass +// endpoints that are in the accessibility tree. +enum class AXSelectionBehavior { kShrinkToValidRange, kExtendToValidRange }; class MODULES_EXPORT AXSelection final { DISALLOW_NEW(); @@ -45,13 +42,13 @@ class MODULES_EXPORT AXSelection final { static AXSelection FromCurrentSelection( const Document&, - const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidDOMRange); + const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidRange); static AXSelection FromCurrentSelection(const TextControlElement&); static AXSelection FromSelection( const SelectionInDOMTree&, - const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidDOMRange); + const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidRange); AXSelection(const AXSelection&) = default; AXSelection& operator=(const AXSelection&) = default; @@ -68,13 +65,13 @@ class MODULES_EXPORT AXSelection final { const SelectionInDOMTree AsSelection( const AXSelectionBehavior = - AXSelectionBehavior::kExtendToValidDOMRange) const; + AXSelectionBehavior::kExtendToValidRange) const; // Tries to set the DOM selection to this. Returns |false| if the selection // has been cancelled via the "selectionstart" event or if the selection could // not be set for any other reason. bool Select( - const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidDOMRange); + const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidRange); // Returns a string representation of this object. String ToString() const; 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 40c0cb5eba5..0970f700f30 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 @@ -62,7 +62,7 @@ TEST_F(AccessibilitySelectionTest, FromCurrentSelection) { UpdateAllLifecyclePhasesForTest(); const AXObject* ax_static_text_1 = - GetAXObjectByElementId("paragraph1")->FirstChild(); + GetAXObjectByElementId("paragraph1")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text_1); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text_1->RoleValue()); const AXObject* ax_paragraph_2 = GetAXObjectByElementId("paragraph2"); @@ -109,7 +109,7 @@ TEST_F(AccessibilitySelectionTest, FromCurrentSelectionSelectAll) { ASSERT_FALSE(ax_selection.Extent().IsTextPosition()); EXPECT_EQ(GetAXRootObject(), ax_selection.Extent().ContainerObject()); - EXPECT_EQ(GetAXRootObject()->ChildCount(), + EXPECT_EQ(GetAXRootObject()->ChildCountIncludingIgnored(), ax_selection.Extent().ChildIndex()); EXPECT_EQ( @@ -175,7 +175,7 @@ TEST_F(AccessibilitySelectionTest, CancelSelect) { UpdateAllLifecyclePhasesForTest(); const AXObject* ax_static_text_1 = - GetAXObjectByElementId("paragraph1")->FirstChild(); + GetAXObjectByElementId("paragraph1")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text_1); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text_1->RoleValue()); const AXObject* ax_paragraph_2 = GetAXObjectByElementId("paragraph2"); @@ -213,7 +213,7 @@ TEST_F(AccessibilitySelectionTest, DocumentRangeMatchesSelection) { )HTML"); const AXObject* ax_static_text_1 = - GetAXObjectByElementId("paragraph1")->FirstChild(); + GetAXObjectByElementId("paragraph1")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text_1); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text_1->RoleValue()); const AXObject* ax_paragraph_2 = GetAXObjectByElementId("paragraph2"); @@ -241,7 +241,7 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInText) { ASSERT_TRUE(text->IsTextNode()); const AXObject* ax_static_text = - GetAXObjectByElementId("paragraph")->FirstChild(); + GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -272,7 +272,7 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInTextWithWhiteSpace) { ASSERT_TRUE(text->IsTextNode()); const AXObject* ax_static_text = - GetAXObjectByElementId("paragraph")->FirstChild(); + GetAXObjectByElementId("paragraph")->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); @@ -313,7 +313,8 @@ TEST_F(AccessibilitySelectionTest, SetSelectionAcrossLineBreak) { const AXObject* ax_br = GetAXObjectByElementId("br"); ASSERT_NE(nullptr, ax_br); ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue()); - const AXObject* ax_line2 = GetAXObjectByElementId("paragraph")->LastChild(); + const AXObject* ax_line2 = + GetAXObjectByElementId("paragraph")->LastChildIncludingIgnored(); ASSERT_NE(nullptr, ax_line2); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_line2->RoleValue()); @@ -358,7 +359,8 @@ TEST_F(AccessibilitySelectionTest, SetSelectionAcrossLineBreakInEditableText) { const AXObject* ax_br = GetAXObjectByElementId("br"); ASSERT_NE(nullptr, ax_br); ASSERT_EQ(ax::mojom::Role::kLineBreak, ax_br->RoleValue()); - const AXObject* ax_line2 = GetAXObjectByElementId("paragraph")->LastChild(); + const AXObject* ax_line2 = + GetAXObjectByElementId("paragraph")->LastChildIncludingIgnored(); ASSERT_NE(nullptr, ax_line2); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_line2->RoleValue()); @@ -440,9 +442,9 @@ TEST_F(AccessibilitySelectionTest, SetSelectionInDisplayNone) { .Build(); const auto ax_selection_shrink = AXSelection::FromSelection( - selection, AXSelectionBehavior::kShrinkToValidDOMRange); + selection, AXSelectionBehavior::kShrinkToValidRange); const auto ax_selection_extend = AXSelection::FromSelection( - selection, AXSelectionBehavior::kExtendToValidDOMRange); + selection, AXSelectionBehavior::kExtendToValidRange); // The "display: none" content is included in the AXTree as an ignored node, // so shrunk selection should include those AXObjects. Note that the browser @@ -519,13 +521,13 @@ TEST_P(ParameterizedAccessibilitySelectionTest, SetSelectionAroundListBullet) { const AXObject* ax_item_1 = GetAXObjectByElementId("item1"); ASSERT_NE(nullptr, ax_item_1); ASSERT_EQ(ax::mojom::Role::kListItem, ax_item_1->RoleValue()); - const AXObject* ax_bullet_1 = ax_item_1->FirstChild(); + const AXObject* ax_bullet_1 = ax_item_1->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_bullet_1); ASSERT_EQ(ax::mojom::Role::kListMarker, ax_bullet_1->RoleValue()); const AXObject* ax_item_2 = GetAXObjectByElementId("item2"); ASSERT_NE(nullptr, ax_item_2); ASSERT_EQ(ax::mojom::Role::kListItem, ax_item_2->RoleValue()); - const AXObject* ax_text_2 = ax_item_2->LastChild(); + const AXObject* ax_text_2 = ax_item_2->LastChildIncludingIgnored(); ASSERT_NE(nullptr, ax_text_2); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text_2->RoleValue()); @@ -540,7 +542,7 @@ TEST_P(ParameterizedAccessibilitySelectionTest, SetSelectionAroundListBullet) { // child of the first <li>, i.e. the text node containing the text "Item 1.". // This should be further optimized to a text position at the start of the // text object inside the first <li>. - ax_selection.Select(AXSelectionBehavior::kShrinkToValidDOMRange); + ax_selection.Select(AXSelectionBehavior::kShrinkToValidRange); const SelectionInDOMTree shrunk_selection = Selection().GetSelectionInDOMTree(); @@ -553,7 +555,7 @@ TEST_P(ParameterizedAccessibilitySelectionTest, SetSelectionAroundListBullet) { // The list bullet is not included in the DOM tree. Extending the // |AXSelection| should move the anchor to before the first <li>. - ax_selection.Select(AXSelectionBehavior::kExtendToValidDOMRange); + ax_selection.Select(AXSelectionBehavior::kExtendToValidRange); const SelectionInDOMTree extended_selection = Selection().GetSelectionInDOMTree(); @@ -828,7 +830,8 @@ TEST_F(AccessibilitySelectionTest, GetAXObjectByElementId("contenteditable"); ASSERT_NE(nullptr, ax_contenteditable); ASSERT_EQ(ax::mojom::Role::kTextField, ax_contenteditable->RoleValue()); - const AXObject* ax_static_text = ax_contenteditable->FirstChild(); + const AXObject* ax_static_text = + ax_contenteditable->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); // Guard against the structure of the accessibility tree unexpectedly // changing, causing a hard to debug test failure. @@ -887,7 +890,8 @@ TEST_F(AccessibilitySelectionTest, GetAXObjectByElementId("contenteditable"); ASSERT_NE(nullptr, ax_contenteditable); ASSERT_EQ(ax::mojom::Role::kTextField, ax_contenteditable->RoleValue()); - const AXObject* ax_static_text = ax_contenteditable->FirstChild(); + const AXObject* ax_static_text = + ax_contenteditable->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); // Guard against the structure of the accessibility tree unexpectedly // changing, causing a hard to debug test failure. @@ -942,10 +946,10 @@ TEST_F(AccessibilitySelectionTest, GetAXObjectByElementId("contenteditable"); ASSERT_NE(nullptr, ax_contenteditable); ASSERT_EQ(ax::mojom::Role::kTextField, ax_contenteditable->RoleValue()); - ASSERT_EQ(3, ax_contenteditable->ChildCount()) + ASSERT_EQ(3, ax_contenteditable->UnignoredChildCount()) << "The content editable should have two lines with a line break between " "them."; - const AXObject* ax_static_text_2 = ax_contenteditable->Children()[2]; + const AXObject* ax_static_text_2 = ax_contenteditable->UnignoredChildAt(2); ASSERT_NE(nullptr, ax_static_text_2); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text_2->RoleValue()); @@ -1599,7 +1603,7 @@ TEST_F(AccessibilitySelectionTest, GetAXObjectByElementId("contenteditable"); ASSERT_NE(nullptr, ax_contenteditable); ASSERT_EQ(ax::mojom::Role::kTextField, ax_contenteditable->RoleValue()); - const AXObject* ax_text = ax_contenteditable->FirstChild(); + const AXObject* ax_text = ax_contenteditable->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_text->RoleValue()); @@ -1640,8 +1644,9 @@ TEST_F(AccessibilitySelectionTest, const AXObject* ax_contenteditable = GetAXObjectByElementId("contenteditable"); ASSERT_NE(nullptr, ax_contenteditable); - ASSERT_EQ(1, ax_contenteditable->ChildCount()); - const AXObject* ax_static_text = ax_contenteditable->FirstChild(); + ASSERT_EQ(1, ax_contenteditable->ChildCountIncludingIgnored()); + const AXObject* ax_static_text = + ax_contenteditable->FirstChildIncludingIgnored(); ASSERT_NE(nullptr, ax_static_text); ASSERT_EQ(ax::mojom::Role::kStaticText, ax_static_text->RoleValue()); String computed_name = ax_static_text->ComputedName(); @@ -1704,7 +1709,8 @@ TEST_F(AccessibilitySelectionTest, SelectionWithEqualBaseAndExtent) { SetBodyInnerHTML(R"HTML( <select id="sel"><option>1</option></select> )HTML"); - AXObject* ax_sel = GetAXObjectByElementId("sel")->FirstChild(); + AXObject* ax_sel = + GetAXObjectByElementId("sel")->FirstChildIncludingIgnored(); AXPosition ax_position = AXPosition::CreatePositionBeforeObject(*ax_sel); AXSelection::Builder builder; AXSelection ax_selection = @@ -1750,6 +1756,17 @@ TEST_P(ParameterizedAccessibilitySelectionTest, List) { ParameterizedAccessibilitySelectionTest::RunSelectionTest("list"); } +TEST_F(AccessibilitySelectionTest, ParagraphPresentational) { + // The focus of the selection is an "after children" position on a paragraph + // with role="presentation" and in which the last child is an empty div. In + // other words, both the paragraph and its last child are ignored in the + // accessibility tree. In order to become valid, the focus should move to + // before the next unignored child of the presentational paragraph's unignored + // parent, which in this case is another paragraph that comes after the + // presentational one. + RunSelectionTest("paragraph-presentational"); +} + TEST_F(AccessibilitySelectionTest, SVG) { RunSelectionTest("svg"); } 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 061d4130933..7100337bb77 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_slider.cc @@ -114,6 +114,11 @@ bool AXSlider::OnNativeSetValueAction(const String& value) { // Fire change event manually, as LayoutSlider::setValueForPosition does. input->DispatchFormControlChangeEvent(); + // Dispatching an event could result in changes to the document, like + // this AXObject becoming detached. + if (IsDetached()) + return false; + // Ensure the AX node is updated. AXObjectCache().MarkAXObjectDirty(this, false); diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc b/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc index 70f56387646..67bb64c647a 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.cc @@ -75,7 +75,7 @@ String AXVirtualObject::TextAlternative(bool recursive, &found_text_alternative); } -void AXVirtualObject::Trace(Visitor* visitor) { +void AXVirtualObject::Trace(Visitor* visitor) const { visitor->Trace(accessible_node_); AXObject::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h b/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h index 8d9b398efec..4049d30dd26 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/ax_virtual_object.h @@ -17,7 +17,7 @@ class MODULES_EXPORT AXVirtualObject : public AXObject { public: AXVirtualObject(AXObjectCacheImpl&, AccessibleNode*); ~AXVirtualObject() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // AXObject overrides. void Detach() override; 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 7af6e7fa327..b6e8dbc6b5f 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 @@ -386,7 +386,7 @@ class SparseAttributeAXPropertyAdapter protocol::Array<AXProperty>& properties) : ax_object_(&ax_object), properties_(properties) {} - void Trace(Visitor* visitor) { visitor->Trace(ax_object_); } + void Trace(Visitor* visitor) const { visitor->Trace(ax_object_); } private: Member<AXObject> ax_object_; @@ -732,7 +732,8 @@ Response InspectorAccessibilityAgent::getFullAXTree( BuildProtocolAXObject(*ax_object, nullptr, false, *nodes, cache); auto child_ids = std::make_unique<protocol::Array<AXNodeId>>(); - const AXObject::AXObjectVector& children = ax_object->Children(); + const AXObject::AXObjectVector& children = + ax_object->ChildrenIncludingIgnored(); for (unsigned i = 0; i < children.size(); i++) { AXObject& child_ax_object = *children[i].Get(); child_ids->emplace_back(String::Number(child_ax_object.AXObjectID())); @@ -815,7 +816,8 @@ void InspectorAccessibilityAgent::AddChildren( return; } - const AXObject::AXObjectVector& children = ax_object.Children(); + const AXObject::AXObjectVector& children = + ax_object.ChildrenIncludingIgnored(); for (unsigned i = 0; i < children.size(); i++) { AXObject& child_ax_object = *children[i].Get(); child_ids->emplace_back(String::Number(child_ax_object.AXObjectID())); @@ -886,7 +888,7 @@ void InspectorAccessibilityAgent::CreateAXContext() { context_ = std::make_unique<AXContext>(*document); } -void InspectorAccessibilityAgent::Trace(Visitor* visitor) { +void InspectorAccessibilityAgent::Trace(Visitor* visitor) const { visitor->Trace(inspected_frames_); visitor->Trace(dom_agent_); InspectorBaseAgent::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h b/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h index 231229e4129..9a09e8770e5 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/inspector_accessibility_agent.h @@ -31,7 +31,7 @@ class MODULES_EXPORT InspectorAccessibilityAgent void CreateAXContext(); // Base agent methods. - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void Restore() override; // Protocol methods. 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 c379a8f00ad..87c63efce32 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 @@ -22,6 +22,8 @@ String IgnoredReasonName(AXIgnoredReason reason) { switch (reason) { case kAXActiveModalDialog: return "activeModalDialog"; + case kAXAriaModalDialog: + return "activeAriaModalDialog"; case kAXAncestorIsLeafNode: return "ancestorIsLeafNode"; case kAXAriaHiddenElement: diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc index 9056487393e..666729ca020 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc @@ -28,8 +28,6 @@ #include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { -namespace test { - namespace { constexpr char kSelectionTestsRelativePath[] = "selection/"; @@ -150,7 +148,7 @@ class AXSelectionSerializer final { } void SerializeSubtree(const AXObject& subtree) { - if (subtree.ChildCount() == 0) { + if (!subtree.ChildCountIncludingIgnored()) { // Though they are in this particular case both equivalent to an "after // object" position, "Before children" and "after children" positions are // still valid within empty subtrees. @@ -159,7 +157,7 @@ class AXSelectionSerializer final { return; } - for (const AXObject* child : subtree.Children()) { + for (const AXObject* child : subtree.ChildrenIncludingIgnored()) { DCHECK(child); const auto position = AXPosition::CreatePositionBeforeObject(*child); HandleSelection(position); @@ -315,7 +313,7 @@ class AXSelectionDeserializer final { } void HandleObject(const AXObject& object) { - for (const AXObject* child : object.Children()) { + for (const AXObject* child : object.ChildrenIncludingIgnored()) { DCHECK(child); FindSelectionMarkers(*child); } @@ -346,6 +344,11 @@ AccessibilitySelectionTest::AccessibilitySelectionTest( LocalFrameClient* local_frame_client) : AccessibilityTest(local_frame_client) {} +void AccessibilitySelectionTest::SetUp() { + AccessibilityTest::SetUp(); + RuntimeEnabledFeatures::SetAccessibilityExposeHTMLElementEnabled(false); +} + std::string AccessibilitySelectionTest::GetCurrentSelectionText() const { const SelectionInDOMTree selection = GetFrame().Selection().GetSelectionInDOMTree(); @@ -397,10 +400,10 @@ void AccessibilitySelectionTest::RunSelectionTest( static const std::string separator_line = '\n' + std::string(80, '=') + '\n'; const String relative_path = String::FromUTF8(kSelectionTestsRelativePath) + String::FromUTF8(test_name); - const String test_path = AccessibilityTestDataPath(relative_path); + const String test_path = test::AccessibilityTestDataPath(relative_path); const String test_file = test_path + String::FromUTF8(kTestFileSuffix); - scoped_refptr<SharedBuffer> test_file_buffer = ReadFromFile(test_file); + scoped_refptr<SharedBuffer> test_file_buffer = test::ReadFromFile(test_file); auto test_file_chars = test_file_buffer->CopyAs<Vector<char>>(); std::string test_file_contents; std::copy(test_file_chars.begin(), test_file_chars.end(), @@ -413,7 +416,7 @@ void AccessibilitySelectionTest::RunSelectionTest( const String ax_file = test_path + String::FromUTF8(suffix.empty() ? kAXTestExpectationSuffix : suffix); - scoped_refptr<SharedBuffer> ax_file_buffer = ReadFromFile(ax_file); + scoped_refptr<SharedBuffer> ax_file_buffer = test::ReadFromFile(ax_file); auto ax_file_chars = ax_file_buffer->CopyAs<Vector<char>>(); std::string ax_file_contents; std::copy(ax_file_chars.begin(), ax_file_chars.end(), @@ -454,5 +457,4 @@ void ParameterizedAccessibilitySelectionTest::RunSelectionTest( AccessibilitySelectionTest::RunSelectionTest(test_name, suffix); } -} // namespace test } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h index c4c75fc1a1c..1f47988ef88 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h +++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.h @@ -16,8 +16,6 @@ class AXObject; class AXSelection; class LocalFrameClient; -namespace test { - // Makes writing and debugging selection tests easier. class AccessibilitySelectionTest : public AccessibilityTest { USING_FAST_MALLOC(AccessibilitySelectionTest); @@ -26,6 +24,8 @@ class AccessibilitySelectionTest : public AccessibilityTest { AccessibilitySelectionTest(LocalFrameClient* local_frame_client = nullptr); protected: + void SetUp() override; + // Gets a text representation of the accessibility tree that is currently // selected and annotates it with markers indicating the anchor and focus of // |selection|. @@ -83,7 +83,6 @@ INSTANTIATE_TEST_SUITE_P(All, ParameterizedAccessibilitySelectionTest, testing::Bool()); -} // namespace test } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_TESTING_ACCESSIBILITY_SELECTION_TEST_H_ diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.cc b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.cc index 6f8bb3a27d5..b2dc90fd6a8 100644 --- a/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.cc +++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/accessibility_test.cc @@ -14,15 +14,14 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { -namespace test { AccessibilityTest::AccessibilityTest(LocalFrameClient* local_frame_client) : RenderingTest(local_frame_client) {} void AccessibilityTest::SetUp() { RenderingTest::SetUp(); - RuntimeEnabledFeatures::SetAccessibilityExposeHTMLElementEnabled(false); - ax_context_.reset(new AXContext(GetDocument())); + RuntimeEnabledFeatures::SetAccessibilityExposeHTMLElementEnabled(true); + ax_context_ = std::make_unique<AXContext>(GetDocument()); } AXObjectCacheImpl& AccessibilityTest::GetAXObjectCache() const { @@ -32,6 +31,10 @@ AXObjectCacheImpl& AccessibilityTest::GetAXObjectCache() const { return *ax_object_cache; } +AXObject* AccessibilityTest::GetAXObject(LayoutObject* layout_object) const { + return GetAXObjectCache().GetOrCreate(layout_object); +} + AXObject* AccessibilityTest::GetAXObject(const Node& node) const { return GetAXObjectCache().GetOrCreate(&node); } @@ -40,6 +43,10 @@ AXObject* AccessibilityTest::GetAXRootObject() const { return GetAXObjectCache().GetOrCreate(&GetLayoutView()); } +AXObject* AccessibilityTest::GetAXBodyObject() const { + return GetAXObjectCache().GetOrCreate(GetDocument().body()); +} + AXObject* AccessibilityTest::GetAXFocusedObject() const { return GetAXObjectCache().FocusedObject(); } @@ -64,12 +71,11 @@ std::ostringstream& AccessibilityTest::PrintAXTreeHelper( stream << std::string(level * 2, '+'); stream << *root << std::endl; - for (const AXObject* child : root->Children()) { + for (const AXObject* child : root->ChildrenIncludingIgnored()) { DCHECK(child); PrintAXTreeHelper(stream, child, level + 1); } return stream; } -} // namespace test } // namespace blink 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 8b2ab7a994e..985eaec250b 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 @@ -20,8 +20,6 @@ class AXObjectCacheImpl; class LocalFrameClient; class Node; -namespace test { - class AccessibilityTest : public RenderingTest { USING_FAST_MALLOC(AccessibilityTest); @@ -33,10 +31,14 @@ class AccessibilityTest : public RenderingTest { AXObjectCacheImpl& GetAXObjectCache() const; + AXObject* GetAXObject(LayoutObject* layout_object) const; + AXObject* GetAXObject(const Node& node) const; AXObject* GetAXRootObject() const; + AXObject* GetAXBodyObject() const; + // Returns the object with the accessibility focus. AXObject* GetAXFocusedObject() const; @@ -67,7 +69,6 @@ class ParameterizedAccessibilityTest : public testing::WithParamInterface<bool>, INSTANTIATE_TEST_SUITE_P(All, ParameterizedAccessibilityTest, testing::Bool()); -} // namespace test } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_TESTING_ACCESSIBILITY_TEST_H_ diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational-ax.txt b/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational-ax.txt new file mode 100644 index 00000000000..6eff2cebdd8 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational-ax.txt @@ -0,0 +1,12 @@ + +================================================================================ +AXSelection from AX text position in "StaticText": "Some text.", 0 to AX object anchored position in "Main": "", 2 +================================================================================ +++<GenericContainer> +++++<Main> +++++++<Presentational> +^++++++++<StaticText: ^Some text.> +++++++<GenericContainer> +|++++++<Paragraph> +++++++<Paragraph> +++++++++<StaticText: After presentational paragraph.> diff --git a/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational.html b/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational.html new file mode 100644 index 00000000000..27282356677 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/accessibility/testing/data/selection/paragraph-presentational.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> + <body> + <div role="main"> + <p role="presentation">^ + <span>Some text.</span> + <div></div> + |</p> + <p>After presentational paragraph.</p> + </div> + </body> +</html> diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc index 27ba08597e5..8dcd7813cf9 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.cc @@ -63,7 +63,7 @@ WorkletAnimationId AnimationWorklet::NextWorkletAnimationId() { return WorkletAnimationId(worklet_id_, ++last_animation_id_); } -void AnimationWorklet::Trace(Visitor* visitor) { +void AnimationWorklet::Trace(Visitor* visitor) const { Worklet::Trace(visitor); visitor->Trace(proxy_client_); } diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h index b087ab8aad6..cd8a4e99322 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet.h @@ -27,7 +27,7 @@ class MODULES_EXPORT AnimationWorklet final : public Worklet { ~AnimationWorklet() override; WorkletAnimationId NextWorkletAnimationId(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Unique id associated with this worklet that is used by cc to identify all 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 be7439f7da2..398b84ba9e6 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 @@ -52,7 +52,7 @@ AnimationWorkletGlobalScope::AnimationWorkletGlobalScope( AnimationWorkletGlobalScope::~AnimationWorkletGlobalScope() = default; -void AnimationWorkletGlobalScope::Trace(Visitor* visitor) { +void AnimationWorkletGlobalScope::Trace(Visitor* visitor) const { visitor->Trace(animator_definitions_); visitor->Trace(animators_); WorkletGlobalScope::Trace(visitor); @@ -218,9 +218,9 @@ void AnimationWorkletGlobalScope::registerAnimator( // TODO(https://crbug.com/923063): Ensure worklet definitions are compatible // across global scopes. animator_definitions_.Set(name, definition); - // TODO(yigu): Currently one animator name is synced back per registration. - // Eventually all registered names should be synced in batch once a module - // completes its loading in the worklet scope. https://crbug.com/920722. + // TODO(crbug.com/920722): Currently one animator name is synced back per + // registration. Eventually all registered names should be synced in batch + // once a module completes its loading in the worklet scope. if (AnimationWorkletProxyClient* proxy_client = AnimationWorkletProxyClient::From(Clients())) { proxy_client->SynchronizeAnimatorName(name); @@ -295,8 +295,8 @@ void AnimationWorkletGlobalScope::MigrateAnimatorsTo( "Animator", "state"); // If an animator state function throws or the state is not // serializable, the animator will be removed from the global scope. - // TODO(yigu): We should post an error message to console in case of - // exceptions. + // TODO(crbug.com/1090522): We should post an error message to console in + // case of exceptions. v8::Local<v8::Value> state = animator->State(isolate, exception_state); if (exception_state.HadException()) { exception_state.ClearException(); diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h index 441e1dedbc5..b0d42bf4702 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.h @@ -37,7 +37,7 @@ class MODULES_EXPORT AnimationWorkletGlobalScope : public WorkletGlobalScope { WorkerThread*); ~AnimationWorkletGlobalScope() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void Dispose() override; bool IsAnimationWorkletGlobalScope() const final { return true; } diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.cc index ec81d0effa3..80c9fb8db43 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.cc @@ -13,7 +13,7 @@ AnimationWorkletMessagingProxy::AnimationWorkletMessagingProxy( ExecutionContext* execution_context) : ThreadedWorkletMessagingProxy(execution_context) {} -void AnimationWorkletMessagingProxy::Trace(Visitor* visitor) { +void AnimationWorkletMessagingProxy::Trace(Visitor* visitor) const { ThreadedWorkletMessagingProxy::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h index aed2d8a1dea..3656a604f66 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_messaging_proxy.h @@ -24,7 +24,7 @@ class AnimationWorkletMessagingProxy final public: explicit AnimationWorkletMessagingProxy(ExecutionContext*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ~AnimationWorkletMessagingProxy() override; diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc index ab6bcd69778..21803ad7b6c 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animation_worklet_proxy_client.cc @@ -57,7 +57,7 @@ AnimationWorkletProxyClient::AnimationWorkletProxyClient( } } -void AnimationWorkletProxyClient::Trace(Visitor* visitor) { +void AnimationWorkletProxyClient::Trace(Visitor* visitor) const { Supplement<WorkerClients>::Trace(visitor); AnimationWorkletMutator::Trace(visitor); } 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 d9401b03d45..1105d741649 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 @@ -44,7 +44,7 @@ class MODULES_EXPORT AnimationWorkletProxyClient scoped_refptr<base::SingleThreadTaskRunner> compositor_mutatee_runner, base::WeakPtr<AnimationWorkletMutatorDispatcherImpl> main_thread_mutatee, scoped_refptr<base::SingleThreadTaskRunner> main_thread_mutatee_runner); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; virtual void SynchronizeAnimatorName(const String& animator_name); virtual void AddGlobalScope(WorkletGlobalScope*); diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc index ed94ad4a3e3..cd278764bb5 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator.cc @@ -32,7 +32,7 @@ Animator::Animator(v8::Isolate* isolate, Animator::~Animator() = default; -void Animator::Trace(Visitor* visitor) { +void Animator::Trace(Visitor* visitor) const { visitor->Trace(definition_); visitor->Trace(instance_); visitor->Trace(group_effect_); diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animator.h b/chromium/third_party/blink/renderer/modules/animationworklet/animator.h index 01678af53c9..38769e67656 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animator.h +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator.h @@ -33,7 +33,7 @@ class Animator final : public GarbageCollected<Animator>, public NameClient { const Vector<base::Optional<base::TimeDelta>>& local_times, const Vector<Timing>& timings); ~Animator(); - void Trace(Visitor*); + void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "Animator"; } // Returns true if it successfully invoked animate callback in JS. It receives diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.cc b/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.cc index 24e01f70b3c..a3daa638327 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.cc +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.cc @@ -19,7 +19,7 @@ AnimatorDefinition::AnimatorDefinition(V8AnimatorConstructor* constructor, DCHECK(animate_); } -void AnimatorDefinition::Trace(Visitor* visitor) { +void AnimatorDefinition::Trace(Visitor* visitor) const { visitor->Trace(constructor_); visitor->Trace(animate_); visitor->Trace(state_); 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 4a2e8dcb5e2..c7b6efd9b1f 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h +++ b/chromium/third_party/blink/renderer/modules/animationworklet/animator_definition.h @@ -27,7 +27,7 @@ class MODULES_EXPORT AnimatorDefinition final explicit AnimatorDefinition(V8AnimatorConstructor* constructor, V8AnimateCallback* animate, V8StateCallback* state); - virtual void Trace(Visitor* visitor); + virtual void Trace(Visitor* visitor) const; const char* NameInHeapSnapshot() const override { return "AnimatorDefinition"; } diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc b/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc index 60557787a22..e0a7b0c8258 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc +++ b/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.cc @@ -33,7 +33,7 @@ void CSSAnimationWorklet::ContextDestroyed() { animation_worklet_ = nullptr; } -void CSSAnimationWorklet::Trace(Visitor* visitor) { +void CSSAnimationWorklet::Trace(Visitor* visitor) const { visitor->Trace(animation_worklet_); Supplement<LocalDOMWindow>::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h b/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h index 4fea783d8bc..897fdab3e20 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h +++ b/chromium/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.h @@ -29,7 +29,7 @@ class MODULES_EXPORT CSSAnimationWorklet final void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: static CSSAnimationWorklet& From(LocalDOMWindow&); 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 5092b3cd53a..2d13e5883ca 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc +++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.cc @@ -327,11 +327,11 @@ void WorkletAnimation::play(ExceptionState& exception_state) { if (!target) continue; - // TODO(yigu): Currently we have to keep a set of worklet animations in - // ElementAnimations so that the compositor knows that there are active - // worklet animations running. Ideally, this should be done via the regular - // Animation path, i.e., unify the logic between the two Animations. - // https://crbug.com/896249. + // TODO(crbug.com/896249): Currently we have to keep a set of worklet + // animations in ElementAnimations so that the compositor knows that there + // are active worklet animations running. Ideally, this should be done via + // the regular Animation path, i.e., unify the logic between the two + // Animations. target->EnsureElementAnimations().GetWorkletAnimations().insert(this); target->SetNeedsAnimationStyleRecalc(); } @@ -386,13 +386,15 @@ void WorkletAnimation::cancel() { has_started_ = false; local_times_.Fill(base::nullopt); running_on_main_thread_ = false; - // TODO(yigu): Because this animation has been detached and will not receive - // updates anymore, we have to update its value upon cancel. Similar to - // regular animations, we should not detach them immediately and update the - // value in the next frame. See https://crbug.com/883312. + // TODO(crbug.com/883312): Because this animation has been detached and will + // not receive updates anymore, we have to update its value upon cancel. + // Similar to regular animations, we should not detach them immediately and + // update the value in the next frame. if (IsActive(play_state_)) { - for (auto& effect : effects_) - effect->UpdateInheritedTime(base::nullopt, kTimingUpdateOnDemand); + for (auto& effect : effects_) { + effect->UpdateInheritedTime(base::nullopt, base::nullopt, + kTimingUpdateOnDemand); + } } SetPlayState(Animation::kIdle); SetCurrentTime(base::nullopt); @@ -401,11 +403,11 @@ void WorkletAnimation::cancel() { Element* target = effect->EffectTarget(); if (!target) continue; - // TODO(yigu): Currently we have to keep a set of worklet animations in - // ElementAnimations so that the compositor knows that there are active - // worklet animations running. Ideally, this should be done via the regular - // Animation path, i.e., unify the logic between the two Animations. - // https://crbug.com/896249. + // TODO(crbug.com/896249): Currently we have to keep a set of worklet + // animations in ElementAnimations so that the compositor knows that there + // are active worklet animations running. Ideally, this should be done via + // the regular Animation path, i.e., unify the logic between the two + // Animations. target->EnsureElementAnimations().GetWorkletAnimations().erase(this); target->SetNeedsAnimationStyleRecalc(); } @@ -476,7 +478,7 @@ void WorkletAnimation::Update(TimingUpdateReason reason) { effects_[i]->UpdateInheritedTime( local_times_[i] ? base::Optional<double>(local_times_[i]->InSecondsF()) : base::nullopt, - reason); + base::nullopt, reason); } } @@ -619,8 +621,8 @@ bool WorkletAnimation::StartOnCompositor() { // update the compositor to have the correct orientation and start/end // offset information. compositor_animation_ = CompositorAnimation::CreateWorkletAnimation( - id_, animator_name_, playback_rate_, - std::move(options_), std::move(effect_timings_)); + id_, animator_name_, playback_rate_, std::move(options_), + std::move(effect_timings_)); compositor_animation_->SetAnimationDelegate(this); } @@ -668,16 +670,9 @@ bool WorkletAnimation::UpdateOnCompositor() { StartEffectOnCompositor(compositor_animation_.get(), GetEffect()); } - if (timeline_->IsScrollTimeline()) { - auto& timeline = To<ScrollTimeline>(*timeline_); - Node* scroll_source = timeline.ResolvedScrollSource(); - auto start_scroll_offset = timeline.GetResolvedStartScrollOffset(); - auto end_scroll_offset = timeline.GetResolvedEndScrollOffset(); + if (timeline_->IsScrollTimeline()) + timeline_->UpdateCompositorTimeline(); - compositor_animation_->UpdateScrollTimeline( - scroll_timeline_util::GetCompositorScrollElementId(scroll_source), - start_scroll_offset, end_scroll_offset); - } compositor_animation_->UpdatePlaybackRate(playback_rate_); return true; } @@ -865,7 +860,7 @@ void WorkletAnimation::Dispose() { DestroyCompositorAnimation(); } -void WorkletAnimation::Trace(Visitor* visitor) { +void WorkletAnimation::Trace(Visitor* visitor) const { visitor->Trace(document_); visitor->Trace(effects_); visitor->Trace(timeline_); diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h index 472184b62db..6e8c2a30a61 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h +++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_animation.h @@ -140,7 +140,7 @@ class MODULES_EXPORT WorkletAnimation : public WorkletAnimationBase, running_on_main_thread_ = running_on_main_thread; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void Dispose(); private: 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 21172d7bcc0..03d206c2d35 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 @@ -36,7 +36,7 @@ ComputedEffectTiming* WorkletAnimationEffect::getComputedTiming() const { // 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, base::nullopt, Timing::AnimationDirection::kForwards, false, playback_rate); } diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc index 5ed3e613a84..c5923945cae 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc +++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.cc @@ -19,7 +19,7 @@ WorkletGroupEffect::WorkletGroupEffect( } } -void WorkletGroupEffect::Trace(Visitor* visitor) { +void WorkletGroupEffect::Trace(Visitor* visitor) const { visitor->Trace(effects_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h index 1158288db5c..11aaa3d8c9d 100644 --- a/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h +++ b/chromium/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.h @@ -23,7 +23,7 @@ class MODULES_EXPORT WorkletGroupEffect : public ScriptWrappable { const HeapVector<Member<WorkletAnimationEffect>>& getChildren() { return effects_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: HeapVector<Member<WorkletAnimationEffect>> effects_; diff --git a/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc b/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc index 7c0e460bf83..220daf7163f 100644 --- a/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc +++ b/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.cc @@ -128,7 +128,7 @@ void BeforeInstallPromptEvent::BannerDismissed() { user_choice_->Resolve(result); } -void BeforeInstallPromptEvent::Trace(Visitor* visitor) { +void BeforeInstallPromptEvent::Trace(Visitor* visitor) const { visitor->Trace(banner_service_remote_); visitor->Trace(receiver_); visitor->Trace(user_choice_); diff --git a/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.h b/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.h index 8af0f30b404..9c890fb83e8 100644 --- a/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.h +++ b/chromium/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.h @@ -75,7 +75,7 @@ class BeforeInstallPromptEvent final // ScriptWrappable bool HasPendingActivity() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // mojom::blink::AppBannerEvent methods: diff --git a/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc b/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc index 79dbf40fa17..4b63698626c 100644 --- a/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc +++ b/chromium/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.cc @@ -57,7 +57,7 @@ class SetSinkIdResolver : public ScriptPromiseResolver { ~SetSinkIdResolver() override = default; void StartAsync(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void DoSetSinkId(); @@ -145,7 +145,7 @@ void SetSinkIdResolver::OnSetSinkIdComplete( Resolve(); } -void SetSinkIdResolver::Trace(Visitor* visitor) { +void SetSinkIdResolver::Trace(Visitor* visitor) const { visitor->Trace(element_); ScriptPromiseResolver::Trace(visitor); } @@ -194,7 +194,7 @@ HTMLMediaElementAudioOutputDevice& HTMLMediaElementAudioOutputDevice::From( return *supplement; } -void HTMLMediaElementAudioOutputDevice::Trace(Visitor* visitor) { +void HTMLMediaElementAudioOutputDevice::Trace(Visitor* visitor) const { Supplement<HTMLMediaElement>::Trace(visitor); } 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 22f7bfb8aa7..a9a6f5659ec 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 @@ -27,7 +27,7 @@ class MODULES_EXPORT HTMLMediaElementAudioOutputDevice final HTMLMediaElementAudioOutputDevice(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; static String sinkId(HTMLMediaElement&); static ScriptPromise setSinkId(ScriptState*, HTMLMediaElement&, diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc index 8588f047706..4cbe284a7f4 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc @@ -42,7 +42,7 @@ BackgroundFetchBridge::BackgroundFetchBridge( BackgroundFetchBridge::~BackgroundFetchBridge() = default; -void BackgroundFetchBridge::Trace(Visitor* visitor) { +void BackgroundFetchBridge::Trace(Visitor* visitor) const { visitor->Trace(background_fetch_service_); Supplement::Trace(visitor); } 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 76a75654405..3ddc8596655 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 @@ -44,7 +44,7 @@ class BackgroundFetchBridge final explicit BackgroundFetchBridge(ServiceWorkerRegistration& registration); virtual ~BackgroundFetchBridge(); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // Creates a new Background Fetch registration identified by |developer_id| // for the sequence of |requests|. The |callback| will be invoked when the diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.cc index e35a0cea225..e8d2cabfd97 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.cc +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_event.cc @@ -27,7 +27,7 @@ const AtomicString& BackgroundFetchEvent::InterfaceName() const { return event_interface_names::kBackgroundFetchEvent; } -void BackgroundFetchEvent::Trace(Visitor* visitor) { +void BackgroundFetchEvent::Trace(Visitor* visitor) const { visitor->Trace(registration_); ExtendableEvent::Trace(visitor); } 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 40897e54024..5511bf93771 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 @@ -47,7 +47,7 @@ class MODULES_EXPORT BackgroundFetchEvent : public ExtendableEvent { // ExtendableEvent interface. const AtomicString& InterfaceName() const override; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; protected: // Corresponds to the 'registration' attribute in the idl. diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc index cfa4a24909e..7dae06a6350 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.cc @@ -126,7 +126,7 @@ void BackgroundFetchIconLoader::DidGetIcon(SkBitmap icon, double resize_scale) { std::move(icon_callback_).Run(icon, ideal_to_chosen_icon_size_times_hundred); } -void BackgroundFetchIconLoader::Trace(Visitor* visitor) { +void BackgroundFetchIconLoader::Trace(Visitor* visitor) const { visitor->Trace(icons_); visitor->Trace(threaded_icon_loader_); } 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 fa78b04eb76..af9b7c00ad5 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 @@ -36,7 +36,7 @@ class MODULES_EXPORT BackgroundFetchIconLoader final // be run. void Stop(); - void Trace(Visitor* visitor); + void Trace(Visitor* visitor) const; private: friend class BackgroundFetchIconLoaderTest; diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc index ac1bed834e1..2bd8ae92fbb 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader_test.cc @@ -43,7 +43,7 @@ class BackgroundFetchIconLoaderTest : public PageTestBase { : loader_(MakeGarbageCollected<BackgroundFetchIconLoader>()) {} ~BackgroundFetchIconLoaderTest() override { loader_->Stop(); - platform_->GetURLLoaderMockFactory() + WebURLLoaderMockFactory::GetSingletonInstance() ->UnregisterAllURLsAndClearMemoryCache(); } @@ -134,7 +134,7 @@ TEST_F(BackgroundFetchIconLoaderTest, SuccessTest) { LoadIcon(KURL(kBackgroundFetchImageLoaderIcon500x500FullPath), maximum_size, run_loop.QuitClosure()); - platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests(); + WebURLLoaderMockFactory::GetSingletonInstance()->ServeAsynchronousRequests(); run_loop.Run(); @@ -194,7 +194,7 @@ TEST_F(BackgroundFetchIconLoaderTest, EmptySizes) { LoadIcon(KURL(kBackgroundFetchImageLoaderIcon500x500FullPath), maximum_size, run_loop.QuitClosure(), "", "ANY"); - platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests(); + WebURLLoaderMockFactory::GetSingletonInstance()->ServeAsynchronousRequests(); run_loop.Run(); @@ -209,7 +209,7 @@ TEST_F(BackgroundFetchIconLoaderTest, EmptyPurpose) { LoadIcon(KURL(kBackgroundFetchImageLoaderIcon500x500FullPath), maximum_size, run_loop.QuitClosure(), "500X500", ""); - platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests(); + WebURLLoaderMockFactory::GetSingletonInstance()->ServeAsynchronousRequests(); run_loop.Run(); 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 474808db4cd..4166fe0a269 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 @@ -68,7 +68,8 @@ ScriptPromise RejectWithTypeError(ScriptState* script_state, bool ShouldBlockDueToCSP(ExecutionContext* execution_context, const KURL& request_url) { return !execution_context->GetContentSecurityPolicyForWorld() - ->AllowConnectToSource(request_url); + ->AllowConnectToSource(request_url, request_url, + RedirectStatus::kNoRedirect); } bool ShouldBlockPort(const KURL& request_url) { @@ -132,16 +133,11 @@ scoped_refptr<BlobDataHandle> ExtractBlobHandle( ExceptionState& exception_state) { DCHECK(request); - if (request->IsBodyLocked(exception_state) == Body::BodyLocked::kLocked || - request->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) { - DCHECK(!exception_state.HadException()); + if (request->IsBodyLocked() || request->IsBodyUsed()) { exception_state.ThrowTypeError("Request body is already used"); return nullptr; } - if (exception_state.HadException()) - return nullptr; - BodyStreamBuffer* buffer = request->BodyBuffer(); if (!buffer) return nullptr; @@ -559,7 +555,7 @@ void BackgroundFetchManager::DidGetDeveloperIds( NOTREACHED(); } -void BackgroundFetchManager::Trace(Visitor* visitor) { +void BackgroundFetchManager::Trace(Visitor* visitor) const { visitor->Trace(registration_); visitor->Trace(bridge_); visitor->Trace(loaders_); diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h index 792de6c5d9b..6940471261e 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h @@ -52,7 +52,7 @@ class MODULES_EXPORT BackgroundFetchManager final ExceptionState& exception_state); ScriptPromise getIds(ScriptState* script_state); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // ExecutionContextLifecycleObserver interface void ContextDestroyed() override; diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc index 2b90ccf72dd..d1389a8337f 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.cc @@ -103,7 +103,7 @@ const KURL& BackgroundFetchRecord::ObservedUrl() const { return request_->url(); } -void BackgroundFetchRecord::Trace(Visitor* visitor) { +void BackgroundFetchRecord::Trace(Visitor* visitor) const { visitor->Trace(request_); visitor->Trace(response_ready_property_); visitor->Trace(script_state_); diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h index 8465caa13da..d7c7dce2e35 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_record.h @@ -48,7 +48,7 @@ class MODULES_EXPORT BackgroundFetchRecord final : public ScriptWrappable { void SetResponseAndUpdateState(mojom::blink::FetchAPIResponsePtr& response); bool IsRecordPending(); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; void OnRequestCompleted(mojom::blink::FetchAPIResponsePtr response); const KURL& ObservedUrl() const; 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 e60ad86745d..1ebb4701dcc 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 @@ -233,7 +233,7 @@ void BackgroundFetchRegistration::DidGetMatchingRequests( for (auto& fetch : settled_fetches) { Request* request = - Request::Create(script_state, *(fetch->request), + Request::Create(script_state, std::move(fetch->request), Request::ForServiceWorkerFetchEvent::kFalse); auto* record = MakeGarbageCollected<BackgroundFetchRecord>(request, script_state); @@ -354,10 +354,6 @@ const String BackgroundFetchRegistration::failureReason() const { NOTREACHED(); } -void BackgroundFetchRegistration::Dispose() { - observer_receiver_.reset(); -} - bool BackgroundFetchRegistration::HasPendingActivity() const { if (!GetExecutionContext()) return false; @@ -376,7 +372,7 @@ void BackgroundFetchRegistration::UpdateUI( registration_service_->UpdateUI(in_title, in_icon, std::move(callback)); } -void BackgroundFetchRegistration::Trace(Visitor* visitor) { +void BackgroundFetchRegistration::Trace(Visitor* visitor) const { visitor->Trace(registration_); visitor->Trace(observers_); visitor->Trace(observer_receiver_); diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h index afb312e8727..333436babcb 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h @@ -34,7 +34,6 @@ class BackgroundFetchRegistration final public ActiveScriptWrappable<BackgroundFetchRegistration>, public blink::mojom::blink::BackgroundFetchRegistrationObserver { DEFINE_WRAPPERTYPEINFO(); - USING_PRE_FINALIZER(BackgroundFetchRegistration, Dispose); USING_GARBAGE_COLLECTED_MIXIN(BackgroundFetchRegistration); public: @@ -88,9 +87,7 @@ class BackgroundFetchRegistration final const AtomicString& InterfaceName() const override; ExecutionContext* GetExecutionContext() const override; - void Dispose(); - - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // Keeps the object alive until there are non-zero number of |observers_|. bool HasPendingActivity() const final; diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc index 3233b0c57a4..91f9dc38fa6 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc +++ b/chromium/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.cc @@ -38,7 +38,7 @@ BackgroundFetchUpdateUIEvent::BackgroundFetchUpdateUIEvent( BackgroundFetchUpdateUIEvent::~BackgroundFetchUpdateUIEvent() = default; -void BackgroundFetchUpdateUIEvent::Trace(Visitor* visitor) { +void BackgroundFetchUpdateUIEvent::Trace(Visitor* visitor) const { visitor->Trace(service_worker_registration_); visitor->Trace(loader_); BackgroundFetchEvent::Trace(visitor); 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 88f5b3e1d82..30b4ef32773 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 @@ -57,7 +57,7 @@ class MODULES_EXPORT BackgroundFetchUpdateUIEvent final const BackgroundFetchUIOptions* ui_options, ExceptionState&); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: void DidGetIcon(ScriptPromiseResolver* resolver, diff --git a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.cc b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.cc index d09a081ffdc..66c4f6208b2 100644 --- a/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.cc +++ b/chromium/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.cc @@ -53,7 +53,7 @@ ServiceWorkerRegistrationBackgroundFetch::backgroundFetch() { return background_fetch_manager_.Get(); } -void ServiceWorkerRegistrationBackgroundFetch::Trace(Visitor* visitor) { +void ServiceWorkerRegistrationBackgroundFetch::Trace(Visitor* visitor) const { visitor->Trace(registration_); visitor->Trace(background_fetch_manager_); Supplement<ServiceWorkerRegistration>::Trace(visitor); 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 157ad997312..92e7ca9a395 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 @@ -34,7 +34,7 @@ class ServiceWorkerRegistrationBackgroundFetch final ServiceWorkerRegistration& registration); BackgroundFetchManager* backgroundFetch(); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<ServiceWorkerRegistration> registration_; diff --git a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.cc b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.cc index b3b437634bb..72e05f1cf65 100644 --- a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.cc +++ b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.cc @@ -186,7 +186,7 @@ void PeriodicSyncManager::UnregisterCallback( } } -void PeriodicSyncManager::Trace(Visitor* visitor) { +void PeriodicSyncManager::Trace(Visitor* visitor) const { visitor->Trace(registration_); visitor->Trace(background_sync_service_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.h b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.h index 0b7111a3ee3..303ea5b9d21 100644 --- a/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.h +++ b/chromium/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.h @@ -37,7 +37,7 @@ class PeriodicSyncManager final : public ScriptWrappable { ScriptPromise getTags(ScriptState* script_state); ScriptPromise unregister(ScriptState* script_state, const String& tag); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: // Returns an initialized diff --git a/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.cc b/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.cc index 33197156d73..0e3ead92c9d 100644 --- a/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.cc +++ b/chromium/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.cc @@ -65,7 +65,7 @@ PeriodicSyncManager* ServiceWorkerRegistrationSync::periodicSync() { return periodic_sync_manager_.Get(); } -void ServiceWorkerRegistrationSync::Trace(Visitor* visitor) { +void ServiceWorkerRegistrationSync::Trace(Visitor* visitor) const { visitor->Trace(registration_); visitor->Trace(sync_manager_); visitor->Trace(periodic_sync_manager_); 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 71bb2aefcae..78744859f76 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 @@ -38,7 +38,7 @@ class ServiceWorkerRegistrationSync final PeriodicSyncManager* periodicSync(); SyncManager* sync(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<ServiceWorkerRegistration> registration_; diff --git a/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.cc b/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.cc index 0be6cd5c90b..9011c23011b 100644 --- a/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.cc +++ b/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.cc @@ -144,7 +144,7 @@ void SyncManager::GetRegistrationsCallback( } } -void SyncManager::Trace(Visitor* visitor) { +void SyncManager::Trace(Visitor* visitor) const { visitor->Trace(registration_); visitor->Trace(background_sync_service_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.h b/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.h index d356b506079..3f7cf4a00e5 100644 --- a/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.h +++ b/chromium/third_party/blink/renderer/modules/background_sync/sync_manager.h @@ -32,7 +32,7 @@ class SyncManager final : public ScriptWrappable { ExceptionState& exception_state); ScriptPromise getTags(ScriptState*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; enum { kUnregisteredSyncID = -1 }; diff --git a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc index fe45efcad80..78fdac27d92 100644 --- a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc +++ b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.cc @@ -70,7 +70,7 @@ ScriptPromise NavigatorBadge::clearAppBadge(ScriptState* script_state, return ClearAppBadgeHelper(script_state); } -void NavigatorBadge::Trace(Visitor* visitor) { +void NavigatorBadge::Trace(Visitor* visitor) const { Supplement<ExecutionContext>::Trace(visitor); visitor->Trace(context_); diff --git a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h index ed2c5359126..b0ea834ead2 100644 --- a/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h +++ b/chromium/third_party/blink/renderer/modules/badging/navigator_badge.h @@ -38,7 +38,7 @@ class NavigatorBadge final : public GarbageCollected<NavigatorBadge>, static ScriptPromise clearAppBadge(ScriptState*, Navigator&); static ScriptPromise clearAppBadge(ScriptState*, WorkerNavigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: static ScriptPromise SetAppBadgeHelper( 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 72a894be8a4..8879afab544 100644 --- a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc +++ b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.cc @@ -22,7 +22,7 @@ BatteryDispatcher& BatteryDispatcher::Instance() { BatteryDispatcher::BatteryDispatcher() : monitor_(nullptr), has_latest_data_(false) {} -void BatteryDispatcher::Trace(Visitor* visitor) { +void BatteryDispatcher::Trace(Visitor* visitor) const { visitor->Trace(monitor_); PlatformEventDispatcher::Trace(visitor); } 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 2c8f740e689..905a8604c29 100644 --- a/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.h +++ b/chromium/third_party/blink/renderer/modules/battery/battery_dispatcher.h @@ -29,7 +29,7 @@ class MODULES_EXPORT BatteryDispatcher final return has_latest_data_ ? &battery_status_ : nullptr; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void QueryNextStatus(); diff --git a/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc b/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc index 4c85ef6988f..b929f2cccff 100644 --- a/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc +++ b/chromium/third_party/blink/renderer/modules/battery/battery_manager.cc @@ -124,7 +124,7 @@ bool BatteryManager::HasPendingActivity() const { battery_property_->GetState() == BatteryProperty::kPending); } -void BatteryManager::Trace(Visitor* visitor) { +void BatteryManager::Trace(Visitor* visitor) const { visitor->Trace(battery_property_); PlatformEventController::Trace(visitor); EventTargetWithInlineData::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/battery/battery_manager.h b/chromium/third_party/blink/renderer/modules/battery/battery_manager.h index 762d35bbabe..7b2dd65ce7f 100644 --- a/chromium/third_party/blink/renderer/modules/battery/battery_manager.h +++ b/chromium/third_party/blink/renderer/modules/battery/battery_manager.h @@ -63,7 +63,7 @@ class BatteryManager final : public EventTargetWithInlineData, // ScriptWrappable implementation. bool HasPendingActivity() const final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: using BatteryProperty = diff --git a/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc b/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc index f6e060be625..e0985db82e9 100644 --- a/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc +++ b/chromium/third_party/blink/renderer/modules/battery/navigator_battery.cc @@ -55,7 +55,7 @@ NavigatorBattery& NavigatorBattery::From(Navigator& navigator) { return *supplement; } -void NavigatorBattery::Trace(Visitor* visitor) { +void NavigatorBattery::Trace(Visitor* visitor) const { visitor->Trace(battery_manager_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/battery/navigator_battery.h b/chromium/third_party/blink/renderer/modules/battery/navigator_battery.h index 5c62931ddb3..dd09e544833 100644 --- a/chromium/third_party/blink/renderer/modules/battery/navigator_battery.h +++ b/chromium/third_party/blink/renderer/modules/battery/navigator_battery.h @@ -29,7 +29,7 @@ class NavigatorBattery final : public GarbageCollected<NavigatorBattery>, explicit NavigatorBattery(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<BatteryManager> battery_manager_; diff --git a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.cc b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.cc index e0457407518..2ab13087a0f 100644 --- a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.cc +++ b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.cc @@ -26,7 +26,7 @@ NavigatorBeacon::NavigatorBeacon(Navigator& navigator) NavigatorBeacon::~NavigatorBeacon() = default; -void NavigatorBeacon::Trace(Visitor* visitor) { +void NavigatorBeacon::Trace(Visitor* visitor) const { Supplement<Navigator>::Trace(visitor); } 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 a21178f7180..9ebb996bafa 100644 --- a/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h +++ b/chromium/third_party/blink/renderer/modules/beacon/navigator_beacon.h @@ -35,7 +35,7 @@ class NavigatorBeacon final : public GarbageCollected<NavigatorBeacon>, const ArrayBufferViewOrBlobOrStringOrFormDataOrReadableStream&, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: bool SendBeaconImpl( diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc index c9928a23e62..660edb8acc3 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.cc @@ -25,7 +25,6 @@ #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/core/inspector/console_message.h" -#include "third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth_device.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth_error.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.h" @@ -165,14 +164,13 @@ static void ConvertRequestDeviceOptions( ScriptPromise Bluetooth::getAvailability(ScriptState* script_state, ExceptionState& exception_state) { - ExecutionContext* context = GetExecutionContext(); - if (!context || context->IsContextDestroyed()) { + if (window_->IsContextDestroyed()) { exception_state.ThrowTypeError(kInactiveDocumentError); return ScriptPromise(); } - CHECK(context->IsSecureContext()); - EnsureServiceConnection(context); + CHECK(window_->IsSecureContext()); + EnsureServiceConnection(window_); // Subsequent steps are handled in the browser process. auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); @@ -221,16 +219,15 @@ void Bluetooth::RequestDeviceCallback( ScriptPromise Bluetooth::getDevices(ScriptState* script_state, ExceptionState& exception_state) { - ExecutionContext* context = GetExecutionContext(); - if (!context) { + if (window_->IsContextDestroyed()) { exception_state.ThrowTypeError(kInactiveDocumentError); return ScriptPromise(); } - AddUnsupportedPlatformConsoleMessage(context); - CHECK(context->IsSecureContext()); + AddUnsupportedPlatformConsoleMessage(window_); + CHECK(window_->IsSecureContext()); - EnsureServiceConnection(context); + EnsureServiceConnection(window_); auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); @@ -244,29 +241,24 @@ ScriptPromise Bluetooth::getDevices(ScriptState* script_state, ScriptPromise Bluetooth::requestDevice(ScriptState* script_state, const RequestDeviceOptions* options, ExceptionState& exception_state) { - ExecutionContext* context = GetExecutionContext(); - if (!context) { + if (window_->IsContextDestroyed()) { exception_state.ThrowTypeError(kInactiveDocumentError); return ScriptPromise(); } - AddUnsupportedPlatformConsoleMessage(context); - CHECK(context->IsSecureContext()); + AddUnsupportedPlatformConsoleMessage(window_); + CHECK(window_->IsSecureContext()); // If the algorithm is not allowed to show a popup, reject promise with a // SecurityError and abort these steps. - auto* frame = To<LocalDOMWindow>(context)->GetFrame(); - if (!frame) { - exception_state.ThrowTypeError(kInactiveDocumentError); - return ScriptPromise(); - } - + auto* frame = window_->GetFrame(); + DCHECK(frame); if (!LocalFrame::HasTransientUserActivation(frame)) { exception_state.ThrowSecurityError(kHandleGestureForPermissionRequest); return ScriptPromise(); } - EnsureServiceConnection(context); + EnsureServiceConnection(window_); // In order to convert the arguments from service names and aliases to just // UUIDs, do the following substeps: @@ -347,37 +339,33 @@ void Bluetooth::RequestScanningCallback( ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state, const BluetoothLEScanOptions* options, ExceptionState& exception_state) { - ExecutionContext* context = GetExecutionContext(); - if (!context) { + if (window_->IsContextDestroyed()) { exception_state.ThrowTypeError(kInactiveDocumentError); return ScriptPromise(); } // Remind developers when they are using Web Bluetooth on unsupported // platforms. - context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + window_->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( mojom::ConsoleMessageSource::kJavaScript, mojom::ConsoleMessageLevel::kInfo, "Web Bluetooth Scanning is experimental on this platform. See " "https://github.com/WebBluetoothCG/web-bluetooth/blob/gh-pages/" "implementation-status.md")); - CHECK(context->IsSecureContext()); + CHECK(window_->IsSecureContext()); // If the algorithm is not allowed to show a popup, reject promise with a // SecurityError and abort these steps. - auto* frame = To<LocalDOMWindow>(context)->GetFrame(); - if (!frame) { - exception_state.ThrowTypeError(kInactiveDocumentError); - return ScriptPromise(); - } - + auto* frame = window_->GetFrame(); + // If !window_->IsContextDestroyed() then GetFrame() should be valid. + DCHECK(frame); if (!LocalFrame::HasTransientUserActivation(frame)) { exception_state.ThrowSecurityError(kHandleGestureForPermissionRequest); return ScriptPromise(); } - EnsureServiceConnection(context); + EnsureServiceConnection(window_); auto scan_options = mojom::blink::WebBluetoothRequestLEScanOptions::New(); ConvertRequestLEScanOptions(options, scan_options, exception_state); @@ -394,7 +382,7 @@ ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state, // See https://bit.ly/2S0zRAS for task types. mojo::ReceiverId id = client_receivers_.Add(client.InitWithNewEndpointAndPassReceiver(), - context->GetTaskRunner(TaskType::kMiscPlatformAPI)); + window_->GetTaskRunner(TaskType::kMiscPlatformAPI)); auto scan_options_copy = scan_options->Clone(); service_->RequestScanningStart( @@ -407,41 +395,11 @@ ScriptPromise Bluetooth::requestLEScan(ScriptState* script_state, void Bluetooth::AdvertisingEvent( mojom::blink::WebBluetoothAdvertisingEventPtr advertising_event) { - ExecutionContext* context = - ExecutionContextLifecycleObserver::GetExecutionContext(); - DCHECK(context); - - BluetoothDevice* bluetooth_device = GetBluetoothDeviceRepresentingDevice( - std::move(advertising_event->device), context); - - HeapVector<blink::StringOrUnsignedLong> uuids; - for (const String& uuid : advertising_event->uuids) { - StringOrUnsignedLong value; - value.SetString(uuid); - uuids.push_back(value); - } - - auto* manufacturer_data = MakeGarbageCollected<BluetoothManufacturerDataMap>( - advertising_event->manufacturer_data); - auto* service_data = MakeGarbageCollected<BluetoothServiceDataMap>( - advertising_event->service_data); - - base::Optional<int8_t> rssi; - if (advertising_event->rssi_is_set) - rssi = advertising_event->rssi; - - base::Optional<int8_t> tx_power; - if (advertising_event->tx_power_is_set) - tx_power = advertising_event->tx_power; - - base::Optional<uint16_t> appearance; - if (advertising_event->appearance_is_set) - appearance = advertising_event->appearance; - auto* event = MakeGarbageCollected<BluetoothAdvertisingEvent>( - event_type_names::kAdvertisementreceived, bluetooth_device, - advertising_event->name, uuids, appearance, tx_power, rssi, - manufacturer_data, service_data); + event_type_names::kAdvertisementreceived, + GetBluetoothDeviceRepresentingDevice(std::move(advertising_event->device), + window_), + std::move(advertising_event)); DispatchEvent(*event); } @@ -462,24 +420,23 @@ const WTF::AtomicString& Bluetooth::InterfaceName() const { } ExecutionContext* Bluetooth::GetExecutionContext() const { - return ExecutionContextLifecycleObserver::GetExecutionContext(); + return window_; } -void Bluetooth::Trace(Visitor* visitor) { +void Bluetooth::Trace(Visitor* visitor) const { visitor->Trace(device_instance_map_); + visitor->Trace(window_); visitor->Trace(client_receivers_); visitor->Trace(service_); EventTargetWithInlineData::Trace(visitor); - ExecutionContextLifecycleObserver::Trace(visitor); PageVisibilityObserver::Trace(visitor); } -Bluetooth::Bluetooth(ExecutionContext* context) - : ExecutionContextLifecycleObserver(context), - PageVisibilityObserver( - To<LocalDOMWindow>(context)->GetFrame()->GetPage()), - client_receivers_(this, context), - service_(context) {} +Bluetooth::Bluetooth(LocalDOMWindow* dom_window) + : PageVisibilityObserver(dom_window->GetFrame()->GetPage()), + window_(dom_window), + client_receivers_(this, dom_window), + service_(dom_window) {} Bluetooth::~Bluetooth() { DCHECK(client_receivers_.empty()); diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h index 4bae823dd77..2ab1e712b9a 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.h @@ -8,6 +8,7 @@ #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_advertising_event.h" #include "third_party/blink/renderer/modules/bluetooth/bluetooth_device.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -24,14 +25,13 @@ class ScriptPromise; class ScriptState; class Bluetooth final : public EventTargetWithInlineData, - public ExecutionContextLifecycleObserver, public PageVisibilityObserver, public mojom::blink::WebBluetoothAdvertisementClient { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(Bluetooth); public: - explicit Bluetooth(ExecutionContext*); + explicit Bluetooth(LocalDOMWindow*); ~Bluetooth() override; // IDL exposed interface: @@ -55,10 +55,7 @@ class Bluetooth final : public EventTargetWithInlineData, ExecutionContext* GetExecutionContext() const override; // GC - void Trace(Visitor*) override; - - // ExecutionContextLifecycleObserver - void ContextDestroyed() override {} + void Trace(Visitor*) const override; DEFINE_ATTRIBUTE_EVENT_LISTENER(advertisementreceived, kAdvertisementreceived) @@ -68,6 +65,9 @@ class Bluetooth final : public EventTargetWithInlineData, void CancelScan(mojo::ReceiverId); bool IsScanActive(mojo::ReceiverId) const; + BluetoothAdvertisingEvent* CreateBluetoothAdvertisingEvent( + mojom::blink::WebBluetoothAdvertisingEventPtr advertising_event); + private: BluetoothDevice* GetBluetoothDeviceRepresentingDevice( mojom::blink::WebBluetoothDevicePtr, @@ -93,12 +93,14 @@ class Bluetooth final : public EventTargetWithInlineData, // Bluetooth device inside a single global object. HeapHashMap<String, Member<BluetoothDevice>> device_instance_map_; + Member<LocalDOMWindow> window_; + HeapMojoAssociatedReceiverSet<mojom::blink::WebBluetoothAdvertisementClient, Bluetooth> client_receivers_; HeapMojoRemote<mojom::blink::WebBluetoothService, - HeapMojoWrapperMode::kWithoutContextObserver> + HeapMojoWrapperMode::kForceWithoutContextObserver> service_; }; diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl index 21b29c9b24e..1dbb1ff2c1c 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth.idl @@ -10,7 +10,7 @@ SecureContext ] interface Bluetooth : EventTarget { [CallWith=ScriptState, RaisesException] Promise<boolean> getAvailability(); - [RuntimeEnabled=WebBluetoothGetDevices, CallWith=ScriptState, RaisesException] Promise<sequence<BluetoothDevice>> getDevices(); + [RuntimeEnabled=WebBluetoothGetDevices, CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothGetDevices] Promise<sequence<BluetoothDevice>> getDevices(); [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRequestDevice] Promise<BluetoothDevice> requestDevice (optional RequestDeviceOptions options = {}); // https://webbluetoothcg.github.io/web-bluetooth/scanning.html#scanning diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc index 11449f590ab..e26586d55af 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h" + #include "third_party/blink/renderer/bindings/modules/v8/string_or_unsigned_long.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_bluetooth_advertising_event_init.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -29,26 +30,27 @@ BluetoothAdvertisingEvent::BluetoothAdvertisingEvent( BluetoothAdvertisingEvent::BluetoothAdvertisingEvent( const AtomicString& event_type, BluetoothDevice* device, - const String& name, - const HeapVector<StringOrUnsignedLong>& uuids, - base::Optional<uint16_t> appearance, - base::Optional<int8_t> txPower, - base::Optional<int8_t> rssi, - BluetoothManufacturerDataMap* manufacturerData, - BluetoothServiceDataMap* serviceData) + mojom::blink::WebBluetoothAdvertisingEventPtr advertising_event) : Event(event_type, Bubbles::kYes, Cancelable::kYes), device_(std::move(device)), - name_(name), - uuids_(uuids), - appearance_(appearance), - txPower_(txPower), - rssi_(rssi), - manufacturer_data_map_(manufacturerData), - service_data_map_(serviceData) {} + name_(advertising_event->name), + appearance_(advertising_event->appearance), + txPower_(advertising_event->tx_power), + rssi_(advertising_event->rssi), + manufacturer_data_map_(MakeGarbageCollected<BluetoothManufacturerDataMap>( + advertising_event->manufacturer_data)), + service_data_map_(MakeGarbageCollected<BluetoothServiceDataMap>( + advertising_event->service_data)) { + for (const String& uuid : advertising_event->uuids) { + StringOrUnsignedLong value; + value.SetString(uuid); + uuids_.push_back(value); + } +} // namespace blink BluetoothAdvertisingEvent::~BluetoothAdvertisingEvent() {} -void BluetoothAdvertisingEvent::Trace(Visitor* visitor) { +void BluetoothAdvertisingEvent::Trace(Visitor* visitor) const { visitor->Trace(device_); visitor->Trace(uuids_); visitor->Trace(manufacturer_data_map_); diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h index 0db9741d2fb..1e437abfaac 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_ADVERTISING_EVENT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_ADVERTISING_EVENT_H_ +#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink-forward.h" #include "third_party/blink/renderer/core/dom/events/event.h" namespace blink { @@ -22,19 +23,14 @@ class BluetoothAdvertisingEvent final : public Event { BluetoothAdvertisingEvent(const AtomicString& event_type, const BluetoothAdvertisingEventInit* initializer); - BluetoothAdvertisingEvent(const AtomicString& event_type, - BluetoothDevice* device, - const String& name, - const HeapVector<StringOrUnsignedLong>& uuids, - base::Optional<uint16_t> appearance, - base::Optional<int8_t> txPower, - base::Optional<int8_t> rssi, - BluetoothManufacturerDataMap* manufacturer_data_map, - BluetoothServiceDataMap* service_data_map); + BluetoothAdvertisingEvent( + const AtomicString& event_type, + BluetoothDevice* device, + mojom::blink::WebBluetoothAdvertisingEventPtr advertising_event); ~BluetoothAdvertisingEvent() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const AtomicString& InterfaceName() const override; diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc index cc83c5b9c8e..d36fc786ce3 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.cc @@ -91,7 +91,7 @@ void BluetoothAttributeInstanceMap::Clear() { descriptor_id_to_object_.clear(); } -void BluetoothAttributeInstanceMap::Trace(Visitor* visitor) { +void BluetoothAttributeInstanceMap::Trace(Visitor* visitor) const { visitor->Trace(device_); visitor->Trace(service_id_to_object_); visitor->Trace(characteristic_id_to_object_); diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h index eb7a4eaab67..604e9e257db 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h @@ -68,7 +68,7 @@ class BluetoothAttributeInstanceMap final // TODO(crbug.com/654950): Remove descriptors when implemented. void Clear(); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; private: // BluetoothDevice that owns this map. diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc index 33c715ce3d6..daa05e73043 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.cc @@ -10,6 +10,9 @@ #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" +#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_watch_advertisements_options.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/dom/events/event.h" #include "third_party/blink/renderer/core/frame/web_feature.h" @@ -21,6 +24,11 @@ namespace blink { +const char kAbortErrorMessage[] = "The Bluetooth operation was cancelled."; +const char kInactiveDocumentError[] = "Document not active"; +const char kInvalidStateErrorMessage[] = + "Pending watch advertisements operation."; + BluetoothDevice::BluetoothDevice(ExecutionContext* context, mojom::blink::WebBluetoothDevicePtr device, Bluetooth* bluetooth) @@ -29,7 +37,8 @@ BluetoothDevice::BluetoothDevice(ExecutionContext* context, MakeGarbageCollected<BluetoothAttributeInstanceMap>(this)), device_(std::move(device)), gatt_(MakeGarbageCollected<BluetoothRemoteGATTServer>(context, this)), - bluetooth_(bluetooth) {} + bluetooth_(bluetooth), + client_receiver_(this, context) {} BluetoothRemoteGATTService* BluetoothDevice::GetOrCreateRemoteGATTService( mojom::blink::WebBluetoothRemoteGATTServicePtr service, @@ -84,14 +93,116 @@ ExecutionContext* BluetoothDevice::GetExecutionContext() const { return ExecutionContextClient::GetExecutionContext(); } -void BluetoothDevice::Trace(Visitor* visitor) { +void BluetoothDevice::Trace(Visitor* visitor) const { visitor->Trace(attribute_instance_map_); visitor->Trace(gatt_); visitor->Trace(bluetooth_); + visitor->Trace(watch_advertisements_resolver_); + visitor->Trace(client_receiver_); EventTargetWithInlineData::Trace(visitor); ExecutionContextClient::Trace(visitor); } +// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements +ScriptPromise BluetoothDevice::watchAdvertisements( + ScriptState* script_state, + const WatchAdvertisementsOptions* options, + ExceptionState& exception_state) { + ExecutionContext* context = GetExecutionContext(); + if (!context) { + exception_state.ThrowTypeError(kInactiveDocumentError); + return ScriptPromise(); + } + + CHECK(context->IsSecureContext()); + + // 1. If options.signal is present, perform the following sub-steps: + if (options->hasSignal()) { + // 1.1. If options.signal’s aborted flag is set, then abort + // watchAdvertisements with this and abort these steps. + if (options->signal()->aborted()) { + AbortWatchAdvertisements(); + exception_state.ThrowDOMException(DOMExceptionCode::kAbortError, + kAbortErrorMessage); + return ScriptPromise(); + } + + // 1.2. Add the following abort steps to options.signal: + // 1.2.1. Abort watchAdvertisements with this. + // 1.2.2. Reject promise with AbortError. + options->signal()->AddAlgorithm(WTF::Bind( + &BluetoothDevice::AbortWatchAdvertisements, WrapPersistent(this))); + } + + // 2. If this.[[watchAdvertisementsState]] is 'pending-watch': + if (client_receiver_.is_bound() && watch_advertisements_resolver_) { + // 'pending-watch' 2.1. Reject promise with InvalidStateError. + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + kInvalidStateErrorMessage); + return ScriptPromise(); + } + + // 2. If this.[[watchAdvertisementsState]] is 'watching': + // 'watching' 2.1. Resolve promise with undefined. + if (client_receiver_.is_bound() && !watch_advertisements_resolver_) + return ScriptPromise::CastUndefined(script_state); + + // 2. If this.[[watchAdvertisementsState]] is 'not-watching': + DCHECK(!client_receiver_.is_bound()); + + // 'not-watching' 2.1. Set this.[[watchAdvertisementsState]] to + // 'pending-watch'. + watch_advertisements_resolver_ = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + mojo::PendingAssociatedRemote<mojom::blink::WebBluetoothAdvertisementClient> + client; + client_receiver_.Bind(client.InitWithNewEndpointAndPassReceiver(), + context->GetTaskRunner(TaskType::kMiscPlatformAPI)); + + // 'not-watching' 2.2.1. Ensure that the UA is scanning for this device’s + // advertisements. The UA SHOULD NOT filter out "duplicate" advertisements for + // the same device. + bluetooth_->Service()->WatchAdvertisementsForDevice( + device_->id, std::move(client), + WTF::Bind(&BluetoothDevice::WatchAdvertisementsCallback, + WrapPersistent(this))); + return watch_advertisements_resolver_->Promise(); +} + +// https://webbluetoothcg.github.io/web-bluetooth/#abort-watchadvertisements +void BluetoothDevice::AbortWatchAdvertisements() { + // 1. Set this.[[watchAdvertisementsState]] to 'not-watching'. + // 2. Set device.watchingAdvertisements to false. + // 3.1. If no more BluetoothDevices in the whole UA have + // watchingAdvertisements set to true, the UA SHOULD stop scanning for + // advertisements. Otherwise, if no more BluetoothDevices representing the + // same device as this have watchingAdvertisements set to true, the UA SHOULD + // reconfigure the scan to avoid receiving reports for this device. + client_receiver_.reset(); + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements + // 1.2.2. Reject promise with AbortError + if (watch_advertisements_resolver_) { + auto* script_state = watch_advertisements_resolver_->GetScriptState(); + watch_advertisements_resolver_->Reject(V8ThrowDOMException::CreateOrEmpty( + script_state->GetIsolate(), DOMExceptionCode::kAbortError, + kAbortErrorMessage)); + watch_advertisements_resolver_.Clear(); + } +} + +void BluetoothDevice::AdvertisingEvent( + mojom::blink::WebBluetoothAdvertisingEventPtr advertising_event) { + auto* event = MakeGarbageCollected<BluetoothAdvertisingEvent>( + event_type_names::kAdvertisementreceived, this, + std::move(advertising_event)); + DispatchEvent(*event); +} + +bool BluetoothDevice::HasPendingActivity() const { + return GetExecutionContext() && HasEventListeners(); +} + void BluetoothDevice::AddedEventListener( const AtomicString& event_type, RegisteredEventListener& registered_listener) { @@ -103,4 +214,37 @@ void BluetoothDevice::AddedEventListener( } } +void BluetoothDevice::WatchAdvertisementsCallback( + mojom::blink::WebBluetoothResult result) { + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements + // 2.2.3. Queue a task to perform the following steps, but abort when + // this.[[watchAdvertisementsState]] becomes not-watching: + if (!watch_advertisements_resolver_) + return; + + if (!watch_advertisements_resolver_->GetExecutionContext() || + watch_advertisements_resolver_->GetExecutionContext() + ->IsContextDestroyed()) { + return; + } + + // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements + // 2.2.2. If the UA fails to enable scanning, queue a task to perform the + // following steps, and abort these steps: + if (result != mojom::blink::WebBluetoothResult::SUCCESS) { + // 2.2.2.1. Set this.[[watchAdvertisementsState]] to 'not-watching'. + client_receiver_.reset(); + + // 2.2.2.2. Reject promise with one of the following errors: + watch_advertisements_resolver_->Reject( + BluetoothError::CreateDOMException(result)); + watch_advertisements_resolver_.Clear(); + return; + } + + // 2.2.3.3. Resolve promise with undefined. + watch_advertisements_resolver_->Resolve(); + watch_advertisements_resolver_.Clear(); +} + } // 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 7744c65b658..36856ef83ef 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.h @@ -6,12 +6,15 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BLUETOOTH_BLUETOOTH_DEVICE_H_ #include <memory> + #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/execution_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" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -22,6 +25,8 @@ class BluetoothRemoteGATTCharacteristic; class BluetoothRemoteGATTDescriptor; class BluetoothRemoteGATTServer; class BluetoothRemoteGATTService; +class ScriptPromiseResolver; +class WatchAdvertisementsOptions; // BluetoothDevice represents a physical bluetooth device in the DOM. See IDL. // @@ -29,8 +34,11 @@ class BluetoothRemoteGATTService; // CallbackPromiseAdapter templatized with this class. See this class's // "Interface required by CallbackPromiseAdapter" section and the // CallbackPromiseAdapter class comments. -class BluetoothDevice final : public EventTargetWithInlineData, - public ExecutionContextClient { +class BluetoothDevice final + : public EventTargetWithInlineData, + public ExecutionContextClient, + public ActiveScriptWrappable<BluetoothDevice>, + public mojom::blink::WebBluetoothAdvertisementClient { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(BluetoothDevice); @@ -76,13 +84,26 @@ class BluetoothDevice final : public EventTargetWithInlineData, Bluetooth* GetBluetooth() { return bluetooth_; } // Interface required by Garbage Collection: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // IDL exposed interface: + ScriptPromise watchAdvertisements(ScriptState*, + const WatchAdvertisementsOptions*, + ExceptionState&); String id() { return device_->id; } String name() { return device_->name; } BluetoothRemoteGATTServer* gatt() { return gatt_; } + bool watchingAdvertisements() { return client_receiver_.is_bound(); } + + void AbortWatchAdvertisements(); + + // WebBluetoothAdvertisementClient: + void AdvertisingEvent(mojom::blink::WebBluetoothAdvertisingEventPtr) override; + + // ActiveScriptWrappable: + bool HasPendingActivity() const override; + DEFINE_ATTRIBUTE_EVENT_LISTENER(advertisementreceived, kAdvertisementreceived) DEFINE_ATTRIBUTE_EVENT_LISTENER(gattserverdisconnected, kGattserverdisconnected) @@ -92,12 +113,20 @@ class BluetoothDevice final : public EventTargetWithInlineData, RegisteredEventListener&) override; private: + void WatchAdvertisementsCallback(mojom::blink::WebBluetoothResult); + // Holds all GATT Attributes associated with this BluetoothDevice. Member<BluetoothAttributeInstanceMap> attribute_instance_map_; mojom::blink::WebBluetoothDevicePtr device_; Member<BluetoothRemoteGATTServer> gatt_; Member<Bluetooth> bluetooth_; + + Member<ScriptPromiseResolver> watch_advertisements_resolver_; + + HeapMojoAssociatedReceiver<mojom::blink::WebBluetoothAdvertisementClient, + BluetoothDevice> + client_receiver_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl index 99c3c3f9bf8..90d71c919a6 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl @@ -5,15 +5,26 @@ // https://webbluetoothcg.github.io/web-bluetooth/#bluetoothdevice [ + ActiveScriptWrappable, Exposed=Window, RuntimeEnabled=WebBluetooth, SecureContext ] interface BluetoothDevice : EventTarget { - readonly attribute DOMString id; - readonly attribute DOMString? name; - readonly attribute BluetoothRemoteGATTServer gatt; + [ + RuntimeEnabled=WebBluetoothWatchAdvertisements, + CallWith=ScriptState, + RaisesException, + MeasureAs=WebBluetoothWatchAdvertisements + ] Promise<void> watchAdvertisements( + optional WatchAdvertisementsOptions options = {}); - attribute EventHandler ongattserverdisconnected; + readonly attribute DOMString id; + readonly attribute DOMString? name; + readonly attribute BluetoothRemoteGATTServer gatt; + [RuntimeEnabled=WebBluetoothWatchAdvertisements] readonly attribute boolean watchingAdvertisements; + + [RuntimeEnabled=WebBluetoothWatchAdvertisements] attribute EventHandler onadvertisementreceived; + attribute EventHandler ongattserverdisconnected; }; // TODO: Include ServiceEventHandlers mixin (https://crbug.com/421670) 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 fec96c7e663..39527539f66 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_error.cc @@ -86,6 +86,10 @@ DOMException* BluetoothError::CreateDOMException( case mojom::blink::WebBluetoothResult::enumeration: \ return MakeGarbageCollected<DOMException>(name, message); + // AbortErrors: + MAP_ERROR(WATCH_ADVERTISEMENTS_ABORTED, DOMExceptionCode::kAbortError, + "The Bluetooth operation was cancelled."); + // InvalidModificationErrors: MAP_ERROR(GATT_INVALID_ATTRIBUTE_LENGTH, DOMExceptionCode::kInvalidModificationError, 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 b13d92515c6..84df2a30670 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 @@ -64,7 +64,7 @@ bool BluetoothLEScan::stop() { return true; } -void BluetoothLEScan::Trace(Visitor* visitor) { +void BluetoothLEScan::Trace(Visitor* visitor) const { visitor->Trace(filters_); visitor->Trace(bluetooth_); ScriptWrappable::Trace(visitor); 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 db63ac48bcb..9f03eb0c714 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 @@ -29,7 +29,7 @@ class BluetoothLEScan final : public ScriptWrappable { bool stop(); // Interface required by garbage collection. - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: mojo::ReceiverId id_; diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.cc index ef3bd30a856..112106d97de 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.cc @@ -29,7 +29,7 @@ class BluetoothManufacturerDataMapIterationSource final return true; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(map_); PairIterable<uint16_t, Member<DOMDataView>>::IterationSource::Trace( visitor); 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 eadaaeaebde..3c99e9a22ec 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 @@ -162,9 +162,10 @@ void BluetoothRemoteGATTCharacteristic::WriteValueCallback( } } -ScriptPromise BluetoothRemoteGATTCharacteristic::writeValue( +ScriptPromise BluetoothRemoteGATTCharacteristic::WriteCharacteristicValue( ScriptState* script_state, const DOMArrayPiece& value, + mojom::blink::WebBluetoothWriteType write_type, ExceptionState& exception_state) { if (!GetGatt()->connected()) { exception_state.ThrowDOMException( @@ -213,13 +214,42 @@ ScriptPromise BluetoothRemoteGATTCharacteristic::writeValue( mojom::blink::WebBluetoothService* service = device_->GetBluetooth()->Service(); service->RemoteCharacteristicWriteValue( - characteristic_->instance_id, value_vector, + characteristic_->instance_id, value_vector, write_type, WTF::Bind(&BluetoothRemoteGATTCharacteristic::WriteValueCallback, WrapPersistent(this), WrapPersistent(resolver), value_vector)); return promise; } +ScriptPromise BluetoothRemoteGATTCharacteristic::writeValue( + ScriptState* script_state, + const DOMArrayPiece& value, + ExceptionState& exception_state) { + return WriteCharacteristicValue( + script_state, value, + mojom::blink::WebBluetoothWriteType::kWriteDefaultDeprecated, + exception_state); +} + +ScriptPromise BluetoothRemoteGATTCharacteristic::writeValueWithResponse( + ScriptState* script_state, + const DOMArrayPiece& value, + ExceptionState& exception_state) { + return WriteCharacteristicValue( + script_state, value, + mojom::blink::WebBluetoothWriteType::kWriteWithResponse, exception_state); +} + +ScriptPromise BluetoothRemoteGATTCharacteristic::writeValueWithoutResponse( + ScriptState* script_state, + const DOMArrayPiece& value, + ExceptionState& exception_state) { + return WriteCharacteristicValue( + script_state, value, + mojom::blink::WebBluetoothWriteType::kWriteWithoutResponse, + exception_state); +} + void BluetoothRemoteGATTCharacteristic::NotificationsCallback( ScriptPromiseResolver* resolver, mojom::blink::WebBluetoothResult result) { @@ -446,7 +476,7 @@ BluetoothRemoteGATTCharacteristic::CreateInvalidCharacteristicErrorMessage() { "after reconnecting."; } -void BluetoothRemoteGATTCharacteristic::Trace(Visitor* visitor) { +void BluetoothRemoteGATTCharacteristic::Trace(Visitor* visitor) const { visitor->Trace(service_); visitor->Trace(properties_); visitor->Trace(value_); 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 8fae547fe1d..e283d78e1f6 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 @@ -67,7 +67,7 @@ class BluetoothRemoteGATTCharacteristic final bool HasPendingActivity() const override; // Interface required by garbage collection. - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // IDL exposed interface: BluetoothRemoteGATTService* service() { return service_; } @@ -83,6 +83,12 @@ class BluetoothRemoteGATTCharacteristic final ExceptionState&); ScriptPromise readValue(ScriptState*, ExceptionState&); ScriptPromise writeValue(ScriptState*, const DOMArrayPiece&, ExceptionState&); + ScriptPromise writeValueWithResponse(ScriptState*, + const DOMArrayPiece&, + ExceptionState&); + ScriptPromise writeValueWithoutResponse(ScriptState*, + const DOMArrayPiece&, + ExceptionState&); ScriptPromise startNotifications(ScriptState*, ExceptionState&); ScriptPromise stopNotifications(ScriptState*, ExceptionState&); @@ -108,6 +114,11 @@ class BluetoothRemoteGATTCharacteristic final void NotificationsCallback(ScriptPromiseResolver*, mojom::blink::WebBluetoothResult); + ScriptPromise WriteCharacteristicValue(ScriptState*, + const DOMArrayPiece& value, + mojom::blink::WebBluetoothWriteType, + ExceptionState&); + ScriptPromise GetDescriptorsImpl(ScriptState*, ExceptionState&, mojom::blink::WebBluetoothGATTQueryQuantity, diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl index 532bd69d233..da8d2fa4462 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl @@ -18,6 +18,8 @@ [RaisesException, CallWith=ScriptState, MeasureAs=WebBluetoothRemoteCharacteristicGetDescriptors] Promise<sequence<BluetoothRemoteGATTDescriptor>> getDescriptors(optional BluetoothDescriptorUUID descriptor); [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicReadValue] Promise<DataView> readValue(); [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicWriteValue] Promise<void> writeValue(BufferSource value); + [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicWriteValueWithResponse, RuntimeEnabled=WebBluetoothRemoteCharacteristicNewWriteValue] Promise<void> writeValueWithResponse(BufferSource value); + [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicWriteValueWithoutResponse, RuntimeEnabled=WebBluetoothRemoteCharacteristicNewWriteValue] Promise<void> writeValueWithoutResponse(BufferSource value); [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicStartNotifications] Promise<BluetoothRemoteGATTCharacteristic> startNotifications(); [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRemoteCharacteristicStopNotifications] Promise<BluetoothRemoteGATTCharacteristic> stopNotifications(); diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc index f8408a33a40..25b0cf2974c 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.cc @@ -160,7 +160,7 @@ String BluetoothRemoteGATTDescriptor::CreateInvalidDescriptorErrorMessage() { "after reconnecting."; } -void BluetoothRemoteGATTDescriptor::Trace(Visitor* visitor) { +void BluetoothRemoteGATTDescriptor::Trace(Visitor* visitor) const { visitor->Trace(characteristic_); visitor->Trace(value_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.h b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.h index 2022babba6d..fe71c57f8c6 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.h @@ -44,7 +44,7 @@ class BluetoothRemoteGATTDescriptor final : public ScriptWrappable { ScriptPromise writeValue(ScriptState*, const DOMArrayPiece&, ExceptionState&); // Interface required by garbage collection. - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class DescriptorReadValueCallback; 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 5e8bc969b82..4e0d8d3572c 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 @@ -82,7 +82,7 @@ void BluetoothRemoteGATTServer::Dispose() { DisconnectIfConnected(); } -void BluetoothRemoteGATTServer::Trace(Visitor* visitor) { +void BluetoothRemoteGATTServer::Trace(Visitor* visitor) const { visitor->Trace(client_receivers_); visitor->Trace(active_algorithms_); visitor->Trace(device_); 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 41d02aeeda6..a5e857b994f 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 @@ -75,7 +75,7 @@ class BluetoothRemoteGATTServer void Dispose(); // Interface required by Garbage Collectoin: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // IDL exposed interface: BluetoothDevice* device() { return device_; } diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc index 63f38fe71e8..54f4a41eadc 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc @@ -28,7 +28,7 @@ BluetoothRemoteGATTService::BluetoothRemoteGATTService( device_instance_id_(device_instance_id), device_(device) {} -void BluetoothRemoteGATTService::Trace(Visitor* visitor) { +void BluetoothRemoteGATTService::Trace(Visitor* visitor) const { visitor->Trace(device_); ScriptWrappable::Trace(visitor); } 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 0ae8905a417..9380678a6a0 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 @@ -38,7 +38,7 @@ class BluetoothRemoteGATTService final : public ScriptWrappable { BluetoothDevice*); // Interface required by garbage collection. - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // IDL exposed interface: String uuid() { return service_->uuid; } diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.cc b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.cc index 21221ed557a..ed5be4088b0 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.cc @@ -28,7 +28,7 @@ class BluetoothServiceDataMapIterationSource final return true; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(map_); PairIterable<String, Member<DOMDataView>>::IterationSource::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/idls.gni b/chromium/third_party/blink/renderer/modules/bluetooth/idls.gni index 22354b698f5..e784aae1204 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/idls.gni +++ b/chromium/third_party/blink/renderer/modules/bluetooth/idls.gni @@ -22,6 +22,7 @@ modules_dictionary_idl_files = [ "bluetooth_le_scan_filter_init.idl", "bluetooth_le_scan_options.idl", "request_device_options.idl", + "watch_advertisements_options.idl", ] modules_dependency_idl_files = [ "navigator_bluetooth.idl" ] diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc b/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc index 6fe93b68fd3..62a4ed10a9a 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc +++ b/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.cc @@ -29,15 +29,15 @@ Bluetooth* NavigatorBluetooth::bluetooth() { if (bluetooth_) return bluetooth_.Get(); - if (!GetSupplementable()->GetFrame()) + if (!GetSupplementable()->DomWindow()) return nullptr; - bluetooth_ = MakeGarbageCollected<Bluetooth>( - GetSupplementable()->GetFrame()->GetDocument()->GetExecutionContext()); + bluetooth_ = + MakeGarbageCollected<Bluetooth>(GetSupplementable()->DomWindow()); return bluetooth_.Get(); } -void NavigatorBluetooth::Trace(Visitor* visitor) { +void NavigatorBluetooth::Trace(Visitor* visitor) const { visitor->Trace(bluetooth_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.h b/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.h index ec611db8500..81a498d375e 100644 --- a/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.h +++ b/chromium/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.h @@ -32,7 +32,7 @@ class NavigatorBluetooth final : public GarbageCollected<NavigatorBluetooth>, explicit NavigatorBluetooth(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<Bluetooth> bluetooth_; diff --git a/chromium/third_party/blink/renderer/modules/bluetooth/watch_advertisements_options.idl b/chromium/third_party/blink/renderer/modules/bluetooth/watch_advertisements_options.idl new file mode 100644 index 00000000000..483c75b8bee --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/bluetooth/watch_advertisements_options.idl @@ -0,0 +1,9 @@ +// Copyright 2020 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://webbluetoothcg.github.io/web-bluetooth/#dictdef-watchadvertisementsoptions + +dictionary WatchAdvertisementsOptions { + AbortSignal signal; +}; 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 56fbe28dcb0..cf5510635a7 100644 --- a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc +++ b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc @@ -101,7 +101,7 @@ void BroadcastChannel::ContextDestroyed() { close(); } -void BroadcastChannel::Trace(Visitor* visitor) { +void BroadcastChannel::Trace(Visitor* visitor) const { ExecutionContextLifecycleObserver::Trace(visitor); EventTargetWithInlineData::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h index fcc6b83781c..e70fb1ba1a9 100644 --- a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h +++ b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h @@ -55,7 +55,7 @@ class BroadcastChannel final : public EventTargetWithInlineData, // ExecutionContextLifecycleObserver: void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // mojom::blink::BroadcastChannelClient: 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 a4c704f9fc0..5923b8207b6 100644 --- a/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc +++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache.cc @@ -213,7 +213,7 @@ class Cache::FetchResolvedForAdd final : public ScriptFunction { return ScriptValue(GetScriptState()->GetIsolate(), put_promise.V8Value()); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(cache_); visitor->Trace(requests_); ScriptFunction::Trace(visitor); @@ -326,7 +326,7 @@ class Cache::BarrierCallbackForPut final MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError)); } - virtual void Trace(Visitor* visitor) { + virtual void Trace(Visitor* visitor) const { visitor->Trace(cache_); visitor->Trace(resolver_); } @@ -412,7 +412,7 @@ class Cache::BlobHandleCallbackForPut final void Abort() override { barrier_callback_->Abort(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(barrier_callback_); FetchDataLoader::Client::Trace(visitor); } @@ -495,7 +495,7 @@ class Cache::CodeCacheHandleCallbackForPut final void Abort() override { barrier_callback_->Abort(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(script_state_); visitor->Trace(barrier_callback_); FetchDataLoader::Client::Trace(visitor); @@ -678,7 +678,7 @@ Cache::Cache(GlobalFetch::ScopedFetcher* fetcher, cache_remote_.Bind(std::move(cache_pending_remote), std::move(task_runner)); } -void Cache::Trace(Visitor* visitor) { +void Cache::Trace(Visitor* visitor) const { visitor->Trace(scoped_fetcher_); visitor->Trace(blob_client_list_); ScriptWrappable::Trace(visitor); @@ -989,18 +989,10 @@ ScriptPromise Cache::PutImpl(ScriptState* script_state, "Partial response (status code 206) is unsupported"); return promise; } - if (responses[i]->IsBodyLocked(exception_state) == - Body::BodyLocked::kLocked || - responses[i]->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) { - DCHECK(!exception_state.HadException()); + if (responses[i]->IsBodyLocked() || responses[i]->IsBodyUsed()) { barrier_callback->OnError("Response body is already used"); return promise; } - if (exception_state.HadException()) { - // TODO(ricea): Reject the promise with the actual exception. - barrier_callback->OnError("Could not inspect response body state"); - return promise; - } BodyStreamBuffer* buffer = responses[i]->InternalBodyBuffer(); @@ -1101,7 +1093,7 @@ ScriptPromise Cache::KeysImpl(ScriptState* script_state, requests.ReserveInitialCapacity(result->get_keys().size()); for (auto& request : result->get_keys()) { requests.push_back(Request::Create( - resolver->GetScriptState(), *request, + resolver->GetScriptState(), std::move(request), Request::ForServiceWorkerFetchEvent::kFalse)); } resolver->Resolve(requests); 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 8dea8b0b6d7..4e8439fa1bc 100644 --- a/chromium/third_party/blink/renderer/modules/cache_storage/cache.h +++ b/chromium/third_party/blink/renderer/modules/cache_storage/cache.h @@ -84,7 +84,7 @@ class MODULES_EXPORT Cache final : public ScriptWrappable { const CacheQueryOptions*, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: class BarrierCallbackForPut; 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 fa91a7be744..eba3ca68c78 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 @@ -51,7 +51,8 @@ struct TypeConverter<MultiCacheQueryOptionsPtr, MultiCacheQueryOptionsPtr output = MultiCacheQueryOptions::New(); output->query_options = std::move(query_options); - output->cache_name = input->cacheName(); + if (input->hasCacheName()) + output->cache_name = input->cacheName(); return output; } }; @@ -498,7 +499,7 @@ bool CacheStorage::HasPendingActivity() const { return ever_used_; } -void CacheStorage::Trace(Visitor* visitor) { +void CacheStorage::Trace(Visitor* visitor) const { visitor->Trace(scoped_fetcher_); visitor->Trace(blob_client_list_); visitor->Trace(cache_storage_remote_); 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 2f9b73c483a..82b4a0e5c34 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 @@ -45,7 +45,7 @@ class CacheStorage final : public ScriptWrappable, ExceptionState&); bool HasPendingActivity() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ScriptPromise MatchImpl(ScriptState*, 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 index 2028398696f..29f7ca17c60 100644 --- 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 @@ -48,7 +48,7 @@ class CacheStorageBlobClientList::Client owner_->RevokeClient(this); } - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(owner_); visitor->Trace(completion_notifier_); visitor->Trace(client_receiver_); @@ -87,7 +87,7 @@ void CacheStorageBlobClientList::AddClient( this, context, std::move(client_pending_receiver), completion_notifier)); } -void CacheStorageBlobClientList::Trace(Visitor* visitor) { +void CacheStorageBlobClientList::Trace(Visitor* visitor) const { visitor->Trace(clients); } 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 index 5d00e128e6a..ed92282d9d9 100644 --- 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 @@ -25,7 +25,7 @@ class CacheStorageBlobClientList client_pending_receiver, DataPipeBytesConsumer::CompletionNotifier* completion_notifier); - void Trace(Visitor* visitor); + void Trace(Visitor* visitor) const; private: class Client; 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 85dacd210d6..57c578fb767 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 @@ -94,7 +94,7 @@ class ScopedFetcherForTests final int FetchCount() const { return fetch_count_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(response_); GlobalFetch::ScopedFetcher::Trace(visitor); } 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 5921dffdcbd..cbf96ed9be4 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 @@ -76,7 +76,7 @@ class GlobalCacheStorageImpl final return caches_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(caches_); Supplement<T>::Trace(visitor); } 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 5f27c847938..1ab8e2f4570 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 @@ -29,6 +29,7 @@ #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/platform/blob/blob_data.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/network/http_header_map.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" @@ -258,11 +259,11 @@ class ResponsesAccumulator : public RefCounted<ResponsesAccumulator> { for (auto& request : requests) { // All FetchAPIRequests in cache_storage code are supposed to not contain // a body. - DCHECK(!request->blob && !request->body); + DCHECK(!request->blob && request->body.IsEmpty()); auto request_clone_without_body = mojom::blink::FetchAPIRequest::New( request->mode, request->is_main_resource_load, request->destination, request->frame_type, request->url, request->method, request->headers, - nullptr /* blob */, nullptr /* body */, request->referrer.Clone(), + nullptr /* blob */, ResourceRequestBody(), request->referrer.Clone(), request->credentials_mode, request->cache_mode, request->redirect_mode, request->integrity, request->priority, request->fetch_window_id, request->keepalive, request->is_reload, @@ -499,7 +500,7 @@ InspectorCacheStorageAgent::InspectorCacheStorageAgent(InspectedFrames* frames) InspectorCacheStorageAgent::~InspectorCacheStorageAgent() = default; -void InspectorCacheStorageAgent::Trace(Visitor* visitor) { +void InspectorCacheStorageAgent::Trace(Visitor* visitor) const { visitor->Trace(frames_); InspectorBaseAgent::Trace(visitor); } 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 37c2f7ed028..97b8b1d8491 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 @@ -26,7 +26,7 @@ class MODULES_EXPORT InspectorCacheStorageAgent final explicit InspectorCacheStorageAgent(InspectedFrames*); ~InspectorCacheStorageAgent() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void requestCacheNames(const String& security_origin, std::unique_ptr<RequestCacheNamesCallback>) override; diff --git a/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn b/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn index 3a4fad46751..1ef75bd432b 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/canvas/BUILD.gn @@ -9,6 +9,8 @@ blink_modules_sources("canvas") { sources = [ "canvas2d/base_rendering_context_2d.cc", "canvas2d/base_rendering_context_2d.h", + "canvas2d/blink_identifiability_digest_helpers.cc", + "canvas2d/blink_identifiability_digest_helpers.h", "canvas2d/canvas_gradient.cc", "canvas2d/canvas_gradient.h", "canvas2d/canvas_path.cc", @@ -25,6 +27,7 @@ blink_modules_sources("canvas") { "canvas2d/clip_list.h", "canvas2d/hit_region.cc", "canvas2d/hit_region.h", + "canvas2d/identifiability_study_helper.h", "canvas2d/path_2d.h", "htmlcanvas/canvas_context_creation_attributes_helpers.cc", "htmlcanvas/canvas_context_creation_attributes_helpers.h", diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS index 11fa35c31af..a7389356a86 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+services/metrics/public/cpp/ukm_recorder.h", "+third_party/skia/include", ] @@ -7,4 +8,4 @@ specific_include_rules = { ".*_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 b36da920302..b9837cb73ae 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 @@ -8,6 +8,7 @@ #include <cmath> #include <memory> +#include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "base/numerics/checked_math.h" #include "third_party/blink/public/common/features.h" @@ -642,7 +643,10 @@ void BaseRenderingContext2D::DrawPathInternal( { c->drawPath(sk_path, *flags); }, [](const SkIRect& rect) // overdraw test lambda { return false; }, - bounds, paint_type); + bounds, paint_type, + GetState().HasPattern(paint_type) + ? CanvasRenderingContext2DState::kNonOpaqueImage + : CanvasRenderingContext2DState::kNoImage); } static SkPathFillType ParseWinding(const String& winding_rule_string) { @@ -699,15 +703,20 @@ void BaseRenderingContext2D::fillRect(double x, // pattern was unaccelerated is because it was not possible to hold that image // in an accelerated texture - that is, into the GPU). That's why we disable // the acceleration to be sure that it will work. - if (IsAccelerated() && GetState().HasPattern() && - !GetState().PatternIsAccelerated()) + if (IsAccelerated() && + GetState().HasPattern(CanvasRenderingContext2DState::kFillPaintType) && + !GetState().PatternIsAccelerated( + CanvasRenderingContext2DState::kFillPaintType)) DisableAcceleration(); SkRect rect = SkRect::MakeXYWH(fx, fy, fwidth, fheight); Draw([&rect](cc::PaintCanvas* c, const PaintFlags* flags) // draw lambda { c->drawRect(rect, *flags); }, [&rect, this](const SkIRect& clip_bounds) // overdraw test lambda { return RectContainsTransformedRect(rect, clip_bounds); }, - rect, CanvasRenderingContext2DState::kFillPaintType); + rect, CanvasRenderingContext2DState::kFillPaintType, + GetState().HasPattern(CanvasRenderingContext2DState::kFillPaintType) + ? CanvasRenderingContext2DState::kNonOpaqueImage + : CanvasRenderingContext2DState::kNoImage); } static void StrokeRectOnCanvas(const FloatRect& rect, @@ -755,7 +764,10 @@ void BaseRenderingContext2D::strokeRect(double x, { StrokeRectOnCanvas(rect, c, flags); }, [](const SkIRect& clip_bounds) // overdraw test lambda { return false; }, - bounds, CanvasRenderingContext2DState::kStrokePaintType); + bounds, CanvasRenderingContext2DState::kStrokePaintType, + GetState().HasPattern(CanvasRenderingContext2DState::kStrokePaintType) + ? CanvasRenderingContext2DState::kNonOpaqueImage + : CanvasRenderingContext2DState::kNoImage); } void BaseRenderingContext2D::ClipInternal(const Path& path, @@ -1179,9 +1191,7 @@ void BaseRenderingContext2D::drawImage(ScriptState* script_state, FloatSize default_object_size(Width(), Height()); SourceImageStatus source_image_status = kInvalidSourceImageStatus; if (!image_source->IsVideoElement()) { - AccelerationHint hint = - IsAccelerated() ? kPreferAcceleration : kPreferNoAcceleration; - image = image_source->GetSourceImageForCanvas(&source_image_status, hint, + image = image_source->GetSourceImageForCanvas(&source_image_status, default_object_size); if (source_image_status == kUndecodableSourceImageStatus) { exception_state.ThrowDOMException( @@ -1405,8 +1415,7 @@ CanvasPattern* BaseRenderingContext2D::createPattern( FloatSize default_object_size(Width(), Height()); scoped_refptr<Image> image_for_rendering = - image_source->GetSourceImageForCanvas(&status, kPreferNoAcceleration, - default_object_size); + image_source->GetSourceImageForCanvas(&status, default_object_size); switch (status) { case kNormalSourceImageStatus: @@ -1613,7 +1622,7 @@ ImageData* BaseRenderingContext2D::getImageData( // Deferred offscreen canvases might have recorded commands, make sure // that those get drawn here FinalizeFrame(); - scoped_refptr<StaticBitmapImage> snapshot = GetImage(kPreferNoAcceleration); + scoped_refptr<StaticBitmapImage> snapshot = GetImage(); // GetImagedata is faster in Unaccelerated canvases if (IsAccelerated()) @@ -1836,7 +1845,13 @@ void BaseRenderingContext2D::PutByteArray(const unsigned char* source, DCHECK_GE(origin_y, 0); DCHECK_LT(origin_y, source_rect.MaxY()); - const size_t src_bytes_per_row = bytes_per_pixel * source_size.Width(); + const base::CheckedNumeric<size_t> src_bytes_per_row_checked = + base::CheckMul(bytes_per_pixel, source_size.Width()); + if (!src_bytes_per_row_checked.IsValid()) { + VLOG(1) << "Invalid sizes"; + return; + } + const size_t src_bytes_per_row = src_bytes_per_row_checked.ValueOrDie(); const void* src_addr = source + origin_y * src_bytes_per_row + origin_x * bytes_per_pixel; @@ -1997,7 +2012,7 @@ void BaseRenderingContext2D::setTextBaseline(const String& s) { ModifiableState().SetTextBaseline(baseline); } -void BaseRenderingContext2D::Trace(Visitor* visitor) { +void BaseRenderingContext2D::Trace(Visitor* visitor) const { visitor->Trace(state_stack_); } 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 9fd5cb6cb48..de9369d92b0 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 @@ -14,6 +14,7 @@ #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/graphics/image_orientation.h" namespace blink { @@ -195,7 +196,11 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, // 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&); + virtual ImageData* getImageData(int sx, + int sy, + int sw, + int sh, + ExceptionState&); void putImageData(ImageData*, int dx, int dy, ExceptionState&); void putImageData(ImageData*, int dx, @@ -264,7 +269,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, String textBaseline() const; void setTextBaseline(const String&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; enum DrawCallType { kStrokePath = 0, @@ -332,8 +337,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, const ContainsFunc&, const SkRect& bounds, CanvasRenderingContext2DState::PaintType, - CanvasRenderingContext2DState::ImageType = - CanvasRenderingContext2DState::kNoImage); + CanvasRenderingContext2DState::ImageType); void InflateStrokeRect(FloatRect&) const; @@ -348,7 +352,7 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, NOTREACHED(); return false; } - virtual scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) { + virtual scoped_refptr<StaticBitmapImage> GetImage() { NOTREACHED(); return nullptr; } @@ -387,6 +391,19 @@ class MODULES_EXPORT BaseRenderingContext2D : public GarbageCollectedMixin, bool ShouldDrawImageAntialiased(const FloatRect& dest_rect) const; + // When the canvas is stroked or filled with a pattern, which is assumed to + // have a transparent background, the shadow needs to be applied with + // DropShadowPaintFilter for kNonOpaqueImageType + // Used in Draw and CompositedDraw to avoid the shadow offset being modified + // by the transformation matrix + bool ShouldUseDropShadowPaintFilter( + CanvasRenderingContext2DState::PaintType paint_type, + CanvasRenderingContext2DState::ImageType image_type) const { + return (paint_type == CanvasRenderingContext2DState::kFillPaintType || + paint_type == CanvasRenderingContext2DState::kStrokePaintType) && + image_type == CanvasRenderingContext2DState::kNonOpaqueImage; + } + void DrawPathInternal(const Path&, CanvasRenderingContext2DState::PaintType, SkPathFillType = SkPathFillType::kWinding); @@ -461,7 +478,9 @@ void BaseRenderingContext2D::Draw( return; if (IsFullCanvasCompositeMode(GetState().GlobalComposite()) || - StateHasFilter()) { + StateHasFilter() || + (GetState().ShouldDrawShadows() && + ShouldUseDropShadowPaintFilter(paint_type, image_type))) { CompositedDraw(draw_func, GetPaintCanvas(), paint_type, image_type); DidDraw(clip_bounds); } else if (GetState().GlobalComposite() == SkBlendMode::kSrc) { @@ -490,8 +509,11 @@ void BaseRenderingContext2D::CompositedDraw( cc::PaintCanvas* c, CanvasRenderingContext2DState::PaintType paint_type, CanvasRenderingContext2DState::ImageType image_type) { - sk_sp<PaintFilter> filter = StateGetFilter(); - DCHECK(IsFullCanvasCompositeMode(GetState().GlobalComposite()) || filter); + sk_sp<PaintFilter> canvas_filter = StateGetFilter(); + DCHECK(IsFullCanvasCompositeMode(GetState().GlobalComposite()) || + canvas_filter || + (GetState().ShouldDrawShadows() && + ShouldUseDropShadowPaintFilter(paint_type, image_type))); SkMatrix ctm = c->getTotalMatrix(); c->setMatrix(SkMatrix::I()); PaintFlags composite_flags; @@ -502,13 +524,14 @@ void BaseRenderingContext2D::CompositedDraw( *GetState().GetFlags(paint_type, kDrawShadowOnly, image_type); int save_count = c->getSaveCount(); c->save(); - if (filter) { + if (canvas_filter || + ShouldUseDropShadowPaintFilter(paint_type, image_type)) { PaintFlags foreground_flags = *GetState().GetFlags(paint_type, kDrawForegroundOnly, image_type); shadow_flags.setImageFilter(sk_make_sp<ComposePaintFilter>( sk_make_sp<ComposePaintFilter>(foreground_flags.getImageFilter(), shadow_flags.getImageFilter()), - filter)); + canvas_filter)); // Saving the shadow layer before setting the matrix, so the shadow offset // does not get modified by the transformation matrix c->saveLayer(nullptr, &shadow_flags); @@ -524,7 +547,7 @@ void BaseRenderingContext2D::CompositedDraw( c->restoreToCount(save_count); } - composite_flags.setImageFilter(std::move(filter)); + composite_flags.setImageFilter(std::move(canvas_filter)); c->saveLayer(nullptr, &composite_flags); PaintFlags foreground_flags = *GetState().GetFlags(paint_type, kDrawForegroundOnly, image_type); diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.cc new file mode 100644 index 00000000000..89d1e8051dc --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.cc @@ -0,0 +1,34 @@ +// Copyright 2020 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/canvas/canvas2d/blink_identifiability_digest_helpers.h" + +#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h" +#include "third_party/blink/renderer/platform/wtf/shared_buffer.h" +#include "third_party/blink/renderer/platform/wtf/text/string_hash.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +// Arbitrary value chosen to represent null strings. +constexpr uint64_t kNullStringDigest = 6554271438612835841L; + +uint64_t IdentifiabilityDigestHelper(const String& in) { + if (in.IsNull()) + return kNullStringDigest; + // Return the precomputed hash for the string. This makes this method O(1) + // instead of O(n), at the cost of only using the lower 32 bits of the hash. + return StringHash::GetHash(in); +} + +uint16_t IdentifiabilitySensitiveString(const String& in) { + if (in.IsNull()) + return static_cast<uint16_t>(kNullStringDigest); + // Take the precomputed 32-bit hash, and xor the top and bottom halves to + // produce a 16-bit hash. + const uint32_t original_hash = StringHash::GetHash(in); + return ((original_hash & 0xFFFF0000) >> 16) ^ (original_hash & 0xFFFF); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h new file mode 100644 index 00000000000..56c6ef4845e --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h @@ -0,0 +1,30 @@ +// Copyright 2020 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_CANVAS_CANVAS2D_BLINK_IDENTIFIABILITY_DIGEST_HELPERS_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_BLINK_IDENTIFIABILITY_DIGEST_HELPERS_H_ + +#include "third_party/blink/renderer/platform/wtf/forward.h" + +// Provide additional overloads of IdentifiabilityDigestHelper() for +// blink-internal types. +// +// *NOTE*: This header extends the functionality of +// third_party/blink/public/common/privacy_budget/identifiability_metrics.h +// -- it must be included before that header. + +// TODO(crbug.com/973801): Consider moving to another directory. + +namespace blink { + +uint64_t IdentifiabilityDigestHelper(const String&); + +// For sensitive strings, this function narrows the hash width to 16 bits. This +// 16-bit value can be combined with other values using the parameter-pack +// IdentifiabilityDigestHelper() overload. +uint16_t IdentifiabilitySensitiveString(const String&); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_BLINK_IDENTIFIABILITY_DIGEST_HELPERS_H_ 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 e916fc83dab..d4e0d5d0657 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 @@ -36,6 +36,8 @@ #include "base/metrics/histogram_functions.h" #include "base/rand_util.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.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/rendering_context.h" @@ -48,6 +50,7 @@ #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/events/mouse_event.h" #include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/html/canvas/canvas_font_cache.h" #include "third_party/blink/renderer/core/html/canvas/text_metrics.h" #include "third_party/blink/renderer/core/layout/hit_test_canvas_result.h" @@ -133,7 +136,9 @@ CanvasRenderingContext2D::CanvasRenderingContext2D( &CanvasRenderingContext2D::TryRestoreContextEvent), should_prune_local_font_cache_(false), random_generator_((uint32_t)base::RandUint64()), - bernoulli_distribution_(kRasterMetricProbability) { + bernoulli_distribution_(kRasterMetricProbability), + ukm_recorder_(canvas->GetDocument().UkmRecorder()), + ukm_source_id_(canvas->GetDocument().UkmSourceID()) { if (canvas->GetDocument().GetSettings() && canvas->GetDocument().GetSettings()->GetAntialiasedClips2dCanvasEnabled()) clip_antialiasing_ = kAntiAliased; @@ -223,7 +228,7 @@ void CanvasRenderingContext2D::DidSetSurfaceSize() { } } -void CanvasRenderingContext2D::Trace(Visitor* visitor) { +void CanvasRenderingContext2D::Trace(Visitor* visitor) const { visitor->Trace(hit_region_manager_); visitor->Trace(filter_operations_); CanvasRenderingContext::Trace(visitor); @@ -497,6 +502,8 @@ void CanvasRenderingContext2D::setFont(const String& new_font) { // documents. if (!canvas()->GetDocument().GetFrame()) return; + identifiability_study_helper_.MaybeUpdateDigest(CanvasOps::kSetFont, + new_font); base::TimeTicks start_time = base::TimeTicks::Now(); canvas()->GetDocument().UpdateStyleAndLayoutTreeForNode(canvas()); @@ -570,9 +577,8 @@ void CanvasRenderingContext2D::setFont(const String& new_font) { } // The parse succeeded. - String new_font_safe_copy( - new_font); // Create a string copy since newFont can be - // deleted inside realizeSaves. + String new_font_safe_copy(new_font); // Create a string copy since newFont + // can be deleted inside realizeSaves. ModifiableState().SetUnparsedFont(new_font_safe_copy); if (bernoulli_distribution_(random_generator_)) { base::TimeDelta elapsed = base::TimeTicks::Now() - start_time; @@ -662,11 +668,25 @@ bool CanvasRenderingContext2D::CanCreateCanvas2dResourceProvider() const { return canvas()->GetOrCreateCanvas2DLayerBridge(); } -scoped_refptr<StaticBitmapImage> blink::CanvasRenderingContext2D::GetImage( - AccelerationHint hint) { +scoped_refptr<StaticBitmapImage> blink::CanvasRenderingContext2D::GetImage() { if (!IsPaintable()) return nullptr; - return canvas()->GetCanvas2DLayerBridge()->NewImageSnapshot(hint); + return canvas()->GetCanvas2DLayerBridge()->NewImageSnapshot(); +} + +ImageData* CanvasRenderingContext2D::getImageData( + int sx, + int sy, + int sw, + int sh, + ExceptionState& exception_state) { + blink::IdentifiabilityMetricBuilder(ukm_source_id_) + .Set(blink::IdentifiableSurface::FromTypeAndInput( + blink::IdentifiableSurface::Type::kCanvasReadback, + GetContextType()), + 0) + .Record(ukm_recorder_); + return BaseRenderingContext2D::getImageData(sx, sy, sw, sh, exception_state); } void CanvasRenderingContext2D::FinalizeFrame() { @@ -845,6 +865,12 @@ void CanvasRenderingContext2D::DrawTextInternal( if (max_width && (!std::isfinite(*max_width) || *max_width <= 0)) return; + identifiability_study_helper_.MaybeUpdateDigest( + paint_type == CanvasRenderingContext2DState::kFillPaintType + ? CanvasOps::kFillText + : CanvasOps::kStrokeText, + IdentifiabilitySensitiveString(text), x, y, max_width ? *max_width : -1); + const Font& font = AccessFont(); const SimpleFontData* font_data = font.PrimaryFont(); DCHECK(font_data); @@ -919,7 +945,7 @@ void CanvasRenderingContext2D::DrawTextInternal( }, [](const SkIRect& rect) // overdraw test lambda { return false; }, - bounds, paint_type); + bounds, paint_type, CanvasRenderingContext2DState::kNoImage); } const Font& CanvasRenderingContext2D::AccessFont() { @@ -963,6 +989,8 @@ CanvasRenderingContext2D::getContextAttributes() const { settings->setPixelFormat(PixelFormatAsString()); } settings->setDesynchronized(Host()->LowLatencyEnabled()); + if (RuntimeEnabledFeatures::NewCanvas2DAPIEnabled()) + settings->setWillReadFrequently(CreationAttributes().will_read_frequently); return settings; } 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 bda1b439ed3..5bc40f38019 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 @@ -30,15 +30,19 @@ #include <random> #include "base/macros.h" +#include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_canvas_rendering_context_2d_settings.h" #include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h" #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/core/html/canvas/image_data.h" #include "third_party/blink/renderer/core/style/filter_operations.h" #include "third_party/blink/renderer/core/svg/svg_resource_client.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h" #include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_state.h" +#include "third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h" #include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -184,7 +188,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final cc::PaintCanvas* GetPaintCanvas() const final; void DidDraw(const SkIRect& dirty_rect) final; - scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final; + scoped_refptr<StaticBitmapImage> GetImage() final; bool StateHasFilter() final; sk_sp<PaintFilter> StateGetFilter() final; @@ -200,10 +204,20 @@ class MODULES_EXPORT CanvasRenderingContext2D final void WillDrawImage(CanvasImageSource*) const final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; + + ImageData* getImageData(int sx, + int sy, + int sw, + int sh, + ExceptionState&) override; CanvasColorParams ColorParamsForTest() const { return ColorParams(); } + uint64_t IdentifiabilityTextDigest() override { + return identifiability_study_helper_.digest(); + } + protected: CanvasColorParams ColorParams() const override; bool WritePixels(const SkImageInfo& orig_info, @@ -244,7 +258,7 @@ class MODULES_EXPORT CanvasRenderingContext2D final String ColorSpaceAsString() const override; CanvasPixelFormat PixelFormat() const override; - bool Is2d() const override { return true; } + bool IsRenderingContext2D() const override { return true; } bool IsComposited() const override; bool IsAccelerated() const override; bool IsOriginTopLeft() const override; @@ -276,6 +290,11 @@ class MODULES_EXPORT CanvasRenderingContext2D final static constexpr float kRasterMetricProbability = 0.01; std::mt19937 random_generator_; std::bernoulli_distribution bernoulli_distribution_; + + IdentifiabilityStudyHelper identifiability_study_helper_; + + ukm::UkmRecorder* ukm_recorder_; + ukm::SourceId ukm_source_id_; }; } // namespace blink 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 79a5ddca35d..50575304842 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 @@ -46,7 +46,7 @@ CanvasRenderingContext2D* CanvasRenderingContext2DAPITest::Context2D() const { // If the following check fails, perhaps you forgot to call createContext // in your test? EXPECT_NE(nullptr, CanvasElement().RenderingContext()); - EXPECT_TRUE(CanvasElement().RenderingContext()->Is2d()); + EXPECT_TRUE(CanvasElement().RenderingContext()->IsRenderingContext2D()); return static_cast<CanvasRenderingContext2D*>( CanvasElement().RenderingContext()); } @@ -318,7 +318,7 @@ void ResetCanvasForAccessibilityRectTest(Document& document) { canvas->GetCanvasRenderingContext(canvas_type, attributes); EXPECT_NE(nullptr, canvas->RenderingContext()); - EXPECT_TRUE(canvas->RenderingContext()->Is2d()); + EXPECT_TRUE(canvas->RenderingContext()->IsRenderingContext2D()); } TEST_F(CanvasRenderingContext2DAPITest, AccessibilityRectTestForAddHitRegion) { diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl index be91d92a97b..d8bd1c01547 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl @@ -10,5 +10,6 @@ dictionary CanvasRenderingContext2DSettings { [RuntimeEnabled=CanvasColorManagement] CanvasColorSpace colorSpace = "srgb"; [RuntimeEnabled=CanvasColorManagement] CanvasPixelFormat pixelFormat = "uint8"; [RuntimeEnabled=SurfaceEmbeddingFeatures] boolean desynchronized = false; + [RuntimeEnabled=NewCanvas2DAPI] boolean willReadFrequently = false; }; 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 3b2e419bde0..316014a4c06 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 @@ -136,7 +136,7 @@ void CanvasRenderingContext2DState::FontsNeedUpdate(FontSelector* font_selector, resolved_filter_.reset(); } -void CanvasRenderingContext2DState::Trace(Visitor* visitor) { +void CanvasRenderingContext2DState::Trace(Visitor* visitor) const { visitor->Trace(stroke_style_); visitor->Trace(fill_style_); visitor->Trace(filter_value_); @@ -638,15 +638,16 @@ const PaintFlags* CanvasRenderingContext2DState::GetFlags( return flags; } -bool CanvasRenderingContext2DState::HasPattern() const { - return FillStyle() && FillStyle()->GetCanvasPattern() && - FillStyle()->GetCanvasPattern()->GetPattern(); +bool CanvasRenderingContext2DState::HasPattern(PaintType paint_type) const { + return Style(paint_type) && Style(paint_type)->GetCanvasPattern() && + Style(paint_type)->GetCanvasPattern()->GetPattern(); } // Only to be used if the CanvasRenderingContext2DState has Pattern -bool CanvasRenderingContext2DState::PatternIsAccelerated() const { - DCHECK(HasPattern()); - return FillStyle()->GetCanvasPattern()->GetPattern()->IsTextureBacked(); +bool CanvasRenderingContext2DState::PatternIsAccelerated( + PaintType paint_type) const { + DCHECK(HasPattern(paint_type)); + return Style(paint_type)->GetCanvasPattern()->GetPattern()->IsTextureBacked(); } } // namespace blink 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 abfb18fed68..efaafed0a9c 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 @@ -37,7 +37,7 @@ class CanvasRenderingContext2DState final ClipListCopyMode); ~CanvasRenderingContext2DState() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; enum PaintType { kFillPaintType, @@ -110,12 +110,16 @@ class CanvasRenderingContext2DState final void SetFillStyle(CanvasStyle*); CanvasStyle* FillStyle() const { return fill_style_.Get(); } + // Prefer to use Style() over StrokeStyle() and FillStyle() + // if properties of CanvasStyle are concerned CanvasStyle* Style(PaintType) const; - bool HasPattern() const; + // Check the pattern in StrokeStyle or FillStyle depending on the PaintType + bool HasPattern(PaintType) const; // Only to be used if the CanvasRenderingContext2DState has Pattern - bool PatternIsAccelerated() const; + // Pattern is in either StrokeStyle or FillStyle depending on the PaintType + bool PatternIsAccelerated(PaintType) 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 3d1c70fbfff..5d9f02205e9 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 @@ -65,7 +65,6 @@ class FakeImageSource : public CanvasImageSource { FakeImageSource(IntSize, BitmapOpacity); scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*, - AccelerationHint, const FloatSize&) override; bool WouldTaintOrigin() const override { return false; } @@ -95,7 +94,6 @@ FakeImageSource::FakeImageSource(IntSize size, BitmapOpacity opacity) scoped_refptr<Image> FakeImageSource::GetSourceImageForCanvas( SourceImageStatus* status, - AccelerationHint, const FloatSize&) { if (status) *status = kNormalSourceImageStatus; @@ -104,8 +102,6 @@ scoped_refptr<Image> FakeImageSource::GetSourceImageForCanvas( //============================================================================ -enum LinearPixelMathState { kLinearPixelMathDisabled, kLinearPixelMathEnabled }; - class CanvasRenderingContext2DTest : public ::testing::Test { protected: CanvasRenderingContext2DTest(); @@ -130,21 +126,24 @@ class CanvasRenderingContext2DTest : public ::testing::Test { Context2D()->FinalizeFrame(); CanvasElement().PostFinalizeFrame(); // Grabbing an image forces a flush - CanvasElement().Snapshot(kBackBuffer, kPreferAcceleration); + CanvasElement().Snapshot(kBackBuffer); } enum LatencyMode { kNormalLatency, kLowLatency }; - void CreateContext(OpacityMode, LatencyMode = kNormalLatency); + enum class ReadFrequencyMode { kWillReadFrequency, kWillNotReadFrequency }; + + void CreateContext( + OpacityMode, + LatencyMode = kNormalLatency, + ReadFrequencyMode = ReadFrequencyMode::kWillNotReadFrequency); ScriptState* GetScriptState() { return ToScriptStateForMainWorld(canvas_element_->GetFrame()); } void TearDown() override; void UnrefCanvas(); - std::unique_ptr<Canvas2DLayerBridge> MakeBridge( - const IntSize&, - Canvas2DLayerBridge::AccelerationMode); + std::unique_ptr<Canvas2DLayerBridge> MakeBridge(const IntSize&, RasterMode); Document& GetDocument() const { return *web_view_helper_->GetWebView() @@ -168,7 +167,7 @@ class CanvasRenderingContext2DTest : public ::testing::Test { class WrapGradients final : public GarbageCollected<WrapGradients> { public: - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(opaque_gradient_); visitor->Trace(alpha_gradient_); } @@ -202,12 +201,16 @@ CanvasRenderingContext2DTest::CanvasRenderingContext2DTest() opaque_bitmap_(IntSize(10, 10), kOpaqueBitmap), alpha_bitmap_(IntSize(10, 10), kTransparentBitmap) {} -void CanvasRenderingContext2DTest::CreateContext(OpacityMode opacity_mode, - LatencyMode latency_mode) { +void CanvasRenderingContext2DTest::CreateContext( + OpacityMode opacity_mode, + LatencyMode latency_mode, + ReadFrequencyMode read_frequency_mode) { String canvas_type("2d"); CanvasContextCreationAttributesCore attributes; attributes.alpha = opacity_mode == kNonOpaque; attributes.desynchronized = latency_mode == kLowLatency; + attributes.will_read_frequently = + read_frequency_mode == ReadFrequencyMode::kWillReadFrequency; canvas_element_->GetCanvasRenderingContext(canvas_type, attributes); } @@ -273,9 +276,9 @@ void CanvasRenderingContext2DTest::TearDown() { std::unique_ptr<Canvas2DLayerBridge> CanvasRenderingContext2DTest::MakeBridge( const IntSize& size, - Canvas2DLayerBridge::AccelerationMode acceleration_mode) { + RasterMode raster_mode) { std::unique_ptr<Canvas2DLayerBridge> bridge = - std::make_unique<Canvas2DLayerBridge>(size, acceleration_mode, + std::make_unique<Canvas2DLayerBridge>(size, raster_mode, CanvasColorParams()); bridge->SetCanvasResourceHost(canvas_element_); return bridge; @@ -287,9 +290,9 @@ class FakeCanvas2DLayerBridge : public Canvas2DLayerBridge { public: FakeCanvas2DLayerBridge(const IntSize& size, CanvasColorParams color_params, - AccelerationHint hint) - : Canvas2DLayerBridge(size, kDisableAcceleration, color_params), - is_accelerated_(hint != kPreferNoAcceleration) {} + RasterModeHint hint) + : Canvas2DLayerBridge(size, RasterMode::kCPU, color_params), + is_accelerated_(hint != RasterModeHint::kPreferCPU) {} ~FakeCanvas2DLayerBridge() override = default; bool IsAccelerated() const override { return is_accelerated_; } void SetIsAccelerated(bool is_accelerated) { @@ -309,16 +312,15 @@ class FakeCanvasResourceProvider : public CanvasResourceProvider { public: FakeCanvasResourceProvider(const IntSize& size, CanvasColorParams color_params, - AccelerationHint hint) + RasterModeHint hint) : CanvasResourceProvider(CanvasResourceProvider::kBitmap, size, - /*msaa_sample_count=*/0, kLow_SkFilterQuality, color_params, /*is_origin_top_left=*/false, nullptr, nullptr), - is_accelerated_(hint != kPreferNoAcceleration) {} + is_accelerated_(hint != RasterModeHint::kPreferCPU) {} ~FakeCanvasResourceProvider() override = default; bool IsAccelerated() const override { return is_accelerated_; } scoped_refptr<CanvasResource> ProduceCanvasResource() override { @@ -344,9 +346,7 @@ class MockImageBufferSurfaceForOverwriteTesting : public Canvas2DLayerBridge { public: MockImageBufferSurfaceForOverwriteTesting(const IntSize& size, CanvasColorParams color_params) - : Canvas2DLayerBridge(size, - Canvas2DLayerBridge::kDisableAcceleration, - color_params) {} + : Canvas2DLayerBridge(size, RasterMode::kCPU, color_params) {} ~MockImageBufferSurfaceForOverwriteTesting() override = default; MOCK_METHOD0(WillOverwriteCanvas, void()); }; @@ -610,10 +610,10 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) { IntSize size(10, 10); std::unique_ptr<FakeCanvasResourceProvider> fake_resource_provider = std::make_unique<FakeCanvasResourceProvider>(size, CanvasColorParams(), - kPreferAcceleration); + RasterModeHint::kPreferGPU); std::unique_ptr<FakeCanvas2DLayerBridge> fake_2d_layer_bridge = std::make_unique<FakeCanvas2DLayerBridge>(size, CanvasColorParams(), - kPreferAcceleration); + RasterModeHint::kPreferGPU); FakeCanvas2DLayerBridge* fake_2d_layer_bridge_ptr = fake_2d_layer_bridge.get(); CanvasElement().SetResourceProviderForTesting( @@ -638,10 +638,10 @@ TEST_F(CanvasRenderingContext2DTest, GPUMemoryUpdateForAcceleratedCanvas) { IntSize size2(10, 5); std::unique_ptr<FakeCanvas2DLayerBridge> fake_2d_layer_bridge2 = std::make_unique<FakeCanvas2DLayerBridge>(size2, CanvasColorParams(), - kPreferAcceleration); + RasterModeHint::kPreferGPU); std::unique_ptr<FakeCanvasResourceProvider> fake_resource_provider2 = std::make_unique<FakeCanvasResourceProvider>(size2, CanvasColorParams(), - kPreferAcceleration); + RasterModeHint::kPreferGPU); anotherCanvas->SetResourceProviderForTesting( std::move(fake_resource_provider2), std::move(fake_2d_layer_bridge2), size2); @@ -686,7 +686,7 @@ TEST_F(CanvasRenderingContext2DTest, CreateContext(kNonOpaque); IntSize size(10, 10); auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>( - size, CanvasColorParams(), kPreferAcceleration); + size, CanvasColorParams(), RasterModeHint::kPreferGPU); CanvasElement().SetResourceProviderForTesting( nullptr, std::move(fake_accelerate_surface), size); @@ -700,7 +700,7 @@ TEST_F(CanvasRenderingContext2DTest, IntSize size(10, 10); auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>( - size, CanvasColorParams(), kPreferAcceleration); + size, CanvasColorParams(), RasterModeHint::kPreferGPU); CanvasElement().SetResourceProviderForTesting( nullptr, std::move(fake_accelerate_surface), size); CanvasRenderingContext2D* context = Context2D(); @@ -727,13 +727,13 @@ TEST_F(CanvasRenderingContext2DTest, CreateContext(kNonOpaque); IntSize size(10, 10); auto fake_accelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>( - size, CanvasColorParams(), kPreferAcceleration); + size, CanvasColorParams(), RasterModeHint::kPreferGPU); CanvasElement().SetResourceProviderForTesting( nullptr, std::move(fake_accelerate_surface), size); FakeCanvasResourceHost host(size); auto fake_deaccelerate_surface = std::make_unique<FakeCanvas2DLayerBridge>( - size, CanvasColorParams(), kPreferNoAcceleration); + size, CanvasColorParams(), RasterModeHint::kPreferCPU); fake_deaccelerate_surface->SetCanvasResourceHost(&host); FakeCanvas2DLayerBridge* surface_ptr = fake_deaccelerate_surface.get(); @@ -844,12 +844,6 @@ static void TestDrawHighBitDepthPNGsOnWideGamutCanvas( } } -TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnLinearRGBCanvas) { - TestDrawHighBitDepthPNGsOnWideGamutCanvas( - "linear-rgb", GetDocument(), - Persistent<HTMLCanvasElement>(CanvasElement()), GetScriptState()); -} - TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnP3Canvas) { TestDrawHighBitDepthPNGsOnWideGamutCanvas( "p3", GetDocument(), Persistent<HTMLCanvasElement>(CanvasElement()), @@ -862,92 +856,14 @@ TEST_F(CanvasRenderingContext2DTest, DrawHighBitDepthPngOnRec2020Canvas) { GetScriptState()); } -TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) { - Persistent<HTMLCanvasElement> canvas = - Persistent<HTMLCanvasElement>(CanvasElement()); - CanvasContextCreationAttributesCore attributes; - attributes.alpha = true; - attributes.color_space = "srgb"; - CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>( - canvas->GetCanvasRenderingContext("2d", attributes)); - StringOrCanvasGradientOrCanvasPattern fill_style; - fill_style.SetString("#FFC08040"); // 255,192,128,64 - context->setFillStyle(fill_style); - context->fillRect(0, 0, 1, 1); - scoped_refptr<StaticBitmapImage> snapshot = - canvas->Snapshot(kFrontBuffer, kPreferNoAcceleration); - ASSERT_TRUE(snapshot); - sk_sp<SkImage> source_image = - snapshot->PaintImageForCurrentFrame().GetSkImage(); - SkPixmap source_pixmap; - source_image->peekPixels(&source_pixmap); - - // Create and test the ImageBitmap objects. - base::Optional<IntRect> crop_rect = IntRect(0, 0, 1, 1); - for (int conversion_iterator = kColorSpaceConversion_Default; - conversion_iterator <= kColorSpaceConversion_Last; - conversion_iterator++) { - // TODO(crbug.com/898631): Do not test "preserve" which - // is not a valid value of ColorSpaceConversion. - if (conversion_iterator == kColorSpaceConversion_Preserve) - continue; - - // Color convert using ImageBitmap - ImageBitmapOptions* options = ImageBitmapOptions::Create(); - options->setColorSpaceConversion( - ColorCorrectionTestUtils::ColorSpaceConversionToString( - static_cast<ColorSpaceConversion>(conversion_iterator))); - ImageBitmap* image_bitmap = - MakeGarbageCollected<ImageBitmap>(canvas, crop_rect, options); - ASSERT_TRUE(image_bitmap); - sk_sp<SkImage> converted_image = - image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage(); - ASSERT_TRUE(converted_image); - SkPixmap converted_pixmap; - converted_image->peekPixels(&converted_pixmap); - ASSERT_TRUE(converted_pixmap.addr()); - - // Manual color convert for testing - sk_sp<SkColorSpace> color_space = - ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace( - static_cast<ColorSpaceConversion>(conversion_iterator)); - if (conversion_iterator == kColorSpaceConversion_Preserve) - color_space = SkColorSpace::MakeSRGB(); - - // TODO: crbug.com/768855: Remove if statement when CanvasResourceProvider - // does not use SkColorSpaceXformCanvas (which rips off sRGB from - // ImageBitmap). - if (!color_space->isSRGB()) { - EXPECT_TRUE(SkColorSpace::Equals(color_space.get(), - converted_image->colorSpace())); - } - - SkColorType color_type = SkColorType::kN32_SkColorType; - if (color_space && color_space->gammaIsLinear()) - color_type = kRGBA_F16_SkColorType; - SkImageInfo image_info = SkImageInfo::Make( - 1, 1, color_type, SkAlphaType::kPremul_SkAlphaType, color_space); - SkBitmap manual_converted_bitmap; - EXPECT_TRUE(manual_converted_bitmap.tryAllocPixels(image_info)); - source_pixmap.readPixels(manual_converted_bitmap.pixmap(), 0, 0); - - ColorCorrectionTestUtils::CompareColorCorrectedPixels( - converted_pixmap.addr(), manual_converted_bitmap.pixmap().addr(), 1, - (color_type == kN32_SkColorType) ? kPixelFormat_8888 - : kPixelFormat_hhhh, - kAlphaMultiplied, kNoUnpremulRoundTripTolerance); - } -} - // The color settings of the surface of the canvas always remaines loyal to the // first created context 2D. Therefore, we have to test different canvas color // space settings for CanvasRenderingContext2D::putImageData() in different // tests. enum class CanvasColorSpaceSettings : uint8_t { CANVAS_SRGB = 0, - CANVAS_LINEARSRGB = 1, - CANVAS_REC2020 = 2, - CANVAS_P3 = 3, + CANVAS_REC2020 = 1, + CANVAS_P3 = 2, LAST = CANVAS_P3 }; @@ -957,10 +873,9 @@ enum class CanvasColorSpaceSettings : uint8_t { void TestPutImageDataOnCanvasWithColorSpaceSettings( HTMLCanvasElement& canvas_element, CanvasColorSpaceSettings canvas_colorspace_setting) { - unsigned num_image_data_color_spaces = 4; + unsigned num_image_data_color_spaces = 3; CanvasColorSpace image_data_color_spaces[] = { CanvasColorSpace::kSRGB, - CanvasColorSpace::kLinearRGB, CanvasColorSpace::kRec2020, CanvasColorSpace::kP3, }; @@ -972,19 +887,20 @@ void TestPutImageDataOnCanvasWithColorSpaceSettings( }; CanvasColorSpace canvas_color_spaces[] = { - CanvasColorSpace::kSRGB, CanvasColorSpace::kSRGB, - CanvasColorSpace::kLinearRGB, CanvasColorSpace::kRec2020, + CanvasColorSpace::kSRGB, + CanvasColorSpace::kSRGB, + CanvasColorSpace::kRec2020, CanvasColorSpace::kP3, }; String canvas_color_space_names[] = { kSRGBCanvasColorSpaceName, kSRGBCanvasColorSpaceName, - kLinearRGBCanvasColorSpaceName, kRec2020CanvasColorSpaceName, - kP3CanvasColorSpaceName}; + kRec2020CanvasColorSpaceName, kP3CanvasColorSpaceName}; CanvasPixelFormat canvas_pixel_formats[] = { - CanvasPixelFormat::kRGBA8, CanvasPixelFormat::kF16, - CanvasPixelFormat::kF16, CanvasPixelFormat::kF16, + CanvasPixelFormat::kRGBA8, + CanvasPixelFormat::kF16, + CanvasPixelFormat::kF16, CanvasPixelFormat::kF16, }; @@ -1103,12 +1019,6 @@ TEST_F(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnSRGBCanvas) { CanvasElement(), CanvasColorSpaceSettings::CANVAS_SRGB); } -TEST_F(CanvasRenderingContext2DTest, - ColorManagedPutImageDataOnLinearSRGBCanvas) { - TestPutImageDataOnCanvasWithColorSpaceSettings( - CanvasElement(), CanvasColorSpaceSettings::CANVAS_LINEARSRGB); -} - TEST_F(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnRec2020Canvas) { TestPutImageDataOnCanvasWithColorSpaceSettings( CanvasElement(), CanvasColorSpaceSettings::CANVAS_REC2020); @@ -1126,9 +1036,29 @@ TEST_F(CanvasRenderingContext2DTest, DrawSomething(); EXPECT_TRUE(Context2D()->getContextAttributes()->desynchronized()); EXPECT_TRUE(CanvasElement().LowLatencyEnabled()); - EXPECT_FALSE(CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferNoAcceleration) - ->SupportsSingleBuffering()); + EXPECT_FALSE( + CanvasElement() + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferCPU) + ->SupportsSingleBuffering()); + EXPECT_FALSE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); +} + +TEST_F(CanvasRenderingContext2DTest, + UnacceleratedIfNormalLatencyWillReadFrequently) { + CreateContext(kNonOpaque, kNormalLatency, + ReadFrequencyMode::kWillReadFrequency); + DrawSomething(); + EXPECT_TRUE(Context2D()->getContextAttributes()->willReadFrequently()); + EXPECT_FALSE( + CanvasElement().GetOrCreateCanvas2DLayerBridge()->IsAccelerated()); +} + +TEST_F(CanvasRenderingContext2DTest, + UnacceleratedIfLowLatencyWillReadFrequently) { + CreateContext(kNonOpaque, kLowLatency, ReadFrequencyMode::kWillReadFrequency); + // No need to set-up the layer bridge when testing low latency mode. + DrawSomething(); + EXPECT_TRUE(Context2D()->getContextAttributes()->willReadFrequently()); EXPECT_FALSE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); } @@ -1146,8 +1076,8 @@ TEST_F(CanvasRenderingContext2DTestAccelerated, CreateContext(kNonOpaque); IntSize size(300, 300); std::unique_ptr<Canvas2DLayerBridge> bridge = - std::make_unique<Canvas2DLayerBridge>( - size, Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); + std::make_unique<Canvas2DLayerBridge>(size, RasterMode::kGPU, + CanvasColorParams()); // Force hibernatation to occur in an immediate task. bridge->DontUseIdleSchedulingForTesting(); CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge), @@ -1157,8 +1087,7 @@ TEST_F(CanvasRenderingContext2DTestAccelerated, EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); // Take a snapshot to trigger lazy resource provider creation - CanvasElement().GetCanvas2DLayerBridge()->NewImageSnapshot( - kPreferAcceleration); + CanvasElement().GetCanvas2DLayerBridge()->NewImageSnapshot(); EXPECT_TRUE(!!CanvasElement().ResourceProvider()); EXPECT_TRUE(CanvasElement().ResourceProvider()->IsAccelerated()); EXPECT_TRUE(CanvasElement().GetLayoutBoxModelObject()); @@ -1196,8 +1125,8 @@ TEST_F(CanvasRenderingContext2DTestAccelerated, CreateContext(kNonOpaque); IntSize size(300, 300); std::unique_ptr<Canvas2DLayerBridge> bridge = - std::make_unique<Canvas2DLayerBridge>( - size, Canvas2DLayerBridge::kEnableAcceleration, CanvasColorParams()); + std::make_unique<Canvas2DLayerBridge>(size, RasterMode::kGPU, + CanvasColorParams()); // Force hibernatation to occur in an immediate task. bridge->DontUseIdleSchedulingForTesting(); CanvasElement().SetResourceProviderForTesting(nullptr, std::move(bridge), @@ -1230,10 +1159,12 @@ TEST_F(CanvasRenderingContext2DTestAccelerated, LowLatencyIsNotSingleBuffered) { // No need to set-up the layer bridge when testing low latency mode. DrawSomething(); EXPECT_TRUE(Context2D()->getContextAttributes()->desynchronized()); + EXPECT_FALSE(Context2D()->getContextAttributes()->willReadFrequently()); EXPECT_TRUE(CanvasElement().LowLatencyEnabled()); - EXPECT_FALSE(CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) - ->SupportsSingleBuffering()); + EXPECT_FALSE( + CanvasElement() + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) + ->SupportsSingleBuffering()); EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); } @@ -1268,20 +1199,21 @@ TEST_F(CanvasRenderingContext2DTestImageChromium, LowLatencyIsSingleBuffered) { // No need to set-up the layer bridge when testing low latency mode. DrawSomething(); EXPECT_TRUE(Context2D()->getContextAttributes()->desynchronized()); + EXPECT_FALSE(Context2D()->getContextAttributes()->willReadFrequently()); EXPECT_TRUE(CanvasElement().LowLatencyEnabled()); EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); EXPECT_TRUE(CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) ->SupportsSingleBuffering()); auto frame1_resource = CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) ->ProduceCanvasResource(); EXPECT_TRUE(frame1_resource); DrawSomething(); auto frame2_resource = CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) ->ProduceCanvasResource(); EXPECT_TRUE(frame2_resource); EXPECT_EQ(frame1_resource.get(), frame2_resource.get()); @@ -1312,20 +1244,21 @@ TEST_F(CanvasRenderingContext2DTestSwapChain, LowLatencyIsSingleBuffered) { // No need to set-up the layer bridge when testing low latency mode. DrawSomething(); EXPECT_TRUE(Context2D()->getContextAttributes()->desynchronized()); + EXPECT_FALSE(Context2D()->getContextAttributes()->willReadFrequently()); EXPECT_TRUE(CanvasElement().LowLatencyEnabled()); EXPECT_TRUE(CanvasElement().GetCanvas2DLayerBridge()->IsAccelerated()); EXPECT_TRUE(CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) ->SupportsSingleBuffering()); auto frame1_resource = CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) ->ProduceCanvasResource(); EXPECT_TRUE(frame1_resource); DrawSomething(); auto frame2_resource = CanvasElement() - .GetOrCreateCanvasResourceProvider(kPreferAcceleration) + .GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU) ->ProduceCanvasResource(); EXPECT_TRUE(frame2_resource); EXPECT_EQ(frame1_resource.get(), frame2_resource.get()); diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc index db362e3bd6f..9c728290626 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.cc @@ -133,7 +133,7 @@ RGBA32 CanvasStyle::PaintColor() const { return Color::kBlack; } -void CanvasStyle::Trace(Visitor* visitor) { +void CanvasStyle::Trace(Visitor* visitor) const { visitor->Trace(gradient_); visitor->Trace(pattern_); } diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h index fca9d07f187..9d500ad1bf4 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_style.h @@ -59,7 +59,7 @@ class CanvasStyle final : public GarbageCollected<CanvasStyle> { return type_ == kColorRGBA && rgba_ == rgba; } - void Trace(Visitor*); + void Trace(Visitor*) const; private: enum Type { kColorRGBA, kGradient, kImagePattern }; diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc index ab288595cb0..a9b0a45c73e 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc @@ -26,7 +26,7 @@ void HitRegion::RemovePixels(const Path& clear_area) { path_.SubtractPath(clear_area); } -void HitRegion::Trace(Visitor* visitor) { +void HitRegion::Trace(Visitor* visitor) const { visitor->Trace(control_); } @@ -118,7 +118,7 @@ unsigned HitRegionManager::GetHitRegionsCount() const { return hit_region_list_.size(); } -void HitRegionManager::Trace(Visitor* visitor) { +void HitRegionManager::Trace(Visitor* visitor) const { visitor->Trace(hit_region_list_); visitor->Trace(hit_region_id_map_); visitor->Trace(hit_region_control_map_); 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 968009a8535..dc5b137b311 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 @@ -28,7 +28,7 @@ class HitRegion final : public GarbageCollected<HitRegion> { const Path& GetPath() const { return path_; } Element* Control() const { return control_.Get(); } - void Trace(Visitor*); + void Trace(Visitor*) const; private: String id_; @@ -56,7 +56,7 @@ class HitRegionManager final : public GarbageCollected<HitRegionManager> { unsigned GetHitRegionsCount() const; - void Trace(Visitor*); + void Trace(Visitor*) const; private: typedef HeapLinkedHashSet<Member<HitRegion>> HitRegionList; diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h new file mode 100644 index 00000000000..e39074ee39d --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/identifiability_study_helper.h @@ -0,0 +1,61 @@ +// Copyright 2020 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_CANVAS_CANVAS2D_IDENTIFIABILITY_STUDY_HELPER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_IDENTIFIABILITY_STUDY_HELPER_H_ + +#include <stdint.h> + +// Must be included before identifiable_surface.h. +#include "third_party/blink/renderer/modules/canvas/canvas2d/blink_identifiability_digest_helpers.h" + +#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_study_participation.h" + +namespace blink { + +// Text operations supported on different canvas types; the intent is to use +// these values (and any input supplied to these operations) to build a running +// hash that reprensents the sequence of text operations performed on the +// canvas. A hash of all other canvas operations is maintained by hashing the +// serialized PaintOps produced by the canvas in CanvasResourceProvider. +// +// If a canvas method to exfiltrate the canvas buffer is called by a script +// (getData(), etc.), this hash will be uploaded to UKM along with a hash of the +// canvas buffer data. +// +// **Don't renumber after the privacy budget study has started to ensure +// consistency.** +enum class CanvasOps { + // CanvasRenderingContext2D / OffscreenCanvasRenderingContext2D methods. + kSetFont, + kFillText, + kStrokeText, +}; + +// A helper class to simplify maintaining the current text digest for the canvas +// context. An operation count is also maintained to limit the performance +// impact of the study. +class IdentifiabilityStudyHelper { + public: + template <typename... Ts> + void MaybeUpdateDigest(Ts... args) { + constexpr int kMaxOperations = 1 << 20; + if (!IsUserInIdentifiabilityStudy() || operation_count_ > kMaxOperations) { + return; + } + digest_ ^= IdentifiabilityDigestHelper(args...); + operation_count_++; + } + + uint64_t digest() { return digest_; } + + private: + uint64_t digest_ = 0; + int operation_count_ = 0; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CANVAS_CANVAS2D_IDENTIFIABILITY_STUDY_HELPER_H_ diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc index 29e9fbb4961..aecd6cfc5fb 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc @@ -29,6 +29,7 @@ CanvasContextCreationAttributesCore ToCanvasContextCreationAttributes( result.preserve_drawing_buffer = attrs->preserveDrawingBuffer(); result.power_preference = attrs->powerPreference(); result.stencil = attrs->stencil(); + result.will_read_frequently = attrs->willReadFrequently(); result.xr_compatible = attrs->xrCompatible(); return result; } diff --git a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl index 21324b678ac..56955c7b395 100644 --- a/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl +++ b/chromium/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl @@ -46,6 +46,7 @@ dictionary CanvasContextCreationAttributesModule { boolean alpha = true; // Also used for WebGL. [RuntimeEnabled=CanvasColorManagement] CanvasColorSpace colorSpace = "srgb"; [RuntimeEnabled=CanvasColorManagement] CanvasPixelFormat pixelFormat = "uint8"; + [RuntimeEnabled=NewCanvas2DAPI] boolean willReadFrequently = false; // WebGL attributes boolean depth = true; 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 2f2752c5f07..4b94289ec16 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,8 +51,7 @@ void ImageBitmapRenderingContextBase::SetImage(ImageBitmap* image_bitmap) { image_bitmap->close(); } -scoped_refptr<StaticBitmapImage> ImageBitmapRenderingContextBase::GetImage( - AccelerationHint) { +scoped_refptr<StaticBitmapImage> ImageBitmapRenderingContextBase::GetImage() { return image_layer_bridge_->GetImage(); } @@ -84,7 +83,7 @@ bool ImageBitmapRenderingContextBase::IsPaintable() const { return !!image_layer_bridge_->GetImage(); } -void ImageBitmapRenderingContextBase::Trace(Visitor* visitor) { +void ImageBitmapRenderingContextBase::Trace(Visitor* visitor) const { visitor->Trace(image_layer_bridge_); CanvasRenderingContext::Trace(visitor); } 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 d5d8150fbe6..1c52a9285c5 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 @@ -28,7 +28,7 @@ class MODULES_EXPORT ImageBitmapRenderingContextBase const CanvasContextCreationAttributesCore&); ~ImageBitmapRenderingContextBase() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // TODO(juanmihd): Remove this method crbug.com/941579 HTMLCanvasElement* canvas() const { @@ -44,9 +44,7 @@ class MODULES_EXPORT ImageBitmapRenderingContextBase void SetIsBeingDisplayed(bool) override {} bool isContextLost() const override { return false; } void SetImage(ImageBitmap*); - // 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) final; + scoped_refptr<StaticBitmapImage> GetImage() 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 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 266926c5f67..24460a75f43 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 @@ -105,7 +105,7 @@ OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D( canvas->SetDisableReadingFromCanvasTrue(); } -void OffscreenCanvasRenderingContext2D::Trace(Visitor* visitor) { +void OffscreenCanvasRenderingContext2D::Trace(Visitor* visitor) const { CanvasRenderingContext::Trace(visitor); BaseRenderingContext2D::Trace(visitor); } @@ -216,7 +216,7 @@ ImageBitmap* OffscreenCanvasRenderingContext2D::TransferToImageBitmap( if (!GetOrCreateCanvasResourceProvider()) return nullptr; - scoped_refptr<StaticBitmapImage> image = GetImage(kPreferAcceleration); + scoped_refptr<StaticBitmapImage> image = GetImage(); if (!image) return nullptr; image->SetOriginClean(this->OriginClean()); @@ -236,8 +236,7 @@ ImageBitmap* OffscreenCanvasRenderingContext2D::TransferToImageBitmap( return MakeGarbageCollected<ImageBitmap>(std::move(image)); } -scoped_refptr<StaticBitmapImage> OffscreenCanvasRenderingContext2D::GetImage( - AccelerationHint hint) { +scoped_refptr<StaticBitmapImage> OffscreenCanvasRenderingContext2D::GetImage() { FinalizeFrame(); if (!IsPaintable()) return nullptr; @@ -391,6 +390,8 @@ String OffscreenCanvasRenderingContext2D::font() const { void OffscreenCanvasRenderingContext2D::setFont(const String& new_font) { if (GetState().HasRealizedFont() && new_font == GetState().UnparsedFont()) return; + identifiability_study_helper_.MaybeUpdateDigest(CanvasOps::kSetFont, + new_font); base::TimeTicks start_time = base::TimeTicks::Now(); OffscreenFontCache& font_cache = GetOffscreenFontCache(); @@ -509,6 +510,12 @@ void OffscreenCanvasRenderingContext2D::DrawTextInternal( if (max_width && (!std::isfinite(*max_width) || *max_width <= 0)) return; + identifiability_study_helper_.MaybeUpdateDigest( + paint_type == CanvasRenderingContext2DState::kFillPaintType + ? CanvasOps::kFillText + : CanvasOps::kStrokeText, + IdentifiabilitySensitiveString(text), x, y, max_width ? *max_width : -1); + const Font& font = AccessFont(); const SimpleFontData* font_data = font.PrimaryFont(); DCHECK(font_data); @@ -575,9 +582,15 @@ void OffscreenCanvasRenderingContext2D::DrawTextInternal( }, [](const SkIRect& rect) // overdraw test lambda { return false; }, - bounds, paint_type); - paint_canvas->restoreToCount(save_count); - ValidateStateStack(); + bounds, paint_type, CanvasRenderingContext2DState::kNoImage); + + // |paint_canvas| maybe rese during Draw. If that happens, + // GetOrCreatePaintCanvas will create a new |paint_canvas| and return a new + // address. In this case, there is no need to call |restoreToCount|. + if (paint_canvas == GetOrCreatePaintCanvas()) { + paint_canvas->restoreToCount(save_count); + ValidateStateStack(); + } } TextMetrics* OffscreenCanvasRenderingContext2D::measureText( 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 bd98a0a7acf..faa12203c40 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/modules/canvas/canvas2d/identifiability_study_helper.h" namespace blink { @@ -58,7 +59,7 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final // CanvasRenderingContext implementation ~OffscreenCanvasRenderingContext2D() override; ContextType GetContextType() const override { return kContext2D; } - bool Is2d() const override { return true; } + bool IsRenderingContext2D() const override { return true; } bool IsComposited() const override { return false; } bool IsAccelerated() const override; void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final; @@ -69,7 +70,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) final; + scoped_refptr<StaticBitmapImage> GetImage() final; void Reset() override; void RestoreCanvasMatrixClipStack(cc::PaintCanvas* c) const override { RestoreMatrixClipStack(c); @@ -123,10 +124,14 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final ImageBitmap* TransferToImageBitmap(ScriptState*) final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool PushFrame() override; + uint64_t IdentifiabilityTextDigest() override { + return identifiability_study_helper_.digest(); + } + protected: CanvasColorParams ColorParams() const override; bool WritePixels(const SkImageInfo& orig_info, @@ -160,6 +165,8 @@ class MODULES_EXPORT OffscreenCanvasRenderingContext2D final std::mt19937 random_generator_; std::bernoulli_distribution bernoulli_distribution_; + + IdentifiabilityStudyHelper identifiability_study_helper_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc index 66c427ad875..e6e8e68f226 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc +++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.cc @@ -52,7 +52,7 @@ ExecutionContext* Clipboard::GetExecutionContext() const { return ExecutionContextClient::GetExecutionContext(); } -void Clipboard::Trace(Visitor* visitor) { +void Clipboard::Trace(Visitor* visitor) const { EventTargetWithInlineData::Trace(visitor); ExecutionContextClient::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.h b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.h index 0add6fbf205..a7bd32fb267 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard.h +++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard.h @@ -38,7 +38,7 @@ class Clipboard : public EventTargetWithInlineData, const AtomicString& InterfaceName() const override; ExecutionContext* GetExecutionContext() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: DISALLOW_COPY_AND_ASSIGN(Clipboard); diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.cc b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.cc index b352746a38b..ee00cb385f2 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.cc +++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.cc @@ -67,7 +67,7 @@ ScriptPromise ClipboardItem::getType(ScriptState* script_state, return promise; } -void ClipboardItem::Trace(Visitor* visitor) { +void ClipboardItem::Trace(Visitor* visitor) const { visitor->Trace(items_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.h b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.h index e38ddd84cb0..a497ee5f863 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.h +++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_item.h @@ -35,7 +35,7 @@ class ClipboardItem final : public ScriptWrappable { return items_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: HeapVector<std::pair<String, Member<Blob>>> items_; diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc index 76192340437..fc5f32d86fd 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc +++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc @@ -421,15 +421,20 @@ void ClipboardPromise::RequestPermission( return; } - if (!window.IsFeatureEnabled( - mojom::blink::FeaturePolicyFeature::kClipboard, - ReportOptions::kReportOnFailure, - "The Clipboard API has been blocked because of a Feature Policy " - "applied to the current document. See https://goo.gl/EuHzyv for more " - "details.")) { + constexpr char kFeaturePolicyMessage[] = + "The Clipboard API has been blocked because of a Feature Policy applied " + "to the current document. See https://goo.gl/EuHzyv for more details."; + + if ((permission == mojom::blink::PermissionName::CLIPBOARD_READ && + !window.IsFeatureEnabled( + mojom::blink::FeaturePolicyFeature::kClipboardRead, + ReportOptions::kReportOnFailure, kFeaturePolicyMessage)) || + (permission == mojom::blink::PermissionName::CLIPBOARD_WRITE && + !window.IsFeatureEnabled( + mojom::blink::FeaturePolicyFeature::kClipboardWrite, + ReportOptions::kReportOnFailure, kFeaturePolicyMessage))) { script_promise_resolver_->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotAllowedError, - "Disabled in this document by Feature Policy.")); + DOMExceptionCode::kNotAllowedError, kFeaturePolicyMessage)); return; } @@ -478,7 +483,7 @@ scoped_refptr<base::SingleThreadTaskRunner> ClipboardPromise::GetTaskRunner() { return GetExecutionContext()->GetTaskRunner(TaskType::kUserInteraction); } -void ClipboardPromise::Trace(Visitor* visitor) { +void ClipboardPromise::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(script_promise_resolver_); visitor->Trace(clipboard_writer_); 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 0d285d992d3..18efbc8c632 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h +++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_promise.h @@ -50,7 +50,7 @@ class ClipboardPromise final : public GarbageCollected<ClipboardPromise>, // For rejections originating from ClipboardWriter. void RejectFromReadOrDecodeFailure(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Called to begin writing a type. 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 b9c55a88603..47cba154aa2 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc +++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc @@ -88,7 +88,7 @@ ClipboardReader::ClipboardReader(SystemClipboard* system_clipboard) ClipboardReader::~ClipboardReader() = default; -void ClipboardReader::Trace(Visitor* visitor) { +void ClipboardReader::Trace(Visitor* visitor) const { visitor->Trace(system_clipboard_); } diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.h b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.h index 8434810d896..c730c001d37 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.h +++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_reader.h @@ -28,7 +28,7 @@ class ClipboardReader : public GarbageCollected<ClipboardReader> { // Returns nullptr if the data is empty or invalid. virtual Blob* ReadFromSystem() = 0; - void Trace(Visitor* visitor); + void Trace(Visitor* visitor) const; protected: explicit ClipboardReader(SystemClipboard* system_clipboard); diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc index 8ed94dce9fc..2891db58d47 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc +++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc @@ -233,7 +233,7 @@ void ClipboardWriter::DidFail(FileErrorCode error_code) { promise_->RejectFromReadOrDecodeFailure(); } -void ClipboardWriter::Trace(Visitor* visitor) { +void ClipboardWriter::Trace(Visitor* visitor) const { visitor->Trace(promise_); visitor->Trace(system_clipboard_); visitor->Trace(raw_system_clipboard_); diff --git a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.h b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.h index c713c2c3737..527b063cd20 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.h +++ b/chromium/third_party/blink/renderer/modules/clipboard/clipboard_writer.h @@ -48,7 +48,7 @@ class ClipboardWriter : public GarbageCollected<ClipboardWriter>, void DidFinishLoading() override; void DidFail(FileErrorCode) override; - void Trace(Visitor*); + void Trace(Visitor*) const; protected: ClipboardWriter(SystemClipboard* system_clipboard, ClipboardPromise* promise); diff --git a/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.cc b/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.cc index 8bc16b32106..2565c92c2fa 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.cc +++ b/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.cc @@ -28,7 +28,7 @@ Clipboard* NavigatorClipboard::clipboard(ScriptState* script_state, return supplement->clipboard_; } -void NavigatorClipboard::Trace(Visitor* visitor) { +void NavigatorClipboard::Trace(Visitor* visitor) const { visitor->Trace(clipboard_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.h b/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.h index 9ec7666160e..6746c62edbb 100644 --- a/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.h +++ b/chromium/third_party/blink/renderer/modules/clipboard/navigator_clipboard.h @@ -26,7 +26,7 @@ class NavigatorClipboard final : public GarbageCollected<NavigatorClipboard>, explicit NavigatorClipboard(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<Clipboard> clipboard_; diff --git a/chromium/third_party/blink/renderer/modules/compression/compression_stream.cc b/chromium/third_party/blink/renderer/modules/compression/compression_stream.cc index c604d6a38c3..d82f0b8f020 100644 --- a/chromium/third_party/blink/renderer/modules/compression/compression_stream.cc +++ b/chromium/third_party/blink/renderer/modules/compression/compression_stream.cc @@ -26,7 +26,7 @@ WritableStream* CompressionStream::writable() const { return transform_->Writable(); } -void CompressionStream::Trace(Visitor* visitor) { +void CompressionStream::Trace(Visitor* visitor) const { visitor->Trace(transform_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/compression/compression_stream.h b/chromium/third_party/blink/renderer/modules/compression/compression_stream.h index 0686d54073f..f752f96d22d 100644 --- a/chromium/third_party/blink/renderer/modules/compression/compression_stream.h +++ b/chromium/third_party/blink/renderer/modules/compression/compression_stream.h @@ -23,7 +23,7 @@ class CompressionStream final : public ScriptWrappable { ReadableStream* readable() const; WritableStream* writable() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<TransformStream> transform_; diff --git a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.cc b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.cc index 251ec6ae490..5ea0d0c25ab 100644 --- a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.cc +++ b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.cc @@ -27,7 +27,7 @@ WritableStream* DecompressionStream::writable() const { return transform_->Writable(); } -void DecompressionStream::Trace(Visitor* visitor) { +void DecompressionStream::Trace(Visitor* visitor) const { visitor->Trace(transform_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.h b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.h index a9828622cf5..98466752654 100644 --- a/chromium/third_party/blink/renderer/modules/compression/decompression_stream.h +++ b/chromium/third_party/blink/renderer/modules/compression/decompression_stream.h @@ -23,7 +23,7 @@ class DecompressionStream final : public ScriptWrappable { ReadableStream* readable() const; WritableStream* writable() const; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<TransformStream> transform_; diff --git a/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc index 4ee5a115ba8..e663e563d58 100644 --- a/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc +++ b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.cc @@ -132,7 +132,7 @@ void DeflateTransformer::Deflate(const uint8_t* start, } while (stream_.avail_out == 0); } -void DeflateTransformer::Trace(Visitor* visitor) { +void DeflateTransformer::Trace(Visitor* visitor) const { visitor->Trace(script_state_); TransformStreamTransformer::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.h b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.h index ff740df27a2..d753166ccf9 100644 --- a/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.h +++ b/chromium/third_party/blink/renderer/modules/compression/deflate_transformer.h @@ -30,7 +30,7 @@ class DeflateTransformer final : public TransformStreamTransformer { ScriptState* GetScriptState() override { return script_state_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: using IsFinished = util::StrongAlias<class IsFinishedTag, bool>; diff --git a/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc index 414b126ac21..f348a5086e4 100644 --- a/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc +++ b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.cc @@ -159,7 +159,7 @@ void InflateTransformer::Inflate(const uint8_t* start, } while (stream_.avail_out == 0); } -void InflateTransformer::Trace(Visitor* visitor) { +void InflateTransformer::Trace(Visitor* visitor) const { visitor->Trace(script_state_); TransformStreamTransformer::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.h b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.h index e7f0510faf5..290e91808df 100644 --- a/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.h +++ b/chromium/third_party/blink/renderer/modules/compression/inflate_transformer.h @@ -30,7 +30,7 @@ class InflateTransformer final : public TransformStreamTransformer { ScriptState* GetScriptState() override { return script_state_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: using IsFinished = util::StrongAlias<class IsFinishedTag, bool>; 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 df698e7bc9b..41c05fd30e2 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 @@ -100,7 +100,8 @@ constexpr char kIcon[] = "icon"; } // namespace -ContactsManager::ContactsManager() : contacts_manager_(nullptr) {} +ContactsManager::ContactsManager(ExecutionContext* execution_context) + : contacts_manager_(execution_context) {} ContactsManager::~ContactsManager() = default; @@ -234,7 +235,7 @@ ScriptPromise ContactsManager::getProperties(ScriptState* script_state) { ToV8(GetProperties(script_state), script_state)); } -void ContactsManager::Trace(Visitor* visitor) { +void ContactsManager::Trace(Visitor* visitor) const { visitor->Trace(contacts_manager_); ScriptWrappable::Trace(visitor); } 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 7b79ef99ab5..89970986e3a 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 @@ -8,6 +8,7 @@ #include "third_party/blink/public/mojom/contacts/contacts_manager.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_contacts_select_options.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/thread_state.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" @@ -25,7 +26,7 @@ class ContactsManager final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - ContactsManager(); + explicit ContactsManager(ExecutionContext* execution_context); ~ContactsManager() override; // Web-exposed function defined in the IDL file. @@ -35,7 +36,7 @@ class ContactsManager final : public ScriptWrappable { ExceptionState& exception_state); ScriptPromise getProperties(ScriptState* script_state); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: mojom::blink::ContactsManager* GetContactsManager(ScriptState* script_state); diff --git a/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.cc b/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.cc index f1afab2f319..8653bfb40db 100644 --- a/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.cc +++ b/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.cc @@ -30,12 +30,14 @@ ContactsManager* NavigatorContacts::contacts(Navigator& navigator) { } ContactsManager* NavigatorContacts::contacts() { - if (!contacts_manager_) - contacts_manager_ = MakeGarbageCollected<ContactsManager>(); + if (!contacts_manager_) { + contacts_manager_ = MakeGarbageCollected<ContactsManager>( + GetSupplementable()->GetExecutionContext()); + } return contacts_manager_; } -void NavigatorContacts::Trace(Visitor* visitor) { +void NavigatorContacts::Trace(Visitor* visitor) const { visitor->Trace(contacts_manager_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.h b/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.h index 2014315ae0b..b03e32bfc1f 100644 --- a/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.h +++ b/chromium/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.h @@ -29,7 +29,7 @@ class NavigatorContacts final : public GarbageCollected<NavigatorContacts>, explicit NavigatorContacts(Navigator& navigator); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<ContactsManager> contacts_manager_; 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 dc15839c7e5..ac60e4a8065 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 @@ -57,7 +57,8 @@ blink::mojom::blink::ContentDescriptionPtr TypeConverter< result->category = GetContentCategory(description->category()); for (const auto& icon : description->icons()) { result->icons.push_back(blink::mojom::blink::ContentIconDefinition::New( - icon->src(), icon->sizes(), icon->type())); + icon->src(), icon->hasSizes() ? icon->sizes() : String(), + icon->hasType() ? icon->type() : String())); } result->launch_url = description->url(); diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter_test.cc b/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter_test.cc index c97cba6b15e..288f9c075fa 100644 --- a/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter_test.cc +++ b/chromium/third_party/blink/renderer/modules/content_index/content_description_type_converter_test.cc @@ -14,6 +14,8 @@ namespace blink { +namespace { + const blink::ContentDescription* CreateDescription(const WTF::String& category, const WTF::String& url) { auto* description = blink::MakeGarbageCollected<blink::ContentDescription>(); @@ -30,10 +32,27 @@ const blink::ContentDescription* CreateDescription(const WTF::String& category, return description; } +// Migration adapters for operator==(ContentIconDefinition). +base::Optional<String> GetSizesOrNone(const ContentIconDefinition* cid) { + if (cid->hasSizes()) + return cid->sizes(); + return base::nullopt; +} + +base::Optional<String> GetTypeOrNone(const ContentIconDefinition* cid) { + if (cid->hasType()) + return cid->type(); + return base::nullopt; +} + +} // anonymous namespace + +// TODO(crbug.com/1070871): Use fooOr() and drop migration adapters above. bool operator==(const Member<ContentIconDefinition>& cid1, const Member<ContentIconDefinition>& cid2) { - return cid1->src() == cid2->src() && cid1->sizes() == cid2->sizes() && - cid1->type() == cid2->type(); + return cid1->src() == cid2->src() && + GetSizesOrNone(cid1) == GetSizesOrNone(cid2) && + GetTypeOrNone(cid1) == GetTypeOrNone(cid2); } bool operator==(const ContentDescription& cd1, const ContentDescription& cd2) { 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 e5a3a751d90..247034bb36f 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 @@ -272,7 +272,7 @@ void ContentIndex::DidGetDescriptions( } } -void ContentIndex::Trace(Visitor* visitor) { +void ContentIndex::Trace(Visitor* visitor) const { visitor->Trace(registration_); visitor->Trace(content_index_service_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/content_index/content_index.h b/chromium/third_party/blink/renderer/modules/content_index/content_index.h index d6686899b36..839c3ac26c5 100644 --- a/chromium/third_party/blink/renderer/modules/content_index/content_index.h +++ b/chromium/third_party/blink/renderer/modules/content_index/content_index.h @@ -40,7 +40,7 @@ class ContentIndex final : public ScriptWrappable { ScriptPromise getDescriptions(ScriptState* script_state, ExceptionState& exception_state); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: mojom::blink::ContentIndexService* GetService(); 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 da933d03295..b7f6f1f9883 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 @@ -30,7 +30,7 @@ class MODULES_EXPORT ContentIndexIconLoader final const Vector<gfx::Size>& icon_sizes, IconsCallback callback); - void Trace(Visitor* visitor) {} + void Trace(Visitor* visitor) const {} private: void DidGetIcons(mojom::blink::ContentDescriptionPtr description, diff --git a/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.cc b/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.cc index e2ebdceb869..e50bcfe8a4e 100644 --- a/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.cc +++ b/chromium/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.cc @@ -48,7 +48,7 @@ ContentIndex* ServiceWorkerRegistrationContentIndex::index() { return content_index_.Get(); } -void ServiceWorkerRegistrationContentIndex::Trace(Visitor* visitor) { +void ServiceWorkerRegistrationContentIndex::Trace(Visitor* visitor) const { visitor->Trace(registration_); visitor->Trace(content_index_); Supplement<ServiceWorkerRegistration>::Trace(visitor); 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 49e3a83c829..03fc2ef9d7c 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 @@ -32,7 +32,7 @@ class ServiceWorkerRegistrationContentIndex final static ContentIndex* index(ServiceWorkerRegistration& registration); ContentIndex* index(); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<ServiceWorkerRegistration> registration_; diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/OWNERS b/chromium/third_party/blink/renderer/modules/cookie_store/OWNERS index b23c10fd54c..c9ae9e5c245 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/OWNERS +++ b/chromium/third_party/blink/renderer/modules/cookie_store/OWNERS @@ -1,8 +1,4 @@ -# Primary -pwnall@chromium.org - -# Secondary -jsbell@chromium.org +file://content/browser/cookie_store/OWNERS # TEAM: storage-dev@chromium.org # COMPONENT: Blink>Storage>CookiesAPI diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc index f02bb75b83f..db1f40c3a3c 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc +++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.cc @@ -23,7 +23,7 @@ const AtomicString& CookieChangeEvent::InterfaceName() const { return event_interface_names::kCookieChangeEvent; } -void CookieChangeEvent::Trace(Visitor* visitor) { +void CookieChangeEvent::Trace(Visitor* visitor) const { Event::Trace(visitor); visitor->Trace(changed_); visitor->Trace(deleted_); @@ -58,7 +58,7 @@ String ToCookieListItemSameSite(network::mojom::CookieSameSite same_site) { case network::mojom::CookieSameSite::NO_RESTRICTION: return "none"; case network::mojom::CookieSameSite::UNSPECIFIED: - return "unspecified"; + return String(); } NOTREACHED(); @@ -67,6 +67,8 @@ String ToCookieListItemSameSite(network::mojom::CookieSameSite same_site) { } // namespace // static +// TODO(crbug.com/1092695): Update to take in CookieWithAccessResult so +// CookieListItem can use EffectiveSameSite for SameSite. CookieListItem* CookieChangeEvent::ToCookieListItem( const CanonicalCookie& canonical_cookie, bool is_deleted) { @@ -75,7 +77,9 @@ CookieListItem* CookieChangeEvent::ToCookieListItem( list_item->setName(canonical_cookie.Name()); list_item->setPath(canonical_cookie.Path()); list_item->setSecure(canonical_cookie.IsSecure()); - list_item->setSameSite(ToCookieListItemSameSite(canonical_cookie.SameSite())); + auto&& same_site = ToCookieListItemSameSite(canonical_cookie.SameSite()); + if (!same_site.IsNull()) + list_item->setSameSite(same_site); // The domain of host-only cookies is the host name, without a dot (.) prefix. String cookie_domain = canonical_cookie.Domain(); diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h index 43b6f74e7a0..05e8011f72a 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h +++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_change_event.h @@ -59,7 +59,7 @@ class CookieChangeEvent final : public Event { const AtomicString& InterfaceName() const override; // GarbageCollected - void Trace(Visitor*) override; + void Trace(Visitor*) const override; static CookieListItem* ToCookieListItem( const CanonicalCookie& canonical_cookie, diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_options.idl b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_init.idl index 78e14a10627..3c07486849f 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_options.idl +++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_init.idl @@ -1,8 +1,8 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://github.com/WICG/async-cookies-api/blob/gh-pages/explainer.md +// https://wicg.github.io/cookie-store/explainer.html enum CookieSameSite { "strict", @@ -10,9 +10,11 @@ enum CookieSameSite { "none" }; -dictionary CookieStoreSetOptions { - DOMTimeStamp? expires = null; +dictionary CookieInit { + required USVString name; + required USVString value; USVString? domain = null; USVString path = "/"; + DOMTimeStamp? expires = null; CookieSameSite sameSite = "strict"; }; diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl index b6380896903..2602a1fd244 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl +++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl @@ -5,13 +5,13 @@ // https://github.com/WICG/async-cookies-api/blob/gh-pages/explainer.md dictionary CookieListItem { - required USVString name; + USVString name; USVString value; - USVString? domain = null; - USVString path = "/"; - DOMTimeStamp? expires = null; - boolean secure = true; - CookieSameSite sameSite = "strict"; + USVString? domain; + USVString path; + DOMTimeStamp? expires; + boolean secure; + CookieSameSite sameSite; }; typedef sequence<CookieListItem> CookieList; 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 20dbbeeaf7a..27619be7941 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 @@ -10,11 +10,10 @@ #include "services/network/public/mojom/restricted_cookie_manager.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/bindings/modules/v8/v8_cookie_init.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_list_item.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_delete_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_get_options.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_set_extra_options.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_set_options.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/frame/local_dom_window.h" @@ -69,7 +68,7 @@ network::mojom::blink::CookieManagerGetOptionsPtr ToBackendOptions( // Returns no value if and only if an exception is thrown. base::Optional<CanonicalCookie> ToCanonicalCookie( const KURL& cookie_url, - const CookieStoreSetExtraOptions* options, + const CookieInit* options, ExceptionState& exception_state) { const String& name = options->name(); const String& value = options->value(); @@ -79,8 +78,8 @@ base::Optional<CanonicalCookie> ToCanonicalCookie( return base::nullopt; } - base::Time expires = options->hasExpires() - ? base::Time::FromJavaTime(options->expires()) + base::Time expires = options->hasExpiresNonNull() + ? base::Time::FromJavaTime(options->expiresNonNull()) : base::Time(); String cookie_url_host = cookie_url.Host(); @@ -256,7 +255,7 @@ ScriptPromise CookieStore::getAll(ScriptState* script_state, ExceptionState& exception_state) { UseCounter::Count(CurrentExecutionContext(script_state->GetIsolate()), WebFeature::kCookieStoreAPI); - RecordMatchType(options->matchType()); + RecordMatchType(*options); return DoRead(script_state, options, &CookieStore::GetAllForUrlToGetAllResult, exception_state); @@ -275,7 +274,7 @@ ScriptPromise CookieStore::get(ScriptState* script_state, ExceptionState& exception_state) { UseCounter::Count(CurrentExecutionContext(script_state->GetIsolate()), WebFeature::kCookieStoreAPI); - RecordMatchType(options->matchType()); + RecordMatchType(*options); return DoRead(script_state, options, &CookieStore::GetAllForUrlToGetResult, exception_state); @@ -284,22 +283,15 @@ ScriptPromise CookieStore::get(ScriptState* script_state, ScriptPromise CookieStore::set(ScriptState* script_state, const String& name, const String& value, - const CookieStoreSetOptions* options, ExceptionState& exception_state) { - CookieStoreSetExtraOptions* set_options = - CookieStoreSetExtraOptions::Create(); + CookieInit* set_options = CookieInit::Create(); set_options->setName(name); set_options->setValue(value); - if (options->hasExpires()) - set_options->setExpires(options->expires()); - set_options->setDomain(options->domain()); - set_options->setPath(options->path()); - set_options->setSameSite(options->sameSite()); return set(script_state, set_options, exception_state); } ScriptPromise CookieStore::set(ScriptState* script_state, - const CookieStoreSetExtraOptions* options, + const CookieInit* options, ExceptionState& exception_state) { UseCounter::Count(CurrentExecutionContext(script_state->GetIsolate()), WebFeature::kCookieStoreAPI); @@ -313,8 +305,7 @@ ScriptPromise CookieStore::Delete(ScriptState* script_state, UseCounter::Count(CurrentExecutionContext(script_state->GetIsolate()), WebFeature::kCookieStoreAPI); - CookieStoreSetExtraOptions* set_options = - CookieStoreSetExtraOptions::Create(); + CookieInit* set_options = CookieInit::Create(); set_options->setName(name); set_options->setValue(g_empty_string); set_options->setExpires(0); @@ -324,8 +315,7 @@ ScriptPromise CookieStore::Delete(ScriptState* script_state, ScriptPromise CookieStore::Delete(ScriptState* script_state, const CookieStoreDeleteOptions* options, ExceptionState& exception_state) { - CookieStoreSetExtraOptions* set_options = - CookieStoreSetExtraOptions::Create(); + CookieInit* set_options = CookieInit::Create(); set_options->setName(options->name()); set_options->setValue(g_empty_string); set_options->setExpires(0); @@ -335,7 +325,7 @@ ScriptPromise CookieStore::Delete(ScriptState* script_state, return DoWrite(script_state, set_options, exception_state); } -void CookieStore::Trace(Visitor* visitor) { +void CookieStore::Trace(Visitor* visitor) const { visitor->Trace(change_listener_receiver_); EventTargetWithInlineData::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); @@ -427,7 +417,8 @@ ScriptPromise CookieStore::DoRead( // static void CookieStore::GetAllForUrlToGetAllResult( ScriptPromiseResolver* resolver, - const Vector<CanonicalCookie>& backend_cookies) { + const Vector<network::mojom::blink::CookieWithAccessResultPtr> + backend_cookies) { ScriptState* script_state = resolver->GetScriptState(); if (!script_state->ContextIsValid()) return; @@ -437,7 +428,7 @@ void CookieStore::GetAllForUrlToGetAllResult( cookies.ReserveInitialCapacity(backend_cookies.size()); for (const auto& backend_cookie : backend_cookies) { cookies.push_back(CookieChangeEvent::ToCookieListItem( - backend_cookie, false /* is_deleted */)); + backend_cookie->cookie, false /* is_deleted */)); } resolver->Resolve(std::move(cookies)); @@ -446,7 +437,8 @@ void CookieStore::GetAllForUrlToGetAllResult( // static void CookieStore::GetAllForUrlToGetResult( ScriptPromiseResolver* resolver, - const Vector<CanonicalCookie>& backend_cookies) { + const Vector<network::mojom::blink::CookieWithAccessResultPtr> + backend_cookies) { ScriptState* script_state = resolver->GetScriptState(); if (!script_state->ContextIsValid()) return; @@ -459,12 +451,12 @@ void CookieStore::GetAllForUrlToGetResult( const auto& backend_cookie = backend_cookies.front(); CookieListItem* cookie = CookieChangeEvent::ToCookieListItem( - backend_cookie, false /* is_deleted */); + backend_cookie->cookie, false /* is_deleted */); resolver->Resolve(cookie); } ScriptPromise CookieStore::DoWrite(ScriptState* script_state, - const CookieStoreSetExtraOptions* options, + const CookieInit* options, ExceptionState& exception_state) { ExecutionContext* context = ExecutionContext::From(script_state); if (!context->GetSecurityOrigin()->CanAccessCookies()) { 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 7cfec4bfb4d..9fac59972b7 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,6 +7,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "net/cookies/site_for_cookies.h" +#include "services/network/public/mojom/cookie_manager.mojom-blink-forward.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/renderer/bindings/core/v8/script_promise.h" @@ -21,11 +22,9 @@ namespace blink { -class CanonicalCookie; +class CookieInit; class CookieStoreDeleteOptions; class CookieStoreGetOptions; -class CookieStoreSetOptions; -class CookieStoreSetExtraOptions; class ExceptionState; class ScriptPromiseResolver; class ScriptState; @@ -54,20 +53,17 @@ class CookieStore final : public EventTargetWithInlineData, ExceptionState&); ScriptPromise set(ScriptState*, - const CookieStoreSetExtraOptions*, - ExceptionState&); - ScriptPromise set(ScriptState*, const String& name, const String& value, - const CookieStoreSetOptions*, ExceptionState&); + ScriptPromise set(ScriptState*, const CookieInit*, ExceptionState&); ScriptPromise Delete(ScriptState*, const String& name, ExceptionState&); ScriptPromise Delete(ScriptState*, const CookieStoreDeleteOptions*, ExceptionState&); // GarbageCollected - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // ExecutionContextLifecycleObserver void ContextDestroyed() override; @@ -78,7 +74,7 @@ class CookieStore final : public EventTargetWithInlineData, ExecutionContext* GetExecutionContext() const override; void RemoveAllEventListeners() override; - // RestrictedCookieChangeListener + // network::mojom::blink::CookieChangeListener void OnCookieChange( network::mojom::blink::CookieChangeInfoPtr change) override; @@ -90,8 +86,9 @@ class CookieStore final : public EventTargetWithInlineData, const RegisteredEventListener&) final; private: - using DoReadBackendResultConverter = void (*)(ScriptPromiseResolver*, - const Vector<CanonicalCookie>&); + using DoReadBackendResultConverter = + void (*)(ScriptPromiseResolver*, + const Vector<network::mojom::blink::CookieWithAccessResultPtr>); // Common code in CookieStore::{get,getAll}. // @@ -108,18 +105,18 @@ class CookieStore final : public EventTargetWithInlineData, // the promise result expected by CookieStore.getAll. static void GetAllForUrlToGetAllResult( ScriptPromiseResolver*, - const Vector<CanonicalCookie>& backend_result); + const Vector<network::mojom::blink::CookieWithAccessResultPtr> + backend_result); // Converts the result of a RestrictedCookieManager::GetAllForUrl mojo call to // the promise result expected by CookieStore.get. static void GetAllForUrlToGetResult( ScriptPromiseResolver*, - const Vector<CanonicalCookie>& backend_result); + const Vector<network::mojom::blink::CookieWithAccessResultPtr> + backend_result); // Common code in CookieStore::delete and CookieStore::set. - ScriptPromise DoWrite(ScriptState*, - const CookieStoreSetExtraOptions*, - ExceptionState&); + ScriptPromise DoWrite(ScriptState*, const CookieInit*, ExceptionState&); static void OnSetCanonicalCookieResult(ScriptPromiseResolver*, bool backend_result); diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.idl b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.idl index 7d4b6beb7a8..b1bb1b83d0d 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.idl +++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store.idl @@ -21,9 +21,9 @@ // https://wicg.github.io/cookie-store/explainer.html#the-modifications-api [CallWith=ScriptState, Measure, RaisesException] Promise<void> set( - USVString name, USVString value, optional CookieStoreSetOptions options = {}); + USVString name, USVString value); [CallWith=ScriptState, Measure, RaisesException] Promise<void> set( - CookieStoreSetExtraOptions options); + CookieInit cookieInit); [CallWith=ScriptState, ImplementedAs=Delete, Measure, RaisesException] Promise<void> delete(USVString name); [CallWith=ScriptState, ImplementedAs=Delete, Measure, RaisesException] diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc index ee361a79f42..0981ba80b37 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc +++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.cc @@ -105,16 +105,15 @@ KURL DefaultCookieURL(ServiceWorkerRegistration* registration) { CookieStoreManager::CookieStoreManager( ServiceWorkerRegistration* registration, - mojo::Remote<mojom::blink::CookieStore> backend) + HeapMojoRemote<mojom::blink::CookieStore, + HeapMojoWrapperMode::kWithoutContextObserver> backend) : registration_(registration), backend_(std::move(backend)), default_cookie_url_(DefaultCookieURL(registration)) { DCHECK(registration_); - DCHECK(backend_); + DCHECK(backend_.is_bound()); } -CookieStoreManager::~CookieStoreManager() = default; - ScriptPromise CookieStoreManager::subscribe( ScriptState* script_state, const HeapVector<Member<CookieStoreGetOptions>>& subscriptions, @@ -122,7 +121,7 @@ ScriptPromise CookieStoreManager::subscribe( Vector<mojom::blink::CookieChangeSubscriptionPtr> backend_subscriptions; backend_subscriptions.ReserveInitialCapacity(subscriptions.size()); for (const CookieStoreGetOptions* subscription : subscriptions) { - RecordMatchType(subscription->matchType()); + RecordMatchType(*subscription); mojom::blink::CookieChangeSubscriptionPtr backend_subscription = ToBackendSubscription(default_cookie_url_, subscription, exception_state); @@ -148,7 +147,7 @@ ScriptPromise CookieStoreManager::unsubscribe( Vector<mojom::blink::CookieChangeSubscriptionPtr> backend_subscriptions; backend_subscriptions.ReserveInitialCapacity(subscriptions.size()); for (const CookieStoreGetOptions* subscription : subscriptions) { - RecordMatchType(subscription->matchType()); + RecordMatchType(*subscription); mojom::blink::CookieChangeSubscriptionPtr backend_subscription = ToBackendSubscription(default_cookie_url_, subscription, exception_state); @@ -184,8 +183,9 @@ ScriptPromise CookieStoreManager::getSubscriptions( return resolver->Promise(); } -void CookieStoreManager::Trace(Visitor* visitor) { +void CookieStoreManager::Trace(Visitor* visitor) const { visitor->Trace(registration_); + visitor->Trace(backend_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h index ed2f718dd8d..d42c09d23d3 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h +++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h @@ -5,12 +5,13 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_MANAGER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_MANAGER_H_ -#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/cookie_store/cookie_store.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_registration.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/heap_mojo_remote.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -25,11 +26,11 @@ class CookieStoreManager final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - CookieStoreManager(ServiceWorkerRegistration* registration, - mojo::Remote<mojom::blink::CookieStore> backend); - // Needed because of the - // mojo::Remote<network::mojom::blink::CookieStore> - ~CookieStoreManager() override; + CookieStoreManager( + ServiceWorkerRegistration* registration, + HeapMojoRemote<mojom::blink::CookieStore, + HeapMojoWrapperMode::kWithoutContextObserver> backend); + ~CookieStoreManager() override = default; ScriptPromise subscribe( ScriptState* script_state, @@ -43,7 +44,7 @@ class CookieStoreManager final : public ScriptWrappable { ExceptionState& exception_state); // GarbageCollected - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: // The non-static callbacks keep CookieStoreManager alive during mojo calls. @@ -62,7 +63,9 @@ class CookieStoreManager final : public ScriptWrappable { Member<ServiceWorkerRegistration> registration_; // Wraps a Mojo pipe for managing service worker cookie change subscriptions. - mojo::Remote<mojom::blink::CookieStore> backend_; + HeapMojoRemote<mojom::blink::CookieStore, + HeapMojoWrapperMode::kWithoutContextObserver> + backend_; // Default for cookie_url in CookieStoreGetOptions. // diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl index 36568e386b3..8876f55c5e1 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl +++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl @@ -5,8 +5,7 @@ // https://wicg.github.io/cookie-store/explainer.html#the-change-events-api [ - Exposed=(ServiceWorker,Window), - RuntimeEnabled=CookieStoreWorker, + Exposed(ServiceWorker CookieStoreWorker, Window CookieStoreDocument), SecureContext ] interface CookieStoreManager { [CallWith=ScriptState, MeasureAs=CookieStoreAPI, RaisesException] diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.cc b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.cc index 7d841cfa57f..b221803c7f8 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.cc +++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.h" #include "base/metrics/histogram_macros.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_cookie_store_get_options.h" namespace blink { @@ -15,16 +16,22 @@ enum class MatchTypeOption { kUnspecified = 0, kEquals = 1, kStartsWith = 2, - kMaxValue = kStartsWith + kMaxValue = kStartsWith, }; -void RecordMatchType(const String& matchType) { +void RecordMatchType(const CookieStoreGetOptions& options) { MatchTypeOption uma_match_type; - if (matchType.IsEmpty()) { + // TODO(crbug.com/1092328): Switch by V8CookieMatchType::Enum. + if (!options.hasMatchType()) { uma_match_type = MatchTypeOption::kUnspecified; - } else if (matchType == "starts-with") { + } else if (options.matchType() == "equals") { + uma_match_type = MatchTypeOption::kEquals; + } else if (options.matchType() == "starts-with") { uma_match_type = MatchTypeOption::kStartsWith; } else { + NOTREACHED(); + // In case of an invalid value, we assume it's "equals" for the consistency + // of UMA. uma_match_type = MatchTypeOption::kEquals; } UMA_HISTOGRAM_ENUMERATION("Blink.CookieStore.MatchType", uma_match_type); diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.h b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.h index ad7fc8849a0..af2d5a66699 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.h +++ b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_metrics.h @@ -5,12 +5,12 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_METRICS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_COOKIE_STORE_COOKIE_STORE_METRICS_H_ -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - namespace blink { +class CookieStoreGetOptions; + // Record explicitly set MatchType option with UMA. -void RecordMatchType(const String& matchType); +void RecordMatchType(const CookieStoreGetOptions& options); } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_extra_options.idl b/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_extra_options.idl deleted file mode 100644 index 0a1b9a112bb..00000000000 --- a/chromium/third_party/blink/renderer/modules/cookie_store/cookie_store_set_extra_options.idl +++ /dev/null @@ -1,10 +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. - -// https://github.com/WICG/async-cookies-api/blob/gh-pages/explainer.md - -dictionary CookieStoreSetExtraOptions : CookieStoreSetOptions { - required USVString name; - required USVString value; -}; diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc b/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc index 868003337a0..948a81ef34a 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc +++ b/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.cc @@ -20,7 +20,7 @@ const AtomicString& ExtendableCookieChangeEvent::InterfaceName() const { return event_interface_names::kExtendableCookieChangeEvent; } -void ExtendableCookieChangeEvent::Trace(Visitor* visitor) { +void ExtendableCookieChangeEvent::Trace(Visitor* visitor) const { ExtendableEvent::Trace(visitor); visitor->Trace(changed_); visitor->Trace(deleted_); diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h b/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h index db303f001bc..e7ce5ed10b1 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h +++ b/chromium/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.h @@ -57,7 +57,7 @@ class ExtendableCookieChangeEvent final : public ExtendableEvent { const AtomicString& InterfaceName() const override; // GarbageCollected - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc b/chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc index cdb5ad25cc5..85f3a1a05d5 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc +++ b/chromium/third_party/blink/renderer/modules/cookie_store/global_cookie_store.cc @@ -61,7 +61,7 @@ class GlobalCookieStoreImpl final return cookie_store_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(cookie_store_); Supplement<T>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/idls.gni b/chromium/third_party/blink/renderer/modules/cookie_store/idls.gni index bda748d3c21..16de1d6cb2e 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/idls.gni +++ b/chromium/third_party/blink/renderer/modules/cookie_store/idls.gni @@ -11,11 +11,10 @@ modules_idl_files = [ modules_dictionary_idl_files = [ "cookie_change_event_init.idl", + "cookie_init.idl", "cookie_list_item.idl", "cookie_store_delete_options.idl", "cookie_store_get_options.idl", - "cookie_store_set_extra_options.idl", - "cookie_store_set_options.idl", "extendable_cookie_change_event_init.idl", ] diff --git a/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.cc b/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.cc index 91944cf6d07..450d58eb80d 100644 --- a/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.cc +++ b/chromium/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.cc @@ -7,6 +7,8 @@ #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/modules/cookie_store/cookie_store_manager.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_registration.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" namespace blink { @@ -52,7 +54,9 @@ class ServiceWorkerRegistrationCookiesImpl final return nullptr; } - mojo::Remote<mojom::blink::CookieStore> backend; + HeapMojoRemote<mojom::blink::CookieStore, + HeapMojoWrapperMode::kWithoutContextObserver> + backend(execution_context); // TODO(pwnall): Replace TaskType::kInternalDefault with the task queue in // the Cookie Store spec, once that spec is finalized. execution_context->GetBrowserInterfaceBroker().GetInterface( @@ -64,7 +68,7 @@ class ServiceWorkerRegistrationCookiesImpl final return cookie_store_manager_.Get(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(registration_); visitor->Trace(cookie_store_manager_); Supplement<ServiceWorkerRegistration>::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.cc index ecb2b851b7b..d5f410d6f60 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.cc @@ -18,7 +18,7 @@ AuthenticatorAssertionResponse::AuthenticatorAssertionResponse( AuthenticatorAssertionResponse::~AuthenticatorAssertionResponse() = default; -void AuthenticatorAssertionResponse::Trace(Visitor* visitor) { +void AuthenticatorAssertionResponse::Trace(Visitor* visitor) const { visitor->Trace(authenticator_data_); visitor->Trace(signature_); visitor->Trace(user_handle_); diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.h b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.h index 099a9d15603..897395989ab 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.h +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_assertion_response.h @@ -31,7 +31,7 @@ class MODULES_EXPORT AuthenticatorAssertionResponse final DOMArrayBuffer* userHandle() const { return user_handle_.Get(); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: const Member<DOMArrayBuffer> authenticator_data_; diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc index a75213c62af..95c20262d09 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.cc @@ -11,10 +11,16 @@ namespace blink { AuthenticatorAttestationResponse::AuthenticatorAttestationResponse( DOMArrayBuffer* client_data_json, DOMArrayBuffer* attestation_object, - Vector<mojom::AuthenticatorTransport> transports) + Vector<mojom::AuthenticatorTransport> transports, + DOMArrayBuffer* authenticator_data, + DOMArrayBuffer* public_key_der, + int32_t public_key_algo) : AuthenticatorResponse(client_data_json), attestation_object_(attestation_object), - transports_(std::move(transports)) {} + transports_(std::move(transports)), + authenticator_data_(authenticator_data), + public_key_der_(public_key_der), + public_key_algo_(public_key_algo) {} AuthenticatorAttestationResponse::~AuthenticatorAttestationResponse() = default; @@ -27,8 +33,10 @@ Vector<String> AuthenticatorAttestationResponse::getTransports() const { return ret; } -void AuthenticatorAttestationResponse::Trace(Visitor* visitor) { +void AuthenticatorAttestationResponse::Trace(Visitor* visitor) const { visitor->Trace(attestation_object_); + visitor->Trace(authenticator_data_); + visitor->Trace(public_key_der_); AuthenticatorResponse::Trace(visitor); } 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 ea39ef90979..0d231d6377d 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 @@ -23,20 +23,34 @@ class MODULES_EXPORT AuthenticatorAttestationResponse final AuthenticatorAttestationResponse( DOMArrayBuffer* client_data_json, DOMArrayBuffer* attestation_object, - Vector<mojom::AuthenticatorTransport> transports); + Vector<mojom::AuthenticatorTransport> transports, + DOMArrayBuffer* authenticator_data, + DOMArrayBuffer* public_key_der, + int32_t public_key_algorithm); ~AuthenticatorAttestationResponse() override; DOMArrayBuffer* attestationObject() const { return attestation_object_.Get(); } + DOMArrayBuffer* getAuthenticatorData() const { + return authenticator_data_.Get(); + } + + DOMArrayBuffer* getPublicKey() const { return public_key_der_.Get(); } + + int32_t getPublicKeyAlgorithm() const { return public_key_algo_; } + Vector<String> getTransports() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: const Member<DOMArrayBuffer> attestation_object_; const Vector<mojom::AuthenticatorTransport> transports_; + const Member<DOMArrayBuffer> authenticator_data_; + const Member<DOMArrayBuffer> public_key_der_; + const int32_t public_key_algo_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl index 5b4bead7572..f16bdf62398 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.idl @@ -11,4 +11,8 @@ ] interface AuthenticatorAttestationResponse : AuthenticatorResponse { [SameObject] readonly attribute ArrayBuffer attestationObject; sequence<DOMString> getTransports(); + + ArrayBuffer getAuthenticatorData(); + ArrayBuffer? getPublicKey(); + COSEAlgorithmIdentifier getPublicKeyAlgorithm(); }; diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.cc index 03851da82c4..14dbd81fd87 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.cc @@ -11,7 +11,7 @@ AuthenticatorResponse::AuthenticatorResponse(DOMArrayBuffer* client_data_json) AuthenticatorResponse::~AuthenticatorResponse() = default; -void AuthenticatorResponse::Trace(Visitor* visitor) { +void AuthenticatorResponse::Trace(Visitor* visitor) const { visitor->Trace(client_data_json_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.h b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.h index 3679e4cde14..07612d4e992 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.h +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/authenticator_response.h @@ -21,7 +21,7 @@ class MODULES_EXPORT AuthenticatorResponse : public ScriptWrappable { DOMArrayBuffer* clientDataJSON() const { return client_data_json_.Get(); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: const Member<DOMArrayBuffer> client_data_json_; diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credential.cc index c25ae851e48..65c6930e13c 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential.cc @@ -32,7 +32,7 @@ KURL Credential::ParseStringAsURLOrThrow(const String& url, return parsed_url; } -void Credential::Trace(Visitor* visitor) { +void Credential::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential.h b/chromium/third_party/blink/renderer/modules/credentialmanager/credential.h index 15b93a6b005..740be80a7ad 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential.h +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential.h @@ -20,7 +20,7 @@ class MODULES_EXPORT Credential : public ScriptWrappable { public: ~Credential() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; virtual bool IsPasswordCredential() const { return false; } virtual bool IsFederatedCredential() const { return false; } diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_data.idl b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_data.idl index 55c2f8f12c4..6411ad183a0 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/credential_data.idl +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credential_data.idl @@ -5,5 +5,5 @@ // https://w3c.github.io/webappsec-credential-management/#dictdef-credentialdata dictionary CredentialData { - DOMString id; + required USVString id; }; 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 82250375fab..8e720be2118 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 @@ -12,7 +12,10 @@ namespace blink { CredentialManagerProxy::CredentialManagerProxy(LocalDOMWindow& window) - : Supplement<LocalDOMWindow>(window) { + : Supplement<LocalDOMWindow>(window), + authenticator_(window.GetExecutionContext()), + credential_manager_(window.GetExecutionContext()), + sms_receiver_(window.GetExecutionContext()) { LocalFrame* frame = window.GetFrame(); DCHECK(frame); frame->GetBrowserInterfaceBroker().GetInterface( @@ -26,7 +29,7 @@ CredentialManagerProxy::CredentialManagerProxy(LocalDOMWindow& window) CredentialManagerProxy::~CredentialManagerProxy() = default; mojom::blink::SmsReceiver* CredentialManagerProxy::SmsReceiver() { - if (!sms_receiver_) { + if (!sms_receiver_.is_bound()) { LocalFrame* frame = GetSupplementable()->GetFrame(); DCHECK(frame); frame->GetBrowserInterfaceBroker().GetInterface( @@ -50,6 +53,13 @@ CredentialManagerProxy* CredentialManagerProxy::From( return supplement; } +void CredentialManagerProxy::Trace(Visitor* visitor) const { + visitor->Trace(authenticator_); + visitor->Trace(credential_manager_); + visitor->Trace(sms_receiver_); + Supplement<LocalDOMWindow>::Trace(visitor); +} + // static const char CredentialManagerProxy::kSupplementName[] = "CredentialManagerProxy"; 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 45465f978a6..6188ef9ce58 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 @@ -5,13 +5,14 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_CREDENTIAL_MANAGER_PROXY_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_CREDENTIAL_MANAGER_PROXY_H_ -#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/credentialmanager/credential_manager.mojom-blink.h" #include "third_party/blink/public/mojom/sms/sms_receiver.mojom-blink.h" #include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink.h" #include "third_party/blink/renderer/core/frame/local_dom_window.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/mojo/heap_mojo_remote.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" #include "third_party/blink/renderer/platform/supplementable.h" namespace blink { @@ -52,14 +53,22 @@ class MODULES_EXPORT CredentialManagerProxy credential_manager_.FlushForTesting(); } + void Trace(Visitor*) const override; + // Must be called only with argument representing a valid // context corresponding to an attached window. static CredentialManagerProxy* From(ScriptState*); private: - mojo::Remote<mojom::blink::Authenticator> authenticator_; - mojo::Remote<mojom::blink::CredentialManager> credential_manager_; - mojo::Remote<mojom::blink::SmsReceiver> sms_receiver_; + HeapMojoRemote<mojom::blink::Authenticator, + HeapMojoWrapperMode::kForceWithoutContextObserver> + authenticator_; + HeapMojoRemote<mojom::blink::CredentialManager, + HeapMojoWrapperMode::kForceWithoutContextObserver> + credential_manager_; + HeapMojoRemote<mojom::blink::SmsReceiver, + HeapMojoWrapperMode::kForceWithoutContextObserver> + sms_receiver_; }; } // namespace blink 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 7f33a9faad8..88e8a42d3a8 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 @@ -278,13 +278,14 @@ TypeConverter<AttestationConveyancePreference, String>::Convert( } // static -AuthenticatorAttachment TypeConverter<AuthenticatorAttachment, String>::Convert( - const String& attachment) { - if (attachment.IsNull()) +AuthenticatorAttachment +TypeConverter<AuthenticatorAttachment, base::Optional<String>>::Convert( + const base::Optional<String>& attachment) { + if (!attachment.has_value()) return AuthenticatorAttachment::NO_PREFERENCE; - if (attachment == "platform") + if (attachment.value() == "platform") return AuthenticatorAttachment::PLATFORM; - if (attachment == "cross-platform") + if (attachment.value() == "cross-platform") return AuthenticatorAttachment::CROSS_PLATFORM; NOTREACHED(); return AuthenticatorAttachment::NO_PREFERENCE; @@ -297,8 +298,11 @@ TypeConverter<AuthenticatorSelectionCriteriaPtr, Convert(const blink::AuthenticatorSelectionCriteria* criteria) { auto mojo_criteria = blink::mojom::blink::AuthenticatorSelectionCriteria::New(); + base::Optional<String> attachment; + if (criteria->hasAuthenticatorAttachment()) + attachment = criteria->authenticatorAttachment(); mojo_criteria->authenticator_attachment = - ConvertTo<AuthenticatorAttachment>(criteria->authenticatorAttachment()); + ConvertTo<AuthenticatorAttachment>(attachment); mojo_criteria->require_resident_key = criteria->requireResidentKey(); mojo_criteria->user_verification = UserVerificationRequirement::PREFERRED; if (criteria->hasUserVerification()) { @@ -556,7 +560,9 @@ TypeConverter<PublicKeyCredentialRequestOptionsPtr, base::TimeDelta::FromMilliseconds(options->timeout()); } - mojo_options->relying_party_id = options->rpId(); + if (options->hasRpId()) { + mojo_options->relying_party_id = options->rpId(); + } if (options->hasAllowCredentials()) { // Adds the allowList members 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 9766db328d8..fe4afc6659b 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 @@ -88,9 +88,13 @@ struct TypeConverter<blink::mojom::blink::AttestationConveyancePreference, const String&); }; +// TODO(crbug.com/1092328): Second template parameter should be +// base::Optional<blink::V8AuthenticatorAttachment>. template <> -struct TypeConverter<blink::mojom::blink::AuthenticatorAttachment, String> { - static blink::mojom::blink::AuthenticatorAttachment Convert(const String&); +struct TypeConverter<blink::mojom::blink::AuthenticatorAttachment, + base::Optional<String>> { + static blink::mojom::blink::AuthenticatorAttachment Convert( + const base::Optional<String>&); }; template <> diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc index 5f752235ee5..e2c0b140133 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc @@ -405,9 +405,17 @@ void OnMakePublicKeyCredentialComplete( VectorToDOMArrayBuffer(std::move(credential->info->raw_id)); DOMArrayBuffer* attestation_buffer = VectorToDOMArrayBuffer(std::move(credential->attestation_object)); + DOMArrayBuffer* authenticator_data = + VectorToDOMArrayBuffer(std::move(credential->info->authenticator_data)); + DOMArrayBuffer* public_key_der = nullptr; + if (credential->public_key_der) { + public_key_der = + VectorToDOMArrayBuffer(std::move(credential->public_key_der.value())); + } auto* authenticator_response = MakeGarbageCollected<AuthenticatorAttestationResponse>( - client_data_buffer, attestation_buffer, credential->transports); + client_data_buffer, attestation_buffer, credential->transports, + authenticator_data, public_key_der, credential->public_key_algo); AuthenticationExtensionsClientOutputs* extension_outputs = AuthenticationExtensionsClientOutputs::Create(); @@ -435,7 +443,7 @@ void OnGetAssertionComplete( if (status == AuthenticatorStatus::SUCCESS) { DCHECK(credential); DCHECK(!credential->signature.IsEmpty()); - DCHECK(!credential->authenticator_data.IsEmpty()); + DCHECK(!credential->info->authenticator_data.IsEmpty()); UseCounter::Count( resolver->GetExecutionContext(), WebFeature::kCredentialManagerGetPublicKeyCredentialSuccess); @@ -445,7 +453,7 @@ void OnGetAssertionComplete( VectorToDOMArrayBuffer(std::move(credential->info->raw_id)); DOMArrayBuffer* authenticator_buffer = - VectorToDOMArrayBuffer(std::move(credential->authenticator_data)); + VectorToDOMArrayBuffer(std::move(credential->info->authenticator_data)); DOMArrayBuffer* signature_buffer = VectorToDOMArrayBuffer(std::move(credential->signature)); DOMArrayBuffer* user_handle = @@ -486,8 +494,8 @@ void OnSmsReceive(ScriptPromiseResolver* resolver, AssertSecurityRequirementsBeforeResponse( resolver, RequiredOriginType::kSecureAndSameWithAncestors); auto& window = *LocalDOMWindow::From(resolver->GetScriptState()); - ukm::SourceId source_id = window.document()->UkmSourceID(); - ukm::UkmRecorder* recorder = window.document()->UkmRecorder(); + ukm::SourceId source_id = window.UkmSourceID(); + ukm::UkmRecorder* recorder = window.UkmRecorder(); if (status == mojom::blink::SmsStatus::kTimeout) { RecordSmsOutcome(SMSReceiverOutcome::kTimeout, source_id, recorder); diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc index 64bbd1385d2..b44b0c750a0 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/federated_credential.cc @@ -16,20 +16,32 @@ constexpr char kFederatedCredentialType[] = "federated"; FederatedCredential* FederatedCredential::Create( const FederatedCredentialInit* data, ExceptionState& exception_state) { - if (data->id().IsEmpty()) + if (data->id().IsEmpty()) { exception_state.ThrowTypeError("'id' must not be empty."); - if (data->provider().IsEmpty()) + return nullptr; + } + if (data->provider().IsEmpty()) { exception_state.ThrowTypeError("'provider' must not be empty."); + return nullptr; + } + + KURL icon_url; + if (data->hasIconURL()) + icon_url = ParseStringAsURLOrThrow(data->iconURL(), exception_state); + if (exception_state.HadException()) + return nullptr; - KURL icon_url = ParseStringAsURLOrThrow(data->iconURL(), exception_state); KURL provider_url = ParseStringAsURLOrThrow(data->provider(), exception_state); - if (exception_state.HadException()) return nullptr; + String name; + if (data->hasName()) + name = data->name(); + return MakeGarbageCollected<FederatedCredential>( - data->id(), SecurityOrigin::Create(provider_url), data->name(), icon_url); + data->id(), SecurityOrigin::Create(provider_url), name, icon_url); } FederatedCredential* FederatedCredential::Create( diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.cc index b1f1bf0aedb..2c738098f58 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.cc @@ -37,7 +37,7 @@ CredentialsContainer* NavigatorCredentials::credentials() { return credentials_container_.Get(); } -void NavigatorCredentials::Trace(Visitor* visitor) { +void NavigatorCredentials::Trace(Visitor* visitor) const { visitor->Trace(credentials_container_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.h b/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.h index a852ffe3d3a..c2f26a209d2 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.h +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/navigator_credentials.h @@ -28,7 +28,7 @@ class NavigatorCredentials final explicit NavigatorCredentials(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: CredentialsContainer* credentials(); diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.cc index 22dbd5bd338..72705195bd1 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential.cc @@ -22,18 +22,27 @@ constexpr char kPasswordCredentialType[] = "password"; PasswordCredential* PasswordCredential::Create( const PasswordCredentialData* data, ExceptionState& exception_state) { - if (data->id().IsEmpty()) + if (data->id().IsEmpty()) { exception_state.ThrowTypeError("'id' must not be empty."); - if (data->password().IsEmpty()) + return nullptr; + } + if (data->password().IsEmpty()) { exception_state.ThrowTypeError("'password' must not be empty."); + return nullptr; + } - KURL icon_url = ParseStringAsURLOrThrow(data->iconURL(), exception_state); - + KURL icon_url; + if (data->hasIconURL()) + icon_url = ParseStringAsURLOrThrow(data->iconURL(), exception_state); if (exception_state.HadException()) return nullptr; + String name; + if (data->hasName()) + name = data->name(); + return MakeGarbageCollected<PasswordCredential>(data->id(), data->password(), - data->name(), icon_url); + name, icon_url); } // https://w3c.github.io/webappsec-credential-management/#construct-passwordcredential-form @@ -45,7 +54,10 @@ PasswordCredential* PasswordCredential::Create( FormData* form_data = FormData::Create(form, exception_state); if (exception_state.HadException()) return nullptr; + PasswordCredentialData* data = PasswordCredentialData::Create(); + bool is_id_set = false; + bool is_password_set = false; for (ListedElement* submittable_element : form->ListedElements()) { // The "form data set" contains an entry for a |submittable_element| only if // it has a non-empty `name` attribute. @@ -66,16 +78,31 @@ PasswordCredential* PasswordCredential::Create( for (const auto& token : autofill_tokens) { if (token == "current-password" || token == "new-password") { data->setPassword(value.GetAsUSVString()); + is_password_set = true; } else if (token == "photo") { data->setIconURL(value.GetAsUSVString()); } else if (token == "name" || token == "nickname") { data->setName(value.GetAsUSVString()); } else if (token == "username") { data->setId(value.GetAsUSVString()); + is_id_set = true; } } } + // Check required fields of PasswordCredentialData dictionary. + if (!is_id_set) { + exception_state.ThrowTypeError( + "'username' must be specified in the form's autocomplete attribute."); + return nullptr; + } + if (!is_password_set) { + exception_state.ThrowTypeError( + "Either 'current-password' or 'new-password' must be specified in the " + "form's autocomplete attribute."); + return nullptr; + } + // Create a PasswordCredential using the data gathered above. return PasswordCredential::Create(data, exception_state); } diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential_test.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential_test.cc index 2d7d62bc6ae..7374a505ac7 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential_test.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/password_credential_test.cc @@ -97,7 +97,10 @@ TEST_F(PasswordCredentialTest, CreateFromFormNoPassword) { EXPECT_EQ(nullptr, credential); EXPECT_TRUE(exception_state.HadException()); EXPECT_EQ(ESErrorType::kTypeError, exception_state.CodeAs<ESErrorType>()); - EXPECT_EQ("'password' must not be empty.", exception_state.Message()); + EXPECT_EQ( + "Either 'current-password' or 'new-password' must be specified in the " + "form's autocomplete attribute.", + exception_state.Message()); } TEST_F(PasswordCredentialTest, CreateFromFormNoId) { @@ -116,7 +119,9 @@ TEST_F(PasswordCredentialTest, CreateFromFormNoId) { EXPECT_EQ(nullptr, credential); EXPECT_TRUE(exception_state.HadException()); EXPECT_EQ(ESErrorType::kTypeError, exception_state.CodeAs<ESErrorType>()); - EXPECT_EQ("'id' must not be empty.", exception_state.Message()); + EXPECT_EQ( + "'username' must be specified in the form's autocomplete attribute.", + exception_state.Message()); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc b/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc index 37a360e53fc..d80cfd6a569 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc @@ -70,7 +70,7 @@ PublicKeyCredential::getClientExtensionResults() const { extension_outputs_.Get()); } -void PublicKeyCredential::Trace(Visitor* visitor) { +void PublicKeyCredential::Trace(Visitor* visitor) const { visitor->Trace(raw_id_); visitor->Trace(response_); visitor->Trace(extension_outputs_); diff --git a/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h b/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h index 333d4797ee0..81c64a6180c 100644 --- a/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h +++ b/chromium/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h @@ -35,7 +35,7 @@ class MODULES_EXPORT PublicKeyCredential final : public Credential { AuthenticationExtensionsClientOutputs* getClientExtensionResults() const; // Credential: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool IsPublicKeyCredential() const override; private: diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto.cc b/chromium/third_party/blink/renderer/modules/crypto/crypto.cc index 54e21405652..90ffe2ab6e5 100644 --- a/chromium/third_party/blink/renderer/modules/crypto/crypto.cc +++ b/chromium/third_party/blink/renderer/modules/crypto/crypto.cc @@ -81,7 +81,7 @@ SubtleCrypto* Crypto::subtle() { return subtle_crypto_.Get(); } -void Crypto::Trace(Visitor* visitor) { +void Crypto::Trace(Visitor* visitor) const { visitor->Trace(subtle_crypto_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto.h b/chromium/third_party/blink/renderer/modules/crypto/crypto.h index dadf713e160..7005446b4b5 100644 --- a/chromium/third_party/blink/renderer/modules/crypto/crypto.h +++ b/chromium/third_party/blink/renderer/modules/crypto/crypto.h @@ -51,7 +51,7 @@ class Crypto final : public ScriptWrappable { SubtleCrypto* subtle(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<SubtleCrypto> subtle_crypto_; diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc b/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc index 43449672ac6..35cd210a771 100644 --- a/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc +++ b/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.cc @@ -80,7 +80,7 @@ class CryptoResultImpl::Resolver final : public ScriptPromiseResolver { ScriptPromiseResolver::ContextDestroyed(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(result_); ScriptPromiseResolver::Trace(visitor); } @@ -121,7 +121,7 @@ CryptoResultImpl::~CryptoResultImpl() { DCHECK(!resolver_); } -void CryptoResultImpl::Trace(Visitor* visitor) { +void CryptoResultImpl::Trace(Visitor* visitor) const { visitor->Trace(resolver_); CryptoResult::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.h b/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.h index 777632416c9..32305191d77 100644 --- a/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.h +++ b/chromium/third_party/blink/renderer/modules/crypto/crypto_result_impl.h @@ -74,7 +74,7 @@ class MODULES_EXPORT CryptoResultImpl final : public CryptoResult { WebCryptoResult Result() { return WebCryptoResult(this, cancel_.get()); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: class Resolver; diff --git a/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.cc b/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.cc index bfc95b03985..85b2c80e2cd 100644 --- a/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.cc +++ b/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.cc @@ -60,7 +60,7 @@ Crypto* DOMWindowCrypto::crypto() const { return crypto_.Get(); } -void DOMWindowCrypto::Trace(Visitor* visitor) { +void DOMWindowCrypto::Trace(Visitor* visitor) const { visitor->Trace(crypto_); Supplement<LocalDOMWindow>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.h b/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.h index 24aaa2670dd..0687df4f4fb 100644 --- a/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.h +++ b/chromium/third_party/blink/renderer/modules/crypto/dom_window_crypto.h @@ -53,7 +53,7 @@ class DOMWindowCrypto final : public GarbageCollected<DOMWindowCrypto>, Crypto* crypto() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: mutable Member<Crypto> crypto_; diff --git a/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.cc b/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.cc index edcbb9ae64a..ed09931edc3 100644 --- a/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.cc +++ b/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.cc @@ -62,7 +62,7 @@ Crypto* WorkerGlobalScopeCrypto::crypto() const { return crypto_.Get(); } -void WorkerGlobalScopeCrypto::Trace(Visitor* visitor) { +void WorkerGlobalScopeCrypto::Trace(Visitor* visitor) const { visitor->Trace(crypto_); Supplement<WorkerGlobalScope>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.h b/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.h index fceb0c09941..4431a20d0d2 100644 --- a/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.h +++ b/chromium/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.h @@ -54,7 +54,7 @@ class WorkerGlobalScopeCrypto final WorkerGlobalScopeCrypto(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: mutable Member<Crypto> crypto_; diff --git a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc index 99800626bee..2b801859836 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc +++ b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_definition.cc @@ -109,7 +109,7 @@ void CSSPaintDefinition::MaybeCreatePaintInstance() { instance_.Set(constructor_->GetIsolate(), paint_instance.V8Value()); } -void CSSPaintDefinition::Trace(Visitor* visitor) { +void CSSPaintDefinition::Trace(Visitor* visitor) const { visitor->Trace(constructor_); visitor->Trace(paint_); visitor->Trace(instance_); 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 5e0a3168f8c..bf10dc8e1fd 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 @@ -72,7 +72,7 @@ class MODULES_EXPORT CSSPaintDefinition final ScriptState* GetScriptState() const { return script_state_; } - virtual void Trace(Visitor* visitor); + virtual void Trace(Visitor* visitor) const; const char* NameInHeapSnapshot() const override { return "CSSPaintDefinition"; } diff --git a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc index 2df94870e00..e7764e28d41 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc +++ b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc @@ -138,7 +138,7 @@ int CSSPaintImageGeneratorImpl::WorkletId() const { return paint_worklet_->WorkletId(); } -void CSSPaintImageGeneratorImpl::Trace(Visitor* visitor) { +void CSSPaintImageGeneratorImpl::Trace(Visitor* visitor) const { visitor->Trace(observer_); visitor->Trace(paint_worklet_); CSSPaintImageGenerator::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h index ab77c331d57..45d3aa276eb 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h +++ b/chromium/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h @@ -54,7 +54,7 @@ class MODULES_EXPORT CSSPaintImageGeneratorImpl final } unsigned GetRegisteredDefinitionCountForTesting() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Used for main-thread CSS Paint. diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h index 47ccf6cf3f7..423194777d7 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h @@ -37,7 +37,7 @@ class MODULES_EXPORT PaintRenderingContext2D : public ScriptWrappable, float zoom, float device_scale_factor); - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(context_settings_); ScriptWrappable::Trace(visitor); BaseRenderingContext2D::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc index e72fae35cc5..0100e5858c4 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.cc @@ -144,7 +144,7 @@ scoped_refptr<Image> PaintWorklet::Paint(const String& name, // static const char PaintWorklet::kSupplementName[] = "PaintWorklet"; -void PaintWorklet::Trace(Visitor* visitor) { +void PaintWorklet::Trace(Visitor* visitor) const { visitor->Trace(pending_generator_registry_); visitor->Trace(proxy_client_); Worklet::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.h index 7d6fd5751e4..71ecbee99ac 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.h +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet.h @@ -46,7 +46,7 @@ class MODULES_EXPORT PaintWorklet : public Worklet, float device_scale_factor); int WorkletId() const { return worklet_id_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // The DocumentDefinitionMap tracks definitions registered via // registerProperty; definitions are only considered valid once all global diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc index dfba381725d..35ecb53934b 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc @@ -245,7 +245,7 @@ double PaintWorkletGlobalScope::devicePixelRatio() const { : PaintWorkletProxyClient::From(Clients())->DevicePixelRatio(); } -void PaintWorkletGlobalScope::Trace(Visitor* visitor) { +void PaintWorkletGlobalScope::Trace(Visitor* visitor) const { visitor->Trace(paint_definitions_); WorkletGlobalScope::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h index c444623ff4a..6ef81a2a15b 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h @@ -53,7 +53,7 @@ class MODULES_EXPORT PaintWorkletGlobalScope final : public WorkletGlobalScope { CSSPaintDefinition* FindDefinition(const String& name); double devicePixelRatio() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Registers the global scope with a proxy client, if not already done. Only diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc index 18a35b669a4..421b7a18b76 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc @@ -90,7 +90,7 @@ CSSPaintDefinition* PaintWorkletGlobalScopeProxy::FindDefinition( return global_scope_->FindDefinition(name); } -void PaintWorkletGlobalScopeProxy::Trace(Visitor* visitor) { +void PaintWorkletGlobalScopeProxy::Trace(Visitor* visitor) const { visitor->Trace(global_scope_); } 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 7206214aa94..ca566bb5b2a 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 @@ -47,7 +47,7 @@ class MODULES_EXPORT PaintWorkletGlobalScopeProxy PaintWorkletGlobalScope* global_scope() const { return global_scope_.Get(); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: std::unique_ptr<MainThreadWorkletReportingProxy> reporting_proxy_; diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.cc index ec955943eb2..70bc077b4fb 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.cc @@ -13,7 +13,7 @@ PaintWorkletMessagingProxy::PaintWorkletMessagingProxy( ExecutionContext* execution_context) : ThreadedWorkletMessagingProxy(execution_context) {} -void PaintWorkletMessagingProxy::Trace(Visitor* visitor) { +void PaintWorkletMessagingProxy::Trace(Visitor* visitor) const { ThreadedWorkletMessagingProxy::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h index 8a745086ca5..a5646995f6f 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h @@ -21,7 +21,7 @@ class PaintWorkletMessagingProxy final : public ThreadedWorkletMessagingProxy { public: explicit PaintWorkletMessagingProxy(ExecutionContext*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ~PaintWorkletMessagingProxy() override; diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.cc index 0865d7dc2ef..8bf6336a270 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.cc +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.cc @@ -30,7 +30,7 @@ void PaintWorkletPendingGeneratorRegistry::AddPendingGenerator( set->insert(generator); } -void PaintWorkletPendingGeneratorRegistry::Trace(Visitor* visitor) { +void PaintWorkletPendingGeneratorRegistry::Trace(Visitor* visitor) const { visitor->Trace(pending_generators_); } diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.h b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.h index e65c2c60ff7..9b8361ef01b 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.h +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_pending_generator_registry.h @@ -25,7 +25,7 @@ class PaintWorkletPendingGeneratorRegistry void NotifyGeneratorReady(const String& name); void AddPendingGenerator(const String& name, CSSPaintImageGeneratorImpl*); - void Trace(Visitor*); + void Trace(Visitor*) const; private: // The map of CSSPaintImageGeneratorImpl which are waiting for a diff --git a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.cc b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.cc index 5d77dd2bb13..a59c79bff05 100644 --- a/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.cc +++ b/chromium/third_party/blink/renderer/modules/csspaint/paint_worklet_proxy_client.cc @@ -158,7 +158,7 @@ void PaintWorkletProxyClient::Dispose() { global_scopes_.clear(); } -void PaintWorkletProxyClient::Trace(Visitor* visitor) { +void PaintWorkletProxyClient::Trace(Visitor* visitor) const { Supplement<WorkerClients>::Trace(visitor); PaintWorkletPainter::Trace(visitor); } 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 c7899c29f72..45f2a0e2429 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 @@ -74,7 +74,7 @@ class MODULES_EXPORT PaintWorkletProxyClient // after the first have no effect. void Dispose(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Hooks for testing. const Vector<CrossThreadPersistent<PaintWorkletGlobalScope>>& diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/DEPS b/chromium/third_party/blink/renderer/modules/delegated_ink/DEPS new file mode 100644 index 00000000000..830557a2691 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/delegated_ink/DEPS @@ -0,0 +1,5 @@ +specific_include_rules = { + "delegated_ink_trail_presenter.*.cc" : [ + "+components/viz/common/delegated_ink_metadata.h", + ] +} diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc index ee31e24dbd0..f7ac1045015 100644 --- a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc +++ b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.cc @@ -4,26 +4,128 @@ #include "third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h" +#include "components/viz/common/delegated_ink_metadata.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ink_trail_style.h" +#include "third_party/blink/renderer/core/css/parser/css_parser.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/events/pointer_event.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/geometry/dom_rect.h" +#include "third_party/blink/renderer/core/layout/layout_view.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/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { -DelegatedInkTrailPresenter::DelegatedInkTrailPresenter(Element* element) - : presentation_area_(element) {} +DelegatedInkTrailPresenter* DelegatedInkTrailPresenter::CreatePresenter( + Element* element, + LocalFrame* frame) { + DCHECK(!element || element->GetDocument() == frame->GetDocument()); + + return MakeGarbageCollected<DelegatedInkTrailPresenter>(element, frame); +} + +DelegatedInkTrailPresenter::DelegatedInkTrailPresenter(Element* element, + LocalFrame* frame) + : presentation_area_(element), local_frame_(frame) {} + +void ThrowException(v8::Isolate* isolate, + ExceptionCode code, + const String& error_message) { + ExceptionState exception_state(isolate, ExceptionState::kExecutionContext, + "DelegatedInkTrailPresenter", + "updateInkTrailStatePoint"); + exception_state.ThrowException(code, error_message); +} void DelegatedInkTrailPresenter::updateInkTrailStartPoint( + ScriptState* state, PointerEvent* evt, InkTrailStyle* style) { DCHECK(RuntimeEnabledFeatures::DelegatedInkTrailsEnabled()); - return; + + if (!state->ContextIsValid()) { + ThrowException(state->GetIsolate(), + ToExceptionCode(DOMExceptionCode::kInvalidStateError), + "The object is no longer associated with a window."); + return; + } + + if (!evt->isTrusted()) { + ThrowException(state->GetIsolate(), + ToExceptionCode(DOMExceptionCode::kNotAllowedError), + "Only trusted pointerevents are accepted."); + return; + } + + // If diameter is less than or equal to 0, then nothing is going to be + // displayed anyway, so just bail early and save the effort. + if (style->diameter() <= 0) { + ThrowException(state->GetIsolate(), + ToExceptionCode(DOMExceptionCode::kNotSupportedError), + "Delegated ink trail diameter must be greater than 0."); + return; + } + + Color color; + if (!CSSParser::ParseColor(color, style->color(), true /*strict*/)) { + ThrowException(state->GetIsolate(), + ToExceptionCode(ESErrorType::kTypeError), "Unknown color."); + return; + } + + LayoutView* layout_view = local_frame_->ContentLayoutObject(); + DCHECK(layout_view); + const float effective_zoom = layout_view->StyleRef().EffectiveZoom(); + + PhysicalOffset physical_point(LayoutUnit(evt->x()), LayoutUnit(evt->y())); + physical_point.Scale(effective_zoom); + physical_point = layout_view->LocalToAbsolutePoint( + physical_point, kTraverseDocumentBoundaries); + gfx::PointF point(physical_point.left.ToFloat(), + physical_point.top.ToFloat()); + + LayoutBox* layout_box = nullptr; + if (presentation_area_) { + layout_box = presentation_area_->GetLayoutBox(); + DCHECK(layout_box); + } else { + // If presentation_area_ wasn't provided, then default to the layout + // viewport. + layout_box = layout_view; + } + + // TODO(1052145): Move this further into the document lifecycle when layout + // is up to date. + PhysicalRect physical_rect_area = layout_box->LocalToAbsoluteRect( + layout_box->PhysicalBorderBoxRect(), kTraverseDocumentBoundaries); + gfx::RectF area(physical_rect_area.X().ToFloat(), + physical_rect_area.Y().ToFloat(), + physical_rect_area.Width().ToFloat(), + physical_rect_area.Height().ToFloat()); + + TRACE_EVENT_INSTANT2("blink", + "DelegatedInkTrailPresenter::updateInkTrailStartPoint", + TRACE_EVENT_SCOPE_THREAD, "point", point.ToString(), + "area", area.ToString()); + + const double diameter_in_physical_pixels = style->diameter() * effective_zoom; + std::unique_ptr<viz::DelegatedInkMetadata> metadata = + std::make_unique<viz::DelegatedInkMetadata>( + point, diameter_in_physical_pixels, color.Rgb(), + evt->PlatformTimeStamp(), area); + + Page* page = local_frame_->GetPage(); + page->GetChromeClient().SetDelegatedInkMetadata(local_frame_, + std::move(metadata)); } -void DelegatedInkTrailPresenter::Trace(Visitor* visitor) { +void DelegatedInkTrailPresenter::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); visitor->Trace(presentation_area_); + visitor->Trace(local_frame_); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h index d96423b632b..439a57f82f7 100644 --- a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h +++ b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.h @@ -5,27 +5,43 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DELEGATED_INK_DELEGATED_INK_TRAIL_PRESENTER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_DELEGATED_INK_DELEGATED_INK_TRAIL_PRESENTER_H_ +#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" namespace blink { class Element; class InkTrailStyle; +class LocalFrame; class PointerEvent; - -class DelegatedInkTrailPresenter : public ScriptWrappable { +class ScriptState; + +// This class collects the required metadata for rendering a delegated ink +// trail and sends it to cc in a unique_ptr<viz::DelegatedInkMetadata>. This +// information is collected from the presentation_area_ and provided +// PointerEvent and InkTrailStyle, and is transformed into root frame +// coordinates before being packed up and sent to cc. +// +// Explainer for the feature: +// https://github.com/WICG/ink-enhancement/blob/master/README.md +class MODULES_EXPORT DelegatedInkTrailPresenter : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - explicit DelegatedInkTrailPresenter(Element* element); - void updateInkTrailStartPoint(PointerEvent* evt, InkTrailStyle* style); + static DelegatedInkTrailPresenter* CreatePresenter(Element* element, + LocalFrame* frame); + DelegatedInkTrailPresenter(Element* element, LocalFrame* frame); + void updateInkTrailStartPoint(ScriptState* state, + PointerEvent* evt, + InkTrailStyle* style); uint32_t expectedImprovement() const { return expected_improvement_; } Element* presentationArea() const { return presentation_area_; } - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<Element> presentation_area_; + Member<LocalFrame> local_frame_; uint32_t expected_improvement_; }; diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl index fa877ddbfb2..d0f2b650826 100644 --- a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl +++ b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl @@ -8,7 +8,7 @@ RuntimeEnabled=DelegatedInkTrails, Exposed=Window ] interface DelegatedInkTrailPresenter { - void updateInkTrailStartPoint(PointerEvent evt, InkTrailStyle style); + [CallWith=ScriptState] void updateInkTrailStartPoint(PointerEvent evt, InkTrailStyle style); readonly attribute Element? presentationArea; readonly attribute unsigned long expectedImprovement; diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc new file mode 100644 index 00000000000..9a22719628f --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter_unittest.cc @@ -0,0 +1,416 @@ +// Copyright 2020 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/delegated_ink/delegated_ink_trail_presenter.h" + +#include "components/viz/common/delegated_ink_metadata.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_ink_trail_style.h" +#include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/events/pointer_event.h" +#include "third_party/blink/renderer/core/html/html_iframe_element.h" +#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" +#include "third_party/blink/renderer/core/testing/sim/sim_request.h" +#include "third_party/blink/renderer/core/testing/sim/sim_test.h" + +namespace blink { +namespace { + +class TestDelegatedInkMetadata { + public: + explicit TestDelegatedInkMetadata(viz::DelegatedInkMetadata* metadata) + : point_(metadata->point()), + color_(metadata->color()), + diameter_(metadata->diameter()), + area_(metadata->presentation_area()) {} + explicit TestDelegatedInkMetadata(gfx::RectF area, + float device_pixel_ratio = 1.0) + : area_(area) { + area_.Scale(device_pixel_ratio); + } + + void ExpectEqual(TestDelegatedInkMetadata actual) const { + // LayoutUnits cast floats to ints, causing the actual point and area to be + // off a small amount from what is expected. + EXPECT_NEAR(point_.x(), actual.point_.x(), LayoutUnit::Epsilon()); + EXPECT_NEAR(point_.y(), actual.point_.y(), LayoutUnit::Epsilon()); + EXPECT_EQ(color_, actual.color_); + EXPECT_EQ(diameter_, actual.diameter_); + EXPECT_NEAR(area_.x(), actual.area_.x(), LayoutUnit::Epsilon()); + EXPECT_NEAR(area_.y(), actual.area_.y(), LayoutUnit::Epsilon()); + EXPECT_NEAR(area_.width(), actual.area_.width(), LayoutUnit::Epsilon()); + EXPECT_NEAR(area_.height(), actual.area_.height(), LayoutUnit::Epsilon()); + } + + void SetPoint(gfx::PointF pt) { point_ = pt; } + void SetColor(SkColor color) { color_ = color; } + void SetDiameter(double diameter) { diameter_ = diameter; } + void SetArea(gfx::RectF area) { area_ = area; } + + private: + gfx::PointF point_; + SkColor color_; + double diameter_; + gfx::RectF area_; +}; + +DelegatedInkTrailPresenter* CreatePresenter(Element* element, + LocalFrame* frame) { + return DelegatedInkTrailPresenter::CreatePresenter(element, frame); +} + +} // namespace + +class DelegatedInkTrailPresenterUnitTest : public SimTest { + protected: + PointerEvent* CreatePointerMoveEvent(gfx::PointF pt) { + PointerEventInit* init = PointerEventInit::Create(); + init->setClientX(pt.x()); + init->setClientY(pt.y()); + PointerEvent* event = PointerEvent::Create("pointermove", init); + event->SetTrusted(true); + return event; + } + + TestDelegatedInkMetadata GetActualMetadata() { + return TestDelegatedInkMetadata( + WebWidgetClient().layer_tree_host()->DelegatedInkMetadataForTesting()); + } + + void SetPageZoomFactor(const float zoom) { + GetDocument().GetFrame()->SetPageZoomFactor(zoom); + } +}; + +// Confirm that all the information is collected and transformed correctly, if +// necessary. Numbers and color used were chosen arbitrarily. +TEST_F(DelegatedInkTrailPresenterUnitTest, CollectAndPropagateMetadata) { + SimRequest main_resource("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + } + canvas { + width: 191px; + height: 234px; + } + </style> + <canvas id='canvas'></canvas> + )HTML"); + + Compositor().BeginFrame(); + + const float kCanvasWidth = 191.f; + const float kCanvasHeight = 234.f; + + TestDelegatedInkMetadata expected_metadata( + gfx::RectF(0, 0, kCanvasWidth, kCanvasHeight)); + + DelegatedInkTrailPresenter* presenter = CreatePresenter( + GetDocument().getElementById("canvas"), GetDocument().GetFrame()); + DCHECK(presenter); + + InkTrailStyle style; + style.setDiameter(5); + style.setColor("blue"); + expected_metadata.SetDiameter(style.diameter()); + expected_metadata.SetColor(SK_ColorBLUE); + + gfx::PointF pt(100, 100); + presenter->updateInkTrailStartPoint( + ToScriptStateForMainWorld(GetDocument().GetFrame()), + CreatePointerMoveEvent(pt), &style); + expected_metadata.SetPoint(pt); + + expected_metadata.ExpectEqual(GetActualMetadata()); +} + +// Confirm that presentation area defaults to the size of the viewport. +// Numbers and color used were chosen arbitrarily. +TEST_F(DelegatedInkTrailPresenterUnitTest, PresentationAreaNotProvided) { + const int kViewportHeight = 555; + const int kViewportWidth = 333; + WebView().MainFrameWidget()->Resize(WebSize(kViewportWidth, kViewportHeight)); + + DelegatedInkTrailPresenter* presenter = + CreatePresenter(nullptr, GetDocument().GetFrame()); + DCHECK(presenter); + + TestDelegatedInkMetadata expected_metadata( + gfx::RectF(0, 0, kViewportWidth, kViewportHeight)); + + InkTrailStyle style; + style.setDiameter(3.6); + style.setColor("yellow"); + expected_metadata.SetDiameter(style.diameter()); + expected_metadata.SetColor(SK_ColorYELLOW); + + gfx::PointF pt(70, 109); + presenter->updateInkTrailStartPoint( + ToScriptStateForMainWorld(GetDocument().GetFrame()), + CreatePointerMoveEvent(pt), &style); + expected_metadata.SetPoint(pt); + + expected_metadata.ExpectEqual(GetActualMetadata()); +} + +// Confirm that everything is still calculated correctly when the +// DevicePixelRatio is not 1. Numbers and color used were chosen arbitrarily. +TEST_F(DelegatedInkTrailPresenterUnitTest, NotDefaultDevicePixelRatio) { + const float kZoom = 1.7; + SetPageZoomFactor(kZoom); + + SimRequest main_resource("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + } + canvas { + width: 281px; + height: 190px; + } + </style> + <canvas id='canvas'></canvas> + )HTML"); + + Compositor().BeginFrame(); + + const float kCanvasWidth = 281.f; + const float kCanvasHeight = 190.f; + + TestDelegatedInkMetadata expected_metadata( + gfx::RectF(0, 0, kCanvasWidth, kCanvasHeight), kZoom); + + DelegatedInkTrailPresenter* presenter = CreatePresenter( + GetDocument().getElementById("canvas"), GetDocument().GetFrame()); + DCHECK(presenter); + + InkTrailStyle style; + style.setDiameter(101.5); + style.setColor("magenta"); + expected_metadata.SetDiameter(style.diameter() * kZoom); + expected_metadata.SetColor(SK_ColorMAGENTA); + + gfx::PointF pt(87, 113); + presenter->updateInkTrailStartPoint( + ToScriptStateForMainWorld(GetDocument().GetFrame()), + CreatePointerMoveEvent(pt), &style); + pt.Scale(kZoom); + expected_metadata.SetPoint(pt); + + expected_metadata.ExpectEqual(GetActualMetadata()); +} + +// Confirm that the offset is correct. Numbers and color used were chosen +// arbitrarily. +TEST_F(DelegatedInkTrailPresenterUnitTest, CanvasNotAtOrigin) { + SimRequest main_resource("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + } + canvas { + width: 250px; + height: 350px; + position: fixed; + top: 375px; + left: 166px; + } + </style> + <canvas id='canvas'></canvas> + )HTML"); + + Compositor().BeginFrame(); + + const float kCanvasWidth = 250.f; + const float kCanvasHeight = 350.f; + const float kCanvasTopOffset = 375.f; + const float kCanvasLeftOffset = 166.f; + + TestDelegatedInkMetadata expected_metadata(gfx::RectF( + kCanvasLeftOffset, kCanvasTopOffset, kCanvasWidth, kCanvasHeight)); + + DelegatedInkTrailPresenter* presenter = CreatePresenter( + GetDocument().getElementById("canvas"), GetDocument().GetFrame()); + DCHECK(presenter); + + InkTrailStyle style; + style.setDiameter(8.6); + style.setColor("red"); + expected_metadata.SetDiameter(style.diameter()); + expected_metadata.SetColor(SK_ColorRED); + + gfx::PointF pt(380, 175); + presenter->updateInkTrailStartPoint( + ToScriptStateForMainWorld(GetDocument().GetFrame()), + CreatePointerMoveEvent(pt), &style); + expected_metadata.SetPoint(pt); + + expected_metadata.ExpectEqual(GetActualMetadata()); +} + +// Confirm that values, specifically offsets, are transformed correctly when +// the canvas is in an iframe. Numbers and color used were chosen arbitrarily. +TEST_F(DelegatedInkTrailPresenterUnitTest, CanvasInIFrame) { + SimRequest main_resource("https://example.com/test.html", "text/html"); + SimRequest frame_resource("https://example.com/iframe.html", "text/html"); + LoadURL("https://example.com/test.html"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + } + iframe { + width: 500px; + height: 500px; + position: fixed; + top: 26px; + left: 57px; + } + </style> + <iframe id='iframe' src='https://example.com/iframe.html'> + </iframe> + )HTML"); + + frame_resource.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + } + canvas { + width: 250px; + height: 250px; + position: fixed; + top: 33px; + left: 16px; + } + </style> + <canvas id='canvas'></canvas> + )HTML"); + + Compositor().BeginFrame(); + + // When creating the expected metadata, we have to take into account the + // offsets that are applied to the iframe that the canvas is in, and the 2px + // border around the iframe. + const float kIframeBorder = 2.f; + const float kIframeLeftOffset = 57.f + kIframeBorder; + const float kIframeTopOffset = 26.f + kIframeBorder; + const float kCanvasLeftOffset = 16.f; + const float kCanvasTopOffset = 33.f; + const float kCanvasHeight = 250.f; + const float kCanvasWidth = 250.f; + + auto* iframe_element = + To<HTMLIFrameElement>(GetDocument().getElementById("iframe")); + auto* iframe_localframe = To<LocalFrame>(iframe_element->ContentFrame()); + Document* iframe_document = iframe_element->contentDocument(); + + TestDelegatedInkMetadata expected_metadata(gfx::RectF( + kIframeLeftOffset + kCanvasLeftOffset, + kIframeTopOffset + kCanvasTopOffset, kCanvasWidth, kCanvasHeight)); + + DelegatedInkTrailPresenter* presenter = CreatePresenter( + iframe_localframe->GetDocument()->getElementById("canvas"), + iframe_document->GetFrame()); + DCHECK(presenter); + + InkTrailStyle style; + style.setDiameter(0.3); + style.setColor("cyan"); + expected_metadata.SetDiameter(style.diameter()); + expected_metadata.SetColor(SK_ColorCYAN); + + gfx::PointF pt(380, 375); + presenter->updateInkTrailStartPoint( + ToScriptStateForMainWorld(iframe_document->GetFrame()), + CreatePointerMoveEvent(pt), &style); + expected_metadata.SetPoint( + gfx::PointF(pt.x() + kIframeLeftOffset, pt.y() + kIframeTopOffset)); + + expected_metadata.ExpectEqual(GetActualMetadata()); +} + +// Confirm that values are correct when an iframe is used and presentation area +// isn't provided. Numbers and color used were chosen arbitrarily. +TEST_F(DelegatedInkTrailPresenterUnitTest, IFrameNoPresentationArea) { + SimRequest main_resource("https://example.com/test.html", "text/html"); + SimRequest frame_resource("https://example.com/iframe.html", "text/html"); + LoadURL("https://example.com/test.html"); + main_resource.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + } + iframe { + width: 500px; + height: 500px; + position: fixed; + top: 56px; + left: 72px; + } + </style> + <iframe id='iframe' src='https://example.com/iframe.html'> + </iframe> + )HTML"); + + frame_resource.Complete(R"HTML( + <!DOCTYPE html> + <style> + body { + margin: 0; + } + </style> + )HTML"); + + Compositor().BeginFrame(); + + // When creating the expected metadata, we have to take into account the + // offsets that are applied to the iframe, and the 2px border. + const float kIframeBorder = 2.f; + const float kIframeLeftOffset = 72.f + kIframeBorder; + const float kIframeTopOffset = 56.f + kIframeBorder; + const float kIframeHeight = 500.f; + const float kIframeWidth = 500.f; + + Document* iframe_document = + To<HTMLIFrameElement>(GetDocument().getElementById("iframe")) + ->contentDocument(); + + TestDelegatedInkMetadata expected_metadata(gfx::RectF( + kIframeLeftOffset, kIframeTopOffset, kIframeWidth, kIframeHeight)); + + DelegatedInkTrailPresenter* presenter = + CreatePresenter(nullptr, iframe_document->GetFrame()); + DCHECK(presenter); + + InkTrailStyle style; + style.setDiameter(0.01); + style.setColor("white"); + expected_metadata.SetDiameter(style.diameter()); + expected_metadata.SetColor(SK_ColorWHITE); + + gfx::PointF pt(380, 375); + presenter->updateInkTrailStartPoint( + ToScriptStateForMainWorld(iframe_document->GetFrame()), + CreatePointerMoveEvent(pt), &style); + expected_metadata.SetPoint( + gfx::PointF(pt.x() + kIframeLeftOffset, pt.y() + kIframeTopOffset)); + + expected_metadata.ExpectEqual(GetActualMetadata()); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/ink.cc b/chromium/third_party/blink/renderer/modules/delegated_ink/ink.cc index 58596952dde..fbf7632dac8 100644 --- a/chromium/third_party/blink/renderer/modules/delegated_ink/ink.cc +++ b/chromium/third_party/blink/renderer/modules/delegated_ink/ink.cc @@ -9,6 +9,8 @@ namespace blink { +Ink::Ink(LocalFrame* frame) : local_frame_(frame) {} + ScriptPromise Ink::requestPresenter(ScriptState* state, String type, Element* presentationArea) { @@ -20,25 +22,28 @@ ScriptPromise Ink::requestPresenter(ScriptState* state, if (!state->ContextIsValid()) { resolver->Reject(V8ThrowException::CreateError( - state->GetIsolate(), "Unable to create presenter")); + state->GetIsolate(), + "The object is no longer associated with a window.")); return promise; } if (type != "delegated-ink-trail") { - resolver->Reject( - V8ThrowException::CreateTypeError(state->GetIsolate(), "Bad type")); + resolver->Reject(V8ThrowException::CreateTypeError( + state->GetIsolate(), "Unknown type requested.")); return promise; } DelegatedInkTrailPresenter* trail_presenter = - MakeGarbageCollected<DelegatedInkTrailPresenter>(presentationArea); + DelegatedInkTrailPresenter::CreatePresenter(presentationArea, + local_frame_); resolver->Resolve(trail_presenter); return promise; } -void Ink::Trace(Visitor* visitor) { +void Ink::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); + visitor->Trace(local_frame_); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/ink.h b/chromium/third_party/blink/renderer/modules/delegated_ink/ink.h index e1cfb7ed4da..41365b0ed46 100644 --- a/chromium/third_party/blink/renderer/modules/delegated_ink/ink.h +++ b/chromium/third_party/blink/renderer/modules/delegated_ink/ink.h @@ -12,6 +12,7 @@ namespace blink { class Element; +class LocalFrame; class ScriptPromise; class ScriptState; @@ -19,11 +20,15 @@ class Ink : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: + explicit Ink(LocalFrame* frame); ScriptPromise requestPresenter(ScriptState* state, String type, Element* presentationArea = nullptr); - void Trace(blink::Visitor*) override; + void Trace(blink::Visitor*) const override; + + private: + Member<LocalFrame> local_frame_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.cc b/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.cc index 2e8237eaccb..f42358abef7 100644 --- a/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.cc +++ b/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.cc @@ -12,7 +12,8 @@ namespace blink { const char NavigatorInk::kSupplementName[] = "NavigatorInk"; NavigatorInk::NavigatorInk(Navigator& navigator) - : Supplement<Navigator>(navigator), ink_(MakeGarbageCollected<Ink>()) {} + : Supplement<Navigator>(navigator), + ink_(MakeGarbageCollected<Ink>(GetSupplementable()->GetFrame())) {} Ink* NavigatorInk::ink(Navigator& navigator) { DCHECK(RuntimeEnabledFeatures::DelegatedInkTrailsEnabled()); @@ -27,7 +28,7 @@ Ink* NavigatorInk::ink(Navigator& navigator) { return supplement->ink_; } -void NavigatorInk::Trace(Visitor* visitor) { +void NavigatorInk::Trace(Visitor* visitor) const { visitor->Trace(ink_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.h b/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.h index 73c10fa9e58..2567e1b6cb5 100644 --- a/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.h +++ b/chromium/third_party/blink/renderer/modules/delegated_ink/navigator_ink.h @@ -23,7 +23,7 @@ class NavigatorInk : public GarbageCollected<NavigatorInk>, explicit NavigatorInk(Navigator& navigator); - void Trace(blink::Visitor*) override; + void Trace(blink::Visitor*) const override; private: Member<Ink> ink_; 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 88fecfaf891..b23256c41e2 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 @@ -65,7 +65,7 @@ void DeviceMotionController::DidAddEventListener( {mojom::blink::FeaturePolicyFeature::kAccelerometer, mojom::blink::FeaturePolicyFeature::kGyroscope})) { DeviceOrientationController::LogToConsolePolicyFeaturesDisabled( - GetWindow().GetFrame(), EventTypeName()); + *GetWindow().GetFrame(), EventTypeName()); return; } } @@ -81,13 +81,8 @@ bool DeviceMotionController::HasLastData() { void DeviceMotionController::RegisterWithDispatcher() { if (!motion_event_pump_) { - LocalFrame* frame = GetWindow().GetFrame(); - if (!frame) - return; - scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame->GetTaskRunner(TaskType::kSensor); motion_event_pump_ = - MakeGarbageCollected<DeviceMotionEventPump>(task_runner); + MakeGarbageCollected<DeviceMotionEventPump>(*GetWindow().GetFrame()); } motion_event_pump_->SetController(this); } @@ -113,7 +108,7 @@ const AtomicString& DeviceMotionController::EventTypeName() const { return event_type_names::kDevicemotion; } -void DeviceMotionController::Trace(Visitor* visitor) { +void DeviceMotionController::Trace(Visitor* visitor) const { DeviceSingleWindowEventController::Trace(visitor); visitor->Trace(motion_event_pump_); Supplement<LocalDOMWindow>::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h index a22ce09961c..54ce48d95da 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_controller.h @@ -31,7 +31,7 @@ class MODULES_EXPORT DeviceMotionController final void DidAddEventListener(LocalDOMWindow*, const AtomicString& event_type) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Inherited from PlatformEventController. diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.cc index 7ece6d0b274..2ef1aa080c7 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.cc @@ -70,7 +70,7 @@ DeviceMotionData::DeviceMotionData( rotation_rate_(rotation_rate), interval_(interval) {} -void DeviceMotionData::Trace(Visitor* visitor) { +void DeviceMotionData::Trace(Visitor* visitor) const { visitor->Trace(acceleration_); visitor->Trace(acceleration_including_gravity_); visitor->Trace(rotation_rate_); diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.h index 0c0cb798b31..d32948852a2 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.h +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_data.h @@ -53,7 +53,7 @@ class MODULES_EXPORT DeviceMotionData final DeviceMotionEventRotationRate*, double interval); - void Trace(Visitor*); + void Trace(Visitor*) const; DeviceMotionEventAcceleration* GetAcceleration() const { return acceleration_.Get(); diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.cc index 9620836278e..bc867ac91dd 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.cc @@ -68,7 +68,7 @@ const AtomicString& DeviceMotionEvent::InterfaceName() const { return event_interface_names::kDeviceMotionEvent; } -void DeviceMotionEvent::Trace(Visitor* visitor) { +void DeviceMotionEvent::Trace(Visitor* visitor) const { visitor->Trace(device_motion_data_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.h index cc05253b058..73b44e6755a 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.h +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event.h @@ -70,7 +70,7 @@ class DeviceMotionEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<const DeviceMotionData> device_motion_data_; diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.cc index 313e6f187ee..54ad5fdf4ea 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.cc @@ -36,9 +36,9 @@ DeviceMotionEventAcceleration* DeviceMotionEventAcceleration::Create(double x, DeviceMotionEventAcceleration* DeviceMotionEventAcceleration::Create( const DeviceMotionEventAccelerationInit* init) { - double x = init->hasX() ? init->x() : NAN; - double y = init->hasY() ? init->y() : NAN; - double z = init->hasZ() ? init->z() : NAN; + double x = init->hasXNonNull() ? init->xNonNull() : NAN; + double y = init->hasYNonNull() ? init->yNonNull() : NAN; + double z = init->hasZNonNull() ? init->zNonNull() : NAN; return DeviceMotionEventAcceleration::Create(x, y, z); } 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 be3e7cd9439..1256f3fd762 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 @@ -29,15 +29,15 @@ constexpr double kDefaultPumpDelayMilliseconds = namespace blink { -DeviceMotionEventPump::DeviceMotionEventPump( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : DeviceSensorEventPump(std::move(task_runner)) { +DeviceMotionEventPump::DeviceMotionEventPump(LocalFrame& frame) + : DeviceSensorEventPump(frame) { accelerometer_ = MakeGarbageCollected<DeviceSensorEntry>( - this, device::mojom::blink::SensorType::ACCELEROMETER); + this, frame.DomWindow(), device::mojom::blink::SensorType::ACCELEROMETER); linear_acceleration_sensor_ = MakeGarbageCollected<DeviceSensorEntry>( - this, device::mojom::blink::SensorType::LINEAR_ACCELERATION); + this, frame.DomWindow(), + device::mojom::blink::SensorType::LINEAR_ACCELERATION); gyroscope_ = MakeGarbageCollected<DeviceSensorEntry>( - this, device::mojom::blink::SensorType::GYROSCOPE); + this, frame.DomWindow(), device::mojom::blink::SensorType::GYROSCOPE); } DeviceMotionEventPump::~DeviceMotionEventPump() = default; @@ -47,7 +47,7 @@ void DeviceMotionEventPump::SetController(PlatformEventController* controller) { DCHECK(!controller_); controller_ = controller; - StartListening(controller_->GetWindow().GetFrame()); + StartListening(*controller_->GetWindow().GetFrame()); } void DeviceMotionEventPump::RemoveController() { @@ -59,7 +59,7 @@ DeviceMotionData* DeviceMotionEventPump::LatestDeviceMotionData() { return data_.Get(); } -void DeviceMotionEventPump::Trace(Visitor* visitor) { +void DeviceMotionEventPump::Trace(Visitor* visitor) const { visitor->Trace(accelerometer_); visitor->Trace(linear_acceleration_sensor_); visitor->Trace(gyroscope_); @@ -68,19 +68,15 @@ void DeviceMotionEventPump::Trace(Visitor* visitor) { DeviceSensorEventPump::Trace(visitor); } -void DeviceMotionEventPump::StartListening(LocalFrame* frame) { - // TODO(crbug.com/850619): ensure a valid frame is passed - if (!frame) - return; +void DeviceMotionEventPump::StartListening(LocalFrame& frame) { Start(frame); } -void DeviceMotionEventPump::SendStartMessage(LocalFrame* frame) { - if (!sensor_provider_) { - DCHECK(frame); - - frame->GetBrowserInterfaceBroker().GetInterface( - sensor_provider_.BindNewPipeAndPassReceiver()); +void DeviceMotionEventPump::SendStartMessage(LocalFrame& frame) { + if (!sensor_provider_.is_bound()) { + frame.GetBrowserInterfaceBroker().GetInterface( + sensor_provider_.BindNewPipeAndPassReceiver( + frame.GetTaskRunner(TaskType::kSensor))); 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 e2e1a3d9431..70a9ae70ad3 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 @@ -22,7 +22,7 @@ class MODULES_EXPORT DeviceMotionEventPump USING_GARBAGE_COLLECTED_MIXIN(DeviceMotionEventPump); public: - explicit DeviceMotionEventPump(scoped_refptr<base::SingleThreadTaskRunner>); + explicit DeviceMotionEventPump(LocalFrame&); ~DeviceMotionEventPump() override; void SetController(PlatformEventController*); @@ -31,10 +31,10 @@ class MODULES_EXPORT DeviceMotionEventPump // Note that the returned object is owned by this class. DeviceMotionData* LatestDeviceMotionData(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // DeviceSensorEventPump: - void SendStartMessage(LocalFrame* frame) override; + void SendStartMessage(LocalFrame& frame) override; void SendStopMessage() override; protected: @@ -48,7 +48,7 @@ class MODULES_EXPORT DeviceMotionEventPump private: friend class DeviceMotionEventPumpTest; - void StartListening(LocalFrame*); + void StartListening(LocalFrame&); void StopListening(); void NotifyController(); 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 e428ac1e682..c7eb637e3bf 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 @@ -39,7 +39,7 @@ class MockDeviceMotionController final motion_pump_(motion_pump) {} ~MockDeviceMotionController() override {} - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { PlatformEventController::Trace(visitor); visitor->Trace(motion_pump_); } @@ -79,17 +79,17 @@ class DeviceMotionEventPumpTest : public testing::Test { protected: void SetUp() override { + page_holder_ = std::make_unique<DummyPageHolder>(); + mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider; sensor_provider_.Bind(sensor_provider.InitWithNewPipeAndPassReceiver()); - auto* motion_pump = MakeGarbageCollected<DeviceMotionEventPump>( - base::ThreadTaskRunnerHandle::Get()); + auto* motion_pump = + MakeGarbageCollected<DeviceMotionEventPump>(page_holder_->GetFrame()); motion_pump->SetSensorProviderForTesting( mojo::PendingRemote<device::mojom::blink::SensorProvider>( sensor_provider.PassPipe(), device::mojom::SensorProvider::Version_)); - page_holder_ = std::make_unique<DummyPageHolder>(); - controller_ = MakeGarbageCollected<MockDeviceMotionController>( motion_pump, *page_holder_->GetFrame().DomWindow()); @@ -138,86 +138,8 @@ class DeviceMotionEventPumpTest : public testing::Test { DISALLOW_COPY_AND_ASSIGN(DeviceMotionEventPumpTest); }; -TEST_F(DeviceMotionEventPumpTest, MultipleStartAndStopWithWait) { - controller()->motion_pump()->Start(nullptr); - base::RunLoop().RunUntilIdle(); - - ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE); - EXPECT_EQ(DeviceMotionEventPump::PumpState::RUNNING, - controller()->motion_pump()->GetPumpStateForTesting()); - - controller()->motion_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED); - EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED, - controller()->motion_pump()->GetPumpStateForTesting()); - - controller()->motion_pump()->Start(nullptr); - base::RunLoop().RunUntilIdle(); - - ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE); - EXPECT_EQ(DeviceMotionEventPump::PumpState::RUNNING, - controller()->motion_pump()->GetPumpStateForTesting()); - - controller()->motion_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED); - EXPECT_EQ(DeviceMotionEventPump::PumpState::STOPPED, - controller()->motion_pump()->GetPumpStateForTesting()); -} - -TEST_F(DeviceMotionEventPumpTest, CallStop) { - controller()->motion_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::NOT_INITIALIZED); -} - -TEST_F(DeviceMotionEventPumpTest, CallStartAndStop) { - controller()->motion_pump()->Start(nullptr); - controller()->motion_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -TEST_F(DeviceMotionEventPumpTest, CallStartMultipleTimes) { - controller()->motion_pump()->Start(nullptr); - controller()->motion_pump()->Start(nullptr); - controller()->motion_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -TEST_F(DeviceMotionEventPumpTest, CallStopMultipleTimes) { - controller()->motion_pump()->Start(nullptr); - controller()->motion_pump()->Stop(); - controller()->motion_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -// Test multiple DeviceSensorEventPump::Start() calls only bind sensor once. -TEST_F(DeviceMotionEventPumpTest, SensorOnlyBindOnce) { - controller()->motion_pump()->Start(nullptr); - controller()->motion_pump()->Stop(); - controller()->motion_pump()->Start(nullptr); - base::RunLoop().RunUntilIdle(); - - ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE); - - controller()->motion_pump()->Stop(); - - ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) { controller()->RegisterWithDispatcher(); - controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -250,7 +172,7 @@ TEST_F(DeviceMotionEventPumpTest, AllSensorsAreActive) { EXPECT_EQ(gfx::RadToDeg(9.0), received_data->GetRotationRate()->gamma().value()); - controller()->motion_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED); } @@ -259,7 +181,6 @@ TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) { sensor_provider()->set_linear_acceleration_sensor_is_available(false); controller()->RegisterWithDispatcher(); - controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAccelerometerStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -293,7 +214,7 @@ TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) { EXPECT_EQ(gfx::RadToDeg(9.0), received_data->GetRotationRate()->gamma().value()); - controller()->motion_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectAccelerometerStateToBe(DeviceSensorEntry::State::SUSPENDED); ExpectLinearAccelerationSensorStateToBe( @@ -303,7 +224,6 @@ TEST_F(DeviceMotionEventPumpTest, TwoSensorsAreActive) { TEST_F(DeviceMotionEventPumpTest, SomeSensorDataFieldsNotAvailable) { controller()->RegisterWithDispatcher(); - controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -333,7 +253,7 @@ TEST_F(DeviceMotionEventPumpTest, SomeSensorDataFieldsNotAvailable) { received_data->GetRotationRate()->beta().value()); EXPECT_FALSE(received_data->GetRotationRate()->gamma().has_value()); - controller()->motion_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED); } @@ -345,7 +265,6 @@ TEST_F(DeviceMotionEventPumpTest, FireAllNullEvent) { sensor_provider()->set_gyroscope_is_available(false); controller()->RegisterWithDispatcher(); - controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::NOT_INITIALIZED); @@ -362,7 +281,7 @@ TEST_F(DeviceMotionEventPumpTest, FireAllNullEvent) { EXPECT_FALSE(received_data->GetRotationRate()->HasRotationData()); - controller()->motion_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::NOT_INITIALIZED); } @@ -370,7 +289,6 @@ TEST_F(DeviceMotionEventPumpTest, FireAllNullEvent) { TEST_F(DeviceMotionEventPumpTest, NotFireEventWhenSensorReadingTimeStampIsZero) { controller()->RegisterWithDispatcher(); - controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -391,7 +309,7 @@ TEST_F(DeviceMotionEventPumpTest, // Event is fired only after all the available sensors have data. EXPECT_TRUE(controller()->did_change_device_motion()); - controller()->motion_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED); } @@ -405,7 +323,6 @@ TEST_F(DeviceMotionEventPumpTest, PumpThrottlesEventRate) { DeviceMotionEventPump::kDefaultPumpDelayMicroseconds); controller()->RegisterWithDispatcher(); - controller()->motion_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -419,7 +336,7 @@ TEST_F(DeviceMotionEventPumpTest, PumpThrottlesEventRate) { FROM_HERE, loop.QuitWhenIdleClosure(), base::TimeDelta::FromMilliseconds(100)); loop.Run(); - controller()->motion_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectAllThreeSensorsStateToBe(DeviceSensorEntry::State::SUSPENDED); diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.cc index 90aa1e5a89a..e8f009d63f3 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.cc @@ -36,9 +36,9 @@ DeviceMotionEventRotationRate::Create(double alpha, double beta, double gamma) { DeviceMotionEventRotationRate* DeviceMotionEventRotationRate::Create( const DeviceMotionEventRotationRateInit* init) { - double alpha = init->hasAlpha() ? init->alpha() : NAN; - double beta = init->hasBeta() ? init->beta() : NAN; - double gamma = init->hasGamma() ? init->gamma() : NAN; + double alpha = init->hasAlphaNonNull() ? init->alphaNonNull() : NAN; + double beta = init->hasBetaNonNull() ? init->betaNonNull() : NAN; + double gamma = init->hasGammaNonNull() ? init->gammaNonNull() : NAN; return DeviceMotionEventRotationRate::Create(alpha, beta, gamma); } 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 810ee484c37..30cd0df7d2c 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 @@ -65,7 +65,7 @@ void DeviceOrientationAbsoluteController::DidAddEventListener( {mojom::blink::FeaturePolicyFeature::kAccelerometer, mojom::blink::FeaturePolicyFeature::kGyroscope, mojom::blink::FeaturePolicyFeature::kMagnetometer})) { - LogToConsolePolicyFeaturesDisabled(GetWindow().GetFrame(), + LogToConsolePolicyFeaturesDisabled(*GetWindow().GetFrame(), EventTypeName()); return; } @@ -78,7 +78,7 @@ const AtomicString& DeviceOrientationAbsoluteController::EventTypeName() const { return event_type_names::kDeviceorientationabsolute; } -void DeviceOrientationAbsoluteController::Trace(Visitor* visitor) { +void DeviceOrientationAbsoluteController::Trace(Visitor* visitor) const { DeviceOrientationController::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h index 12d75ea2d8b..8762da3c905 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h @@ -24,7 +24,7 @@ class MODULES_EXPORT DeviceOrientationAbsoluteController final void DidAddEventListener(LocalDOMWindow*, const AtomicString& event_type) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Inherited from PlatformEventController. diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc index 82de83b3d63..701ea76138b 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.cc @@ -74,7 +74,7 @@ void DeviceOrientationController::DidAddEventListener( if (!CheckPolicyFeatures( {mojom::blink::FeaturePolicyFeature::kAccelerometer, mojom::blink::FeaturePolicyFeature::kGyroscope})) { - LogToConsolePolicyFeaturesDisabled(GetWindow().GetFrame(), + LogToConsolePolicyFeaturesDisabled(*GetWindow().GetFrame(), EventTypeName()); return; } @@ -132,7 +132,7 @@ void DeviceOrientationController::ClearOverride() { DidUpdateData(); } -void DeviceOrientationController::Trace(Visitor* visitor) { +void DeviceOrientationController::Trace(Visitor* visitor) const { visitor->Trace(override_orientation_data_); visitor->Trace(orientation_event_pump_); DeviceSingleWindowEventController::Trace(visitor); @@ -141,26 +141,17 @@ void DeviceOrientationController::Trace(Visitor* visitor) { void DeviceOrientationController::RegisterWithOrientationEventPump( bool absolute) { - // The window's frame may be null if the window was already shut down. - LocalFrame* frame = GetWindow().GetFrame(); if (!orientation_event_pump_) { - if (!frame) - return; - scoped_refptr<base::SingleThreadTaskRunner> task_runner = - frame->GetTaskRunner(TaskType::kSensor); - orientation_event_pump_ = - MakeGarbageCollected<DeviceOrientationEventPump>(task_runner, absolute); + orientation_event_pump_ = MakeGarbageCollected<DeviceOrientationEventPump>( + *GetWindow().GetFrame(), absolute); } - // TODO(crbug.com/850619): Ensure a valid frame is passed. orientation_event_pump_->SetController(this); } // static void DeviceOrientationController::LogToConsolePolicyFeaturesDisabled( - LocalFrame* frame, + LocalFrame& frame, const AtomicString& event_name) { - if (!frame) - return; const String& message = String::Format( "The %s events are blocked by feature policy. " "See " @@ -170,7 +161,7 @@ void DeviceOrientationController::LogToConsolePolicyFeaturesDisabled( auto* console_message = MakeGarbageCollected<ConsoleMessage>( mojom::ConsoleMessageSource::kJavaScript, mojom::ConsoleMessageLevel::kWarning, std::move(message)); - frame->Console().AddMessage(console_message); + frame.Console().AddMessage(console_message); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h index df89e20b22f..54e26c27aa8 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h @@ -36,10 +36,10 @@ class MODULES_EXPORT DeviceOrientationController void SetOverride(DeviceOrientationData*); void ClearOverride(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; static void LogToConsolePolicyFeaturesDisabled( - LocalFrame*, + LocalFrame&, const AtomicString& event_name); protected: diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.h index 6dd83bc084d..a9e5db47d76 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.h +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_data.h @@ -50,7 +50,7 @@ class MODULES_EXPORT DeviceOrientationData final const base::Optional<double>& gamma, bool absolute); - void Trace(Visitor* visitor) {} + void Trace(Visitor* visitor) const {} double Alpha() const; double Beta() const; diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.cc index 87548473a7d..0948a3a1c98 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.cc @@ -73,7 +73,7 @@ const AtomicString& DeviceOrientationEvent::InterfaceName() const { return event_interface_names::kDeviceOrientationEvent; } -void DeviceOrientationEvent::Trace(Visitor* visitor) { +void DeviceOrientationEvent::Trace(Visitor* visitor) const { visitor->Trace(orientation_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.h index c8939433d31..a5bbee82321 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.h +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_event.h @@ -70,7 +70,7 @@ class DeviceOrientationEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<DeviceOrientationData> orientation_; 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 83ff95cdb07..cabfa05c1f0 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 @@ -44,16 +44,15 @@ namespace blink { const double DeviceOrientationEventPump::kOrientationThreshold = 0.1; -DeviceOrientationEventPump::DeviceOrientationEventPump( - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - bool absolute) - : DeviceSensorEventPump(std::move(task_runner)), - absolute_(absolute), - fall_back_to_absolute_orientation_sensor_(!absolute) { +DeviceOrientationEventPump::DeviceOrientationEventPump(LocalFrame& frame, + bool absolute) + : DeviceSensorEventPump(frame), absolute_(absolute) { relative_orientation_sensor_ = MakeGarbageCollected<DeviceSensorEntry>( - this, device::mojom::SensorType::RELATIVE_ORIENTATION_EULER_ANGLES); + this, frame.DomWindow(), + device::mojom::SensorType::RELATIVE_ORIENTATION_EULER_ANGLES); absolute_orientation_sensor_ = MakeGarbageCollected<DeviceSensorEntry>( - this, device::mojom::SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES); + this, frame.DomWindow(), + device::mojom::SensorType::ABSOLUTE_ORIENTATION_EULER_ANGLES); } DeviceOrientationEventPump::~DeviceOrientationEventPump() = default; @@ -64,12 +63,13 @@ void DeviceOrientationEventPump::SetController( DCHECK(!controller_); controller_ = controller; - StartListening(controller_->GetWindow().GetFrame()); + Start(*controller_->GetWindow().GetFrame()); } void DeviceOrientationEventPump::RemoveController() { controller_ = nullptr; - StopListening(); + Stop(); + data_.Clear(); } DeviceOrientationData* @@ -77,26 +77,19 @@ DeviceOrientationEventPump::LatestDeviceOrientationData() { return data_.Get(); } -void DeviceOrientationEventPump::Trace(Visitor* visitor) { +void DeviceOrientationEventPump::Trace(Visitor* visitor) const { visitor->Trace(relative_orientation_sensor_); visitor->Trace(absolute_orientation_sensor_); visitor->Trace(data_); visitor->Trace(controller_); + DeviceSensorEventPump::Trace(visitor); } -void DeviceOrientationEventPump::StartListening(LocalFrame* frame) { - // TODO(crbug.com/850619): ensure a valid frame is passed - if (!frame) - return; - Start(frame); -} - -void DeviceOrientationEventPump::SendStartMessage(LocalFrame* frame) { - if (!sensor_provider_) { - DCHECK(frame); - - frame->GetBrowserInterfaceBroker().GetInterface( - sensor_provider_.BindNewPipeAndPassReceiver()); +void DeviceOrientationEventPump::SendStartMessage(LocalFrame& frame) { + if (!sensor_provider_.is_bound()) { + frame.GetBrowserInterfaceBroker().GetInterface( + sensor_provider_.BindNewPipeAndPassReceiver( + frame.GetTaskRunner(TaskType::kSensor))); sensor_provider_.set_disconnect_handler( WTF::Bind(&DeviceSensorEventPump::HandleSensorProviderError, WrapWeakPersistent(this))); @@ -105,39 +98,22 @@ void DeviceOrientationEventPump::SendStartMessage(LocalFrame* frame) { if (absolute_) { absolute_orientation_sensor_->Start(sensor_provider_.get()); } else { - fall_back_to_absolute_orientation_sensor_ = true; - should_suspend_absolute_orientation_sensor_ = false; + // Start() is asynchronous. Therefore IsConnected() can not be checked right + // away to determine if we should attempt to fall back to + // absolute_orientation_sensor_. + attempted_to_fall_back_to_absolute_orientation_sensor_ = false; relative_orientation_sensor_->Start(sensor_provider_.get()); } } -void DeviceOrientationEventPump::StopListening() { - Stop(); - data_.Clear(); -} - void DeviceOrientationEventPump::SendStopMessage() { // SendStopMessage() gets called both when the page visibility changes and if // all device orientation event listeners are unregistered. Since removing // the event listener is more rare than the page visibility changing, // Sensor::Suspend() is used to optimize this case for not doing extra work. - relative_orientation_sensor_->Stop(); - // This is needed in case we fallback to using the absolute orientation - // sensor. In this case, the relative orientation sensor is marked as - // SensorState::SHOULD_SUSPEND, and if the relative orientation sensor - // is not available, the absolute orientation sensor should also be marked as - // SensorState::SHOULD_SUSPEND, but only after the - // absolute_orientation_sensor_.Start() is called for initializing - // the absolute orientation sensor in - // DeviceOrientationEventPump::DidStartIfPossible(). - if (relative_orientation_sensor_->state() == - DeviceSensorEntry::State::SHOULD_SUSPEND && - fall_back_to_absolute_orientation_sensor_) { - should_suspend_absolute_orientation_sensor_ = true; - } - absolute_orientation_sensor_->Stop(); + relative_orientation_sensor_->Stop(); // Reset the cached data because DeviceOrientationDispatcher resets its // data when stopping. If we don't reset here as well, then when starting back @@ -161,18 +137,23 @@ void DeviceOrientationEventPump::FireEvent(TimerBase*) { } void DeviceOrientationEventPump::DidStartIfPossible() { - if (!absolute_ && !relative_orientation_sensor_->IsConnected() && - fall_back_to_absolute_orientation_sensor_ && sensor_provider_) { - // When relative orientation sensor is not available fall back to using - // the absolute orientation sensor but only on the first failure. - fall_back_to_absolute_orientation_sensor_ = false; + if (!absolute_ && sensor_provider_.is_bound() && + !relative_orientation_sensor_->IsConnected() && + !attempted_to_fall_back_to_absolute_orientation_sensor_) { + // If relative_orientation_sensor_ was requested but was not able to connect + // then fall back to using absolute_orientation_sensor_. + attempted_to_fall_back_to_absolute_orientation_sensor_ = true; absolute_orientation_sensor_->Start(sensor_provider_.get()); - if (should_suspend_absolute_orientation_sensor_) { - // The absolute orientation sensor needs to be marked as - // SensorState::SUSPENDED when it is successfully initialized. + if (relative_orientation_sensor_->state() == + DeviceSensorEntry::State::SHOULD_SUSPEND) { + // If SendStopMessage() was called before the OnSensorCreated() callback + // registered that relative_orientation_sensor_ was not able to connect + // then absolute_orientation_sensor_ needs to be Stop()'d so that it + // matches the relative_orientation_sensor_ state. absolute_orientation_sensor_->Stop(); - should_suspend_absolute_orientation_sensor_ = false; } + // Start() is asynchronous. Give the OnSensorCreated() callback time to fire + // before calling DeviceSensorEventPump::DidStartIfPossible(). return; } DeviceSensorEventPump::DidStartIfPossible(); 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 f75b7598cb8..090caf924d6 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 @@ -26,9 +26,7 @@ class MODULES_EXPORT DeviceOrientationEventPump // sufficiently different. static const double kOrientationThreshold; - explicit DeviceOrientationEventPump( - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - bool absolute); + explicit DeviceOrientationEventPump(LocalFrame&, bool absolute); ~DeviceOrientationEventPump() override; void SetController(PlatformEventController*); @@ -37,10 +35,10 @@ class MODULES_EXPORT DeviceOrientationEventPump // Note that the returned object is owned by this class. DeviceOrientationData* LatestDeviceOrientationData(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // DeviceSensorEventPump: - void SendStartMessage(LocalFrame* frame) override; + void SendStartMessage(LocalFrame& frame) override; void SendStopMessage() override; protected: @@ -55,8 +53,6 @@ class MODULES_EXPORT DeviceOrientationEventPump friend class DeviceOrientationEventPumpTest; friend class DeviceAbsoluteOrientationEventPumpTest; - void StartListening(LocalFrame*); - void StopListening(); void NotifyController(); // DeviceSensorEventPump: @@ -67,8 +63,9 @@ class MODULES_EXPORT DeviceOrientationEventPump bool ShouldFireEvent(const DeviceOrientationData* data) const; bool absolute_; - bool fall_back_to_absolute_orientation_sensor_; - bool should_suspend_absolute_orientation_sensor_ = false; + // If relative_orientation_sensor_ is requested but fails to initialize then + // attempt to fall back to absolute_orientation_sensor_ once. + bool attempted_to_fall_back_to_absolute_orientation_sensor_; Member<DeviceOrientationData> data_; Member<PlatformEventController> controller_; 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 5cbb10cce94..bbff6ce39b5 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 @@ -43,7 +43,7 @@ class MockDeviceOrientationController final orientation_pump_(orientation_pump) {} ~MockDeviceOrientationController() override {} - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { PlatformEventController::Trace(visitor); visitor->Trace(orientation_pump_); } @@ -58,12 +58,6 @@ class MockDeviceOrientationController final } void RegisterWithDispatcher() override { - // In the typical case, |frame| should be non-null. Passing nullptr here - // causes DeviceOrientationEventPump to exit early from StartListening - // before DeviceOrientationEventPump::Start is called. As a workaround, - // Start is called manually by each test case. - // TODO(crbug.com/850619): Ensure a non-null LocalFrame is passed, and use - // SetController/RemoveController to start and stop the event pump. orientation_pump_->SetController(this); } @@ -96,17 +90,17 @@ class DeviceOrientationEventPumpTest : public testing::Test { protected: void SetUp() override { + page_holder_ = std::make_unique<DummyPageHolder>(); + mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider; sensor_provider_.Bind(sensor_provider.InitWithNewPipeAndPassReceiver()); auto* orientation_pump = MakeGarbageCollected<DeviceOrientationEventPump>( - base::ThreadTaskRunnerHandle::Get(), false /* absolute */); + page_holder_->GetFrame(), false /* absolute */); orientation_pump->SetSensorProviderForTesting( mojo::PendingRemote<device::mojom::blink::SensorProvider>( sensor_provider.PassPipe(), device::mojom::SensorProvider::Version_)); - page_holder_ = std::make_unique<DummyPageHolder>(); - controller_ = MakeGarbageCollected<MockDeviceOrientationController>( orientation_pump, *page_holder_->GetFrame().DomWindow()); @@ -146,201 +140,8 @@ class DeviceOrientationEventPumpTest : public testing::Test { DISALLOW_COPY_AND_ASSIGN(DeviceOrientationEventPumpTest); }; -TEST_F(DeviceOrientationEventPumpTest, MultipleStartAndStopWithWait) { - controller()->orientation_pump()->Start(nullptr); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); - EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING, - controller()->orientation_pump()->GetPumpStateForTesting()); - - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); - EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED, - controller()->orientation_pump()->GetPumpStateForTesting()); - - controller()->orientation_pump()->Start(nullptr); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); - EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING, - controller()->orientation_pump()->GetPumpStateForTesting()); - - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); - EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED, - controller()->orientation_pump()->GetPumpStateForTesting()); -} - -TEST_F(DeviceOrientationEventPumpTest, - MultipleStartAndStopWithWaitWithSensorFallback) { - sensor_provider()->set_relative_orientation_sensor_is_available(false); - - controller()->orientation_pump()->Start(nullptr); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); - EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING, - controller()->orientation_pump()->GetPumpStateForTesting()); - - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); - EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED, - controller()->orientation_pump()->GetPumpStateForTesting()); - - controller()->orientation_pump()->Start(nullptr); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); - EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING, - controller()->orientation_pump()->GetPumpStateForTesting()); - - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); - EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED, - controller()->orientation_pump()->GetPumpStateForTesting()); -} - -TEST_F(DeviceOrientationEventPumpTest, CallStop) { - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); -} - -TEST_F(DeviceOrientationEventPumpTest, CallStopWithSensorFallback) { - sensor_provider()->set_relative_orientation_sensor_is_available(false); - - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); - ExpectAbsoluteOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); -} - -TEST_F(DeviceOrientationEventPumpTest, CallStartAndStop) { - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -TEST_F(DeviceOrientationEventPumpTest, CallStartAndStopWithSensorFallback) { - sensor_provider()->set_relative_orientation_sensor_is_available(false); - - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -TEST_F(DeviceOrientationEventPumpTest, CallStartMultipleTimes) { - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -TEST_F(DeviceOrientationEventPumpTest, - CallStartMultipleTimesWithSensorFallback) { - sensor_provider()->set_relative_orientation_sensor_is_available(false); - - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -TEST_F(DeviceOrientationEventPumpTest, CallStopMultipleTimes) { - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Stop(); - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -TEST_F(DeviceOrientationEventPumpTest, - CallStopMultipleTimesWithSensorFallback) { - sensor_provider()->set_relative_orientation_sensor_is_available(false); - - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Stop(); - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -// Test a sequence of Start(), Stop(), Start() calls only bind sensor once. -TEST_F(DeviceOrientationEventPumpTest, SensorOnlyBindOnce) { - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Stop(); - controller()->orientation_pump()->Start(nullptr); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); - - controller()->orientation_pump()->Stop(); - - ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -// Test when using fallback from relative orientation to absolute orientation, -// a sequence of Start(), Stop(), Start() calls only bind sensor once. -TEST_F(DeviceOrientationEventPumpTest, SensorOnlyBindOnceWithSensorFallback) { - sensor_provider()->set_relative_orientation_sensor_is_available(false); - - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Stop(); - controller()->orientation_pump()->Start(nullptr); - base::RunLoop().RunUntilIdle(); - - ExpectRelativeOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); - - controller()->orientation_pump()->Stop(); - - ExpectRelativeOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - TEST_F(DeviceOrientationEventPumpTest, SensorIsActive) { controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -363,7 +164,7 @@ TEST_F(DeviceOrientationEventPumpTest, SensorIsActive) { EXPECT_TRUE(received_data->CanProvideGamma()); EXPECT_FALSE(received_data->Absolute()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); } @@ -372,7 +173,6 @@ TEST_F(DeviceOrientationEventPumpTest, SensorIsActiveWithSensorFallback) { sensor_provider()->set_relative_orientation_sensor_is_available(false); controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectRelativeOrientationSensorStateToBe( @@ -401,7 +201,7 @@ TEST_F(DeviceOrientationEventPumpTest, SensorIsActiveWithSensorFallback) { // fallback to provide absolute orientation data. EXPECT_TRUE(received_data->Absolute()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectRelativeOrientationSensorStateToBe( DeviceSensorEntry::State::NOT_INITIALIZED); @@ -410,7 +210,6 @@ TEST_F(DeviceOrientationEventPumpTest, SensorIsActiveWithSensorFallback) { TEST_F(DeviceOrientationEventPumpTest, SomeSensorDataFieldsNotAvailable) { controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -430,7 +229,7 @@ TEST_F(DeviceOrientationEventPumpTest, SomeSensorDataFieldsNotAvailable) { EXPECT_TRUE(received_data->CanProvideGamma()); EXPECT_FALSE(received_data->Absolute()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); } @@ -440,7 +239,6 @@ TEST_F(DeviceOrientationEventPumpTest, sensor_provider()->set_relative_orientation_sensor_is_available(false); controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectRelativeOrientationSensorStateToBe( @@ -467,7 +265,7 @@ TEST_F(DeviceOrientationEventPumpTest, // fallback to provide absolute orientation data. EXPECT_TRUE(received_data->Absolute()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectRelativeOrientationSensorStateToBe( DeviceSensorEntry::State::NOT_INITIALIZED); @@ -480,7 +278,6 @@ TEST_F(DeviceOrientationEventPumpTest, FireAllNullEvent) { sensor_provider()->set_absolute_orientation_sensor_is_available(false); controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectRelativeOrientationSensorStateToBe( @@ -498,7 +295,7 @@ TEST_F(DeviceOrientationEventPumpTest, FireAllNullEvent) { EXPECT_FALSE(received_data->CanProvideGamma()); EXPECT_FALSE(received_data->Absolute()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectRelativeOrientationSensorStateToBe( DeviceSensorEntry::State::NOT_INITIALIZED); @@ -509,7 +306,6 @@ TEST_F(DeviceOrientationEventPumpTest, FireAllNullEvent) { TEST_F(DeviceOrientationEventPumpTest, NotFireEventWhenSensorReadingTimeStampIsZero) { controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -518,7 +314,7 @@ TEST_F(DeviceOrientationEventPumpTest, EXPECT_FALSE(controller()->did_change_device_orientation()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); } @@ -528,7 +324,6 @@ TEST_F(DeviceOrientationEventPumpTest, sensor_provider()->set_relative_orientation_sensor_is_available(false); controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectRelativeOrientationSensorStateToBe( @@ -539,7 +334,7 @@ TEST_F(DeviceOrientationEventPumpTest, EXPECT_FALSE(controller()->did_change_device_orientation()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectRelativeOrientationSensorStateToBe( DeviceSensorEntry::State::NOT_INITIALIZED); @@ -548,7 +343,6 @@ TEST_F(DeviceOrientationEventPumpTest, TEST_F(DeviceOrientationEventPumpTest, UpdateRespectsOrientationThreshold) { controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -610,7 +404,7 @@ TEST_F(DeviceOrientationEventPumpTest, UpdateRespectsOrientationThreshold) { EXPECT_TRUE(received_data->CanProvideGamma()); EXPECT_FALSE(received_data->Absolute()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectRelativeOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); } @@ -620,7 +414,6 @@ TEST_F(DeviceOrientationEventPumpTest, sensor_provider()->set_relative_orientation_sensor_is_available(false); controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectRelativeOrientationSensorStateToBe( @@ -691,7 +484,7 @@ TEST_F(DeviceOrientationEventPumpTest, EXPECT_TRUE(received_data->CanProvideGamma()); EXPECT_TRUE(received_data->Absolute()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectRelativeOrientationSensorStateToBe( DeviceSensorEntry::State::NOT_INITIALIZED); @@ -704,18 +497,18 @@ class DeviceAbsoluteOrientationEventPumpTest : public testing::Test { protected: void SetUp() override { + page_holder_ = std::make_unique<DummyPageHolder>(); + mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider; sensor_provider_.Bind(sensor_provider.InitWithNewPipeAndPassReceiver()); auto* absolute_orientation_pump = MakeGarbageCollected<DeviceOrientationEventPump>( - base::ThreadTaskRunnerHandle::Get(), true /* absolute */); + page_holder_->GetFrame(), true /* absolute */); absolute_orientation_pump->SetSensorProviderForTesting( mojo::PendingRemote<device::mojom::blink::SensorProvider>( sensor_provider.PassPipe(), device::mojom::SensorProvider::Version_)); - page_holder_ = std::make_unique<DummyPageHolder>(); - controller_ = MakeGarbageCollected<MockDeviceOrientationController>( absolute_orientation_pump, *page_holder_->GetFrame().DomWindow()); @@ -746,87 +539,8 @@ class DeviceAbsoluteOrientationEventPumpTest : public testing::Test { DISALLOW_COPY_AND_ASSIGN(DeviceAbsoluteOrientationEventPumpTest); }; -TEST_F(DeviceAbsoluteOrientationEventPumpTest, MultipleStartAndStopWithWait) { - controller()->orientation_pump()->Start(nullptr); - base::RunLoop().RunUntilIdle(); - - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); - EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING, - controller()->orientation_pump()->GetPumpStateForTesting()); - - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); - EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED, - controller()->orientation_pump()->GetPumpStateForTesting()); - - controller()->orientation_pump()->Start(nullptr); - base::RunLoop().RunUntilIdle(); - - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); - EXPECT_EQ(DeviceOrientationEventPump::PumpState::RUNNING, - controller()->orientation_pump()->GetPumpStateForTesting()); - - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); - EXPECT_EQ(DeviceOrientationEventPump::PumpState::STOPPED, - controller()->orientation_pump()->GetPumpStateForTesting()); -} - -TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStop) { - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectAbsoluteOrientationSensorStateToBe( - DeviceSensorEntry::State::NOT_INITIALIZED); -} - -TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStartAndStop) { - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStartMultipleTimes) { - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -TEST_F(DeviceAbsoluteOrientationEventPumpTest, CallStopMultipleTimes) { - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Stop(); - controller()->orientation_pump()->Stop(); - base::RunLoop().RunUntilIdle(); - - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - -// Test multiple DeviceSensorEventPump::Start() calls only bind sensor once. -TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorOnlyBindOnce) { - controller()->orientation_pump()->Start(nullptr); - controller()->orientation_pump()->Stop(); - controller()->orientation_pump()->Start(nullptr); - base::RunLoop().RunUntilIdle(); - - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); - - controller()->orientation_pump()->Stop(); - - ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); -} - TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorIsActive) { controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -847,7 +561,7 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorIsActive) { EXPECT_TRUE(received_data->CanProvideGamma()); EXPECT_TRUE(received_data->Absolute()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); } @@ -855,7 +569,6 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, SensorIsActive) { TEST_F(DeviceAbsoluteOrientationEventPumpTest, SomeSensorDataFieldsNotAvailable) { controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -875,7 +588,7 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, EXPECT_TRUE(received_data->CanProvideGamma()); EXPECT_TRUE(received_data->Absolute()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); } @@ -885,7 +598,6 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, FireAllNullEvent) { sensor_provider()->set_absolute_orientation_sensor_is_available(false); controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAbsoluteOrientationSensorStateToBe( @@ -901,7 +613,7 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, FireAllNullEvent) { EXPECT_FALSE(received_data->CanProvideGamma()); EXPECT_TRUE(received_data->Absolute()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectAbsoluteOrientationSensorStateToBe( DeviceSensorEntry::State::NOT_INITIALIZED); @@ -910,7 +622,6 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, FireAllNullEvent) { TEST_F(DeviceAbsoluteOrientationEventPumpTest, NotFireEventWhenSensorReadingTimeStampIsZero) { controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -919,7 +630,7 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, EXPECT_FALSE(controller()->did_change_device_orientation()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); } @@ -927,7 +638,6 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, TEST_F(DeviceAbsoluteOrientationEventPumpTest, UpdateRespectsOrientationThreshold) { controller()->RegisterWithDispatcher(); - controller()->orientation_pump()->Start(nullptr); base::RunLoop().RunUntilIdle(); ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::ACTIVE); @@ -991,7 +701,7 @@ TEST_F(DeviceAbsoluteOrientationEventPumpTest, EXPECT_TRUE(received_data->CanProvideGamma()); EXPECT_TRUE(received_data->Absolute()); - controller()->orientation_pump()->Stop(); + controller()->UnregisterWithDispatcher(); ExpectAbsoluteOrientationSensorStateToBe(DeviceSensorEntry::State::SUSPENDED); } diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc index 3dc0b53c75c..a729ddba21c 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.cc @@ -27,7 +27,7 @@ DeviceOrientationInspectorAgent::DeviceOrientationInspectorAgent( beta_(&agent_state_, /*default_value=*/0.0), gamma_(&agent_state_, /*default_value=*/0.0) {} -void DeviceOrientationInspectorAgent::Trace(Visitor* visitor) { +void DeviceOrientationInspectorAgent::Trace(Visitor* visitor) const { visitor->Trace(inspected_frames_); visitor->Trace(sensor_agent_); InspectorBaseAgent::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.h b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.h index a762711f1cc..f667b6e0f1b 100644 --- a/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.h +++ b/chromium/third_party/blink/renderer/modules/device_orientation/device_orientation_inspector_agent.h @@ -21,7 +21,7 @@ class MODULES_EXPORT DeviceOrientationInspectorAgent final public: explicit DeviceOrientationInspectorAgent(InspectedFrames*); ~DeviceOrientationInspectorAgent() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Protocol methods. protocol::Response setDeviceOrientationOverride(double, 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 0a41f8aaf7b..d07fc29d49a 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 @@ -6,6 +6,7 @@ #include "services/device/public/cpp/generic_sensor/sensor_reading.h" #include "services/device/public/cpp/generic_sensor/sensor_reading_shared_buffer_reader.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -13,12 +14,12 @@ namespace blink { DeviceSensorEntry::DeviceSensorEntry(DeviceSensorEventPump* event_pump, + ExecutionContext* context, device::mojom::blink::SensorType type) - : event_pump_(event_pump), type_(type) {} - -void DeviceSensorEntry::Dispose() { - client_receiver_.reset(); -} + : event_pump_(event_pump), + sensor_remote_(context), + client_receiver_(this, context), + type_(type) {} DeviceSensorEntry::~DeviceSensorEntry() = default; @@ -46,7 +47,7 @@ void DeviceSensorEntry::Start( } void DeviceSensorEntry::Stop() { - if (sensor_remote_) { + if (sensor_remote_.is_bound()) { sensor_remote_->Suspend(); state_ = State::SUSPENDED; } else if (state_ == State::INITIALIZING) { @@ -71,7 +72,7 @@ bool DeviceSensorEntry::ReadyOrErrored() const { } bool DeviceSensorEntry::GetReading(device::SensorReading* reading) { - if (!sensor_remote_) + if (!sensor_remote_.is_bound()) return false; DCHECK(shared_buffer_reader_); @@ -84,8 +85,10 @@ bool DeviceSensorEntry::GetReading(device::SensorReading* reading) { return true; } -void DeviceSensorEntry::Trace(Visitor* visitor) { +void DeviceSensorEntry::Trace(Visitor* visitor) const { visitor->Trace(event_pump_); + visitor->Trace(sensor_remote_); + visitor->Trace(client_receiver_); } void DeviceSensorEntry::RaiseError() { @@ -118,8 +121,9 @@ void DeviceSensorEntry::OnSensorCreated( DCHECK_EQ(0u, params->buffer_offset % kReadBufferSize); - sensor_remote_.Bind(std::move(params->sensor)); - client_receiver_.Bind(std::move(params->client_receiver)); + sensor_remote_.Bind(std::move(params->sensor), event_pump_->task_runner_); + client_receiver_.Bind(std::move(params->client_receiver), + event_pump_->task_runner_); 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 0f24fc58705..1754edf8ae9 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 @@ -5,11 +5,13 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_SENSOR_ENTRY_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_DEVICE_ORIENTATION_DEVICE_SENSOR_ENTRY_H_ -#include "mojo/public/cpp/bindings/receiver.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/execution_context/execution_context.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" namespace device { union SensorReading; @@ -22,8 +24,6 @@ class DeviceSensorEventPump; class DeviceSensorEntry : public GarbageCollected<DeviceSensorEntry>, public device::mojom::blink::SensorClient { - USING_PRE_FINALIZER(DeviceSensorEntry, Dispose); - public: // The sensor state is an automaton with allowed transitions as follows: // NOT_INITIALIZED -> INITIALIZING @@ -43,8 +43,8 @@ class DeviceSensorEntry : public GarbageCollected<DeviceSensorEntry>, }; DeviceSensorEntry(DeviceSensorEventPump* pump, + ExecutionContext* context, device::mojom::blink::SensorType sensor_type); - void Dispose(); ~DeviceSensorEntry() override; void Start(device::mojom::blink::SensorProvider* sensor_provider); @@ -55,7 +55,7 @@ class DeviceSensorEntry : public GarbageCollected<DeviceSensorEntry>, State state() const { return state_; } - void Trace(Visitor* visitor); + void Trace(Visitor* visitor) const; private: // device::mojom::SensorClient: @@ -75,8 +75,13 @@ class DeviceSensorEntry : public GarbageCollected<DeviceSensorEntry>, State state_ = State::NOT_INITIALIZED; - mojo::Remote<device::mojom::blink::Sensor> sensor_remote_; - mojo::Receiver<device::mojom::blink::SensorClient> client_receiver_{this}; + HeapMojoRemote<device::mojom::blink::Sensor, + HeapMojoWrapperMode::kWithoutContextObserver> + sensor_remote_; + HeapMojoReceiver<device::mojom::blink::SensorClient, + DeviceSensorEntry, + HeapMojoWrapperMode::kWithoutContextObserver> + client_receiver_; device::mojom::blink::SensorType type_; 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 c2d7c399ae3..822de52a92e 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 @@ -3,10 +3,11 @@ // found in the LICENSE file. #include "third_party/blink/renderer/modules/device_orientation/device_sensor_event_pump.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" namespace blink { -void DeviceSensorEventPump::Start(LocalFrame* frame) { +void DeviceSensorEventPump::Start(LocalFrame& frame) { DVLOG(2) << "requested start"; if (state_ != PumpState::STOPPED) @@ -42,7 +43,10 @@ void DeviceSensorEventPump::HandleSensorProviderError() { void DeviceSensorEventPump::SetSensorProviderForTesting( mojo::PendingRemote<device::mojom::blink::SensorProvider> sensor_provider) { - sensor_provider_.Bind(std::move(sensor_provider)); + sensor_provider_.Bind(std::move(sensor_provider), task_runner_); + sensor_provider_.set_disconnect_handler( + WTF::Bind(&DeviceSensorEventPump::HandleSensorProviderError, + WrapWeakPersistent(this))); } DeviceSensorEventPump::PumpState @@ -50,10 +54,17 @@ DeviceSensorEventPump::GetPumpStateForTesting() { return state_; } -DeviceSensorEventPump::DeviceSensorEventPump( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : state_(PumpState::STOPPED), - timer_(std::move(task_runner), this, &DeviceSensorEventPump::FireEvent) {} +void DeviceSensorEventPump::Trace(Visitor* visitor) const { + visitor->Trace(sensor_provider_); +} + +DeviceSensorEventPump::DeviceSensorEventPump(LocalFrame& frame) + : sensor_provider_(frame.DomWindow()), + task_runner_(frame.GetTaskRunner(TaskType::kSensor)), + state_(PumpState::STOPPED), + timer_(frame.GetTaskRunner(TaskType::kSensor), + this, + &DeviceSensorEventPump::FireEvent) {} DeviceSensorEventPump::~DeviceSensorEventPump() = default; 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 1f41dd4066a..f13389a06ad 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 @@ -6,10 +6,11 @@ #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" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" #include "third_party/blink/renderer/platform/timer.h" namespace blink { @@ -30,9 +31,6 @@ class MODULES_EXPORT DeviceSensorEventPump : public GarbageCollectedMixin { // RUNNING -> STOPPED enum class PumpState { STOPPED, RUNNING, PENDING_START }; - virtual void Start(LocalFrame* frame); - virtual void Stop(); - void HandleSensorProviderError(); void SetSensorProviderForTesting( @@ -40,21 +38,26 @@ class MODULES_EXPORT DeviceSensorEventPump : public GarbageCollectedMixin { sensor_provider); PumpState GetPumpStateForTesting(); + void Trace(Visitor* visitor) const override; + protected: friend class DeviceSensorEntry; - explicit DeviceSensorEventPump( - scoped_refptr<base::SingleThreadTaskRunner> task_runner); + explicit DeviceSensorEventPump(LocalFrame&); virtual ~DeviceSensorEventPump(); + // Manage PumpState and call SendStartMessage. + void Start(LocalFrame& frame); + // This method is expected to send an IPC to the browser process to let it // know that it should start observing. - // It is expected for subclasses to override it. - virtual void SendStartMessage(LocalFrame*) = 0; + virtual void SendStartMessage(LocalFrame&) = 0; + + // Manage PumpState and call SendStopMessage. + void Stop(); // This method is expected to send an IPC to the browser process to let it // know that it should start observing. - // It is expected for subclasses to override it. virtual void SendStopMessage() = 0; // Even though the TimerBase* parameter is not used, it is required by @@ -63,7 +66,11 @@ class MODULES_EXPORT DeviceSensorEventPump : public GarbageCollectedMixin { virtual void DidStartIfPossible(); - mojo::Remote<device::mojom::blink::SensorProvider> sensor_provider_; + HeapMojoRemote<device::mojom::blink::SensorProvider, + HeapMojoWrapperMode::kWithoutContextObserver> + sensor_provider_; + + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; private: virtual bool SensorsReadyOrErrored() const = 0; diff --git a/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.cc b/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.cc index 26e258b726a..0d130c84c4f 100644 --- a/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.cc +++ b/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.cc @@ -39,7 +39,7 @@ namespace blink { NavigatorDoNotTrack::NavigatorDoNotTrack(Navigator& navigator) : Supplement<Navigator>(navigator) {} -void NavigatorDoNotTrack::Trace(Visitor* visitor) { +void NavigatorDoNotTrack::Trace(Visitor* visitor) const { Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.h b/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.h index 3c849c94a07..28865396c57 100644 --- a/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.h +++ b/chromium/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.h @@ -54,7 +54,7 @@ class NavigatorDoNotTrack final : public GarbageCollected<NavigatorDoNotTrack>, explicit NavigatorDoNotTrack(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc index 716c221d6e0..a0f2962e22f 100644 --- a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc +++ b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.cc @@ -92,7 +92,7 @@ class TextDecoderStream::Transformer final : public TransformStreamTransformer { ScriptState* GetScriptState() override { return script_state_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(script_state_); TransformStreamTransformer::Trace(visitor); } @@ -183,7 +183,7 @@ WritableStream* TextDecoderStream::writable() const { return transform_->Writable(); } -void TextDecoderStream::Trace(Visitor* visitor) { +void TextDecoderStream::Trace(Visitor* visitor) const { visitor->Trace(transform_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h index 81f24eee6ab..5af8a9488f0 100644 --- a/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h +++ b/chromium/third_party/blink/renderer/modules/encoding/text_decoder_stream.h @@ -47,7 +47,7 @@ class TextDecoderStream final : public ScriptWrappable { ReadableStream* readable() const; WritableStream* writable() const; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: class Transformer; diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc index 32d89eb2d4a..a5e3e38fda6 100644 --- a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc +++ b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.cc @@ -39,7 +39,7 @@ class TextEncoderStream::Transformer final : public TransformStreamTransformer { ScriptPromise Transform(v8::Local<v8::Value> chunk, TransformStreamDefaultController* controller, ExceptionState& exception_state) override { - V8StringResource<> input_resource = chunk; + V8StringResource<> input_resource{chunk}; if (!input_resource.Prepare(script_state_->GetIsolate(), exception_state)) return ScriptPromise(); const String input = input_resource; @@ -95,7 +95,7 @@ class TextEncoderStream::Transformer final : public TransformStreamTransformer { ScriptState* GetScriptState() override { return script_state_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(script_state_); TransformStreamTransformer::Trace(visitor); } @@ -186,7 +186,7 @@ WritableStream* TextEncoderStream::writable() const { return transform_->Writable(); } -void TextEncoderStream::Trace(Visitor* visitor) { +void TextEncoderStream::Trace(Visitor* visitor) const { visitor->Trace(transform_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.h b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.h index 91caa3f2992..4ba6eced9ff 100644 --- a/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.h +++ b/chromium/third_party/blink/renderer/modules/encoding/text_encoder_stream.h @@ -37,7 +37,7 @@ class TextEncoderStream final : public ScriptWrappable { ReadableStream* readable() const; WritableStream* writable() const; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: class Transformer; 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 b1595b5c544..1aa33c70b22 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 @@ -148,7 +148,7 @@ bool ContentDecryptionModuleResultPromise::IsValidToFulfillPromise() { return GetExecutionContext() && !GetExecutionContext()->IsContextDestroyed(); } -void ContentDecryptionModuleResultPromise::Trace(Visitor* visitor) { +void ContentDecryptionModuleResultPromise::Trace(Visitor* visitor) const { visitor->Trace(resolver_); ContentDecryptionModuleResult::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h index 8b93db4d114..44b23a323d9 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/content_decryption_module_result_promise.h @@ -50,7 +50,7 @@ class ContentDecryptionModuleResultPromise // It is only valid to call this before completion. ScriptPromise Promise(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: // |interface_name| and |property_name| must have static life time. diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.cc index ce81c63d4e2..29a83ff6043 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.cc @@ -37,7 +37,7 @@ class SetMediaKeysHandler : public ScriptPromiseResolver { SetMediaKeysHandler(ScriptState*, HTMLMediaElement&, MediaKeys*); ~SetMediaKeysHandler() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void TimerFired(TimerBase*); @@ -320,7 +320,7 @@ void SetMediaKeysHandler::SetFailed(ExceptionCode code, Fail(code, error_message); } -void SetMediaKeysHandler::Trace(Visitor* visitor) { +void SetMediaKeysHandler::Trace(Visitor* visitor) const { visitor->Trace(element_); visitor->Trace(new_media_keys_); ScriptPromiseResolver::Trace(visitor); @@ -473,7 +473,7 @@ HTMLMediaElementEncryptedMedia::ContentDecryptionModule() { return media_keys_ ? media_keys_->ContentDecryptionModule() : nullptr; } -void HTMLMediaElementEncryptedMedia::Trace(Visitor* visitor) { +void HTMLMediaElementEncryptedMedia::Trace(Visitor* visitor) const { visitor->Trace(media_element_); visitor->Trace(media_keys_); Supplement<HTMLMediaElement>::Trace(visitor); 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 f1176cbc7a3..1e1512afb24 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 @@ -57,7 +57,7 @@ class MODULES_EXPORT HTMLMediaElementEncryptedMedia final HTMLMediaElementEncryptedMedia(HTMLMediaElement&); ~HTMLMediaElementEncryptedMedia(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class SetMediaKeysHandler; diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.cc index e3ce0669138..70db76855f2 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.cc @@ -42,7 +42,7 @@ const AtomicString& MediaEncryptedEvent::InterfaceName() const { return event_interface_names::kMediaEncryptedEvent; } -void MediaEncryptedEvent::Trace(Visitor* visitor) { +void MediaEncryptedEvent::Trace(Visitor* visitor) const { visitor->Trace(init_data_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.h index 43d7e59a575..c8aad351d2c 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.h +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.h @@ -50,7 +50,7 @@ class MediaEncryptedEvent final : public Event { String initDataType() const { return init_data_type_; } DOMArrayBuffer* initData() const { return init_data_.Get(); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: String init_data_type_; diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.cc index fd806f81d1e..8505ac9a0f9 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.cc @@ -47,7 +47,7 @@ const AtomicString& MediaKeyMessageEvent::InterfaceName() const { return event_interface_names::kMediaKeyMessageEvent; } -void MediaKeyMessageEvent::Trace(Visitor* visitor) { +void MediaKeyMessageEvent::Trace(Visitor* visitor) const { visitor->Trace(message_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.h index 4e112adb4e0..21392ccf0a1 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.h +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.h @@ -58,7 +58,7 @@ class MediaKeyMessageEvent final : public Event { String messageType() const { return message_type_; } DOMArrayBuffer* message() const { return message_.Get(); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: String message_type_; 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 dcad30cee42..8eeb8099d78 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 @@ -210,7 +210,7 @@ class MediaKeySession::PendingAction final string_data_(string_data) {} ~PendingAction() = default; - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(result_); visitor->Trace(data_); } @@ -248,7 +248,7 @@ class NewSessionResultPromise : public ContentDecryptionModuleResultPromise { Resolve(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(session_); ContentDecryptionModuleResultPromise::Trace(visitor); } @@ -286,7 +286,7 @@ class LoadSessionResultPromise : public ContentDecryptionModuleResultPromise { Resolve(true); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(session_); ContentDecryptionModuleResultPromise::Trace(visitor); } @@ -317,7 +317,7 @@ class SimpleResultPromise : public ContentDecryptionModuleResultPromise { Resolve(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(session_); ContentDecryptionModuleResultPromise::Trace(visitor); } @@ -355,7 +355,7 @@ MediaKeySession::MediaKeySession(ScriptState* script_state, // initializeNewSession() is called in response to the user calling // generateRequest(). WebContentDecryptionModule* cdm = media_keys->ContentDecryptionModule(); - session_ = cdm->CreateSession(); + session_ = cdm->CreateSession(session_type); session_->SetClientInterface(this); // From https://w3c.github.io/encrypted-media/#createSession: @@ -501,7 +501,7 @@ void MediaKeySession::GenerateRequestTask(ContentDecryptionModuleResult* result, // initializeNewSession() in Chromium will execute steps 10.1 to 10.9. session_->InitializeNewSession( init_data_type, static_cast<unsigned char*>(init_data_buffer->Data()), - init_data_buffer->ByteLengthAsSizeT(), session_type_, result->Result()); + init_data_buffer->ByteLengthAsSizeT(), result->Result()); // Remaining steps (10.10) executed in finishGenerateRequest(), // called when |result| is resolved. @@ -1032,7 +1032,7 @@ void MediaKeySession::ContextDestroyed() { pending_actions_.clear(); } -void MediaKeySession::Trace(Visitor* visitor) { +void MediaKeySession::Trace(Visitor* visitor) const { visitor->Trace(async_event_queue_); visitor->Trace(pending_actions_); visitor->Trace(media_keys_); diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h index 1265494e9de..d3444d54e4b 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_session.h @@ -107,7 +107,7 @@ class MediaKeySession final // ExecutionContextLifecycleObserver void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: class PendingAction; 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 7d481b963b6..212d509a455 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 @@ -56,7 +56,7 @@ class MediaKeyStatusMap::MapEntry final return a->KeyId()->ByteLengthAsSizeT() < b->KeyId()->ByteLengthAsSizeT(); } - virtual void Trace(Visitor* visitor) { visitor->Trace(key_id_); } + virtual void Trace(Visitor* visitor) const { visitor->Trace(key_id_); } private: const Member<DOMArrayBuffer> key_id_; @@ -85,7 +85,7 @@ class MapIterationSource final return true; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(map_); PairIterable<ArrayBufferOrArrayBufferView, String>::IterationSource::Trace( visitor); @@ -149,7 +149,7 @@ MediaKeyStatusMap::StartIteration(ScriptState*, ExceptionState&) { return MakeGarbageCollected<MapIterationSource>(this); } -void MediaKeyStatusMap::Trace(Visitor* visitor) { +void MediaKeyStatusMap::Trace(Visitor* visitor) const { visitor->Trace(entries_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h index 318fc6f2738..9e430ed332a 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.h @@ -46,7 +46,7 @@ class MediaKeyStatusMap final bool has(const ArrayBufferOrArrayBufferView& key_id); ScriptValue get(ScriptState*, const ArrayBufferOrArrayBufferView& key_id); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // PairIterable<> implementation. diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc index d85c50fe2db..478ceb87ab2 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.cc @@ -149,7 +149,7 @@ ScriptPromise MediaKeySystemAccessInitializerBase::Promise() { return resolver_->Promise(); } -void MediaKeySystemAccessInitializerBase::Trace(Visitor* visitor) { +void MediaKeySystemAccessInitializerBase::Trace(Visitor* visitor) const { visitor->Trace(resolver_); EncryptedMediaRequest::Trace(visitor); ExecutionContextClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h index 7dec3123887..905e6e38c3e 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access_initializer_base.h @@ -41,7 +41,7 @@ class MediaKeySystemAccessInitializerBase : public EncryptedMediaRequest, // Promise() in script_promise_resolver.h ScriptPromise Promise(); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; protected: // Returns true if the ExecutionContext is valid, false otherwise. 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 833b1db8d58..aa103c6210d 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.cc @@ -96,7 +96,7 @@ class MediaKeys::PendingAction final const String& string_data) : type_(type), result_(result), data_(data), string_data_(string_data) {} - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(result_); visitor->Trace(data_); } @@ -150,7 +150,7 @@ class SetCertificateResultPromise exception_code, system_code, error_message); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(media_keys_); ContentDecryptionModuleResultPromise::Trace(visitor); } @@ -183,7 +183,7 @@ class GetStatusForPolicyResultPromise Resolve(EncryptedMediaUtils::ConvertKeyStatusToString(key_status)); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(media_keys_); ContentDecryptionModuleResultPromise::Trace(visitor); } @@ -221,6 +221,13 @@ MediaKeySession* MediaKeys::createSession(ScriptState* script_state, DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << "(" << this << ") " << session_type_string; + // If the context for MediaKeys has been destroyed, fail. + if (!GetExecutionContext()) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError, + "The context provided is invalid."); + return nullptr; + } + // [RuntimeEnabled] does not work with enum values. So we have to check it // here. See https://crbug.com/871867 for details. if (!RuntimeEnabledFeatures:: @@ -267,6 +274,13 @@ ScriptPromise MediaKeys::setServerCertificate( ScriptState* script_state, const DOMArrayPiece& server_certificate, ExceptionState& exception_state) { + // If the context for MediaKeys has been destroyed, fail. + if (!GetExecutionContext()) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError, + "The context provided is invalid."); + return ScriptPromise(); + } + // From https://w3c.github.io/encrypted-media/#setServerCertificate // The setServerCertificate(serverCertificate) method provides a server // certificate to be used to encrypt messages to the license server. @@ -309,6 +323,15 @@ void MediaKeys::SetServerCertificateTask( ContentDecryptionModuleResult* result) { DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << "(" << this << ")"; + // If the context has been destroyed, don't proceed. Try to have the promise + // be rejected. + if (!GetExecutionContext()) { + result->CompleteWithError( + kWebContentDecryptionModuleExceptionInvalidStateError, 0, + "The context provided is invalid."); + return; + } + // 5.1 Let cdm be the cdm during the initialization of this object. WebContentDecryptionModule* cdm = ContentDecryptionModule(); @@ -325,7 +348,15 @@ void MediaKeys::SetServerCertificateTask( ScriptPromise MediaKeys::getStatusForPolicy( ScriptState* script_state, - const MediaKeysPolicy* media_keys_policy) { + const MediaKeysPolicy* media_keys_policy, + ExceptionState& exception_state) { + // If the context for MediaKeys has been destroyed, fail. + if (!GetExecutionContext()) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError, + "The context provided is invalid."); + return ScriptPromise(); + } + // TODO(xhwang): Pass MediaKeysPolicy classes all the way to Chromium when // we have more than one policy to check. String min_hdcp_version = media_keys_policy->minHdcpVersion(); @@ -349,6 +380,15 @@ void MediaKeys::GetStatusForPolicyTask(const String& min_hdcp_version, ContentDecryptionModuleResult* result) { DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << ": " << min_hdcp_version; + // If the context has been destroyed, don't proceed. Try to have the promise + // be rejected. + if (!GetExecutionContext()) { + result->CompleteWithError( + kWebContentDecryptionModuleExceptionInvalidStateError, 0, + "The context provided is invalid."); + return; + } + WebContentDecryptionModule* cdm = ContentDecryptionModule(); cdm->GetStatusForPolicy(min_hdcp_version, result->Result()); } @@ -417,7 +457,7 @@ WebContentDecryptionModule* MediaKeys::ContentDecryptionModule() { return cdm_.get(); } -void MediaKeys::Trace(Visitor* visitor) { +void MediaKeys::Trace(Visitor* visitor) const { visitor->Trace(pending_actions_); visitor->Trace(media_element_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h index ba2d0093ba8..ad23239df08 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys.h @@ -71,9 +71,11 @@ class MediaKeys : public ScriptWrappable, ScriptPromise setServerCertificate(ScriptState*, const DOMArrayPiece& server_certificate, - ExceptionState& exception_state); + ExceptionState&); - ScriptPromise getStatusForPolicy(ScriptState*, const MediaKeysPolicy*); + ScriptPromise getStatusForPolicy(ScriptState*, + const MediaKeysPolicy*, + ExceptionState&); // Indicates that the provided HTMLMediaElement wants to use this object. // Returns true if no other HTMLMediaElement currently references this @@ -93,7 +95,7 @@ class MediaKeys : public ScriptWrappable, WebContentDecryptionModule* ContentDecryptionModule(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // ExecutionContextLifecycleObserver implementation. // FIXME: This class could derive from ExecutionContextLifecycleObserver diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h index e53eb2c7fd3..ab21267fb84 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_controller.h @@ -30,7 +30,9 @@ class MODULES_EXPORT MediaKeysController final MediaKeysController(); - void Trace(Visitor* visitor) override { Supplement<Page>::Trace(visitor); } + void Trace(Visitor* visitor) const override { + Supplement<Page>::Trace(visitor); + } }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc index 0b12f4d3a03..c6e7ff4a754 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.cc @@ -14,10 +14,12 @@ namespace blink { ScriptPromise MediaKeysGetStatusForPolicy::getStatusForPolicy( ScriptState* script_state, MediaKeys& media_keys, - const MediaKeysPolicy* media_keys_policy) { + const MediaKeysPolicy* media_keys_policy, + ExceptionState& exception_state) { DVLOG(1) << __func__; - return media_keys.getStatusForPolicy(script_state, media_keys_policy); + return media_keys.getStatusForPolicy(script_state, media_keys_policy, + exception_state); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h index 246e7a5aac8..62317f6c037 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.h @@ -20,7 +20,8 @@ class MediaKeysGetStatusForPolicy { public: static ScriptPromise getStatusForPolicy(ScriptState*, MediaKeys&, - const MediaKeysPolicy*); + const MediaKeysPolicy*, + ExceptionState&); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl index 15a6ca073ec..671ba323111 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl @@ -8,5 +8,5 @@ ImplementedAs=MediaKeysGetStatusForPolicy, SecureContext ] partial interface MediaKeys { - [Measure, CallWith=ScriptState] Promise<MediaKeyStatus> getStatusForPolicy(MediaKeysPolicy policy); + [Measure, CallWith=ScriptState, RaisesException] Promise<MediaKeyStatus> getStatusForPolicy(MediaKeysPolicy policy); }; diff --git a/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc b/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc index abbfe697430..823ac106e84 100644 --- a/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc +++ b/chromium/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.cc @@ -16,7 +16,6 @@ #include "third_party/blink/public/platform/web_vector.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/dom_exception.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/deprecation.h" @@ -60,7 +59,7 @@ class MediaKeySystemAccessInitializer final std::unique_ptr<WebContentDecryptionModuleAccess>) override; void RequestNotSupported(const WebString& error_message) override; - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { MediaKeySystemAccessInitializerBase::Trace(visitor); } @@ -154,7 +153,7 @@ ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess( } UseCounter::Count(*window, WebFeature::kEncryptedMediaSecureOrigin); - window->document()->CountUseOnlyInCrossOriginIframe( + window->CountUseOnlyInCrossOriginIframe( WebFeature::kEncryptedMediaCrossOriginIframe); // 4. Let origin be the origin of document. diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc b/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc index 1bf07407f3b..6174b99240e 100644 --- a/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc +++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source.cc @@ -359,7 +359,7 @@ bool EventSource::HasPendingActivity() const { return state_ != kClosed; } -void EventSource::Trace(Visitor* visitor) { +void EventSource::Trace(Visitor* visitor) const { visitor->Trace(parser_); visitor->Trace(loader_); EventTargetWithInlineData::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source.h b/chromium/third_party/blink/renderer/modules/eventsource/event_source.h index 28c28d52645..b6c2c3379fe 100644 --- a/chromium/third_party/blink/renderer/modules/eventsource/event_source.h +++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source.h @@ -98,7 +98,7 @@ class MODULES_EXPORT EventSource final // ScriptWrappable bool HasPendingActivity() const final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void DidReceiveResponse(uint64_t, const ResourceResponse&) override; diff --git a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc index 461a09b3565..8b9c2b7f7b2 100644 --- a/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc +++ b/chromium/third_party/blink/renderer/modules/eventsource/event_source_parser.cc @@ -132,7 +132,7 @@ String EventSourceParser::FromUTF8(const char* bytes, uint32_t size) { return codec_->Decode(bytes, size, WTF::FlushBehavior::kDataEOF); } -void EventSourceParser::Trace(Visitor* visitor) { +void EventSourceParser::Trace(Visitor* visitor) const { visitor->Trace(client_); } 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 4291b23a5c7..ec8c4d7965f 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 @@ -25,7 +25,7 @@ class MODULES_EXPORT EventSourceParser final const String& data, const AtomicString& last_event_id) = 0; virtual void OnReconnectionTimeSet(uint64_t reconnection_time) = 0; - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} }; EventSourceParser(const AtomicString& last_event_id, Client*); @@ -34,7 +34,7 @@ class MODULES_EXPORT EventSourceParser final const AtomicString& LastEventId() const { return last_event_id_; } // Stop parsing. This can be called from Client::onMessageEvent. void Stop() { is_stopped_ = true; } - void Trace(Visitor*); + void Trace(Visitor*) const; private: void ParseLine(); 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 90acf6ba628..6cecda78c78 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 @@ -77,7 +77,7 @@ class StoppingClient : public GarbageCollected<StoppingClient>, events_.push_back(EventOrReconnectionTimeSetting(reconnection_time)); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(parser_); EventSourceParser::Client::Trace(visitor); } 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 f9d724741f7..2d1cb162b9f 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 @@ -234,17 +234,14 @@ unsigned WebAXObject::ChildCount() const { if (IsDetached()) return 0; - return private_->Children().size(); + return private_->ChildCountIncludingIgnored(); } WebAXObject WebAXObject::ChildAt(unsigned index) const { if (IsDetached()) return WebAXObject(); - if (private_->Children().size() <= index) - return WebAXObject(); - - return WebAXObject(private_->Children()[index]); + return WebAXObject(private_->ChildAtIncludingIgnored(int{index})); } WebAXObject WebAXObject::ParentObject() const { @@ -347,6 +344,13 @@ bool WebAXObject::IsModal() const { return private_->IsModal(); } +bool WebAXObject::IsNativeTextControl() const { + if (IsDetached()) + return false; + + return private_->IsNativeTextControl(); +} + bool WebAXObject::IsOffScreen() const { if (IsDetached()) return false; 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 f88e7058c05..a8b33c2fbfa 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 @@ -76,8 +76,12 @@ namespace blink { WebServiceWorkerInstalledScriptsManagerParams:: WebServiceWorkerInstalledScriptsManagerParams( WebVector<WebURL> installed_scripts_urls, - mojo::ScopedMessagePipeHandle manager_receiver, - mojo::ScopedMessagePipeHandle manager_host_remote) + CrossVariantMojoReceiver< + mojom::blink::ServiceWorkerInstalledScriptsManagerInterfaceBase> + manager_receiver, + CrossVariantMojoRemote< + mojom::blink::ServiceWorkerInstalledScriptsManagerHostInterfaceBase> + 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)) { @@ -105,9 +109,12 @@ void WebEmbeddedWorkerImpl::StartWorkerContext( 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 browser_interface_broker, + CrossVariantMojoRemote< + mojom::blink::WorkerContentSettingsProxyInterfaceBase> content_settings, + CrossVariantMojoRemote<mojom::blink::CacheStorageInterfaceBase> + cache_storage, + CrossVariantMojoRemote<mojom::blink::BrowserInterfaceBrokerInterfaceBase> + browser_interface_broker, scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner) { DCHECK(!asked_to_terminate_); @@ -138,15 +145,8 @@ void WebEmbeddedWorkerImpl::StartWorkerContext( 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_), - mojo::PendingRemote<mojom::blink::BrowserInterfaceBroker>( - std::move(browser_interface_broker), - mojom::blink::BrowserInterfaceBroker::Version_), + std::move(content_settings)), + std::move(cache_storage), std::move(browser_interface_broker), std::move(initiator_thread_task_runner)); } @@ -285,8 +285,8 @@ void WebEmbeddedWorkerImpl::StartWorkerThread( // We are now ready to inspect worker thread. worker_context_client_->WorkerReadyForInspectionOnInitiatorThread( - devtools_agent_remote.PassPipe(), - devtools_agent_host_receiver.PassPipe()); + std::move(devtools_agent_remote), + std::move(devtools_agent_host_receiver)); } std::unique_ptr<CrossThreadFetchClientSettingsObjectData> 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 7ca19eefdb1..579700aed8a 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 @@ -66,9 +66,13 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final : public WebEmbeddedWorker { void StartWorkerContext( std::unique_ptr<WebEmbeddedWorkerStartData>, std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>, - mojo::ScopedMessagePipeHandle content_settings_handle, - mojo::ScopedMessagePipeHandle cache_storage, - mojo::ScopedMessagePipeHandle browser_interface_broker, + CrossVariantMojoRemote< + mojom::blink::WorkerContentSettingsProxyInterfaceBase> + content_settings, + CrossVariantMojoRemote<mojom::blink::CacheStorageInterfaceBase> + cache_storage, + CrossVariantMojoRemote<mojom::blink::BrowserInterfaceBrokerInterfaceBase> + browser_interface_broker, scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner) override; void TerminateWorkerContext() override; diff --git a/chromium/third_party/blink/renderer/modules/filesystem/README.md b/chromium/third_party/blink/renderer/modules/filesystem/README.md index a08a077e0d8..893d8d12219 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/README.md +++ b/chromium/third_party/blink/renderer/modules/filesystem/README.md @@ -34,41 +34,3 @@ for writing and modifying to files and directories, as well as a way to get access to a origin scoped sandboxed filesystem. TODO(mek): More details - -### Writable Files - -Finally this directory contains the implementation of the new and still under -development [Writable Files API](https://github.com/WICG/writable-files/blob/master/EXPLAINER.md). -This API is mostly implemented on top of the same backend as the previous two -APIs, but hopes to eventually replace both of those, while also adding new -functionality. - -It consists of the following parts: - - * `FileSystemBaseHandle`, `FileSystemFileHandle` and `FileSystemDirectoryHandle`: - these interfaces mimic the old `Entry` interfaces (and inherit from `EntryBase` - to share as much of the implementation as possible), but expose a more modern - promisified API. - - * `getSystemDirectory`: An entry point (exposed via `FileSystemDirectoryHandle`) - that today only gives access to the same sandboxed filesystem as what was - available through the old API. In the future this could get extended to add - support for other directories as well. - - * `FileSystemWriter`: a more modern API with similar functionality to the - old `FileWriter` API. The implementation of this actually does make use of - a different mojom interface than the old API. But since the functionality is - mostly the same, hopefully we will be able to migrate the old implementation - to the new mojom API as well. - - * `chooseFileSystemEntries`: An entry point, currently on `window`, that lets - a website pop-up a file picker, prompting the user to select one or more - files or directories, to which the website than gets access. - -Since the `Handle` interfaces are based on the implementation of the `Entry` -interfaces, internally and across IPC these are still represented by -`filesystem://` URLs. Hopefully in the future we will be able to change this and -turn it into a more capabilities based API (where having a mojo handle gives you -access to specific files or directories), as with the current implementation it -is very hard to properly support transferring handles to other processes via -postMessage (which is something we do want to support in the future). diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.cc b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.cc index e4078f96006..3a155c40775 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.cc @@ -85,7 +85,7 @@ void DirectoryEntry::removeRecursively(V8VoidCallback* success_callback, std::move(error_callback_wrapper)); } -void DirectoryEntry::Trace(Visitor* visitor) { +void DirectoryEntry::Trace(Visitor* visitor) const { Entry::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.h b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.h index fa00c74c684..fffc809009b 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry.h @@ -65,7 +65,7 @@ class MODULES_EXPORT DirectoryEntry final : public Entry { void removeRecursively(V8VoidCallback* success_callback = nullptr, V8ErrorCallback* = nullptr) const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc index 1519b81c804..0be39de3938 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.cc @@ -98,7 +98,7 @@ void DirectoryEntrySync::removeRecursively(ExceptionState& exception_state) { sync_helper->GetResultOrThrow(exception_state); } -void DirectoryEntrySync::Trace(Visitor* visitor) { +void DirectoryEntrySync::Trace(Visitor* visitor) const { EntrySync::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.h index 2acad4d90fd..7f29e9175c0 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_entry_sync.h @@ -59,7 +59,7 @@ class DirectoryEntrySync final : public EntrySync { ExceptionState&); void removeRecursively(ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; template <> diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc index 45c6f38858e..dd0b68a977a 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.cc @@ -118,7 +118,7 @@ void DirectoryReader::OnError(base::File::Error error) { } } -void DirectoryReader::Trace(Visitor* visitor) { +void DirectoryReader::Trace(Visitor* visitor) const { visitor->Trace(entries_); visitor->Trace(entries_callback_); visitor->Trace(error_callback_); diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h index fbe53440fdb..0b8183eb283 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader.h @@ -53,7 +53,7 @@ class DirectoryReader : public DirectoryReaderBase { return static_cast<DOMFileSystem*>(file_system_.Get()); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void AddEntries(const EntryHeapVector& entries); diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_base.h b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_base.h index 992ff2e051f..c1c7e8b5ef8 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_base.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_base.h @@ -49,7 +49,7 @@ class DirectoryReaderBase : public ScriptWrappable { ~DirectoryReaderBase() override = default; - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(file_system_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc index ffd3430f3d3..e7830e47d0c 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.cc @@ -81,7 +81,7 @@ EntrySyncHeapVector DirectoryReaderSync::readEntries( return result; } -void DirectoryReaderSync::Trace(Visitor* visitor) { +void DirectoryReaderSync::Trace(Visitor* visitor) const { visitor->Trace(entries_); DirectoryReaderBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h index 9f92b6daeab..dc42fa6239d 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/directory_reader_sync.h @@ -52,7 +52,7 @@ class DirectoryReaderSync : public DirectoryReaderBase { EntrySyncHeapVector readEntries(ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: bool has_called_read_directory_ = false; diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc index 1e5a4b8ff85..2bde1a6b357 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.cc @@ -178,7 +178,7 @@ void DOMFileSystem::ScheduleCallback(ExecutionContext* execution_context, WTF::Passed(std::move(identifier)))); } -void DOMFileSystem::Trace(Visitor* visitor) { +void DOMFileSystem::Trace(Visitor* visitor) const { visitor->Trace(root_entry_); DOMFileSystemBase::Trace(visitor); ExecutionContextClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h index 58b7ed31393..061326ab0e9 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system.h @@ -88,7 +88,7 @@ class MODULES_EXPORT DOMFileSystem final static void ScheduleCallback(ExecutionContext* execution_context, base::OnceClosure task); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: static String TaskNameForInstrumentation() { return "FileSystem"; } diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc index 86fe8b8cb2d..5488b401288 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc @@ -67,7 +67,7 @@ DOMFileSystemBase::DOMFileSystemBase(ExecutionContext* context, DOMFileSystemBase::~DOMFileSystemBase() = default; -void DOMFileSystemBase::Trace(Visitor* visitor) { +void DOMFileSystemBase::Trace(Visitor* visitor) const { visitor->Trace(context_); ScriptWrappable::Trace(visitor); } 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 2132b9d63dd..b56517807ea 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 @@ -152,7 +152,7 @@ class MODULES_EXPORT DOMFileSystemBase : public ScriptWrappable { EntriesCallbacks::ErrorCallback, SynchronousType = kAsynchronous); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: DOMFileSystemBase(ExecutionContext*, diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc index bb505a269f4..e95f82da74b 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc @@ -90,7 +90,7 @@ class CreateFileHelper final : public SnapshotFileCallbackBase { base::File::Error error_; Member<File> file_; - void Trace(Visitor* visitor) { visitor->Trace(file_); } + void Trace(Visitor* visitor) const { visitor->Trace(file_); } }; static std::unique_ptr<SnapshotFileCallbackBase> Create( @@ -173,7 +173,7 @@ FileWriterSync* DOMFileSystemSync::CreateWriter( return success ? file_writer : nullptr; } -void DOMFileSystemSync::Trace(Visitor* visitor) { +void DOMFileSystemSync::Trace(Visitor* visitor) const { visitor->Trace(root_entry_); DOMFileSystemBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h index cf2dbd1f9e8..8fba495d736 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.h @@ -60,7 +60,7 @@ class DOMFileSystemSync final : public DOMFileSystemBase { File* CreateFile(const FileEntrySync*, ExceptionState&); FileWriterSync* CreateWriter(const FileEntrySync*, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<DirectoryEntrySync> root_entry_; diff --git a/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.cc b/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.cc index dd4a6028b18..01dcaa19c84 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/dragged_isolated_file_system_impl.cc @@ -67,7 +67,7 @@ DraggedIsolatedFileSystemImpl* DraggedIsolatedFileSystemImpl::From( data_object); } -void DraggedIsolatedFileSystemImpl::Trace(Visitor* visitor) { +void DraggedIsolatedFileSystemImpl::Trace(Visitor* visitor) const { visitor->Trace(filesystems_); Supplement<DataObject>::Trace(visitor); } 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 57803e73f90..55e7c2fdaf2 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 @@ -59,7 +59,7 @@ class DraggedIsolatedFileSystemImpl final DraggedIsolatedFileSystemImpl() = default; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; static void PrepareForDataObject(DataObject*); diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry.cc b/chromium/third_party/blink/renderer/modules/filesystem/entry.cc index 18051936981..6b96eb276f0 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/entry.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/entry.cc @@ -152,7 +152,7 @@ String Entry::toURL(ScriptState* script_state) const { return static_cast<const EntryBase*>(this)->toURL(); } -void Entry::Trace(Visitor* visitor) { +void Entry::Trace(Visitor* visitor) const { EntryBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry.h b/chromium/third_party/blink/renderer/modules/filesystem/entry.h index 63be093dc40..7a930452299 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/entry.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/entry.h @@ -76,7 +76,7 @@ class MODULES_EXPORT Entry : public EntryBase { V8ErrorCallback* = nullptr) const; String toURL(ScriptState*) const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry_base.cc b/chromium/third_party/blink/renderer/modules/filesystem/entry_base.cc index 38d25b459fd..e1b3c9fc481 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/entry_base.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/entry_base.cc @@ -55,7 +55,7 @@ String EntryBase::toURL() const { return cached_url_; } -void EntryBase::Trace(Visitor* visitor) { +void EntryBase::Trace(Visitor* visitor) const { visitor->Trace(file_system_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry_base.h b/chromium/third_party/blink/renderer/modules/filesystem/entry_base.h index a6d315101fa..a8f1fafdf4e 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/entry_base.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/entry_base.h @@ -56,7 +56,7 @@ class MODULES_EXPORT EntryBase : public ScriptWrappable { String toURL() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: EntryBase(DOMFileSystemBase*, const String& full_path); diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.cc index e63accd6df2..19136864451 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.cc @@ -122,7 +122,7 @@ EntrySync* EntrySync::getParent() const { EntrySync::EntrySync(DOMFileSystemBase* file_system, const String& full_path) : EntryBase(file_system, full_path) {} -void EntrySync::Trace(Visitor* visitor) { +void EntrySync::Trace(Visitor* visitor) const { EntryBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.h index 0768db2cb8a..fb2bbe6557a 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/entry_sync.h @@ -62,7 +62,7 @@ class EntrySync : public EntryBase { void remove(ExceptionState&) const; EntrySync* getParent() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: EntrySync(DOMFileSystemBase*, const String& full_path); diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_entry.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_entry.cc index cc5e1a1dd4b..159ffc2e9ca 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_entry.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_entry.cc @@ -72,7 +72,7 @@ void FileEntry::file(V8FileCallback* success_callback, std::move(error_callback_wrapper)); } -void FileEntry::Trace(Visitor* visitor) { +void FileEntry::Trace(Visitor* visitor) const { Entry::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_entry.h b/chromium/third_party/blink/renderer/modules/filesystem/file_entry.h index d1d33f9596e..24c40eaa564 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_entry.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_entry.h @@ -52,7 +52,7 @@ class MODULES_EXPORT FileEntry final : public Entry { bool isFile() const override { return true; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.cc index 4e2a86d3633..6e469dd27b4 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.cc @@ -48,7 +48,7 @@ FileWriterSync* FileEntrySync::createWriter(ExceptionState& exception_state) { return filesystem()->CreateWriter(this, exception_state); } -void FileEntrySync::Trace(Visitor* visitor) { +void FileEntrySync::Trace(Visitor* visitor) const { EntrySync::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.h index de881ebe3b5..b79de76e748 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_entry_sync.h @@ -53,7 +53,7 @@ class FileEntrySync final : public EntrySync { File* file(ExceptionState&); FileWriterSync* createWriter(ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; template <> 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 7eacd92ca5d..63ef4642e6e 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 @@ -331,7 +331,8 @@ void FileSystemDispatcher::Truncate(const KURL& path, int64_t offset, int* request_id_out, StatusCallback callback) { - mojo::Remote<mojom::blink::FileSystemCancellableOperation> op_remote; + HeapMojoRemote<mojom::blink::FileSystemCancellableOperation> op_remote( + GetSupplementable()); // See https://bit.ly/2S0zRAS for task types mojo::PendingReceiver<mojom::blink::FileSystemCancellableOperation> op_receiver = op_remote.BindNewPipeAndPassReceiver( @@ -341,7 +342,8 @@ void FileSystemDispatcher::Truncate(const KURL& path, op_remote.set_disconnect_handler( WTF::Bind(&FileSystemDispatcher::RemoveOperationRemote, WrapWeakPersistent(this), operation_id)); - cancellable_operations_.insert(operation_id, std::move(op_remote)); + cancellable_operations_.insert(operation_id, + WrapDisallowNew(std::move(op_remote))); GetFileSystemManager().Truncate( path, offset, std::move(op_receiver), WTF::Bind(&FileSystemDispatcher::DidTruncate, WrapWeakPersistent(this), @@ -365,7 +367,8 @@ void FileSystemDispatcher::Write(const KURL& path, int* request_id_out, const WriteCallback& success_callback, StatusCallback error_callback) { - mojo::Remote<mojom::blink::FileSystemCancellableOperation> op_remote; + HeapMojoRemote<mojom::blink::FileSystemCancellableOperation> op_remote( + GetSupplementable()); // See https://bit.ly/2S0zRAS for task types scoped_refptr<base::SequencedTaskRunner> task_runner = GetSupplementable()->GetTaskRunner(blink::TaskType::kMiscPlatformAPI); @@ -375,7 +378,8 @@ void FileSystemDispatcher::Write(const KURL& path, op_remote.set_disconnect_handler( WTF::Bind(&FileSystemDispatcher::RemoveOperationRemote, WrapWeakPersistent(this), operation_id)); - cancellable_operations_.insert(operation_id, std::move(op_remote)); + cancellable_operations_.insert(operation_id, + WrapDisallowNew(std::move(op_remote))); mojo::PendingRemote<mojom::blink::FileSystemOperationListener> listener; mojo::PendingReceiver<mojom::blink::FileSystemOperationListener> receiver = @@ -419,9 +423,10 @@ void FileSystemDispatcher::Cancel(int request_id_to_cancel, return; } cancellable_operations_.find(request_id_to_cancel) - ->value->Cancel(WTF::Bind(&FileSystemDispatcher::DidCancel, - WrapWeakPersistent(this), std::move(callback), - request_id_to_cancel)); + ->value->Value() + ->Cancel(WTF::Bind(&FileSystemDispatcher::DidCancel, + WrapWeakPersistent(this), std::move(callback), + request_id_to_cancel)); } void FileSystemDispatcher::CreateSnapshotFile( @@ -446,8 +451,9 @@ void FileSystemDispatcher::CreateSnapshotFileSync( std::move(listener)); } -void FileSystemDispatcher::Trace(Visitor* visitor) { +void FileSystemDispatcher::Trace(Visitor* visitor) const { visitor->Trace(file_system_manager_); + visitor->Trace(cancellable_operations_); visitor->Trace(op_listeners_); Supplement<ExecutionContext>::Trace(visitor); } @@ -599,8 +605,4 @@ void FileSystemDispatcher::RemoveOperationRemote(int operation_id) { cancellable_operations_.erase(it); } -void FileSystemDispatcher::Prefinalize() { - 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 9fc7c75d891..727b807f86a 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 @@ -10,10 +10,11 @@ #include "mojo/public/cpp/bindings/pending_remote.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/disallow_new_wrapper.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap_allocator.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_unique_receiver_set.h" -#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" #include "third_party/blink/renderer/platform/supplementable.h" namespace WTF { @@ -32,7 +33,6 @@ class SecurityOrigin; class FileSystemDispatcher : public GarbageCollected<FileSystemDispatcher>, public Supplement<ExecutionContext> { USING_GARBAGE_COLLECTED_MIXIN(FileSystemDispatcher); - USING_PRE_FINALIZER(FileSystemDispatcher, Prefinalize); public: using StatusCallback = base::OnceCallback<void(base::File::Error error)>; @@ -145,7 +145,7 @@ class FileSystemDispatcher : public GarbageCollected<FileSystemDispatcher>, const KURL& file_path, std::unique_ptr<SnapshotFileCallbackBase> callbacks); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: class WriteListener; @@ -198,19 +198,14 @@ class FileSystemDispatcher : public GarbageCollected<FileSystemDispatcher>, void RemoveOperationRemote(int operation_id); - void Prefinalize(); - - HeapMojoRemote<mojom::blink::FileSystemManager, - HeapMojoWrapperMode::kWithoutContextObserver> - file_system_manager_; + HeapMojoRemote<mojom::blink::FileSystemManager> file_system_manager_; using OperationsMap = - HashMap<int, mojo::Remote<mojom::blink::FileSystemCancellableOperation>>; + HeapHashMap<int, + Member<DisallowNewWrapper<HeapMojoRemote< + mojom::blink::FileSystemCancellableOperation>>>>; OperationsMap cancellable_operations_; int next_operation_id_; - HeapMojoUniqueReceiverSet< - mojom::blink::FileSystemOperationListener, - std::default_delete<mojom::blink::FileSystemOperationListener>, - HeapMojoWrapperMode::kWithoutContextObserver> + HeapMojoUniqueReceiverSet<mojom::blink::FileSystemOperationListener> op_listeners_; }; diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc index 28815e50d9e..80240c735ce 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.cc @@ -335,7 +335,7 @@ void FileWriter::Dispose() { queued_operation_ = kOperationNone; } -void FileWriter::Trace(Visitor* visitor) { +void FileWriter::Trace(Visitor* visitor) const { visitor->Trace(error_); visitor->Trace(blob_being_written_); EventTargetWithInlineData::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h index e80ca27017f..14ed4b3ad4a 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer.h @@ -97,7 +97,7 @@ class FileWriter final : public EventTargetWithInlineData, DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError) DEFINE_ATTRIBUTE_EVENT_LISTENER(writeend, kWriteend) - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: enum Operation { diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h index c996b53a05f..e5bc45dac5a 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_base.h @@ -47,7 +47,7 @@ class MODULES_EXPORT FileWriterBase : public GarbageCollectedMixin { int64_t position() const { return position_; } int64_t length() const { return length_; } - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} virtual void Truncate(int64_t length); virtual void Write(int64_t position, const String& id); diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc index c61757182c5..0e8d854ded9 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc @@ -136,7 +136,7 @@ void FileWriterSync::PrepareForWrite() { FileWriterSync::~FileWriterSync() = default; -void FileWriterSync::Trace(Visitor* visitor) { +void FileWriterSync::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); FileWriterBase::Trace(visitor); ExecutionContextClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h index ba48e6d46c7..06c2ed308d1 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/file_writer_sync.h @@ -51,7 +51,7 @@ class FileWriterSync final : public ScriptWrappable, public: explicit FileWriterSync(ExecutionContext* context); ~FileWriterSync() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void write(Blob*, ExceptionState&); void seek(int64_t position, ExceptionState&); 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 9e929f7c99a..2d3f7f104c7 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 @@ -55,7 +55,9 @@ class TestableFileWriter : public GarbageCollected<TestableFileWriter>, fail_error_received_ = static_cast<base::File::Error>(0); } - void Trace(Visitor* visitor) override { FileWriterBase::Trace(visitor); } + void Trace(Visitor* visitor) const override { + FileWriterBase::Trace(visitor); + } bool received_truncate_; KURL received_truncate_path_; diff --git a/chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h b/chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h index a902d7c622c..307646c0b2c 100644 --- a/chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h +++ b/chromium/third_party/blink/renderer/modules/filesystem/sync_callback_helper.h @@ -46,7 +46,7 @@ class DOMFileSystemCallbacksSyncHelper final public: DOMFileSystemCallbacksSyncHelper() = default; - void Trace(Visitor* visitor) { visitor->Trace(result_); } + void Trace(Visitor* visitor) const { visitor->Trace(result_); } // Simple/new success and error callback wrappers. void OnSuccess(CallbackArg* arg) { diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_iterator.cc b/chromium/third_party/blink/renderer/modules/font_access/font_iterator.cc index 97cb193ae7b..7aeaa07ae20 100644 --- a/chromium/third_party/blink/renderer/modules/font_access/font_iterator.cc +++ b/chromium/third_party/blink/renderer/modules/font_access/font_iterator.cc @@ -34,7 +34,7 @@ ScriptPromise FontIterator::next(ScriptState* script_state) { return ScriptPromise::Cast(script_state, ToV8(result, script_state)); } -void FontIterator::Trace(Visitor* visitor) { +void FontIterator::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); visitor->Trace(entries_); } diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_iterator.h b/chromium/third_party/blink/renderer/modules/font_access/font_iterator.h index 3d8e72bc10f..3e2c1fff9ac 100644 --- a/chromium/third_party/blink/renderer/modules/font_access/font_iterator.h +++ b/chromium/third_party/blink/renderer/modules/font_access/font_iterator.h @@ -24,7 +24,7 @@ class FontIterator final : public ScriptWrappable { ScriptPromise next(ScriptState*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: HeapDeque<Member<FontMetadata>> entries_; diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_manager.cc b/chromium/third_party/blink/renderer/modules/font_access/font_manager.cc index d4996562e56..34783d3cc73 100644 --- a/chromium/third_party/blink/renderer/modules/font_access/font_manager.cc +++ b/chromium/third_party/blink/renderer/modules/font_access/font_manager.cc @@ -43,7 +43,7 @@ ScriptValue FontManager::query(ScriptState* script_state) { return ScriptValue(script_state->GetIsolate(), result); } -void FontManager::Trace(blink::Visitor* visitor) { +void FontManager::Trace(blink::Visitor* visitor) const { ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_manager.h b/chromium/third_party/blink/renderer/modules/font_access/font_manager.h index 49044cc52a2..80d36c73a3e 100644 --- a/chromium/third_party/blink/renderer/modules/font_access/font_manager.h +++ b/chromium/third_party/blink/renderer/modules/font_access/font_manager.h @@ -23,7 +23,7 @@ class FontManager final : public ScriptWrappable { ScriptValue query(ScriptState*); DISALLOW_COPY_AND_ASSIGN(FontManager); - void Trace(blink::Visitor*) override; + void Trace(blink::Visitor*) const override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_metadata.cc b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.cc index c79af6824f5..56f00cf5f1c 100644 --- a/chromium/third_party/blink/renderer/modules/font_access/font_metadata.cc +++ b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/font_access/font_metadata.h" #include "base/big_endian.h" +#include "base/metrics/histogram_functions.h" #include "base/sys_byteorder.h" #include "build/build_config.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -13,6 +14,7 @@ #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" +#include "third_party/skia/include/core/SkStream.h" #include "third_party/skia/include/core/SkTypes.h" namespace { @@ -147,6 +149,22 @@ ScriptPromise FontMetadata::getTables(ScriptState* script_state, return promise; } +ScriptPromise FontMetadata::blob(ScriptState* script_state) { + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + + Thread::Current()->GetTaskRunner()->PostTask( + FROM_HERE, WTF::Bind(&FontMetadata::blobImpl, WrapPersistent(resolver), + postscriptName_)); + + return promise; +} + +void FontMetadata::Trace(blink::Visitor* visitor) const { + ScriptWrappable::Trace(visitor); +} + // static void FontMetadata::getTablesImpl(ScriptPromiseResolver* resolver, const String& postscriptName, @@ -238,8 +256,68 @@ void FontMetadata::getTablesImpl(ScriptPromiseResolver* resolver, resolver->Resolve(map); } -void FontMetadata::Trace(blink::Visitor* visitor) { - ScriptWrappable::Trace(visitor); +// static +void FontMetadata::blobImpl(ScriptPromiseResolver* resolver, + const String& postscriptName) { + if (!resolver->GetScriptState()->ContextIsValid()) + return; + + FontDescription description; + scoped_refptr<SimpleFontData> font_data = + FontCache::GetFontCache()->GetFontData(description, + AtomicString(postscriptName)); + if (!font_data) { + auto message = String::Format("The font %s could not be accessed.", + postscriptName.Latin1().c_str()); + ScriptState::Scope scope(resolver->GetScriptState()); + resolver->Reject(V8ThrowException::CreateTypeError( + resolver->GetScriptState()->GetIsolate(), message)); + return; + } + + const SkTypeface* typeface = font_data->PlatformData().Typeface(); + + // On Mac, this will not be as efficient as on other platforms: data from + // tables will be copied and assembled into valid SNFT font data. This is + // because Mac system APIs only return per-table data. + int ttc_index = 0; + std::unique_ptr<SkStreamAsset> stream = typeface->openStream(&ttc_index); + + if (!(stream && stream->getMemoryBase())) { + // TODO(https://crbug.com/1086840): openStream rarely fails, but it happens + // sometimes. A potential remediation is to synthesize a font from tables + // at the cost of memory and throughput. + // For reference, the UMA metric "Blink.Fonts.HarfBuzzFaceZeroCopyAccess" + // indicates that the success rate is close to 100% on all platforms where + // it applies, but failures do happen. + base::UmaHistogramBoolean("Blink.Fonts.DataAccess.StreamCreation", false); + + auto message = String::Format("Font data for %s could not be accessed.", + postscriptName.Latin1().c_str()); + ScriptState::Scope scope(resolver->GetScriptState()); + resolver->Reject(V8ThrowException::CreateTypeError( + resolver->GetScriptState()->GetIsolate(), message)); + return; + } + + base::UmaHistogramBoolean("Blink.Fonts.DataAccess.StreamCreation", true); + wtf_size_t font_byte_size = SafeCast<wtf_size_t>(stream->getLength()); + + // TODO(https://crbug.com/1069900): This copies the font bytes. Lazy load and + // stream the data instead. + Vector<char> bytes(font_byte_size); + size_t returned_size = stream->read(bytes.data(), font_byte_size); + DCHECK_EQ(returned_size, font_byte_size); + + scoped_refptr<RawData> raw_data = RawData::Create(); + bytes.swap(*raw_data->MutableData()); + auto blob_data = std::make_unique<BlobData>(); + blob_data->AppendData(std::move(raw_data)); + blob_data->SetContentType("application/octet-stream"); + + auto* blob = MakeGarbageCollected<Blob>( + BlobDataHandle::Create(std::move(blob_data), font_byte_size)); + resolver->Resolve(blob); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_metadata.h b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.h index 9610789b2ad..c8ba8ef3100 100644 --- a/chromium/third_party/blink/renderer/modules/font_access/font_metadata.h +++ b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.h @@ -46,13 +46,16 @@ class BLINK_EXPORT FontMetadata final : public ScriptWrappable { ScriptPromise getTables(ScriptState*); ScriptPromise getTables(ScriptState*, const Vector<String>& tables); + ScriptPromise blob(ScriptState*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: static void getTablesImpl(ScriptPromiseResolver* resolver, const String& postscriptName, const Vector<String>& tables); + static void blobImpl(ScriptPromiseResolver* resolver, + const String& postscriptName); String postscriptName_; String fullName_; String family_; diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_metadata.idl b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.idl index 2371d9ac923..a4ae2c2bfd8 100644 --- a/chromium/third_party/blink/renderer/modules/font_access/font_metadata.idl +++ b/chromium/third_party/blink/renderer/modules/font_access/font_metadata.idl @@ -12,4 +12,5 @@ readonly attribute USVString fullName; readonly attribute USVString family; [CallWith=ScriptState] Promise<FontTableMap> getTables(optional sequence<ByteString> tables); + [CallWith=ScriptState] Promise<Blob> blob(); }; diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_table_map.cc b/chromium/third_party/blink/renderer/modules/font_access/font_table_map.cc index 3baf10e429f..8fad2f5931e 100644 --- a/chromium/third_party/blink/renderer/modules/font_access/font_table_map.cc +++ b/chromium/third_party/blink/renderer/modules/font_access/font_table_map.cc @@ -8,7 +8,7 @@ namespace blink { -void FontTableMap::Trace(Visitor* visitor) { +void FontTableMap::Trace(Visitor* visitor) const { visitor->Trace(table_map_); ScriptWrappable::Trace(visitor); } @@ -37,7 +37,7 @@ class FontTableMapIterationSource final return true; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(table_data_); PairIterable<String, Member<Blob>>::IterationSource::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/font_access/font_table_map.h b/chromium/third_party/blink/renderer/modules/font_access/font_table_map.h index 399b366d8d2..b48a3e9f8c9 100644 --- a/chromium/third_party/blink/renderer/modules/font_access/font_table_map.h +++ b/chromium/third_party/blink/renderer/modules/font_access/font_table_map.h @@ -28,7 +28,7 @@ class BLINK_EXPORT FontTableMap final : public ScriptWrappable, // IDL attributes / methods uint32_t size() const { return table_map_.size(); } - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: PairIterable<String, Member<Blob>>::IterationSource* StartIteration( diff --git a/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.cc b/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.cc index e576fc113da..e7014afb191 100644 --- a/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.cc +++ b/chromium/third_party/blink/renderer/modules/font_access/navigator_fonts.cc @@ -45,7 +45,7 @@ class NavigatorFontsImpl final : public GarbageCollected<NavigatorFontsImpl<T>>, return font_manager_.Get(); } - void Trace(blink::Visitor* visitor) override { + void Trace(blink::Visitor* visitor) const override { visitor->Trace(font_manager_); Supplement<T>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc index c14806f6edb..21f6dafa82a 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.cc @@ -166,7 +166,7 @@ void Gamepad::SetTimestamp(const device::Gamepad& device_gamepad) { } } -void Gamepad::Trace(Visitor* visitor) { +void Gamepad::Trace(Visitor* visitor) const { visitor->Trace(client_); visitor->Trace(buttons_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.h index 9bd4a0bd64a..57187bd2229 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad.h +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad.h @@ -88,7 +88,7 @@ class MODULES_EXPORT Gamepad final : public ScriptWrappable { return vibration_actuator_type_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void SetTimestamp(const device::Gamepad& device_gamepad); diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc index 09afaf5b727..203d76c51f4 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.cc @@ -40,10 +40,10 @@ void GamepadDispatcher::ResetVibrationActuator( std::move(callback)); } -GamepadDispatcher::GamepadDispatcher(ExecutionContext* context) +GamepadDispatcher::GamepadDispatcher(ExecutionContext& context) : // See https://bit.ly/2S0zRAS for task types. - task_runner_(context->GetTaskRunner(TaskType::kMiscPlatformAPI)), - gamepad_haptics_manager_remote_(context) {} + task_runner_(context.GetTaskRunner(TaskType::kMiscPlatformAPI)), + gamepad_haptics_manager_remote_(&context) {} GamepadDispatcher::~GamepadDispatcher() = default; @@ -55,7 +55,7 @@ void GamepadDispatcher::InitializeHaptics() { } } -void GamepadDispatcher::Trace(Visitor* visitor) { +void GamepadDispatcher::Trace(Visitor* visitor) const { visitor->Trace(reader_); visitor->Trace(gamepad_haptics_manager_remote_); PlatformEventDispatcher::Trace(visitor); 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 e9c79328793..a78369458fd 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_dispatcher.h @@ -30,7 +30,7 @@ class GamepadDispatcher final : public GarbageCollected<GamepadDispatcher>, USING_GARBAGE_COLLECTED_MIXIN(GamepadDispatcher); public: - explicit GamepadDispatcher(ExecutionContext* context); + explicit GamepadDispatcher(ExecutionContext& context); ~GamepadDispatcher() override; void SampleGamepads(device::Gamepads&); @@ -44,7 +44,7 @@ class GamepadDispatcher final : public GarbageCollected<GamepadDispatcher>, device::mojom::blink::GamepadHapticsManager:: ResetVibrationActuatorCallback); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void InitializeHaptics(); diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.cc index 3a6971b4579..a12a0374345 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.cc +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.cc @@ -25,7 +25,7 @@ const AtomicString& GamepadEvent::InterfaceName() const { return event_interface_names::kGamepadEvent; } -void GamepadEvent::Trace(Visitor* visitor) { +void GamepadEvent::Trace(Visitor* visitor) const { visitor->Trace(gamepad_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.h index ed42ca0c95b..1553eccdb66 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.h +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_event.h @@ -35,7 +35,7 @@ class GamepadEvent : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<Gamepad> gamepad_; 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 d7f8d2cb256..8c22fcf72dc 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 @@ -57,18 +57,11 @@ String ResultToString(GamepadHapticsResult result) { namespace blink { -// static -GamepadHapticActuator* GamepadHapticActuator::Create(ExecutionContext* context, - int pad_index) { - return MakeGarbageCollected<GamepadHapticActuator>( - context, pad_index, device::GamepadHapticActuatorType::kDualRumble); -} - GamepadHapticActuator::GamepadHapticActuator( - ExecutionContext* context, + ExecutionContext& context, int pad_index, device::GamepadHapticActuatorType type) - : ExecutionContextClient(context), + : ExecutionContextClient(&context), pad_index_(pad_index), gamepad_dispatcher_(MakeGarbageCollected<GamepadDispatcher>(context)) { SetType(type); @@ -185,7 +178,7 @@ void GamepadHapticActuator::OnResetCompleted( resolver->Resolve(ResultToString(result)); } -void GamepadHapticActuator::Trace(Visitor* visitor) { +void GamepadHapticActuator::Trace(Visitor* visitor) const { visitor->Trace(gamepad_dispatcher_); ScriptWrappable::Trace(visitor); ExecutionContextClient::Trace(visitor); 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 51a19f32680..01eb13827d8 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 @@ -26,10 +26,7 @@ class GamepadHapticActuator final : public ScriptWrappable, USING_GARBAGE_COLLECTED_MIXIN(GamepadHapticActuator); public: - static GamepadHapticActuator* Create(ExecutionContext* context, - int pad_index); - - GamepadHapticActuator(ExecutionContext* context, + GamepadHapticActuator(ExecutionContext& context, int pad_index, device::GamepadHapticActuatorType type); ~GamepadHapticActuator() override; @@ -43,7 +40,7 @@ class GamepadHapticActuator final : public ScriptWrappable, ScriptPromise reset(ScriptState*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void OnPlayEffectCompleted(ScriptPromiseResolver*, diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.cc b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.cc index 1a02569388e..4fef64698b9 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.cc +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.cc @@ -39,7 +39,7 @@ Gamepad* GamepadList::item(unsigned index) { return index < length() ? items_[index].Get() : nullptr; } -void GamepadList::Trace(Visitor* visitor) { +void GamepadList::Trace(Visitor* visitor) const { for (unsigned index = 0; index < device::Gamepads::kItemsLengthCap; index++) { visitor->Trace(items_[index]); } diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.h index 858d7936ae4..7975e1f373d 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.h +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_list.h @@ -44,7 +44,7 @@ class MODULES_EXPORT GamepadList final : public ScriptWrappable { Gamepad* item(unsigned index); unsigned length() const { return device::Gamepads::kItemsLengthCap; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<Gamepad> items_[device::Gamepads::kItemsLengthCap]; 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 c72847f088b..724adad862d 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 @@ -28,7 +28,7 @@ GamepadSharedMemoryReader::GamepadSharedMemoryReader(LocalFrame& frame) receiver_.BindNewPipeAndPassRemote(task_runner)); } -void GamepadSharedMemoryReader::Trace(Visitor* visitor) { +void GamepadSharedMemoryReader::Trace(Visitor* visitor) const { visitor->Trace(receiver_); visitor->Trace(gamepad_monitor_remote_); } diff --git a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.h b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.h index 55e48611855..e21ba88d3c0 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.h +++ b/chromium/third_party/blink/renderer/modules/gamepad/gamepad_shared_memory_reader.h @@ -36,7 +36,7 @@ class GamepadSharedMemoryReader public: explicit GamepadSharedMemoryReader(LocalFrame& frame); ~GamepadSharedMemoryReader() override; - void Trace(Visitor*); + void Trace(Visitor*) const; void SampleGamepads(device::Gamepads* gamepads); void Start(blink::GamepadListener* listener); 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 107bb68bb94..a517bbac43f 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc +++ b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc @@ -146,15 +146,14 @@ GamepadHapticActuator* NavigatorGamepad::GetVibrationActuatorForGamepad( int pad_index = gamepad.index(); DCHECK_GE(pad_index, 0); if (!vibration_actuators_[pad_index]) { - ExecutionContext* context = DomWindow(); - auto* actuator = GamepadHapticActuator::Create(context, pad_index); - actuator->SetType(gamepad.GetVibrationActuatorType()); + auto* actuator = MakeGarbageCollected<GamepadHapticActuator>( + *DomWindow(), pad_index, gamepad.GetVibrationActuatorType()); vibration_actuators_[pad_index] = actuator; } return vibration_actuators_[pad_index].Get(); } -void NavigatorGamepad::Trace(Visitor* visitor) { +void NavigatorGamepad::Trace(Visitor* visitor) const { visitor->Trace(gamepads_); visitor->Trace(gamepads_back_); visitor->Trace(vibration_actuators_); @@ -193,7 +192,7 @@ NavigatorGamepad::NavigatorGamepad(Navigator& navigator) ExecutionContextClient(navigator.DomWindow()), PlatformEventController(*navigator.DomWindow()), gamepad_dispatcher_( - MakeGarbageCollected<GamepadDispatcher>(navigator.DomWindow())) { + MakeGarbageCollected<GamepadDispatcher>(*navigator.DomWindow())) { navigator.DomWindow()->RegisterEventListenerObserver(this); // Fetch |window.performance.timing.navigationStart|. Gamepad timestamps are 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 9b8c58ea904..4effac4e62e 100644 --- a/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h +++ b/chromium/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h @@ -68,7 +68,7 @@ class MODULES_EXPORT NavigatorGamepad final static GamepadList* getGamepads(Navigator&); GamepadList* Gamepads(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void SampleGamepads(); 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 848196b3b99..46ebf734ac9 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc +++ b/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.cc @@ -37,7 +37,7 @@ GeoNotifier::GeoNotifier(Geolocation* geolocation, /* buckets = */ 20); } -void GeoNotifier::Trace(Visitor* visitor) { +void GeoNotifier::Trace(Visitor* visitor) const { visitor->Trace(geolocation_); visitor->Trace(options_); visitor->Trace(success_callback_); @@ -86,7 +86,7 @@ bool GeoNotifier::IsTimerActive() const { return timer_->IsActive(); } -void GeoNotifier::Timer::Trace(Visitor* visitor) { +void GeoNotifier::Timer::Trace(Visitor* visitor) const { visitor->Trace(notifier_); } 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 21322392da7..4348d707fe3 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h +++ b/chromium/third_party/blink/renderer/modules/geolocation/geo_notifier.h @@ -27,7 +27,7 @@ class GeoNotifier final : public GarbageCollected<GeoNotifier>, V8PositionErrorCallback*, const PositionOptions*); ~GeoNotifier() = default; - void Trace(Visitor*); + void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "GeoNotifier"; } const PositionOptions* Options() const { return options_; } @@ -61,7 +61,7 @@ class GeoNotifier final : public GarbageCollected<GeoNotifier>, void (GeoNotifier::*member_func)(TimerBase*)) : timer_(web_task_runner, notifier, member_func), notifier_(notifier) {} - void Trace(Visitor*); + void Trace(Visitor*) const; // TimerBase-compatible API void StartOneShot(base::TimeDelta interval, const base::Location& caller); diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc index 56253e50da7..adf5437c795 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.cc @@ -32,7 +32,6 @@ #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" -#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/deprecation.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/performance_monitor.h" @@ -114,7 +113,7 @@ Geolocation::Geolocation(ExecutionContext* context) Geolocation::~Geolocation() = default; -void Geolocation::Trace(Visitor* visitor) { +void Geolocation::Trace(Visitor* visitor) const { visitor->Trace(one_shots_); visitor->Trace(watchers_); visitor->Trace(one_shots_being_invoked_); @@ -155,7 +154,7 @@ void Geolocation::RecordOriginTypeAccess() const { String insecure_origin_msg; if (window->IsSecureContext(insecure_origin_msg)) { UseCounter::Count(window, WebFeature::kGeolocationSecureOrigin); - window->document()->CountUseOnlyInCrossOriginIframe( + window->CountUseOnlyInCrossOriginIframe( WebFeature::kGeolocationSecureOriginIframe); } else if (GetFrame() ->GetSettings() @@ -165,13 +164,13 @@ void Geolocation::RecordOriginTypeAccess() const { Deprecation::CountDeprecation( window, WebFeature::kGeolocationInsecureOriginDeprecatedNotRemoved); Deprecation::CountDeprecationCrossOriginIframe( - *window->document(), + window, WebFeature::kGeolocationInsecureOriginIframeDeprecatedNotRemoved); } else { Deprecation::CountDeprecation(window, WebFeature::kGeolocationInsecureOrigin); Deprecation::CountDeprecationCrossOriginIframe( - *window->document(), WebFeature::kGeolocationInsecureOriginIframe); + window, WebFeature::kGeolocationInsecureOriginIframe); } } diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h index b65b92941c0..c6eec4ab5cb 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation.h @@ -68,7 +68,7 @@ class MODULES_EXPORT Geolocation final explicit Geolocation(ExecutionContext*); ~Geolocation() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Inherited from ExecutionContextLifecycleObserver and // PageVisibilityObserver. 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 a48a02b863d..27edc2196ad 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_error.h +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_error.h @@ -37,7 +37,7 @@ class GeolocationError final : public GarbageCollected<GeolocationError> { GeolocationError(ErrorCode code, const String& message) : code_(code), message_(message) {} - void Trace(Visitor* visitor) {} + void Trace(Visitor* visitor) const {} ErrorCode Code() const { return code_; } const String& Message() const { return message_; } diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.cc b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.cc index 8a97ec70a93..1e7a3b0ce1c 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.cc +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.cc @@ -9,7 +9,7 @@ namespace blink { -void GeolocationWatchers::Trace(Visitor* visitor) { +void GeolocationWatchers::Trace(Visitor* visitor) const { visitor->Trace(id_to_notifier_map_); visitor->Trace(notifier_to_id_map_); } diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h index 6d6efc9c97d..602564837df 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h +++ b/chromium/third_party/blink/renderer/modules/geolocation/geolocation_watchers.h @@ -16,7 +16,7 @@ class GeolocationWatchers final : public GarbageCollected<GeolocationWatchers>, public NameClient { public: GeolocationWatchers() = default; - void Trace(Visitor*); + void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "GeolocationWatchers"; } diff --git a/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h b/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h index c34b1c44112..09aacc530ed 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h +++ b/chromium/third_party/blink/renderer/modules/geolocation/geoposition.h @@ -44,7 +44,7 @@ class Geoposition final : public ScriptWrappable { DCHECK(coordinates_); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(coordinates_); ScriptWrappable::Trace(visitor); } 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 5e53e0b9f35..9cd543f4a78 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc +++ b/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.cc @@ -56,7 +56,7 @@ Geolocation* NavigatorGeolocation::geolocation() { return geolocation_; } -void NavigatorGeolocation::Trace(Visitor* visitor) { +void NavigatorGeolocation::Trace(Visitor* visitor) const { visitor->Trace(geolocation_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h b/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h index 91c5cb1308f..b72326470ae 100644 --- a/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h +++ b/chromium/third_party/blink/renderer/modules/geolocation/navigator_geolocation.h @@ -45,7 +45,7 @@ class NavigatorGeolocation final explicit NavigatorGeolocation(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const char* NameInHeapSnapshot() const override { return "NavigatorGeolocation"; } diff --git a/chromium/third_party/blink/renderer/modules/hid/hid.cc b/chromium/third_party/blink/renderer/modules/hid/hid.cc index 9164c5035bc..17f957d6f54 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid.cc +++ b/chromium/third_party/blink/renderer/modules/hid/hid.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/hid/hid.h" +#include <utility> + #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" @@ -103,8 +105,36 @@ const AtomicString& HID::InterfaceName() const { void HID::AddedEventListener(const AtomicString& event_type, RegisteredEventListener& listener) { EventTargetWithInlineData::AddedEventListener(event_type, listener); - // TODO(mattreynolds): Connect to the HID service and register for connect - // and disconnect events. + + if (event_type != event_type_names::kConnect && + event_type != event_type_names::kDisconnect) { + return; + } + + auto* context = GetExecutionContext(); + if (!context || + !context->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kHid, + ReportOptions::kDoNotReport)) { + return; + } + + EnsureServiceConnection(); + if (!receiver_.is_bound()) + service_->RegisterClient(receiver_.BindNewEndpointAndPassRemote()); +} + +void HID::DeviceAdded(device::mojom::blink::HidDeviceInfoPtr device_info) { + auto* device = GetOrCreateDevice(std::move(device_info)); + + DispatchEvent(*MakeGarbageCollected<HIDConnectionEvent>( + event_type_names::kConnect, device)); +} + +void HID::DeviceRemoved(device::mojom::blink::HidDeviceInfoPtr device_info) { + auto* device = GetOrCreateDevice(std::move(device_info)); + + DispatchEvent(*MakeGarbageCollected<HIDConnectionEvent>( + event_type_names::kDisconnect, device)); } ScriptPromise HID::getDevices(ScriptState* script_state, @@ -141,7 +171,7 @@ ScriptPromise HID::requestDevice(ScriptState* script_state, return ScriptPromise(); } - if (!frame->GetDocument()->IsFeatureEnabled( + if (!GetExecutionContext()->IsFeatureEnabled( mojom::blink::FeaturePolicyFeature::kHid, ReportOptions::kReportOnFailure)) { exception_state.ThrowSecurityError(kFeaturePolicyBlocked); @@ -253,7 +283,7 @@ void HID::OnServiceConnectionError() { resolver->Resolve(HeapVector<Member<HIDDevice>>()); } -void HID::Trace(Visitor* visitor) { +void HID::Trace(Visitor* visitor) const { visitor->Trace(service_); visitor->Trace(get_devices_promises_); visitor->Trace(request_device_promises_); diff --git a/chromium/third_party/blink/renderer/modules/hid/hid.h b/chromium/third_party/blink/renderer/modules/hid/hid.h index bd48422e22d..99d39972e09 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid.h +++ b/chromium/third_party/blink/renderer/modules/hid/hid.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_HID_HID_H_ +#include "mojo/public/cpp/bindings/associated_receiver.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" @@ -24,7 +25,9 @@ class HIDDeviceRequestOptions; class ScriptPromiseResolver; class ScriptState; -class HID : public EventTargetWithInlineData, public ExecutionContextClient { +class HID : public EventTargetWithInlineData, + public ExecutionContextClient, + public device::mojom::blink::HidManagerClient { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(HID); @@ -36,6 +39,11 @@ class HID : public EventTargetWithInlineData, public ExecutionContextClient { ExecutionContext* GetExecutionContext() const override; const AtomicString& InterfaceName() const override; + // device::mojom::HidManagerClient: + void DeviceAdded(device::mojom::blink::HidDeviceInfoPtr device_info) override; + void DeviceRemoved( + device::mojom::blink::HidDeviceInfoPtr device_info) override; + // Web-exposed interfaces: DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect) DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect) @@ -49,7 +57,7 @@ class HID : public EventTargetWithInlineData, public ExecutionContextClient { connection_client, device::mojom::blink::HidManager::ConnectCallback callback); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: // EventTarget: @@ -73,6 +81,8 @@ class HID : public EventTargetWithInlineData, public ExecutionContextClient { HeapMojoRemote<mojom::blink::HidService, HeapMojoWrapperMode::kWithoutContextObserver> service_; + mojo::AssociatedReceiver<device::mojom::blink::HidManagerClient> receiver_{ + this}; HeapHashSet<Member<ScriptPromiseResolver>> get_devices_promises_; HeapHashSet<Member<ScriptPromiseResolver>> request_device_promises_; HeapHashMap<String, WeakMember<HIDDevice>> device_cache_; 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 901da6a0c37..f8851a5e86b 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 @@ -58,7 +58,7 @@ uint32_t HIDCollectionInfo::collectionType() const { return collection_type_; } -void HIDCollectionInfo::Trace(Visitor* visitor) { +void HIDCollectionInfo::Trace(Visitor* visitor) const { visitor->Trace(children_); visitor->Trace(input_reports_); visitor->Trace(output_reports_); 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 60b13edc0d7..094fecf2860 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 @@ -30,7 +30,7 @@ class MODULES_EXPORT HIDCollectionInfo : public ScriptWrappable { const HeapVector<Member<HIDReportInfo>>& featureReports() const; uint32_t collectionType() const; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: uint16_t usage_page_; diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.cc b/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.cc index f99b723eed3..bb9bb1acb18 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.cc +++ b/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.cc @@ -27,9 +27,10 @@ HIDConnectionEvent::HIDConnectionEvent( HIDConnectionEvent::HIDConnectionEvent(const AtomicString& type, HIDDevice* device) - : Event(type, Bubbles::kNo, Cancelable::kNo) {} + : Event(type, Bubbles::kNo, Cancelable::kNo), device_(device) {} -void HIDConnectionEvent::Trace(Visitor* visitor) { +void HIDConnectionEvent::Trace(Visitor* visitor) const { + visitor->Trace(device_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.h b/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.h index 134826a65c1..3d2a08426eb 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.h +++ b/chromium/third_party/blink/renderer/modules/hid/hid_connection_event.h @@ -24,9 +24,12 @@ class HIDConnectionEvent final : public Event { HIDConnectionEvent(const AtomicString& type, const HIDConnectionEventInit*); HIDConnectionEvent(const AtomicString& type, HIDDevice*); - HIDDevice* device() const { return nullptr; } + HIDDevice* device() const { return device_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; + + private: + Member<HIDDevice> device_; }; } // namespace blink 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 06d46513f02..01dbcc3971c 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_device.cc +++ b/chromium/third_party/blink/renderer/modules/hid/hid_device.cc @@ -274,7 +274,7 @@ void HIDDevice::ContextDestroyed() { device_requests_.clear(); } -void HIDDevice::Trace(Visitor* visitor) { +void HIDDevice::Trace(Visitor* visitor) const { visitor->Trace(parent_); visitor->Trace(connection_); visitor->Trace(receiver_); 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 df60fd14a5f..8077844d776 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_device.h +++ b/chromium/third_party/blink/renderer/modules/hid/hid_device.h @@ -71,7 +71,7 @@ class MODULES_EXPORT HIDDevice // ExecutionContextLifecycleObserver: void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: bool EnsureNoDeviceChangeInProgress(ScriptPromiseResolver* resolver) const; diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.cc b/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.cc index a6a9bf6c687..cf960d4a93a 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.cc +++ b/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.cc @@ -27,7 +27,7 @@ const AtomicString& HIDInputReportEvent::InterfaceName() const { return event_interface_names::kHIDInputReportEvent; } -void HIDInputReportEvent::Trace(Visitor* visitor) { +void HIDInputReportEvent::Trace(Visitor* visitor) const { visitor->Trace(device_); visitor->Trace(data_); Event::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.h b/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.h index bd5ce902d37..db262dff403 100644 --- a/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.h +++ b/chromium/third_party/blink/renderer/modules/hid/hid_input_report_event.h @@ -29,7 +29,7 @@ class HIDInputReportEvent final : public Event { // Event: const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<HIDDevice> device_; 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 a54ee2a8fe6..0e39ccb9b96 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 @@ -26,7 +26,7 @@ const HeapVector<Member<HIDReportItem>>& HIDReportInfo::items() const { return items_; } -void HIDReportInfo::Trace(Visitor* visitor) { +void HIDReportInfo::Trace(Visitor* visitor) const { visitor->Trace(items_); ScriptWrappable::Trace(visitor); } 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 7384a8d9289..dbdfb69bff7 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 @@ -25,7 +25,7 @@ class MODULES_EXPORT HIDReportInfo : public ScriptWrappable { uint8_t reportId() const; const HeapVector<Member<HIDReportItem>>& items() const; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: uint8_t report_id_; diff --git a/chromium/third_party/blink/renderer/modules/hid/navigator_hid.cc b/chromium/third_party/blink/renderer/modules/hid/navigator_hid.cc index c6d0e591085..37790882638 100644 --- a/chromium/third_party/blink/renderer/modules/hid/navigator_hid.cc +++ b/chromium/third_party/blink/renderer/modules/hid/navigator_hid.cc @@ -29,7 +29,7 @@ HID* NavigatorHID::hid() { return hid_; } -void NavigatorHID::Trace(Visitor* visitor) { +void NavigatorHID::Trace(Visitor* visitor) const { visitor->Trace(hid_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/hid/navigator_hid.h b/chromium/third_party/blink/renderer/modules/hid/navigator_hid.h index 2f6979e53bf..2981276ad1e 100644 --- a/chromium/third_party/blink/renderer/modules/hid/navigator_hid.h +++ b/chromium/third_party/blink/renderer/modules/hid/navigator_hid.h @@ -28,7 +28,7 @@ class NavigatorHID final : public GarbageCollected<NavigatorHID>, static HID* hid(Navigator&); HID* hid(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; explicit NavigatorHID(Navigator&); diff --git a/chromium/third_party/blink/renderer/modules/idle/idle_detector.cc b/chromium/third_party/blink/renderer/modules/idle/idle_detector.cc index 3b7df5d1049..8dafda3126f 100644 --- a/chromium/third_party/blink/renderer/modules/idle/idle_detector.cc +++ b/chromium/third_party/blink/renderer/modules/idle/idle_detector.cc @@ -208,7 +208,7 @@ void IdleDetector::Update(mojom::blink::IdleStatePtr state) { DispatchEvent(*Event::Create(event_type_names::kChange)); } -void IdleDetector::Trace(Visitor* visitor) { +void IdleDetector::Trace(Visitor* visitor) const { visitor->Trace(signal_); visitor->Trace(resolver_); visitor->Trace(receiver_); 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 fcdb47eaf6c..03bf778f7a2 100644 --- a/chromium/third_party/blink/renderer/modules/idle/idle_detector.h +++ b/chromium/third_party/blink/renderer/modules/idle/idle_detector.h @@ -54,7 +54,7 @@ class IdleDetector final : public EventTargetWithInlineData, ScriptPromise start(ScriptState*, const IdleOptions*, ExceptionState&); DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange) - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // mojom::blink::IdleMonitor implementation. Invoked on a state change, and 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 f2ab0bc0199..fb0fc97d689 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 @@ -253,7 +253,7 @@ void ImageDownloaderImpl::DidFetchImage( std::move(callback).Run(http_status_code, images); } -void ImageDownloaderImpl::Trace(Visitor* visitor) { +void ImageDownloaderImpl::Trace(Visitor* visitor) const { visitor->Trace(receiver_); Supplement<LocalFrame>::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); 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 36b6d772739..0634a03bdf5 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 @@ -24,7 +24,6 @@ class ImageDownloaderImpl final : public GarbageCollected<ImageDownloaderImpl>, public Supplement<LocalFrame>, public ExecutionContextLifecycleObserver, public mojom::blink::ImageDownloader { - USING_PRE_FINALIZER(ImageDownloaderImpl, Dispose); USING_GARBAGE_COLLECTED_MIXIN(ImageDownloaderImpl); public: @@ -40,7 +39,7 @@ class ImageDownloaderImpl final : public GarbageCollected<ImageDownloaderImpl>, static void ProvideTo(LocalFrame&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // OverExecutionContextLifecycleObserver overrides. void ContextDestroyed() override; @@ -68,8 +67,6 @@ class ImageDownloaderImpl final : public GarbageCollected<ImageDownloaderImpl>, void CreateMojoService( mojo::PendingReceiver<mojom::blink::ImageDownloader> receiver); - // USING_PRE_FINALIZER interface. - // Called before the object gets garbage collected. void Dispose(); // Requests to fetch an image. When done, the image downloader is notified by 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 b88de431f99..79767cd1334 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc +++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.cc @@ -7,9 +7,10 @@ #include <memory> #include <utility> +#include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/permissions/permission_status.mojom-blink.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" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_capabilities.h" @@ -23,8 +24,10 @@ #include "third_party/blink/renderer/modules/imagecapture/media_settings_range.h" #include "third_party/blink/renderer/modules/imagecapture/photo_capabilities.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_track.h" +#include "third_party/blink/renderer/modules/permissions/permission_utils.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/mojo/mojo_helper.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -95,7 +98,14 @@ ImageCapture* ImageCapture::Create(ExecutionContext* context, return nullptr; } - return MakeGarbageCollected<ImageCapture>(context, track); + // The initial PTZ permission comes from the internal ImageCapture object of + // the track, if already created. + bool pan_tilt_zoom_allowed = + (track->GetImageCapture() && + track->GetImageCapture()->HasPanTiltZoomPermissionGranted()); + + return MakeGarbageCollected<ImageCapture>(context, track, + pan_tilt_zoom_allowed); } ImageCapture::~ImageCapture() { @@ -258,39 +268,6 @@ ScriptPromise ImageCapture::setOptions(ScriptState* script_state, return promise; } -ScriptPromise ImageCapture::takePhoto(ScriptState* script_state) { - TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"), - "ImageCapture::takePhoto", TRACE_EVENT_SCOPE_PROCESS); - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise promise = resolver->Promise(); - - if (TrackIsInactive(*stream_track_)) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError, - "The associated Track is in an invalid state.")); - return promise; - } - if (!service_.is_bound()) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotFoundError, kNoServiceError)); - return promise; - } - - service_requests_.insert(resolver); - - // m_streamTrack->component()->source()->id() is the renderer "name" of the - // camera; - // TODO(mcasas) consider sending the security origin as well: - // scriptState->getExecutionContext()->getSecurityOrigin()->toString() - TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"), - "ImageCapture::takePhoto", TRACE_EVENT_SCOPE_PROCESS); - service_->TakePhoto( - stream_track_->Component()->Source()->Id(), - WTF::Bind(&ImageCapture::OnMojoTakePhoto, WrapPersistent(this), - WrapPersistent(resolver))); - return promise; -} - ScriptPromise ImageCapture::takePhoto(ScriptState* script_state, const PhotoSettings* photo_settings) { TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("video_and_image_capture"), @@ -323,19 +300,63 @@ ScriptPromise ImageCapture::grabFrame(ScriptState* script_state) { return promise; } - // The platform does not know about MediaStreamTrack, so we wrap it up. - WebMediaStreamTrack track(stream_track_->Component()); auto resolver_callback_adapter = std::make_unique<CallbackPromiseAdapter<ImageBitmap, void>>(resolver); - frame_grabber_->GrabFrame(&track, std::move(resolver_callback_adapter), + frame_grabber_->GrabFrame(stream_track_->Component(), + std::move(resolver_callback_adapter), ExecutionContext::From(script_state) ->GetTaskRunner(TaskType::kDOMManipulation)); return promise; } -MediaTrackCapabilities* ImageCapture::GetMediaTrackCapabilities() const { - return capabilities_; +void ImageCapture::GetMediaTrackCapabilities( + MediaTrackCapabilities* capabilities) const { + // Merge any present |capabilities_| members into |capabilities|. + + if (capabilities_->hasWhiteBalanceMode()) + capabilities->setWhiteBalanceMode(capabilities_->whiteBalanceMode()); + if (capabilities_->hasExposureMode()) + capabilities->setExposureMode(capabilities_->exposureMode()); + if (capabilities_->hasFocusMode()) + capabilities->setFocusMode(capabilities_->focusMode()); + if (capabilities_->hasExposureCompensation()) { + capabilities->setExposureCompensation( + capabilities_->exposureCompensation()); + } + if (capabilities_->hasExposureTime()) + capabilities->setExposureTime(capabilities_->exposureTime()); + + if (capabilities_->hasColorTemperature()) + capabilities->setColorTemperature(capabilities_->colorTemperature()); + if (capabilities_->hasIso()) + capabilities->setIso(capabilities_->iso()); + + if (capabilities_->hasBrightness()) + capabilities->setBrightness(capabilities_->brightness()); + if (capabilities_->hasContrast()) + capabilities->setContrast(capabilities_->contrast()); + if (capabilities_->hasSaturation()) + capabilities->setSaturation(capabilities_->saturation()); + if (capabilities_->hasSharpness()) + capabilities->setSharpness(capabilities_->sharpness()); + + if (capabilities_->hasFocusDistance()) + capabilities->setFocusDistance(capabilities_->focusDistance()); + + if (HasPanTiltZoomPermissionGranted()) { + if (capabilities_->hasPan()) + capabilities->setPan(capabilities_->pan()); + if (capabilities_->hasTilt()) + capabilities->setTilt(capabilities_->tilt()); + } + // TODO(crbug.com/934063): Check HasPanTiltZoomPermissionGranted() as well if + // upcoming metrics show that zoom may be moved under this permission. + if (capabilities_->hasZoom()) + capabilities->setZoom(capabilities_->zoom()); + + if (capabilities_->hasTorch()) + capabilities->setTorch(capabilities_->torch()); } // TODO(mcasas): make the implementation fully Spec compliant, see the TODOs @@ -404,8 +425,12 @@ void ImageCapture::SetMediaTrackConstraints( (constraints->hasSaturation() && !capabilities_->hasSaturation()) || (constraints->hasSharpness() && !capabilities_->hasSharpness()) || (constraints->hasFocusDistance() && !capabilities_->hasFocusDistance()) || - (constraints->hasPan() && !capabilities_->hasPan()) || - (constraints->hasTilt() && !capabilities_->hasTilt()) || + (constraints->hasPan() && + !(capabilities_->hasPan() && HasPanTiltZoomPermissionGranted())) || + (constraints->hasTilt() && + !(capabilities_->hasTilt() && HasPanTiltZoomPermissionGranted())) || + // TODO(crbug.com/934063): Check HasPanTiltZoomPermissionGranted() as well + // if upcoming metrics show that zoom may be moved under this permission. (constraints->hasZoom() && !capabilities_->hasZoom()) || (constraints->hasTorch() && !capabilities_->hasTorch())) { resolver->Reject(MakeGarbageCollected<DOMException>( @@ -716,26 +741,39 @@ void ImageCapture::GetMediaTrackSettings(MediaTrackSettings* settings) const { if (settings_->hasFocusDistance()) settings->setFocusDistance(settings_->focusDistance()); - if (settings_->hasPan()) - settings->setPan(settings_->pan()); - if (settings_->hasTilt()) - settings->setTilt(settings_->tilt()); + if (HasPanTiltZoomPermissionGranted()) { + if (settings_->hasPan()) + settings->setPan(settings_->pan()); + if (settings_->hasTilt()) + settings->setTilt(settings_->tilt()); + } + // TODO(crbug.com/934063): Check HasPanTiltZoomPermissionGranted() as well if + // upcoming metrics show that zoom may be moved under this permission. if (settings_->hasZoom()) settings->setZoom(settings_->zoom()); + if (settings_->hasTorch()) settings->setTorch(settings_->torch()); } -ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track) +ImageCapture::ImageCapture(ExecutionContext* context, + MediaStreamTrack* track, + bool pan_tilt_zoom_allowed) : ExecutionContextLifecycleObserver(context), stream_track_(track), service_(context), + pan_tilt_zoom_permission_(pan_tilt_zoom_allowed + ? mojom::blink::PermissionStatus::GRANTED + : mojom::blink::PermissionStatus::ASK), + permission_service_(context), + permission_observer_receiver_(this, context), capabilities_(MediaTrackCapabilities::Create()), settings_(MediaTrackSettings::Create()), current_constraints_(MediaTrackConstraintSet::Create()), photo_settings_(PhotoSettings::Create()) { DCHECK(stream_track_); DCHECK(!service_.is_bound()); + DCHECK(!permission_service_.is_bound()); // This object may be constructed over an ExecutionContext that has already // been detached. In this case the ImageCapture service will not be available. @@ -754,6 +792,30 @@ ImageCapture::ImageCapture(ExecutionContext* context, MediaStreamTrack* track) service_->GetPhotoState(stream_track_->Component()->Source()->Id(), WTF::Bind(&ImageCapture::UpdateMediaTrackCapabilities, WrapPersistent(this))); + + ConnectToPermissionService( + context, permission_service_.BindNewPipeAndPassReceiver( + context->GetTaskRunner(TaskType::kMiscPlatformAPI))); + + mojo::PendingRemote<mojom::blink::PermissionObserver> observer; + permission_observer_receiver_.Bind( + observer.InitWithNewPipeAndPassReceiver(), + context->GetTaskRunner(TaskType::kMiscPlatformAPI)); + permission_service_->AddPermissionObserver( + CreateVideoCapturePermissionDescriptor(/*pan_tilt_zoom=*/true), + pan_tilt_zoom_permission_, std::move(observer)); +} + +void ImageCapture::OnPermissionStatusChange( + mojom::blink::PermissionStatus status) { + pan_tilt_zoom_permission_ = status; +} + +bool ImageCapture::HasPanTiltZoomPermissionGranted() const { + if (!RuntimeEnabledFeatures::MediaCapturePanTiltEnabled()) + return false; + + return pan_tilt_zoom_permission_ == mojom::blink::PermissionStatus::GRANTED; } void ImageCapture::OnMojoGetPhotoState( @@ -951,14 +1013,18 @@ void ImageCapture::UpdateMediaTrackCapabilities( settings_->setFocusDistance(photo_state->focus_distance->current); } - if (photo_state->pan->max != photo_state->pan->min) { - capabilities_->setPan(MediaSettingsRange::Create(*photo_state->pan)); - settings_->setPan(photo_state->pan->current); - } - if (photo_state->tilt->max != photo_state->tilt->min) { - capabilities_->setTilt(MediaSettingsRange::Create(*photo_state->tilt)); - settings_->setTilt(photo_state->tilt->current); + if (HasPanTiltZoomPermissionGranted()) { + if (photo_state->pan->max != photo_state->pan->min) { + capabilities_->setPan(MediaSettingsRange::Create(*photo_state->pan)); + settings_->setPan(photo_state->pan->current); + } + if (photo_state->tilt->max != photo_state->tilt->min) { + capabilities_->setTilt(MediaSettingsRange::Create(*photo_state->tilt)); + settings_->setTilt(photo_state->tilt->current); + } } + // TODO(crbug.com/934063): Check HasPanTiltZoomPermissionGranted() as well if + // upcoming metrics show that zoom may be moved under this permission. if (photo_state->zoom->max != photo_state->zoom->min) { capabilities_->setZoom(MediaSettingsRange::Create(*photo_state->zoom)); settings_->setZoom(photo_state->zoom->current); @@ -995,9 +1061,11 @@ void ImageCapture::ResolveWithPhotoCapabilities( resolver->Resolve(photo_capabilities_); } -void ImageCapture::Trace(Visitor* visitor) { +void ImageCapture::Trace(Visitor* visitor) const { visitor->Trace(stream_track_); visitor->Trace(service_); + visitor->Trace(permission_service_); + visitor->Trace(permission_observer_receiver_); visitor->Trace(capabilities_); visitor->Trace(settings_); visitor->Trace(photo_settings_); 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 d35156e61bf..7a5365b2ed4 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 "third_party/blink/public/mojom/permissions/permission.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" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_capabilities.h" @@ -17,6 +18,7 @@ #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.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/platform/mojo/heap_mojo_receiver.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" @@ -33,7 +35,8 @@ class ScriptPromiseResolver; class MODULES_EXPORT ImageCapture final : public EventTargetWithInlineData, public ActiveScriptWrappable<ImageCapture>, - public ExecutionContextLifecycleObserver { + public ExecutionContextLifecycleObserver, + public mojom::blink::PermissionObserver { USING_GARBAGE_COLLECTED_MIXIN(ImageCapture); DEFINE_WRAPPERTYPEINFO(); @@ -42,7 +45,9 @@ class MODULES_EXPORT ImageCapture final MediaStreamTrack*, ExceptionState&); - ImageCapture(ExecutionContext*, MediaStreamTrack*); + ImageCapture(ExecutionContext*, + MediaStreamTrack*, + bool pan_tilt_zoom_allowed); ~ImageCapture() override; // EventTarget implementation. @@ -64,12 +69,11 @@ class MODULES_EXPORT ImageCapture final const PhotoSettings*, bool trigger_take_photo = false); - ScriptPromise takePhoto(ScriptState*); ScriptPromise takePhoto(ScriptState*, const PhotoSettings*); ScriptPromise grabFrame(ScriptState*); - MediaTrackCapabilities* GetMediaTrackCapabilities() const; + void GetMediaTrackCapabilities(MediaTrackCapabilities*) const; void SetMediaTrackConstraints( ScriptPromiseResolver*, const HeapVector<Member<MediaTrackConstraintSet>>&); @@ -77,12 +81,18 @@ class MODULES_EXPORT ImageCapture final void ClearMediaTrackConstraints(); void GetMediaTrackSettings(MediaTrackSettings*) const; - void Trace(Visitor*) override; + bool HasPanTiltZoomPermissionGranted() const; + + void Trace(Visitor*) const override; private: using PromiseResolverFunction = base::OnceCallback<void(ScriptPromiseResolver*)>; + // mojom::blink::PermissionObserver implementation. + // Called when we get an updated PTZ permission value from the browser. + void OnPermissionStatusChange(mojom::blink::PermissionStatus) override; + void OnMojoGetPhotoState(ScriptPromiseResolver*, PromiseResolverFunction, bool trigger_take_photo, @@ -105,6 +115,13 @@ class MODULES_EXPORT ImageCapture final HeapMojoWrapperMode::kWithoutContextObserver> service_; + // Whether the user has granted permission for the user to control camera PTZ. + mojom::blink::PermissionStatus pan_tilt_zoom_permission_; + // The permission service, enabling us to check for the PTZ permission. + HeapMojoRemote<mojom::blink::PermissionService> permission_service_; + HeapMojoReceiver<mojom::blink::PermissionObserver, ImageCapture> + permission_observer_receiver_; + Member<MediaTrackCapabilities> capabilities_; Member<MediaTrackSettings> settings_; Member<MediaTrackConstraintSet> current_constraints_; diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl index d27b2659a99..9f70ed62bde 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl +++ b/chromium/third_party/blink/renderer/modules/imagecapture/image_capture.idl @@ -13,6 +13,6 @@ [CallWith=ScriptState] Promise<PhotoCapabilities> getPhotoCapabilities(); [CallWith=ScriptState] Promise<PhotoSettings> getPhotoSettings(); - [CallWith=ScriptState] Promise<Blob> takePhoto(optional PhotoSettings photoSettings); + [CallWith=ScriptState] Promise<Blob> takePhoto(optional PhotoSettings photoSettings = {}); [CallWith=ScriptState] Promise<ImageBitmap> grabFrame(); }; 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 dfc36212876..211f6e2e831 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 @@ -9,9 +9,9 @@ #include "media/base/video_types.h" #include "media/base/video_util.h" #include "skia/ext/platform_canvas.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/renderer/core/imagebitmap/image_bitmap.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.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/thread_safe_ref_counted.h" @@ -187,14 +187,14 @@ ImageCaptureFrameGrabber::~ImageCaptureFrameGrabber() { } void ImageCaptureFrameGrabber::GrabFrame( - WebMediaStreamTrack* track, + MediaStreamComponent* component, std::unique_ptr<ImageCaptureGrabFrameCallbacks> callbacks, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(!!callbacks); - DCHECK(track && !track->IsNull() && track->GetPlatformTrack()); - DCHECK_EQ(WebMediaStreamSource::kTypeVideo, track->Source().GetType()); + DCHECK(component && component->GetPlatformTrack()); + DCHECK_EQ(MediaStreamSource::kTypeVideo, component->Source()->GetType()); if (frame_grab_in_progress_) { // Reject grabFrame()s too close back to back. @@ -212,7 +212,7 @@ void ImageCaptureFrameGrabber::GrabFrame( // https://crbug.com/623042. frame_grab_in_progress_ = true; MediaStreamVideoSink::ConnectToTrack( - *track, + component, ConvertToBaseRepeatingCallback(CrossThreadBindRepeating( &SingleShotFrameHandler::OnVideoFrameOnIOThread, base::MakeRefCounted<SingleShotFrameHandler>(), 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 f050a850607..a4376955763 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 @@ -22,7 +22,7 @@ class SkImage; namespace blink { class ImageBitmap; -class WebMediaStreamTrack; +class MediaStreamComponent; // A ScopedWebCallbacks is a move-only scoper which helps manage the lifetime of // a blink::WebCallbacks object. This is particularly useful when you're @@ -130,7 +130,7 @@ class ImageCaptureFrameGrabber final : public MediaStreamVideoSink { ImageCaptureFrameGrabber(); ~ImageCaptureFrameGrabber() override; - void GrabFrame(WebMediaStreamTrack* track, + void GrabFrame(MediaStreamComponent* component, std::unique_ptr<ImageCaptureGrabFrameCallbacks> callbacks, scoped_refptr<base::SingleThreadTaskRunner> task_runner); diff --git a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc index 04cea46c1d5..e3121991b06 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc +++ b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.cc @@ -45,7 +45,7 @@ bool PhotoCapabilities::IsRedEyeReductionControllable() const { media::mojom::blink::RedEyeReduction::CONTROLLABLE; } -void PhotoCapabilities::Trace(Visitor* visitor) { +void PhotoCapabilities::Trace(Visitor* visitor) const { visitor->Trace(image_height_); visitor->Trace(image_width_); ScriptWrappable::Trace(visitor); 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 273ec23828b..ec69a6f3014 100644 --- a/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h +++ b/chromium/third_party/blink/renderer/modules/imagecapture/photo_capabilities.h @@ -38,7 +38,7 @@ class PhotoCapabilities final : public ScriptWrappable { } bool IsRedEyeReductionControllable() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<MediaSettingsRange> image_height_; diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc b/chromium/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc index 4989637cd4c..95add2a4b3b 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/global_indexed_db.cc @@ -41,7 +41,7 @@ class GlobalIndexedDBImpl final return idb_factory_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(idb_factory_); Supplement<T>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.cc index aa1a275705a..4104ec54504 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.cc @@ -111,7 +111,7 @@ IDBAny::IDBAny(std::unique_ptr<IDBKey> key) IDBAny::IDBAny(int64_t value) : type_(kIntegerType), integer_(value) {} -void IDBAny::Trace(Visitor* visitor) { +void IDBAny::Trace(Visitor* visitor) const { visitor->Trace(dom_string_list_); visitor->Trace(idb_cursor_); visitor->Trace(idb_database_); 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 825eeae6ffa..47e49e0c7f3 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_any.h @@ -78,7 +78,7 @@ class MODULES_EXPORT IDBAny final : public GarbageCollected<IDBAny> { explicit IDBAny(int64_t); ~IDBAny(); - void Trace(Visitor*); + void Trace(Visitor*) const; void ContextWillBeDestroyed(); Type GetType() const { return type_; } diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc index b0552bc3e58..76d204bc33a 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc @@ -64,7 +64,7 @@ IDBCursor::IDBCursor(std::unique_ptr<WebIDBCursor> backend, IDBCursor::~IDBCursor() = default; -void IDBCursor::Trace(Visitor* visitor) { +void IDBCursor::Trace(Visitor* visitor) const { visitor->Trace(request_); visitor->Trace(source_); visitor->Trace(transaction_); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.h index 86ca472dff3..b6363d932b1 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_cursor.h @@ -59,7 +59,7 @@ class IDBCursor : public ScriptWrappable { IDBTransaction*); ~IDBCursor() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void ContextWillBeDestroyed() { backend_.reset(); } WARN_UNUSED_RESULT v8::Local<v8::Object> AssociateWithWrapper( 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 3f2764199a4..c534f7f2b69 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc @@ -121,7 +121,7 @@ IDBDatabase::~IDBDatabase() { backend_->Close(); } -void IDBDatabase::Trace(Visitor* visitor) { +void IDBDatabase::Trace(Visitor* visitor) const { visitor->Trace(version_change_transaction_); visitor->Trace(transactions_); visitor->Trace(observers_); 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 6eef002a162..8f373975b6a 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h @@ -74,7 +74,7 @@ class MODULES_EXPORT IDBDatabase final mojo::PendingRemote<mojom::blink::ObservedFeature> connection_lifetime); ~IDBDatabase() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Overwrites the database metadata, including object store and index // metadata. Used to pass metadata to the database when it is opened. diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc index 14e8037e5a2..cfa159625c1 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database_callbacks.cc @@ -34,7 +34,7 @@ IDBDatabaseCallbacks::IDBDatabaseCallbacks() : database_(nullptr) {} IDBDatabaseCallbacks::~IDBDatabaseCallbacks() = default; -void IDBDatabaseCallbacks::Trace(Visitor* visitor) { +void IDBDatabaseCallbacks::Trace(Visitor* visitor) const { visitor->Trace(database_); } 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 76c09201024..e7705b02e9f 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 @@ -41,7 +41,7 @@ class MODULES_EXPORT IDBDatabaseCallbacks public: IDBDatabaseCallbacks(); virtual ~IDBDatabaseCallbacks(); - void Trace(Visitor*); + void Trace(Visitor*) const; // IDBDatabaseCallbacks virtual void OnForcedClose(); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.cc index a17ecbae88c..fd21e6d5f53 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.cc @@ -55,7 +55,7 @@ IDBIndex::IDBIndex(scoped_refptr<IDBIndexMetadata> metadata, IDBIndex::~IDBIndex() = default; -void IDBIndex::Trace(Visitor* visitor) { +void IDBIndex::Trace(Visitor* visitor) const { visitor->Trace(object_store_); visitor->Trace(transaction_); ScriptWrappable::Trace(visitor); 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 8bb99e9366f..339a25d3917 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_index.h @@ -51,7 +51,7 @@ class IDBIndex final : public ScriptWrappable { IDBIndex(scoped_refptr<IDBIndexMetadata>, IDBObjectStore*, IDBTransaction*); ~IDBIndex() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Implement the IDL const String& name() const { return Metadata().name; } diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.h index 55311ab0e86..803ffe6619e 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_key_range.h @@ -76,7 +76,9 @@ class MODULES_EXPORT IDBKeyRange final : public ScriptWrappable { const ScriptValue&, ExceptionState&); - void Trace(Visitor* visitor) override { ScriptWrappable::Trace(visitor); } + void Trace(Visitor* visitor) const override { + ScriptWrappable::Trace(visitor); + } // Implement the IDBKeyRange IDL IDBKey* Lower() const { return lower_.get(); } diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc index 35993191a53..a998c076f41 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc @@ -62,7 +62,7 @@ IDBObjectStore::IDBObjectStore(scoped_refptr<IDBObjectStoreMetadata> metadata, DCHECK(metadata_.get()); } -void IDBObjectStore::Trace(Visitor* visitor) { +void IDBObjectStore::Trace(Visitor* visitor) const { visitor->Trace(transaction_); visitor->Trace(index_map_); ScriptWrappable::Trace(visitor); @@ -725,7 +725,7 @@ class IndexPopulator final : public NativeEventListener { DCHECK(index_metadata_.get()); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(script_state_); visitor->Trace(database_); NativeEventListener::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.h index 79819338c46..c14f53f866e 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_object_store.h @@ -54,7 +54,7 @@ class MODULES_EXPORT IDBObjectStore final : public ScriptWrappable { IDBObjectStore(scoped_refptr<IDBObjectStoreMetadata>, IDBTransaction*); ~IDBObjectStore() override = default; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const IDBObjectStoreMetadata& Metadata() const { return *metadata_; } const IDBKeyPath& IdbKeyPath() const { return Metadata().key_path; } diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.cc index 923dc0f01c8..168d6d1ab9f 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.cc @@ -81,7 +81,7 @@ void IDBObservation::SetIsolate(v8::Isolate* isolate) { value_->Value()->SetIsolate(isolate); } -void IDBObservation::Trace(Visitor* visitor) { +void IDBObservation::Trace(Visitor* visitor) const { visitor->Trace(key_range_); visitor->Trace(value_); ScriptWrappable::Trace(visitor); 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 11d3d59a04b..8e432325bfb 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observation.h @@ -32,7 +32,7 @@ class IDBObservation final : public ScriptWrappable { ~IDBObservation() override; void SetIsolate(v8::Isolate* isolate); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Implement the IDL ScriptValue key(ScriptState*); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.cc index b4caa0796f3..3a3dad1da71 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.cc @@ -98,7 +98,7 @@ void IDBObserver::unobserve(IDBDatabase* database, database->RemoveObservers(observer_ids_to_remove); } -void IDBObserver::Trace(Visitor* visitor) { +void IDBObserver::Trace(Visitor* visitor) const { visitor->Trace(callback_); visitor->Trace(observer_ids_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h index 6ac5fa3d26c..9fb5b65ac7a 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer.h @@ -36,7 +36,7 @@ class MODULES_EXPORT IDBObserver final : public ScriptWrappable { ExceptionState&); void unobserve(IDBDatabase*, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<V8IDBObserverCallback> callback_; diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.cc index 28c5ffe1c79..97cf33aa4cd 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.cc @@ -49,7 +49,7 @@ void IDBObserverChanges::ExtractChanges( } } -void IDBObserverChanges::Trace(Visitor* visitor) { +void IDBObserverChanges::Trace(Visitor* visitor) const { visitor->Trace(database_); visitor->Trace(transaction_); visitor->Trace(records_); diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.h index d4c6ecd12fb..e0dd4ff162b 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_observer_changes.h @@ -25,7 +25,7 @@ class IDBObserverChanges final : public ScriptWrappable { const Vector<Persistent<IDBObservation>>& observations, const Vector<int32_t>& observation_indices); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Implement IDL IDBTransaction* transaction() const { return transaction_.Get(); } diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc index 8bae0d1d458..cd6dfe8f930 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.cc @@ -64,7 +64,7 @@ IDBOpenDBRequest::IDBOpenDBRequest( IDBOpenDBRequest::~IDBOpenDBRequest() = default; -void IDBOpenDBRequest::Trace(Visitor* visitor) { +void IDBOpenDBRequest::Trace(Visitor* visitor) const { visitor->Trace(database_callbacks_); IDBRequest::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h b/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h index 45282c00a41..29ad082975b 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.h @@ -51,7 +51,7 @@ class MODULES_EXPORT IDBOpenDBRequest final : public IDBRequest { mojo::PendingRemote<mojom::blink::ObservedFeature> connection_lifetime); ~IDBOpenDBRequest() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void EnqueueBlocked(int64_t existing_version) override; void EnqueueUpgradeNeeded(int64_t old_version, diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc index 96b9daef25a..a0d71d34b15 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.cc @@ -145,11 +145,15 @@ IDBRequest::IDBRequest(ScriptState* script_state, TaskType::kDatabaseAccess)) {} IDBRequest::~IDBRequest() { - DCHECK((ready_state_ == DONE && metrics_.IsEmpty()) || - ready_state_ == kEarlyDeath || !GetExecutionContext()); + if (!GetExecutionContext()) + return; + if (ready_state_ == DONE) + DCHECK(metrics_.IsEmpty()) << metrics_.trace_event_name(); + else + DCHECK_EQ(ready_state_, kEarlyDeath); } -void IDBRequest::Trace(Visitor* visitor) { +void IDBRequest::Trace(Visitor* visitor) const { visitor->Trace(transaction_); visitor->Trace(source_); visitor->Trace(result_); 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 ed3bf8e446c..4f4997f7282 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_request.h @@ -149,6 +149,8 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData, size_t PopulateForNewEvent(const char* trace_event_name); private: + friend class IDBRequest; + // The name of the async trace events tracked by this instance. // // Null is used to signal that the instance is empty, so the event name @@ -180,7 +182,7 @@ class MODULES_EXPORT IDBRequest : public EventTargetWithInlineData, IDBRequest(ScriptState*, const Source&, IDBTransaction*, AsyncTraceState); ~IDBRequest() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; v8::Isolate* GetIsolate() const { return isolate_; } ScriptValue result(ScriptState*, ExceptionState&); 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 e4c632f56cc..212bd13b97a 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 @@ -175,7 +175,7 @@ class BackendDatabaseWithMockedClose class IDBRequestTest : public testing::Test { protected: void SetUp() override { - url_loader_mock_factory_ = platform_->GetURLLoaderMockFactory(); + url_loader_mock_factory_ = WebURLLoaderMockFactory::GetSingletonInstance(); WebURLResponse response; response.SetCurrentRequestUrl(KURL("blob:")); url_loader_mock_factory_->RegisterURLProtocol(WebString("blob"), response, 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 8a6c2696438..d9403a61087 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.cc @@ -147,7 +147,7 @@ IDBTransaction::~IDBTransaction() { DCHECK(request_list_.IsEmpty() || !GetExecutionContext()); } -void IDBTransaction::Trace(Visitor* visitor) { +void IDBTransaction::Trace(Visitor* visitor) const { visitor->Trace(database_); visitor->Trace(open_db_request_); visitor->Trace(error_); 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 298c182f981..fcc0ce4843e 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_transaction.h @@ -102,7 +102,7 @@ class MODULES_EXPORT IDBTransaction final const IDBDatabaseMetadata&); ~IDBTransaction() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; static mojom::IDBTransactionMode StringToMode(const String&); 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 0dfa392fae3..12a9fcd34ed 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 @@ -78,7 +78,7 @@ class IDBTransactionTest : public testing::Test, public ScopedMockOverlayScrollbars { protected: void SetUp() override { - url_loader_mock_factory_ = platform_->GetURLLoaderMockFactory(); + url_loader_mock_factory_ = WebURLLoaderMockFactory::GetSingletonInstance(); WebURLResponse response; response.SetCurrentRequestUrl(KURL("blob:")); url_loader_mock_factory_->RegisterURLProtocol(WebString("blob"), response, diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.cc b/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.cc index f04f4877bd7..978eee688da 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.cc +++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.cc @@ -66,7 +66,7 @@ const AtomicString& IDBVersionChangeEvent::InterfaceName() const { return event_interface_names::kIDBVersionChangeEvent; } -void IDBVersionChangeEvent::Trace(Visitor* visitor) { +void IDBVersionChangeEvent::Trace(Visitor* visitor) const { Event::Trace(visitor); } 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 93ab233cb01..0a1e0322d43 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 @@ -68,7 +68,7 @@ class IDBVersionChangeEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: uint64_t old_version_; 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 5c0ec1f2105..bc72b01835a 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 @@ -208,8 +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 = mojo::PendingRemote<blink::mojom::blink::Blob>( - info.CloneBlobHandle(), blink::mojom::blink::Blob::Version_); + blob_info->blob = info.CloneBlobRemote(); external_objects.push_back( blink::mojom::blink::IDBExternalObject::NewBlobOrFile( std::move(blob_info))); @@ -257,10 +256,10 @@ bool StructTraits<blink::mojom::IDBValueDataView, value_blob_info.emplace_back( info->uuid, info->file->name, info->mime_type, blink::NullableTimeToOptionalTime(info->file->last_modified), - info->size, info->blob.PassPipe()); + info->size, std::move(info->blob)); } else { value_blob_info.emplace_back(info->uuid, info->mime_type, info->size, - info->blob.PassPipe()); + std::move(info->blob)); } break; } 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 4b9e3f9ad36..56a2da16f1b 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 @@ -271,7 +271,7 @@ class OpenDatabaseCallback final : public NativeEventListener { idb_database->close(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(script_state_); NativeEventListener::Trace(visitor); } @@ -610,7 +610,7 @@ class OpenCursorCallback final : public NativeEventListener { request_callback_->sendSuccess(std::move(result_), has_more); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(script_state_); NativeEventListener::Trace(visitor); } @@ -1187,7 +1187,7 @@ void InspectorIndexedDBAgent::deleteDatabase( false); } -void InspectorIndexedDBAgent::Trace(Visitor* visitor) { +void InspectorIndexedDBAgent::Trace(Visitor* visitor) const { visitor->Trace(inspected_frames_); InspectorBaseAgent::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h b/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h index f584276e2f8..16d2c8631ce 100644 --- a/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h +++ b/chromium/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.h @@ -47,7 +47,7 @@ class MODULES_EXPORT InspectorIndexedDBAgent final public: InspectorIndexedDBAgent(InspectedFrames*, v8_inspector::V8InspectorSession*); ~InspectorIndexedDBAgent() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void Restore() override; void DidCommitLoadForLocalFrame(LocalFrame*) override; 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 410a9a9d182..37ce41a18e9 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 @@ -105,7 +105,7 @@ void InstalledAppController::OnFilterInstalledApps( callbacks->OnSuccess(applications); } -void InstalledAppController::Trace(Visitor* visitor) { +void InstalledAppController::Trace(Visitor* visitor) const { visitor->Trace(provider_); Supplement<LocalDOMWindow>::Trace(visitor); ExecutionContextClient::Trace(visitor); 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 71ac9b24463..37d31d2895b 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 @@ -46,7 +46,7 @@ class MODULES_EXPORT InstalledAppController final static InstalledAppController* From(LocalDOMWindow&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Callback for the result of GetInstalledRelatedApps. diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc index 02fdf05b106..07a9ec15c8d 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc +++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.cc @@ -33,7 +33,7 @@ ScriptPromise Keyboard::getLayoutMap(ScriptState* state, return keyboard_layout_->GetKeyboardLayoutMap(state, exception_state); } -void Keyboard::Trace(Visitor* visitor) { +void Keyboard::Trace(Visitor* visitor) const { visitor->Trace(keyboard_lock_); visitor->Trace(keyboard_layout_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.h b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.h index c1e9a3fecb4..1e53101c0af 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard.h +++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard.h @@ -31,7 +31,7 @@ class Keyboard final : public ScriptWrappable { ScriptPromise getLayoutMap(ScriptState*, ExceptionState&); // ScriptWrappable override. - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<KeyboardLock> keyboard_lock_; 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 e6982582103..d6717d40636 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc +++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.cc @@ -116,7 +116,7 @@ void KeyboardLayout::GotKeyboardLayoutMap( script_promise_resolver_ = nullptr; } -void KeyboardLayout::Trace(Visitor* visitor) { +void KeyboardLayout::Trace(Visitor* visitor) const { visitor->Trace(script_promise_resolver_); visitor->Trace(service_); ExecutionContextClient::Trace(visitor); 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 526fc436ed4..eee27364fd1 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h +++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout.h @@ -29,7 +29,7 @@ class KeyboardLayout final : public GarbageCollected<KeyboardLayout>, ScriptPromise GetKeyboardLayoutMap(ScriptState*, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Returns true if the local frame is attached to the renderer. diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.cc b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.cc index bac1738b672..ac3741ce6f5 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.cc +++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.cc @@ -24,7 +24,7 @@ class KeyboardLayoutMapIterationSource final return true; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(map_); PairIterable<String, String>::IterationSource::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h index 007bda236b3..a73e8ebd609 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h +++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.h @@ -25,7 +25,9 @@ class KeyboardLayoutMap final : public ScriptWrappable, // IDL attributes / methods uint32_t size() const { return layout_map_.size(); } - void Trace(Visitor* visitor) override { ScriptWrappable::Trace(visitor); } + void Trace(Visitor* visitor) const override { + ScriptWrappable::Trace(visitor); + } private: // Maplike implementation. 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 7d979c12f11..cdf99fdfbcf 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc +++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.cc @@ -155,7 +155,7 @@ void KeyboardLock::LockRequestFinished( request_keylock_resolver_ = nullptr; } -void KeyboardLock::Trace(Visitor* visitor) { +void KeyboardLock::Trace(Visitor* visitor) const { visitor->Trace(service_); visitor->Trace(request_keylock_resolver_); ExecutionContextClient::Trace(visitor); 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 c583f19ccc7..c8dfbd09918 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h +++ b/chromium/third_party/blink/renderer/modules/keyboard/keyboard_lock.h @@ -30,7 +30,7 @@ class KeyboardLock final : public GarbageCollected<KeyboardLock>, ScriptPromise lock(ScriptState*, const Vector<String>&, ExceptionState&); void unlock(ScriptState*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Returns true if the local frame is attached to the renderer. diff --git a/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc b/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc index 74bec5bad5c..bb3aad01275 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc +++ b/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.cc @@ -30,7 +30,7 @@ Keyboard* NavigatorKeyboard::keyboard(Navigator& navigator) { return supplement->keyboard_; } -void NavigatorKeyboard::Trace(Visitor* visitor) { +void NavigatorKeyboard::Trace(Visitor* visitor) const { visitor->Trace(keyboard_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.h b/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.h index 332b0d24f38..ac491280e4e 100644 --- a/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.h +++ b/chromium/third_party/blink/renderer/modules/keyboard/navigator_keyboard.h @@ -26,7 +26,7 @@ class NavigatorKeyboard final : public GarbageCollected<NavigatorKeyboard>, explicit NavigatorKeyboard(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<Keyboard> keyboard_; diff --git a/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc b/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc index 03084803c8e..17959aae866 100644 --- a/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc +++ b/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc @@ -29,7 +29,7 @@ void DOMWindowLaunchQueue::UpdateLaunchFiles( MakeGarbageCollected<LaunchParams>(std::move(files))); } -void DOMWindowLaunchQueue::Trace(Visitor* visitor) { +void DOMWindowLaunchQueue::Trace(Visitor* visitor) const { visitor->Trace(launch_queue_); Supplement<LocalDOMWindow>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h b/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h index 1df758fedc9..a18f4eee18a 100644 --- a/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h +++ b/chromium/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h @@ -36,7 +36,7 @@ class DOMWindowLaunchQueue final static void UpdateLaunchFiles(LocalDOMWindow*, HeapVector<Member<NativeFileSystemHandle>>); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: static DOMWindowLaunchQueue* FromState(LocalDOMWindow* window); diff --git a/chromium/third_party/blink/renderer/modules/launch/launch_params.cc b/chromium/third_party/blink/renderer/modules/launch/launch_params.cc index e90b0d00099..a02768ab8ee 100644 --- a/chromium/third_party/blink/renderer/modules/launch/launch_params.cc +++ b/chromium/third_party/blink/renderer/modules/launch/launch_params.cc @@ -14,7 +14,7 @@ LaunchParams::LaunchParams(HeapVector<Member<NativeFileSystemHandle>> files) LaunchParams::~LaunchParams() = default; -void LaunchParams::Trace(Visitor* visitor) { +void LaunchParams::Trace(Visitor* visitor) const { visitor->Trace(files_); ScriptWrappable::Trace(visitor); } 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 44c12302404..eac86d952c6 100644 --- a/chromium/third_party/blink/renderer/modules/launch/launch_params.h +++ b/chromium/third_party/blink/renderer/modules/launch/launch_params.h @@ -24,7 +24,7 @@ class LaunchParams final : public ScriptWrappable { // LaunchParams IDL interface. const HeapVector<Member<NativeFileSystemHandle>>& files() { return files_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: HeapVector<Member<NativeFileSystemHandle>> files_; diff --git a/chromium/third_party/blink/renderer/modules/launch/launch_queue.cc b/chromium/third_party/blink/renderer/modules/launch/launch_queue.cc index 9c2e9ca30cc..20fe5975b2d 100644 --- a/chromium/third_party/blink/renderer/modules/launch/launch_queue.cc +++ b/chromium/third_party/blink/renderer/modules/launch/launch_queue.cc @@ -38,7 +38,7 @@ void LaunchQueue::setConsumer(V8LaunchConsumer* consumer) { } } -void LaunchQueue::Trace(Visitor* visitor) { +void LaunchQueue::Trace(Visitor* visitor) const { visitor->Trace(unconsumed_launch_params_); visitor->Trace(consumer_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/launch/launch_queue.h b/chromium/third_party/blink/renderer/modules/launch/launch_queue.h index b683f1e21d1..7651232b430 100644 --- a/chromium/third_party/blink/renderer/modules/launch/launch_queue.h +++ b/chromium/third_party/blink/renderer/modules/launch/launch_queue.h @@ -28,7 +28,7 @@ class LaunchQueue final : public ScriptWrappable { void setConsumer(V8LaunchConsumer*); // ScriptWrappable: - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: HeapVector<Member<LaunchParams>> unconsumed_launch_params_; diff --git a/chromium/third_party/blink/renderer/modules/locks/lock.cc b/chromium/third_party/blink/renderer/modules/locks/lock.cc index d1ad92ec67b..b388d592287 100644 --- a/chromium/third_party/blink/renderer/modules/locks/lock.cc +++ b/chromium/third_party/blink/renderer/modules/locks/lock.cc @@ -39,7 +39,7 @@ class Lock::ThenFunction final : public ScriptFunction { ThenFunction(ScriptState* script_state, Lock* lock, ResolveType type) : ScriptFunction(script_state), lock_(lock), resolve_type_(type) {} - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(lock_); ScriptFunction::Trace(visitor); } @@ -124,7 +124,7 @@ void Lock::ContextDestroyed() { ReleaseIfHeld(); } -void Lock::Trace(Visitor* visitor) { +void Lock::Trace(Visitor* visitor) const { ExecutionContextLifecycleObserver::Trace(visitor); ScriptWrappable::Trace(visitor); visitor->Trace(resolver_); diff --git a/chromium/third_party/blink/renderer/modules/locks/lock.h b/chromium/third_party/blink/renderer/modules/locks/lock.h index cb28dd9c2e2..bd37cb0892c 100644 --- a/chromium/third_party/blink/renderer/modules/locks/lock.h +++ b/chromium/third_party/blink/renderer/modules/locks/lock.h @@ -36,7 +36,7 @@ class Lock final : public ScriptWrappable, LockManager*); ~Lock() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Lock.idl String name() const { return name_; } 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 b1ce0b4ce05..489c674052d 100644 --- a/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc +++ b/chromium/third_party/blink/renderer/modules/locks/lock_manager.cc @@ -88,7 +88,7 @@ class LockManager::LockRequestImpl final ~LockRequestImpl() override = default; - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(resolver_); visitor->Trace(manager_); visitor->Trace(callback_); @@ -414,7 +414,7 @@ bool LockManager::IsPendingRequest(LockRequestImpl* request) { return pending_requests_.Contains(request); } -void LockManager::Trace(Visitor* visitor) { +void LockManager::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); visitor->Trace(pending_requests_); 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 98e86bbbb7b..91805925304 100644 --- a/chromium/third_party/blink/renderer/modules/locks/lock_manager.h +++ b/chromium/third_party/blink/renderer/modules/locks/lock_manager.h @@ -44,7 +44,7 @@ class LockManager final : public ScriptWrappable, ScriptPromise query(ScriptState*, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Terminate all outstanding requests when the context is destroyed, since // this can unblock requests by other contexts. diff --git a/chromium/third_party/blink/renderer/modules/locks/navigator_locks.cc b/chromium/third_party/blink/renderer/modules/locks/navigator_locks.cc index f7e7d1f91a3..23f56830bf4 100644 --- a/chromium/third_party/blink/renderer/modules/locks/navigator_locks.cc +++ b/chromium/third_party/blink/renderer/modules/locks/navigator_locks.cc @@ -43,7 +43,7 @@ class NavigatorLocksImpl final : public GarbageCollected<NavigatorLocksImpl<T>>, return lock_manager_.Get(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(lock_manager_); Supplement<T>::Trace(visitor); } 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 1fe95c562e8..d98302cf579 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 @@ -102,8 +102,10 @@ blink::mojom::blink::ManifestImageResourcePtr TypeConverter< image_resource) { auto image_resource_ptr = blink::mojom::blink::ManifestImageResource::New(); image_resource_ptr->src = blink::KURL(image_resource->src()); - image_resource_ptr->sizes = ParseSizes(image_resource->sizes()); - image_resource_ptr->purpose = ParsePurpose(image_resource->purpose()); + if (image_resource->hasSizes()) + image_resource_ptr->sizes = ParseSizes(image_resource->sizes()); + if (image_resource->hasPurpose()) + image_resource_ptr->purpose = ParsePurpose(image_resource->purpose()); image_resource_ptr->type = ParseType(image_resource->type()); return image_resource_ptr; } diff --git a/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.cc b/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.cc index ddf452fa9bb..18d81314bf1 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.cc +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_change_notifier.cc @@ -18,7 +18,7 @@ ManifestChangeNotifier::ManifestChangeNotifier(LocalDOMWindow& window) ManifestChangeNotifier::~ManifestChangeNotifier() = default; -void ManifestChangeNotifier::Trace(Visitor* visitor) { +void ManifestChangeNotifier::Trace(Visitor* visitor) const { visitor->Trace(window_); visitor->Trace(manifest_change_observer_); } 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 9db2f5cf4c7..812f798e6a3 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 @@ -22,7 +22,7 @@ class MODULES_EXPORT ManifestChangeNotifier explicit ManifestChangeNotifier(LocalDOMWindow& window); virtual ~ManifestChangeNotifier(); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; virtual void DidChangeManifest(); 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 32fac093f64..d43b8e65563 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.cc @@ -8,6 +8,7 @@ #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" #include "third_party/blink/renderer/core/loader/threadable_loader.h" +#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" namespace blink { @@ -18,6 +19,7 @@ ManifestFetcher::~ManifestFetcher() = default; void ManifestFetcher::Start(LocalDOMWindow& window, bool use_credentials, + ResourceFetcher* resource_fetcher, ManifestFetcher::Callback callback) { callback_ = std::move(callback); @@ -33,8 +35,8 @@ void ManifestFetcher::Start(LocalDOMWindow& window, ResourceLoaderOptions resource_loader_options; resource_loader_options.data_buffering_policy = kDoNotBufferData; - loader_ = MakeGarbageCollected<ThreadableLoader>(window, this, - resource_loader_options); + loader_ = MakeGarbageCollected<ThreadableLoader>( + window, this, resource_loader_options, resource_fetcher); loader_->Start(std::move(request)); } @@ -88,7 +90,7 @@ void ManifestFetcher::DidFailRedirectCheck() { DidFail(ResourceError::Failure(NullURL())); } -void ManifestFetcher::Trace(Visitor* visitor) { +void ManifestFetcher::Trace(Visitor* visitor) const { visitor->Trace(loader_); ThreadableLoaderClient::Trace(visitor); } 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 ab79172e7c7..0b6fb284949 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.h +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_fetcher.h @@ -12,6 +12,7 @@ #include "third_party/blink/renderer/core/loader/threadable_loader_client.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/member.h" +#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -40,6 +41,7 @@ class ManifestFetcher final : public GarbageCollected<ManifestFetcher>, void Start(LocalDOMWindow& window, bool use_credentials, + ResourceFetcher* resource_fetcher, ManifestFetcher::Callback callback); void Cancel(); @@ -50,7 +52,7 @@ class ManifestFetcher final : public GarbageCollected<ManifestFetcher>, void DidFail(const ResourceError&) override; void DidFailRedirectCheck() override; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: KURL url_; 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 1ea4f4ea4f5..58df39c2d5b 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.cc @@ -156,8 +156,9 @@ void ManifestManager::FetchManifest() { } LocalDOMWindow& window = *GetSupplementable(); + ResourceFetcher* document_fetcher = window.document()->Fetcher(); fetcher_ = MakeGarbageCollected<ManifestFetcher>(manifest_url_); - fetcher_->Start(window, ManifestUseCredentials(), + fetcher_->Start(window, ManifestUseCredentials(), document_fetcher, WTF::Bind(&ManifestManager::OnManifestFetchComplete, WrapWeakPersistent(this), window.Url())); } @@ -259,7 +260,7 @@ void ManifestManager::ContextDestroyed() { ResolveCallbacks(ResolveStateFailure); } -void ManifestManager::Trace(Visitor* visitor) { +void ManifestManager::Trace(Visitor* visitor) const { visitor->Trace(fetcher_); visitor->Trace(manifest_change_notifier_); visitor->Trace(receivers_); 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 692c83789c1..2a1b8dd19f5 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_manager.h @@ -62,7 +62,7 @@ class MODULES_EXPORT ManifestManager void RequestManifestDebugInfo( RequestManifestDebugInfoCallback callback) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: enum ResolveState { ResolveStateSuccess, ResolveStateFailure }; 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 ecd54713a6d..8a80176fb46 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.cc @@ -12,7 +12,9 @@ #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/renderer/core/css/parser/css_parser.h" #include "third_party/blink/renderer/modules/manifest/manifest_uma_util.h" +#include "third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h" #include "third_party/blink/renderer/platform/json/json_parser.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.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/string_utf8_adaptor.h" @@ -82,6 +84,7 @@ void ManifestParser::Parse() { manifest_->share_target = std::move(*share_target); manifest_->file_handlers = ParseFileHandlers(root_object.get()); + manifest_->protocol_handlers = ParseProtocolHandlers(root_object.get()); manifest_->related_applications = ParseRelatedApplications(root_object.get()); manifest_->prefer_related_applications = @@ -850,6 +853,98 @@ bool ManifestParser::ParseFileHandlerAcceptExtension(const JSONValue* extension, return true; } +Vector<mojom::blink::ManifestProtocolHandlerPtr> +ManifestParser::ParseProtocolHandlers(const JSONObject* from) { + Vector<mojom::blink::ManifestProtocolHandlerPtr> protocols; + if (!RuntimeEnabledFeatures::ParseUrlProtocolHandlerEnabled() || + !from->Get("protocol_handlers")) { + return protocols; + } + + JSONArray* protocol_list = from->GetArray("protocol_handlers"); + if (!protocol_list) { + AddErrorInfo("property 'protocol_handlers' ignored, type array expected."); + return protocols; + } + + for (wtf_size_t i = 0; i < protocol_list->size(); ++i) { + const JSONObject* protocol_object = JSONObject::Cast(protocol_list->at(i)); + if (!protocol_object) { + AddErrorInfo("protocol_handlers entry ignored, type object expected."); + continue; + } + + base::Optional<mojom::blink::ManifestProtocolHandlerPtr> protocol = + ParseProtocolHandler(protocol_object); + if (!protocol) + continue; + + protocols.push_back(std::move(protocol.value())); + } + + return protocols; +} + +base::Optional<mojom::blink::ManifestProtocolHandlerPtr> +ManifestParser::ParseProtocolHandler(const JSONObject* object) { + DCHECK(RuntimeEnabledFeatures::ParseUrlProtocolHandlerEnabled()); + if (!object->Get("protocol")) { + AddErrorInfo( + "protocol_handlers entry ignored, required property 'protocol' is " + "missing."); + return base::nullopt; + } + + auto protocol_handler = mojom::blink::ManifestProtocolHandler::New(); + base::Optional<String> protocol = ParseString(object, "protocol", Trim); + String error_message; + bool is_valid_protocol = protocol.has_value(); + + if (is_valid_protocol && + !VerifyCustomHandlerScheme(protocol.value(), error_message)) { + AddErrorInfo(error_message); + is_valid_protocol = false; + } + + if (!is_valid_protocol) { + AddErrorInfo( + "protocol_handlers entry ignored, required property 'protocol' is " + "invalid."); + return base::nullopt; + } + protocol_handler->protocol = protocol.value(); + + if (!object->Get("url")) { + AddErrorInfo( + "protocol_handlers entry ignored, required property 'url' is missing."); + return base::nullopt; + } + protocol_handler->url = ParseURL(object, "url", manifest_url_, + ParseURLOriginRestrictions::kSameOriginOnly); + bool is_valid_url = protocol_handler->url.IsValid(); + if (is_valid_url) { + const char kToken[] = "%s"; + String user_url = protocol_handler->url.GetString(); + String tokenless_url = protocol_handler->url.GetString(); + tokenless_url.Remove(user_url.Find(kToken), base::size(kToken) - 1); + KURL full_url(manifest_url_, tokenless_url); + + if (!VerifyCustomHandlerURLSyntax(full_url, manifest_url_, user_url, + error_message)) { + AddErrorInfo(error_message); + is_valid_url = false; + } + } + + if (!is_valid_url) { + AddErrorInfo( + "protocol_handlers entry ignored, required property 'url' is invalid."); + return base::nullopt; + } + + return std::move(protocol_handler); +} + String ManifestParser::ParseRelatedApplicationPlatform( const JSONObject* application) { base::Optional<String> platform = ParseString(application, "platform", Trim); 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 ff29cd4c72c..def6a447bc8 100644 --- a/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h +++ b/chromium/third_party/blink/renderer/modules/manifest/manifest_parser.h @@ -269,6 +269,25 @@ class MODULES_EXPORT ManifestParser { bool ParseFileHandlerAcceptExtension(const JSONValue* extension, String* ouput); + // Parses the 'protocol_handlers' field of a Manifest, as defined in: + // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/URLProtocolHandler/explainer.md + // Returns the parsed list of ProtocolHandlers. The returned ProtocolHandlers + // are empty if the field didn't exist, parsing failed, or the input list was + // empty. + // This feature is experimental and would only be enabled behind the blink + // feature flag: RuntimeEnabledFeatures::ParseUrlProtocolHandlerEnabled() + Vector<mojom::blink::ManifestProtocolHandlerPtr> ParseProtocolHandlers( + const JSONObject* object); + + // Parses a single ProtocolHandle field of a Manifest, as defined in: + // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/URLProtocolHandler/explainer.md + // Returns |base::nullopt| if the ProtocolHandler was invalid, or a + // ProtocolHandler if parsing succeeded. + // This feature is experimental and should only be used behind the blink + // feature flag: RuntimeEnabledFeatures::ParseUrlProtocolHandlerEnabled() + base::Optional<mojom::blink::ManifestProtocolHandlerPtr> ParseProtocolHandler( + const JSONObject* protocol_dictionary); + // Parses the 'platform' field of a related application, as defined in: // https://w3c.github.io/manifest/#dfn-steps-for-processing-the-platform-member-of-an-application // Returns the parsed string if any, a null string if the parsing failed. 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 62738df4543..b64e15008aa 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 @@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/optional.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" namespace blink { @@ -1867,6 +1868,206 @@ TEST_F(ManifestParserTest, FileHandlerParseRules) { } } +TEST_F(ManifestParserTest, ProtocolHandlerParseRules) { + // Does not contain protocol_handlers field. + { + auto& manifest = ParseManifest("{ }"); + ASSERT_EQ(0u, GetErrorCount()); + EXPECT_EQ(0u, manifest->protocol_handlers.size()); + } + + // protocol_handlers is not an array. + { + auto& manifest = ParseManifest("{ \"protocol_handlers\": { } }"); + EXPECT_EQ(1u, GetErrorCount()); + EXPECT_EQ("property 'protocol_handlers' ignored, type array expected.", + errors()[0]); + EXPECT_EQ(0u, manifest->protocol_handlers.size()); + } + + // Contains protocol_handlers field but no protocol handlers. + { + auto& manifest = ParseManifest("{ \"protocol_handlers\": [ ] }"); + ASSERT_EQ(0u, GetErrorCount()); + EXPECT_EQ(0u, manifest->protocol_handlers.size()); + } + + // Entries must be objects + { + auto& manifest = ParseManifest( + "{" + " \"protocol_handlers\": [" + " \"hello world\"" + " ]" + "}"); + ASSERT_EQ(1u, GetErrorCount()); + EXPECT_EQ("protocol_handlers entry ignored, type object expected.", + errors()[0]); + EXPECT_EQ(0u, manifest->protocol_handlers.size()); + } + + // A valid protocol handler. + { + auto& manifest = ParseManifest( + "{" + " \"protocol_handlers\": [" + " {" + " \"protocol\": \"web+github\"," + " \"url\": \"http://foo.com/?profile=%s\"" + " }" + " ]" + "}"); + auto& protocol_handlers = manifest->protocol_handlers; + + ASSERT_EQ(0u, GetErrorCount()); + ASSERT_EQ(1u, protocol_handlers.size()); + + ASSERT_EQ("web+github", protocol_handlers[0]->protocol); + ASSERT_EQ("http://foo.com/?profile=%s", protocol_handlers[0]->url); + } + + // An invalid protocol handler with the URL not being from the same origin. + { + auto& manifest = ParseManifest( + "{" + " \"protocol_handlers\": [" + " {" + " \"protocol\": \"web+github\"," + " \"url\": \"http://bar.com/?profile=%s\"" + " }" + " ]" + "}"); + auto& protocol_handlers = manifest->protocol_handlers; + + ASSERT_EQ(2u, GetErrorCount()); + EXPECT_EQ("property 'url' ignored, should be same origin as document.", + errors()[0]); + EXPECT_EQ( + "protocol_handlers entry ignored, required property 'url' is invalid.", + errors()[1]); + ASSERT_EQ(0u, protocol_handlers.size()); + } + + // An invalid protocol handler with no value for protocol. + { + auto& manifest = ParseManifest( + "{" + " \"protocol_handlers\": [" + " {" + " \"url\": \"http://foo.com/?profile=%s\"" + " }" + " ]" + "}"); + auto& protocol_handlers = manifest->protocol_handlers; + + ASSERT_EQ(1u, GetErrorCount()); + EXPECT_EQ( + "protocol_handlers entry ignored, required property 'protocol' is " + "missing.", + errors()[0]); + ASSERT_EQ(0u, protocol_handlers.size()); + } + + // An invalid protocol handler with no url. + { + auto& manifest = ParseManifest( + "{" + " \"protocol_handlers\": [" + " {" + " \"protocol\": \"web+github\"" + " }" + " ]" + "}"); + auto& protocol_handlers = manifest->protocol_handlers; + + ASSERT_EQ(1u, GetErrorCount()); + EXPECT_EQ( + "protocol_handlers entry ignored, required property 'url' is missing.", + errors()[0]); + ASSERT_EQ(0u, protocol_handlers.size()); + } + + // An invalid protocol handler with a url that doesn't contain the %s token. + { + auto& manifest = ParseManifest( + "{" + " \"protocol_handlers\": [" + " {" + " \"protocol\": \"web+github\"," + " \"url\": \"http://foo.com/?profile=\"" + " }" + " ]" + "}"); + auto& protocol_handlers = manifest->protocol_handlers; + + ASSERT_EQ(2u, GetErrorCount()); + EXPECT_EQ( + "The url provided ('http://foo.com/?profile=') does not contain '%s'.", + errors()[0]); + EXPECT_EQ( + "protocol_handlers entry ignored, required property 'url' is invalid.", + errors()[1]); + ASSERT_EQ(0u, protocol_handlers.size()); + } + + // An invalid protocol handler with a non-allowed protocol. + { + auto& manifest = ParseManifest( + "{" + " \"protocol_handlers\": [" + " {" + " \"protocol\": \"github\"," + " \"url\": \"http://foo.com/?profile=\"" + " }" + " ]" + "}"); + auto& protocol_handlers = manifest->protocol_handlers; + + ASSERT_EQ(2u, GetErrorCount()); + EXPECT_EQ( + "The scheme 'github' doesn't belong to the scheme allowlist. Please " + "prefix non-allowlisted schemes with the string 'web+'.", + errors()[0]); + EXPECT_EQ( + "protocol_handlers entry ignored, required property 'protocol' is " + "invalid.", + errors()[1]); + ASSERT_EQ(0u, protocol_handlers.size()); + } + + // Multiple valid protocol handlers + { + auto& manifest = ParseManifest( + "{" + " \"protocol_handlers\": [" + " {" + " \"protocol\": \"web+github\"," + " \"url\": \"http://foo.com/?profile=%s\"" + " }," + " {" + " \"protocol\": \"web+test\"," + " \"url\": \"http://foo.com/?test=%s\"" + " }," + " {" + " \"protocol\": \"web+relative\"," + " \"url\": \"relativeURL=%s\"" + " }" + " ]" + "}"); + auto& protocol_handlers = manifest->protocol_handlers; + + ASSERT_EQ(0u, GetErrorCount()); + ASSERT_EQ(3u, protocol_handlers.size()); + + ASSERT_EQ("web+github", protocol_handlers[0]->protocol); + ASSERT_EQ("http://foo.com/?profile=%s", protocol_handlers[0]->url); + ASSERT_EQ("web+test", protocol_handlers[1]->protocol); + ASSERT_EQ("http://foo.com/?test=%s", protocol_handlers[1]->url); + ASSERT_EQ("web+relative", protocol_handlers[2]->protocol); + ASSERT_EQ("http://foo.com/relativeURL=%s", protocol_handlers[2]->url); + } +} + TEST_F(ManifestParserTest, ShareTargetParseRules) { // Contains share_target field but no keys. { 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 54496503116..5b7c0967506 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 @@ -52,6 +52,11 @@ TypeConverter<blink::Manifest, blink::mojom::blink::ManifestPtr>::Convert( output.file_handlers.push_back(entry.To<blink::Manifest::FileHandler>()); } + for (auto& uri_protocol : input->protocol_handlers) { + output.protocol_handlers.push_back( + uri_protocol.To<blink::Manifest::ProtocolHandler>()); + } + for (auto& related_application : input->related_applications) { output.related_applications.push_back( related_application.To<blink::Manifest::RelatedApplication>()); @@ -225,6 +230,18 @@ TypeConverter<blink::Manifest::FileHandler, return output; } +blink::Manifest::ProtocolHandler +TypeConverter<blink::Manifest::ProtocolHandler, + blink::mojom::blink::ManifestProtocolHandlerPtr>:: + Convert(const blink::mojom::blink::ManifestProtocolHandlerPtr& input) { + blink::Manifest::ProtocolHandler output; + if (input.is_null()) + return output; + output.protocol = blink::WebString(input->protocol).Utf16(); + output.url = input->url; + return output; +} + blink::Manifest::RelatedApplication TypeConverter<blink::Manifest::RelatedApplication, blink::mojom::blink::ManifestRelatedApplicationPtr>:: 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 ffb17b076c2..7d96fb6e5f4 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 @@ -67,6 +67,13 @@ struct TypeConverter<blink::Manifest::FileHandler, }; template <> +struct TypeConverter<blink::Manifest::ProtocolHandler, + blink::mojom::blink::ManifestProtocolHandlerPtr> { + static blink::Manifest::ProtocolHandler Convert( + const blink::mojom::blink::ManifestProtocolHandlerPtr& input); +}; + +template <> struct TypeConverter<blink::Manifest::RelatedApplication, blink::mojom::blink::ManifestRelatedApplicationPtr> { static blink::Manifest::RelatedApplication Convert( diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/DEPS b/chromium/third_party/blink/renderer/modules/media_capabilities/DEPS index 02607e024ed..3b8d2749b4f 100644 --- a/chromium/third_party/blink/renderer/modules/media_capabilities/DEPS +++ b/chromium/third_party/blink/renderer/modules/media_capabilities/DEPS @@ -7,6 +7,8 @@ include_rules = [ "+media/mojo/mojom/media_types.mojom-blink.h", "+media/mojo/mojom/video_decode_perf_history.mojom-blink.h", "+media/mojo/mojom/media_metrics_provider.mojom-blink.h", + "+media/video/gpu_video_accelerator_factories.h", + "+media/video/supported_video_decoder_config.h", "-third_party/blink/renderer/modules", "+third_party/blink/renderer/modules/encryptedmedia", "+third_party/blink/renderer/modules/media_capabilities", @@ -20,5 +22,6 @@ specific_include_rules = { "+base/strings/string_number_conversions.h", "+base/test/bind_test_util.h", "+media/mojo/mojom/watch_time_recorder.mojom-blink.h", + "+media/video/mock_gpu_video_accelerator_factories.h", ], }
\ No newline at end of file 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 f6675530f49..d571e609430 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 @@ -10,19 +10,25 @@ #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" +#include "base/metrics/histogram_macros.h" #include "base/optional.h" #include "media/base/media_switches.h" +#include "media/base/media_util.h" #include "media/base/mime_util.h" #include "media/base/supported_types.h" +#include "media/base/video_decoder_config.h" #include "media/filters/stream_parser_factory.h" #include "media/learning/common/media_learning_tasks.h" #include "media/learning/common/target_histogram.h" #include "media/learning/mojo/public/mojom/learning_task_controller.mojom-blink.h" #include "media/mojo/mojom/media_metrics_provider.mojom-blink.h" #include "media/mojo/mojom/media_types.mojom-blink.h" +#include "media/video/gpu_video_accelerator_factories.h" +#include "media/video/supported_video_decoder_config.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/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" @@ -55,6 +61,7 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #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/heap/persistent.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" @@ -62,6 +69,8 @@ #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" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" namespace blink { @@ -104,6 +113,24 @@ double GetLearningNnrThreshold() { kLearningNnrThresholdDefault); } +// static +bool UseGpuFactoriesForPowerEfficient( + ExecutionContext* execution_context, + const MediaKeySystemAccess* key_system_access) { + // TODO(1105258): GpuFactories isn't available in worker scope yet. + if (!execution_context || execution_context->IsWorkerGlobalScope()) + return false; + + // TODO(1105258): Decoding w/ EME often means we can't use the GPU accelerated + // path. Add additional logic to detect when GPU acceleration is really + // available. + if (key_system_access) + return false; + + return base::FeatureList::IsEnabled( + media::kMediaCapabilitiesQueryGpuFactories); +} + // Utility function that will create a MediaCapabilitiesDecodingInfo object with // all the values set to either true or false. MediaCapabilitiesDecodingInfo* CreateDecodingInfoWith(bool value) { @@ -167,7 +194,7 @@ class MediaCapabilitiesKeySystemAccessInitializer final resolver_->Resolve(info); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { MediaKeySystemAccessInitializerBase::Trace(visitor); } @@ -377,43 +404,48 @@ void ParseDynamicRangeConfigurations( // discrepancies between mime type and colorGamut/transferFunction; for now, // give precedence to the latter. - const String& hdr_metadata_type = video_config->hdrMetadataType(); - if (hdr_metadata_type == kSmpteSt2086HdrMetadataType) { - *hdr_metadata = media::HdrMetadataType::kSmpteSt2086; - } else if (hdr_metadata_type == kSmpteSt209410HdrMetadataType) { - *hdr_metadata = media::HdrMetadataType::kSmpteSt2094_10; - } else if (hdr_metadata_type == kSmpteSt209440HdrMetadataType) { - *hdr_metadata = media::HdrMetadataType::kSmpteSt2094_40; - } else if (hdr_metadata_type.IsNull()) { - *hdr_metadata = media::HdrMetadataType::kNone; + if (video_config->hasHdrMetadataType()) { + const auto& hdr_metadata_type = video_config->hdrMetadataType(); + // TODO(crbug.com/1092328): Switch by V8HdrMetadataType::Enum. + if (hdr_metadata_type == kSmpteSt2086HdrMetadataType) { + *hdr_metadata = media::HdrMetadataType::kSmpteSt2086; + } else if (hdr_metadata_type == kSmpteSt209410HdrMetadataType) { + *hdr_metadata = media::HdrMetadataType::kSmpteSt2094_10; + } else if (hdr_metadata_type == kSmpteSt209440HdrMetadataType) { + *hdr_metadata = media::HdrMetadataType::kSmpteSt2094_40; + } else { + NOTREACHED(); + } } else { - NOTREACHED(); + *hdr_metadata = media::HdrMetadataType::kNone; } - const String& color_gamut = video_config->colorGamut(); - if (color_gamut == kSrgbColorGamut) { - color_space->primaries = media::VideoColorSpace::PrimaryID::BT709; - } else if (color_gamut == kP3ColorGamut) { - color_space->primaries = media::VideoColorSpace::PrimaryID::SMPTEST431_2; - } else if (color_gamut == kRec2020ColorGamut) { - color_space->primaries = media::VideoColorSpace::PrimaryID::BT2020; - } else if (color_gamut.IsNull()) { - // Leave |color_space->primaries| as-is. - } else { - NOTREACHED(); + if (video_config->hasColorGamut()) { + const auto& color_gamut = video_config->colorGamut(); + // TODO(crbug.com/1092328): Switch by V8ColorGamut::Enum. + if (color_gamut == kSrgbColorGamut) { + color_space->primaries = media::VideoColorSpace::PrimaryID::BT709; + } else if (color_gamut == kP3ColorGamut) { + color_space->primaries = media::VideoColorSpace::PrimaryID::SMPTEST431_2; + } else if (color_gamut == kRec2020ColorGamut) { + color_space->primaries = media::VideoColorSpace::PrimaryID::BT2020; + } else { + NOTREACHED(); + } } - const String& transfer_function = video_config->transferFunction(); - if (transfer_function == kSrgbTransferFunction) { - color_space->transfer = media::VideoColorSpace::TransferID::BT709; - } else if (transfer_function == kPqTransferFunction) { - color_space->transfer = media::VideoColorSpace::TransferID::SMPTEST2084; - } else if (transfer_function == kHlgTransferFunction) { - color_space->transfer = media::VideoColorSpace::TransferID::ARIB_STD_B67; - } else if (transfer_function.IsNull()) { - // Leave |color_space->transfer| as-is. - } else { - NOTREACHED(); + if (video_config->hasTransferFunction()) { + const auto& transfer_function = video_config->transferFunction(); + // TODO(crbug.com/1092328): Switch by V8TransferFunction::Enum. + if (transfer_function == kSrgbTransferFunction) { + color_space->transfer = media::VideoColorSpace::TransferID::BT709; + } else if (transfer_function == kPqTransferFunction) { + color_space->transfer = media::VideoColorSpace::TransferID::SMPTEST2084; + } else if (transfer_function == kHlgTransferFunction) { + color_space->transfer = media::VideoColorSpace::TransferID::ARIB_STD_B67; + } else { + NOTREACHED(); + } } } @@ -507,16 +539,14 @@ bool IsAudioConfigurationSupported( // Returns whether the VideoConfiguration is supported. // IsVideoCodecValid() MUST be called before. -bool IsVideoConfigurationSupported( - const blink::VideoConfiguration* video_config, - const String& mime_type, - const String& codec) { +bool IsVideoConfigurationSupported(const String& mime_type, + const String& codec, + media::VideoColorSpace video_color_space, + media::HdrMetadataType hdr_metadata_type) { media::VideoCodec video_codec = media::kUnknownVideoCodec; media::VideoCodecProfile video_profile; uint8_t video_level = 0; - media::VideoColorSpace video_color_space; bool is_video_codec_ambiguous = true; - media::HdrMetadataType hdr_metadata_type; // Must succeed as IsVideoCodecValid() should have been called before. bool parsed = media::ParseVideoCodecString( @@ -524,9 +554,6 @@ bool IsVideoConfigurationSupported( &video_profile, &video_level, &video_color_space); DCHECK(parsed && !is_video_codec_ambiguous); - ParseDynamicRangeConfigurations(video_config, &video_color_space, - &hdr_metadata_type); - return media::IsSupportedVideoType({video_codec, video_profile, video_level, video_color_space, hdr_metadata_type}); } @@ -578,7 +605,7 @@ MediaCapabilities::MediaCapabilities(ExecutionContext* context) bad_window_predictor_(context), nnr_predictor_(context) {} -void MediaCapabilities::Trace(blink::Visitor* visitor) { +void MediaCapabilities::Trace(blink::Visitor* visitor) const { visitor->Trace(decode_history_service_); visitor->Trace(bad_window_predictor_); visitor->Trace(nnr_predictor_); @@ -588,10 +615,14 @@ void MediaCapabilities::Trace(blink::Visitor* visitor) { MediaCapabilities::PendingCallbackState::PendingCallbackState( ScriptPromiseResolver* resolver, - MediaKeySystemAccess* access) - : resolver(resolver), key_system_access(access) {} - -void MediaCapabilities::PendingCallbackState::Trace(blink::Visitor* visitor) { + MediaKeySystemAccess* access, + const base::TimeTicks& request_time) + : resolver(resolver), + key_system_access(access), + request_time(request_time) {} + +void MediaCapabilities::PendingCallbackState::Trace( + blink::Visitor* visitor) const { visitor->Trace(key_system_access); visitor->Trace(resolver); } @@ -600,6 +631,8 @@ ScriptPromise MediaCapabilities::decodingInfo( ScriptState* script_state, const MediaDecodingConfiguration* config, ExceptionState& exception_state) { + const base::TimeTicks request_time = base::TimeTicks::Now(); + if (config->hasKeySystemConfiguration()) { UseCounter::Count( ExecutionContext::From(script_state), @@ -684,10 +717,18 @@ ScriptPromise MediaCapabilities::decodingInfo( // Validation errors should return above. DCHECK(message.IsEmpty()); + media::VideoColorSpace video_color_space; + media::HdrMetadataType hdr_metadata_type = media::HdrMetadataType::kNone; + if (config->hasVideo()) { + ParseDynamicRangeConfigurations(config->video(), &video_color_space, + &hdr_metadata_type); + } + if (config->hasKeySystemConfiguration()) { // GetEmeSupport() will call the VideoDecodePerfHistory service after // receiving info about support for the configuration for encrypted content. - return GetEmeSupport(script_state, video_codec, video_profile, config, + return GetEmeSupport(script_state, video_codec, video_profile, + video_color_space, config, request_time, exception_state); } @@ -710,8 +751,8 @@ ScriptPromise MediaCapabilities::decodingInfo( DCHECK(config->hasVideo()); // Return early for unsupported configurations. - if (!IsVideoConfigurationSupported(config->video(), video_mime_str, - video_codec_str)) { + if (!IsVideoConfigurationSupported(video_mime_str, video_codec_str, + video_color_space, hdr_metadata_type)) { return ScriptPromise::Cast( script_state, ToV8(CreateDecodingInfoWith(false), script_state)); } @@ -723,8 +764,8 @@ ScriptPromise MediaCapabilities::decodingInfo( // undefined. See comment above Promise() in script_promise_resolver.h ScriptPromise promise = resolver->Promise(); - GetPerfInfo(video_codec, video_profile, config->video(), resolver, - nullptr /* access */); + GetPerfInfo(video_codec, video_profile, video_color_space, config, + request_time, resolver, nullptr /* access */); return promise; } @@ -859,7 +900,9 @@ ScriptPromise MediaCapabilities::GetEmeSupport( ScriptState* script_state, media::VideoCodec video_codec, media::VideoCodecProfile video_profile, + media::VideoColorSpace video_color_space, const MediaDecodingConfiguration* configuration, + const base::TimeTicks& request_time, ExceptionState& exception_state) { DVLOG(3) << __func__; DCHECK(configuration->hasKeySystemConfiguration()); @@ -982,8 +1025,8 @@ ScriptPromise MediaCapabilities::GetEmeSupport( MakeGarbageCollected<MediaCapabilitiesKeySystemAccessInitializer>( script_state, key_system_config->keySystem(), config_vector, WTF::Bind(&MediaCapabilities::GetPerfInfo, WrapPersistent(this), - video_codec, video_profile, - WrapPersistent(configuration->video()))); + video_codec, video_profile, video_color_space, + WrapPersistent(configuration), request_time)); // IMPORTANT: Acquire the promise before potentially synchronously resolving // it in the code that follows. Otherwise the promise returned to JS will be @@ -998,15 +1041,19 @@ ScriptPromise MediaCapabilities::GetEmeSupport( return promise; } -void MediaCapabilities::GetPerfInfo(media::VideoCodec video_codec, - media::VideoCodecProfile video_profile, - const VideoConfiguration* video_config, - ScriptPromiseResolver* resolver, - MediaKeySystemAccess* access) { +void MediaCapabilities::GetPerfInfo( + media::VideoCodec video_codec, + media::VideoCodecProfile video_profile, + media::VideoColorSpace video_color_space, + const MediaDecodingConfiguration* decoding_config, + const base::TimeTicks& request_time, + ScriptPromiseResolver* resolver, + MediaKeySystemAccess* access) { ExecutionContext* execution_context = resolver->GetExecutionContext(); if (!execution_context || execution_context->IsContextDestroyed()) return; + const VideoConfiguration* video_config = decoding_config->video(); if (!video_config) { // Audio-only is always smooth and power efficient. MediaCapabilitiesDecodingInfo* info = CreateDecodingInfoWith(true); @@ -1031,8 +1078,8 @@ void MediaCapabilities::GetPerfInfo(media::VideoCodec video_codec, const int callback_id = CreateCallbackId(); pending_cb_map_.insert( callback_id, - MakeGarbageCollected<MediaCapabilities::PendingCallbackState>(resolver, - access)); + MakeGarbageCollected<MediaCapabilities::PendingCallbackState>( + resolver, access, request_time)); if (base::FeatureList::IsEnabled(media::kMediaLearningSmoothnessExperiment)) { GetPerfInfo_ML(execution_context, callback_id, video_codec, video_profile, @@ -1048,6 +1095,11 @@ void MediaCapabilities::GetPerfInfo(media::VideoCodec video_codec, decode_history_service_->GetPerfInfo( std::move(features), WTF::Bind(&MediaCapabilities::OnPerfHistoryInfo, WrapPersistent(this), callback_id)); + + if (UseGpuFactoriesForPowerEfficient(execution_context, access)) { + GetGpuFactoriesSupport(callback_id, video_codec, video_profile, + video_color_space, decoding_config); + } } void MediaCapabilities::GetPerfInfo_ML(ExecutionContext* execution_context, @@ -1085,12 +1137,95 @@ void MediaCapabilities::GetPerfInfo_ML(ExecutionContext* execution_context, } } +void MediaCapabilities::GetGpuFactoriesSupport( + int callback_id, + media::VideoCodec video_codec, + media::VideoCodecProfile video_profile, + media::VideoColorSpace video_color_space, + const MediaDecodingConfiguration* decoding_config) { + DCHECK(decoding_config->hasVideo()); + DCHECK(pending_cb_map_.Contains(callback_id)); + + PendingCallbackState* pending_cb = pending_cb_map_.at(callback_id); + ExecutionContext* execution_context = + pending_cb_map_.at(callback_id)->resolver->GetExecutionContext(); + + DCHECK(UseGpuFactoriesForPowerEfficient(execution_context, + pending_cb->key_system_access)); + + // Frame may become detached in the time it takes us to get callback for + // NotifyDecoderSupportKnown. In this case, report false as a means of clean + // shutdown. + if (!execution_context || execution_context->IsContextDestroyed()) { + OnGpuFactoriesSupport(callback_id, false); + return; + } + + media::GpuVideoAcceleratorFactories* gpu_factories = + Platform::Current()->GetGpuFactories(); + if (!gpu_factories) { + OnGpuFactoriesSupport(callback_id, false); + return; + } + + if (!gpu_factories->IsDecoderSupportKnown()) { + gpu_factories->NotifyDecoderSupportKnown( + WTF::Bind(&MediaCapabilities::GetGpuFactoriesSupport, + WrapPersistent(this), callback_id, video_codec, video_profile, + video_color_space, WrapPersistent(decoding_config))); + return; + } + + // TODO(chcunningham): Get the actual scheme and alpha mode from + // |decoding_config| once implemented (its already spec'ed). + media::EncryptionScheme encryption_scheme = + decoding_config->hasKeySystemConfiguration() + ? media::EncryptionScheme::kCenc + : media::EncryptionScheme::kUnencrypted; + media::VideoDecoderConfig::AlphaMode alpha_mode = + media::VideoDecoderConfig::AlphaMode::kIsOpaque; + + // A few things aren't known until demuxing time. These include: coded size, + // visible rect, and extra data. Make reasonable guesses below. Ideally the + // differences won't be make/break GPU acceleration support. + VideoConfiguration* video_config = decoding_config->video(); + gfx::Size natural_size(video_config->width(), video_config->height()); + media::VideoDecoderConfig config( + video_codec, video_profile, alpha_mode, video_color_space, + media::VideoTransformation(), natural_size /* coded_size */, + gfx::Rect(natural_size) /* visible_rect */, natural_size, + media::EmptyExtraData(), encryption_scheme); + + static_assert(media::VideoDecoderImplementation::kAlternate == + media::VideoDecoderImplementation::kMaxValue, + "Keep the array below in sync."); + media::VideoDecoderImplementation decoder_impls[] = { + media::VideoDecoderImplementation::kDefault, + media::VideoDecoderImplementation::kAlternate}; + media::GpuVideoAcceleratorFactories::Supported supported = + media::GpuVideoAcceleratorFactories::Supported::kUnknown; + for (const auto& impl : decoder_impls) { + supported = gpu_factories->IsDecoderConfigSupported(impl, config); + DCHECK_NE(supported, + media::GpuVideoAcceleratorFactories::Supported::kUnknown); + if (supported == media::GpuVideoAcceleratorFactories::Supported::kTrue) + break; + } + + OnGpuFactoriesSupport( + callback_id, + supported == media::GpuVideoAcceleratorFactories::Supported::kTrue); +} + void MediaCapabilities::ResolveCallbackIfReady(int callback_id) { DCHECK(pending_cb_map_.Contains(callback_id)); PendingCallbackState* pending_cb = pending_cb_map_.at(callback_id); + ExecutionContext* execution_context = + pending_cb_map_.at(callback_id)->resolver->GetExecutionContext(); if (!pending_cb->db_is_power_efficient.has_value()) return; + // Both db_* fields should be set simultaneously by the DB callback. DCHECK(pending_cb->db_is_smooth.has_value()); @@ -1102,6 +1237,12 @@ void MediaCapabilities::ResolveCallbackIfReady(int callback_id) { !pending_cb->is_bad_window_prediction_smooth.has_value()) return; + if (UseGpuFactoriesForPowerEfficient(execution_context, + pending_cb->key_system_access) && + !pending_cb->is_gpu_factories_supported.has_value()) { + return; + } + if (!pending_cb->resolver->GetExecutionContext() || pending_cb->resolver->GetExecutionContext()->IsContextDestroyed()) { // We're too late! Now that all the callbacks have provided state, its safe @@ -1114,7 +1255,13 @@ void MediaCapabilities::ResolveCallbackIfReady(int callback_id) { MediaCapabilitiesDecodingInfo::Create()); info->setSupported(true); info->setKeySystemAccess(pending_cb->key_system_access); - info->setPowerEfficient(*pending_cb->db_is_power_efficient); + + if (UseGpuFactoriesForPowerEfficient(execution_context, + pending_cb->key_system_access)) { + info->setPowerEfficient(*pending_cb->is_gpu_factories_supported); + } else { + info->setPowerEfficient(*pending_cb->db_is_power_efficient); + } // If ML experiment is running: AND available ML signals. if (pending_cb->is_bad_window_prediction_smooth.has_value() || @@ -1127,6 +1274,21 @@ void MediaCapabilities::ResolveCallbackIfReady(int callback_id) { info->setSmooth(*pending_cb->db_is_smooth); } + const base::TimeDelta process_time = + base::TimeTicks::Now() - pending_cb->request_time; + UMA_HISTOGRAM_TIMES("Media.Capabilities.DecodingInfo.Time.Video", + process_time); + + // Record another time in the appropriate subset, either clear or encrypted + // content. + if (pending_cb->key_system_access) { + UMA_HISTOGRAM_TIMES("Media.Capabilities.DecodingInfo.Time.Video.Encrypted", + process_time); + } else { + UMA_HISTOGRAM_TIMES("Media.Capabilities.DecodingInfo.Time.Video.Clear", + process_time); + } + pending_cb->resolver->Resolve(std::move(info)); pending_cb_map_.erase(callback_id); } @@ -1145,12 +1307,12 @@ void MediaCapabilities::OnBadWindowPrediction( } else { double histogram_average = histogram->Average(); pending_cb->is_bad_window_prediction_smooth = - histogram_average <= GetLearningBadWindowThreshold(); + histogram_average < GetLearningBadWindowThreshold(); histogram_log << histogram_average; } DVLOG(2) << __func__ << " bad_win_avg:" << histogram_log.str() - << " smooth_threshold (<=):" << GetLearningBadWindowThreshold(); + << " smooth_threshold (<):" << GetLearningBadWindowThreshold(); ResolveCallbackIfReady(callback_id); } @@ -1169,12 +1331,12 @@ void MediaCapabilities::OnNnrPrediction( } else { double histogram_average = histogram->Average(); pending_cb->is_nnr_prediction_smooth = - histogram_average <= GetLearningNnrThreshold(); + histogram_average < GetLearningNnrThreshold(); histogram_log << histogram_average; } DVLOG(2) << __func__ << " nnr_avg:" << histogram_log.str() - << " smooth_threshold (<=):" << GetLearningNnrThreshold(); + << " smooth_threshold (<):" << GetLearningNnrThreshold(); ResolveCallbackIfReady(callback_id); } @@ -1191,6 +1353,17 @@ void MediaCapabilities::OnPerfHistoryInfo(int callback_id, ResolveCallbackIfReady(callback_id); } +void MediaCapabilities::OnGpuFactoriesSupport(int callback_id, + bool is_supported) { + DVLOG(2) << __func__ << " is_supported:" << is_supported; + DCHECK(pending_cb_map_.Contains(callback_id)); + PendingCallbackState* pending_cb = pending_cb_map_.at(callback_id); + + pending_cb->is_gpu_factories_supported = is_supported; + + ResolveCallbackIfReady(callback_id); +} + int MediaCapabilities::CreateCallbackId() { ++last_callback_id_; return last_callback_id_; 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 908ceaf1b10..a72e3f58ea3 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 @@ -37,7 +37,7 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable { explicit MediaCapabilities(ExecutionContext* context); - void Trace(blink::Visitor* visitor) override; + void Trace(blink::Visitor* visitor) const override; ScriptPromise decodingInfo(ScriptState*, const MediaDecodingConfiguration*, @@ -50,8 +50,9 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable { class PendingCallbackState : public GarbageCollected<PendingCallbackState> { public: PendingCallbackState(ScriptPromiseResolver* resolver, - MediaKeySystemAccess* access); - virtual void Trace(blink::Visitor* visitor); + MediaKeySystemAccess* access, + const base::TimeTicks& request_time); + virtual void Trace(blink::Visitor* visitor) const; Member<ScriptPromiseResolver> resolver; Member<MediaKeySystemAccess> key_system_access; @@ -59,6 +60,8 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable { base::Optional<bool> is_nnr_prediction_smooth; base::Optional<bool> db_is_smooth; base::Optional<bool> db_is_power_efficient; + base::Optional<bool> is_gpu_factories_supported; + base::TimeTicks request_time; }; // Lazily binds remote LearningTaskControllers for ML smoothness predictions @@ -72,13 +75,17 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable { ScriptPromise GetEmeSupport(ScriptState*, media::VideoCodec, media::VideoCodecProfile, + media::VideoColorSpace, const MediaDecodingConfiguration*, + const base::TimeTicks& request_time, ExceptionState&); // Gets perf info from VideoDecodePerrHistory DB. Will optionally kick off // parallel request to GetPerfInfo_ML() when learning experiment is enabled. void GetPerfInfo(media::VideoCodec, media::VideoCodecProfile, - const VideoConfiguration*, + media::VideoColorSpace, + const MediaDecodingConfiguration*, + const base::TimeTicks& request_time, ScriptPromiseResolver*, MediaKeySystemAccess*); @@ -90,6 +97,15 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable { int width, double framerate); + // Query media::GpuVideoAcceleratorFactories for support of hardware + // accelerate decode. Only called when |UseGpuFactoriesForPowerEfficient()| + // is true. + void GetGpuFactoriesSupport(int callback_id, + media::VideoCodec video_codec, + media::VideoCodecProfile video_profile, + media::VideoColorSpace, + const MediaDecodingConfiguration*); + // Callback for perf info from the VideoDecodePerfHistory service. void OnPerfHistoryInfo(int callback_id, bool is_smooth, @@ -105,6 +121,9 @@ class MODULES_EXPORT MediaCapabilities final : public ScriptWrappable { int callback_id, const base::Optional<::media::learning::TargetHistogram>& histogram); + // Callback for GetGpuFactoriesSupport(). + void OnGpuFactoriesSupport(int callback_id, bool is_supported); + // Resolves the callback with associated |callback_id| and removes it from the // |pending_callback_map_|. void ResolveCallbackIfReady(int callback_id); diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc index 427fd071bfe..19e1176b24c 100644 --- a/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc +++ b/chromium/third_party/blink/renderer/modules/media_capabilities/media_capabilities_test.cc @@ -9,6 +9,7 @@ #include <algorithm> #include "base/strings/string_number_conversions.h" +#include "base/task/post_task.h" #include "base/test/bind_test_util.h" #include "base/test/scoped_feature_list.h" #include "media/base/media_switches.h" @@ -20,6 +21,7 @@ #include "media/mojo/mojom/media_types.mojom-blink.h" #include "media/mojo/mojom/video_decode_perf_history.mojom-blink.h" #include "media/mojo/mojom/watch_time_recorder.mojom-blink.h" +#include "media/video/mock_gpu_video_accelerator_factories.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "testing/gmock/include/gmock/gmock.h" @@ -27,11 +29,14 @@ #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_audio_configuration.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_capabilities_info.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_configuration.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_decoding_configuration.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_video_configuration.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/platform/bindings/exception_state.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/wtf/text/string_view.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -43,7 +48,9 @@ using ::media::learning::FeatureValue; using ::media::learning::ObservationCompletion; using ::media::learning::TargetValue; using ::testing::_; +using ::testing::InSequence; using ::testing::Invoke; +using ::testing::Return; using ::testing::Unused; namespace blink { @@ -213,6 +220,10 @@ class CallbackSaver { nnr_cb_ = std::move(predict_cb); } + void SaveGpuFactoriesNotifyCallback(base::OnceClosure cb) { + gpu_factories_notify_cb_ = std::move(cb); + } + MockPerfHistoryService::GetPerfInfoCallback& perf_history_cb() { return perf_history_cb_; } @@ -226,10 +237,23 @@ class CallbackSaver { return nnr_cb_; } + base::OnceClosure& gpu_factories_notify_cb() { + return gpu_factories_notify_cb_; + } + private: MockPerfHistoryService::GetPerfInfoCallback perf_history_cb_; MockLearningTaskControllerService::PredictDistributionCallback bad_window_cb_; MockLearningTaskControllerService::PredictDistributionCallback nnr_cb_; + base::OnceClosure gpu_factories_notify_cb_; +}; + +class MockPlatform : public TestingPlatformSupport { + public: + MockPlatform() = default; + ~MockPlatform() override = default; + + MOCK_METHOD0(GetGpuFactories, media::GpuVideoAcceleratorFactories*()); }; // This would typically be a test fixture, but we need it to be @@ -300,14 +324,18 @@ class MediaCapabilitiesTestContext { return nnr_service_.get(); } + MockPlatform& GetMockPlatform() { return *mock_platform_; } + void VerifyAndClearMockExpectations() { testing::Mock::VerifyAndClearExpectations(GetPerfHistoryService()); testing::Mock::VerifyAndClearExpectations(GetNnrService()); testing::Mock::VerifyAndClearExpectations(GetBadWindowService()); + testing::Mock::VerifyAndClearExpectations(&GetMockPlatform()); } private: V8TestingScope v8_scope_; + ScopedTestingPlatformSupport<MockPlatform> mock_platform_; std::unique_ptr<MockPerfHistoryService> perf_history_service_; std::unique_ptr<FakeMediaMetricsProvider> fake_metrics_provider_; Persistent<MediaCapabilities> media_capabilities_; @@ -317,6 +345,7 @@ class MediaCapabilitiesTestContext { // |kContentType|, |kCodec|, and |kCodecProfile| must match. const char kContentType[] = "video/webm; codecs=\"vp09.00.10.08\""; +const char kAudioContentType[] = "audio/webm; codecs=\"opus\""; const media::VideoCodecProfile kCodecProfile = media::VP9PROFILE_PROFILE0; const media::VideoCodec kCodec = media::kCodecVP9; const double kFramerate = 20.5; @@ -325,6 +354,16 @@ const int kHeight = 2160; const int kBitrate = 2391000; // Construct VideoConfig using the constants above. +MediaDecodingConfiguration* CreateAudioDecodingConfig() { + auto* audio_config = MakeGarbageCollected<AudioConfiguration>(); + audio_config->setContentType(kAudioContentType); + auto* decoding_config = MakeGarbageCollected<MediaDecodingConfiguration>(); + decoding_config->setType("media-source"); + decoding_config->setAudio(audio_config); + return decoding_config; +} + +// Construct VideoConfig using the constants above. MediaDecodingConfiguration* CreateDecodingConfig() { auto* video_config = MakeGarbageCollected<VideoConfiguration>(); video_config->setFramerate(kFramerate); @@ -375,6 +414,7 @@ enum class PredictionType { kDB, kBadWindow, kNnr, + kGpuFactories, }; // Makes a TargetHistogram with single count at |target_value|. @@ -415,6 +455,10 @@ MlCallback(const Vector<media::learning::FeatureValue>& expected_features, }; } +testing::Action<void(base::OnceClosure)> GpuFactoriesNotifyCallback() { + return [](base::OnceClosure cb) { std::move(cb).Run(); }; +} + // Helper to constructs field trial params with given ML prediction thresholds. base::FieldTrialParams MakeMlParams(double bad_window_threshold, double nnr_threshold) { @@ -446,6 +490,16 @@ MediaCapabilitiesInfo* DecodingInfo( } // namespace +TEST(MediaCapabilitiesTests, BasicAudio) { + MediaCapabilitiesTestContext context; + const MediaDecodingConfiguration* kDecodingConfig = + CreateAudioDecodingConfig(); + MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context); + EXPECT_TRUE(info->supported()); + EXPECT_TRUE(info->smooth()); + EXPECT_TRUE(info->powerEfficient()); +} + // Other tests will assume these match. Test to be sure they stay in sync. TEST(MediaCapabilitiesTests, ConfigMatchesFeatures) { const MediaDecodingConfiguration* kDecodingConfig = CreateDecodingConfig(); @@ -531,6 +585,75 @@ TEST(MediaCapabilitiesTests, PredictWithJustDB) { EXPECT_TRUE(info->powerEfficient()); } +TEST(MediaCapabilitiesTests, PredictPowerEfficientWithGpuFactories) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + // Enable GpuFactories for power predictions. + {media::kMediaCapabilitiesQueryGpuFactories}, + // Disable ML predictions (may/may not be disabled by default). + {media::kMediaLearningSmoothnessExperiment}); + + MediaCapabilitiesTestContext context; + const auto* kDecodingConfig = CreateDecodingConfig(); + const media::mojom::blink::PredictionFeatures kFeatures = CreateFeatures(); + + // Setup DB to return powerEfficient = false. We later verify that opposite + // response from GpuFactories overrides the DB. + EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _)) + .WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*power_eff*/ false)); + + auto mock_gpu_factories = + std::make_unique<media::MockGpuVideoAcceleratorFactories>(nullptr); + ON_CALL(context.GetMockPlatform(), GetGpuFactories()) + .WillByDefault(Return(mock_gpu_factories.get())); + + // First, lets simulate the scenario where we ask before support is known. The + // async path should notify us when the info arrives. We then get GpuFactroies + // again and learn the config is supported. + EXPECT_CALL(context.GetMockPlatform(), GetGpuFactories()).Times(2); + { + // InSequence because we EXPECT two calls to IsDecoderSupportKnown with + // different return values. + InSequence s; + EXPECT_CALL(*mock_gpu_factories, IsDecoderSupportKnown()) + .WillOnce(Return(false)); + EXPECT_CALL(*mock_gpu_factories, NotifyDecoderSupportKnown(_)) + .WillOnce(GpuFactoriesNotifyCallback()); + EXPECT_CALL(*mock_gpu_factories, IsDecoderSupportKnown()) + .WillOnce(Return(true)); + EXPECT_CALL(*mock_gpu_factories, IsDecoderConfigSupported(_, _)) + .WillOnce( + Return(media::GpuVideoAcceleratorFactories::Supported::kTrue)); + } + + // Info should be powerEfficient, preferring response of GpuFactories over + // the DB. + MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context); + EXPECT_TRUE(info->powerEfficient()); + EXPECT_FALSE(info->smooth()); + context.VerifyAndClearMockExpectations(); + testing::Mock::VerifyAndClearExpectations(mock_gpu_factories.get()); + + // Now expect a second query with support is already known to be false. Set + // DB to respond with the opposite answer. + EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _)) + .WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*power_eff*/ true)); + EXPECT_CALL(context.GetMockPlatform(), GetGpuFactories()); + EXPECT_CALL(*mock_gpu_factories, IsDecoderSupportKnown()) + .WillOnce(Return(true)); + EXPECT_CALL(*mock_gpu_factories, IsDecoderConfigSupported(_, _)) + .WillRepeatedly( + Return(media::GpuVideoAcceleratorFactories::Supported::kFalse)); + + // Info should be NOT powerEfficient, preferring response of GpuFactories over + // the DB. + info = DecodingInfo(kDecodingConfig, &context); + EXPECT_FALSE(info->powerEfficient()); + EXPECT_FALSE(info->smooth()); + context.VerifyAndClearMockExpectations(); + testing::Mock::VerifyAndClearExpectations(mock_gpu_factories.get()); +} + // Test with smoothness predictions coming solely from "bad window" ML service. TEST(MediaCapabilitiesTests, PredictWithBadWindowMLService) { // Enable ML predictions with thresholds. -1 disables the NNR predictor. @@ -548,12 +671,12 @@ TEST(MediaCapabilitiesTests, PredictWithBadWindowMLService) { // ML is enabled, but DB should still be called for power efficiency (false). // Its smoothness value (true) should be ignored in favor of ML prediction. - // Only bad window service should be asked for a prediction. We exceed the - // bad window threshold to trigger smooth=false. + // Only bad window service should be asked for a prediction. Expect + // smooth=false because bad window prediction is equal to its threshold. EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _)) .WillOnce(DbCallback(kFeatures, /*smooth*/ true, /*efficient*/ false)); EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _)) - .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold + 0.5)); + .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold)); EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _)).Times(0); MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context); EXPECT_FALSE(info->smooth()); @@ -563,11 +686,11 @@ TEST(MediaCapabilitiesTests, PredictWithBadWindowMLService) { context.VerifyAndClearMockExpectations(); // Same as above, but invert all signals. Expect smooth=true because bad - // window prediction is now = its threshold. + // window prediction is now less than its threshold. EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _)) .WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*efficient*/ true)); EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _)) - .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold)); + .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold - 0.25)); EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _)).Times(0); info = DecodingInfo(kDecodingConfig, &context); EXPECT_TRUE(info->smooth()); @@ -607,14 +730,14 @@ TEST(MediaCapabilitiesTests, PredictWithNnrMLService) { // ML is enabled, but DB should still be called for power efficiency (false). // Its smoothness value (true) should be ignored in favor of ML prediction. - // Only NNR service should be asked for a prediction. We exceed the NNR - // threshold to trigger smooth=false. + // Only NNR service should be asked for a prediction. Expect smooth=false + // because NNR prediction is equal to its threshold. EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _)) .WillOnce(DbCallback(kFeatures, /*smooth*/ true, /*efficient*/ false)); EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _)) .Times(0); EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _)) - .WillOnce(MlCallback(kFeaturesML, kNnrThreshold + 0.5)); + .WillOnce(MlCallback(kFeaturesML, kNnrThreshold)); MediaCapabilitiesInfo* info = DecodingInfo(kDecodingConfig, &context); EXPECT_FALSE(info->smooth()); EXPECT_FALSE(info->powerEfficient()); @@ -623,13 +746,13 @@ TEST(MediaCapabilitiesTests, PredictWithNnrMLService) { context.VerifyAndClearMockExpectations(); // Same as above, but invert all signals. Expect smooth=true because NNR - // prediction is now = its threshold. + // prediction is now less than its threshold. EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _)) .WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*efficient*/ true)); EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _)) .Times(0); EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _)) - .WillOnce(MlCallback(kFeaturesML, kNnrThreshold)); + .WillOnce(MlCallback(kFeaturesML, kNnrThreshold - 0.01)); info = DecodingInfo(kDecodingConfig, &context); EXPECT_TRUE(info->smooth()); EXPECT_TRUE(info->powerEfficient()); @@ -723,16 +846,16 @@ TEST(MediaCapabilitiesTests, PredictWithBothMLServices) { context.VerifyAndClearMockExpectations(); // Same as above, but with ML services predicting exactly their respective - // thresholds. Still expect info->smooth() = true - matching the threshold is - // still considered smooth. + // thresholds. Now expect info->smooth() = false - reaching the threshold is + // considered not smooth. EXPECT_CALL(*context.GetPerfHistoryService(), GetPerfInfo(_, _)) .WillOnce(DbCallback(kFeatures, /*smooth*/ false, /*efficient*/ true)); EXPECT_CALL(*context.GetBadWindowService(), PredictDistribution(_, _)) - .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold / 2)); + .WillOnce(MlCallback(kFeaturesML, kBadWindowThreshold)); EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _)) - .WillOnce(MlCallback(kFeaturesML, kNnrThreshold / 2)); + .WillOnce(MlCallback(kFeaturesML, kNnrThreshold)); info = DecodingInfo(kDecodingConfig, &context); - EXPECT_TRUE(info->smooth()); + EXPECT_FALSE(info->smooth()); EXPECT_TRUE(info->powerEfficient()); context.VerifyAndClearMockExpectations(); } @@ -745,12 +868,18 @@ void RunCallbackPermutationTest(std::vector<PredictionType> callback_order) { const double kBadWindowThreshold = 2; const double kNnrThreshold = 3; base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeatureWithParameters( - media::kMediaLearningSmoothnessExperiment, - MakeMlParams(kBadWindowThreshold, kNnrThreshold)); + scoped_feature_list.InitWithFeaturesAndParameters( + // Enabled features w/ parameters + {{media::kMediaLearningSmoothnessExperiment, + MakeMlParams(kBadWindowThreshold, kNnrThreshold)}, + {media::kMediaCapabilitiesQueryGpuFactories, {}}}, + // Disabled features. + {}); MediaCapabilitiesTestContext context; const auto* kDecodingConfig = CreateDecodingConfig(); + auto mock_gpu_factories = + std::make_unique<media::MockGpuVideoAcceleratorFactories>(nullptr); // DB and both ML services should be called. Save their callbacks. CallbackSaver cb_saver; @@ -761,6 +890,26 @@ void RunCallbackPermutationTest(std::vector<PredictionType> callback_order) { EXPECT_CALL(*context.GetNnrService(), PredictDistribution(_, _)) .WillOnce(Invoke(&cb_saver, &CallbackSaver::SaveNnrCallback)); + // GpuFactories should also be called. Set it up to be async with arrival of + // support info. Save the "notify" callback. + EXPECT_CALL(context.GetMockPlatform(), GetGpuFactories()) + .WillRepeatedly(Return(mock_gpu_factories.get())); + { + // InSequence because we EXPECT two calls to IsDecoderSupportKnown with + // different return values. + InSequence s; + EXPECT_CALL(*mock_gpu_factories, IsDecoderSupportKnown()) + .WillOnce(Return(false)); + EXPECT_CALL(*mock_gpu_factories, NotifyDecoderSupportKnown(_)) + .WillOnce( + Invoke(&cb_saver, &CallbackSaver::SaveGpuFactoriesNotifyCallback)); + EXPECT_CALL(*mock_gpu_factories, IsDecoderSupportKnown()) + .WillOnce(Return(true)); + EXPECT_CALL(*mock_gpu_factories, IsDecoderConfigSupported(_, _)) + .WillRepeatedly( + Return(media::GpuVideoAcceleratorFactories::Supported::kFalse)); + } + // Call decodingInfo() to kick off the calls to prediction services. ScriptPromise promise = context.GetMediaCapabilities()->decodingInfo( context.GetScriptState(), kDecodingConfig, context.GetExceptionState()); @@ -769,7 +918,7 @@ void RunCallbackPermutationTest(std::vector<PredictionType> callback_order) { // Callbacks should all be saved after mojo's pending tasks have run. test::RunPendingTasks(); ASSERT_TRUE(cb_saver.perf_history_cb() && cb_saver.bad_window_cb() && - cb_saver.nnr_cb()); + cb_saver.nnr_cb() && cb_saver.gpu_factories_notify_cb()); // Complete callbacks in whatever order. for (size_t i = 0; i < callback_order.size(); ++i) { @@ -784,9 +933,12 @@ void RunCallbackPermutationTest(std::vector<PredictionType> callback_order) { case PredictionType::kNnr: std::move(cb_saver.nnr_cb()).Run(MakeHistogram(kNnrThreshold + 0.5)); break; + case PredictionType::kGpuFactories: + std::move(cb_saver.gpu_factories_notify_cb()).Run(); + break; } - // Give mojo callbacks a chance to run. + // Give callbacks/tasks a chance to run. test::RunPendingTasks(); // Promise should only be resolved once the final callback has run. @@ -805,15 +957,16 @@ void RunCallbackPermutationTest(std::vector<PredictionType> callback_order) { // Smooth=false because NNR prediction exceeds threshold. EXPECT_FALSE(info->smooth()); - // DB predicted power_efficient = true. - EXPECT_TRUE(info->powerEfficient()); + // DB predicted power_efficient = true, but GpuFactories overrides w/ false. + EXPECT_FALSE(info->powerEfficient()); } // Test that decodingInfo() behaves correctly for all orderings/timings of the // underlying prediction services. TEST(MediaCapabilitiesTests, PredictionCallbackPermutations) { std::vector<PredictionType> callback_order( - {PredictionType::kDB, PredictionType::kBadWindow, PredictionType::kNnr}); + {PredictionType::kDB, PredictionType::kBadWindow, PredictionType::kNnr, + PredictionType::kGpuFactories}); do { RunCallbackPermutationTest(callback_order); } while (std::next_permutation(callback_order.begin(), callback_order.end())); diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.cc b/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.cc index 1de743d0362..8da97e2a083 100644 --- a/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.cc +++ b/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.cc @@ -25,7 +25,7 @@ MediaCapabilities* NavigatorMediaCapabilities::mediaCapabilities( return self.capabilities_.Get(); } -void NavigatorMediaCapabilities::Trace(Visitor* visitor) { +void NavigatorMediaCapabilities::Trace(Visitor* visitor) const { visitor->Trace(capabilities_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.h b/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.h index a29e325682f..429a5fe17cc 100644 --- a/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.h +++ b/chromium/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.h @@ -26,7 +26,7 @@ class NavigatorMediaCapabilities final explicit NavigatorMediaCapabilities(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: static NavigatorMediaCapabilities& From(Navigator&); diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.cc b/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.cc index fa51b598d57..013672b91a6 100644 --- a/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.cc +++ b/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.cc @@ -25,7 +25,7 @@ MediaCapabilities* WorkerNavigatorMediaCapabilities::mediaCapabilities( return self.capabilities_.Get(); } -void WorkerNavigatorMediaCapabilities::Trace(Visitor* visitor) { +void WorkerNavigatorMediaCapabilities::Trace(Visitor* visitor) const { visitor->Trace(capabilities_); Supplement<WorkerNavigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.h b/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.h index e16daef0396..5a856abf00a 100644 --- a/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.h +++ b/chromium/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.h @@ -27,7 +27,7 @@ class WorkerNavigatorMediaCapabilities final explicit WorkerNavigatorMediaCapabilities(WorkerNavigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: static WorkerNavigatorMediaCapabilities& From(WorkerNavigator&); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc index 69e49fac537..fd346f4a72f 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.cc @@ -66,7 +66,7 @@ Element& MediaControlAnimatedArrowContainerElement::AnimatedArrow:: } void MediaControlAnimatedArrowContainerElement::AnimatedArrow::Trace( - Visitor* visitor) { + Visitor* visitor) const { MediaControlAnimationEventListener::Observer::Trace(visitor); HTMLDivElement::Trace(visitor); visitor->Trace(last_arrow_); @@ -121,7 +121,7 @@ void MediaControlAnimatedArrowContainerElement::ShowArrowAnimation( } } -void MediaControlAnimatedArrowContainerElement::Trace(Visitor* visitor) { +void MediaControlAnimatedArrowContainerElement::Trace(Visitor* visitor) const { MediaControlDivElement::Trace(visitor); visitor->Trace(left_jump_arrow_); visitor->Trace(right_jump_arrow_); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h index 33503c4618d..2a5f62c84b9 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animated_arrow_container_element.h @@ -27,7 +27,7 @@ class MODULES_EXPORT MediaControlAnimatedArrowContainerElement final void ShowArrowAnimation(ArrowDirection); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class MediaControlAnimatedArrowContainerElementTest; @@ -52,7 +52,7 @@ class MODULES_EXPORT MediaControlAnimatedArrowContainerElement final // iteration. void Show(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void HideInternal(); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.cc index 21d882f4481..fad64fb2c5d 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.cc @@ -25,7 +25,7 @@ void MediaControlAnimationEventListener::Detach() { event_type_names::kAnimationiteration, this, false); } -void MediaControlAnimationEventListener::Trace(Visitor* visitor) { +void MediaControlAnimationEventListener::Trace(Visitor* visitor) const { visitor->Trace(observer_); EventListener::Trace(visitor); } @@ -44,6 +44,6 @@ void MediaControlAnimationEventListener::Invoke(ExecutionContext* context, NOTREACHED(); } -void MediaControlAnimationEventListener::Observer::Trace(Visitor*) {} +void MediaControlAnimationEventListener::Observer::Trace(Visitor*) const {} } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.h index bd20a520d5c..7b8214f2395 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_animation_event_listener.h @@ -40,13 +40,13 @@ class MODULES_EXPORT MediaControlAnimationEventListener final // This is the element to watch for animation events. virtual Element& WatchedAnimationElement() const = 0; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; explicit MediaControlAnimationEventListener(Observer*); void Detach(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void Invoke(ExecutionContext*, Event*) override; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.cc index a75489c055d..c855845881a 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.cc @@ -36,7 +36,7 @@ bool MediaControlDivElement::IsDisabled() const { return false; } -void MediaControlDivElement::Trace(Visitor* visitor) { +void MediaControlDivElement::Trace(Visitor* visitor) const { HTMLDivElement::Trace(visitor); MediaControlElementBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h index 621041cd56a..d61d47ca8bc 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h @@ -29,7 +29,7 @@ class MODULES_EXPORT MediaControlDivElement : public HTMLDivElement, bool IsDisabled() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: MediaControlDivElement(MediaControlsImpl&); 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 4500a9e8e4e..b600f69c661 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 @@ -59,7 +59,7 @@ bool MediaControlDownloadButtonElement::IsControlPanelButton() const { return true; } -void MediaControlDownloadButtonElement::Trace(Visitor* visitor) { +void MediaControlDownloadButtonElement::Trace(Visitor* visitor) const { MediaControlInputElement::Trace(visitor); } 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 3ed835dabaf..4f6c9867ab0 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 @@ -27,7 +27,7 @@ class MediaControlDownloadButtonElement final bool HasOverflowButton() const final; bool IsControlPanelButton() const final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: const char* GetNameForHistograms() const final; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.cc index e9b2cc02ccb..c4d9cd6da72 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_element_base.cc @@ -62,7 +62,7 @@ HTMLMediaElement& MediaControlElementBase::MediaElement() const { return GetMediaControls().MediaElement(); } -void MediaControlElementBase::Trace(Visitor* visitor) { +void MediaControlElementBase::Trace(Visitor* visitor) const { visitor->Trace(media_controls_); visitor->Trace(element_); } 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 57e232f89a6..2c6249f1030 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 @@ -54,7 +54,7 @@ class MODULES_EXPORT MediaControlElementBase : public GarbageCollectedMixin { // Whether the element has been disabled via the HTML disabled attribute. virtual bool IsDisabled() const = 0; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: MediaControlElementBase(MediaControlsImpl&, 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 57636c51a67..6f563c120c9 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 @@ -295,7 +295,7 @@ bool MediaControlInputElement::IsDisabled() const { return FastHasAttribute(html_names::kDisabledAttr); } -void MediaControlInputElement::Trace(Visitor* visitor) { +void MediaControlInputElement::Trace(Visitor* visitor) const { HTMLInputElement::Trace(visitor); MediaControlElementBase::Trace(visitor); visitor->Trace(overflow_element_); 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 a6ea2d28f72..2c8e3a23b7b 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 @@ -31,7 +31,7 @@ class MODULES_EXPORT MediaControlInputElement : public HTMLInputElement, void SetOverflowElementIsWanted(bool) final; void MaybeRecordDisplayed() final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; MediaControlInputElement* OverflowElementForTests() const { return overflow_element_; 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 73c1684aee2..08be2656f69 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 @@ -35,7 +35,7 @@ class MediaControlInputElementImpl final : public MediaControlInputElement { SetIsWanted(false); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { MediaControlInputElement::Trace(visitor); } 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 c5468bebcdf..70285b7c466 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 @@ -226,7 +226,7 @@ Element& MediaControlLoadingPanelElement::WatchedAnimationElement() const { return *mask1_background_; } -void MediaControlLoadingPanelElement::Trace(Visitor* visitor) { +void MediaControlLoadingPanelElement::Trace(Visitor* visitor) const { MediaControlAnimationEventListener::Observer::Trace(visitor); MediaControlDivElement::Trace(visitor); visitor->Trace(event_listener_); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h index c18ffda7ea4..9edd5503753 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_loading_panel_element.h @@ -34,7 +34,7 @@ class MODULES_EXPORT MediaControlLoadingPanelElement final // Inform the loading panel that the Media Controls have been shown. void OnControlsShown(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class MediaControlLoadingPanelElementTest; 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 d8c82d51874..fcf466f30c9 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 @@ -114,7 +114,7 @@ void MediaControlOverlayPlayButtonElement::SetIsDisplayed(bool displayed) { displayed_ = displayed; } -void MediaControlOverlayPlayButtonElement::Trace(Visitor* visitor) { +void MediaControlOverlayPlayButtonElement::Trace(Visitor* visitor) const { MediaControlInputElement::Trace(visitor); visitor->Trace(internal_button_); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h index 7ed95c22939..36da21e1567 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_overlay_play_button_element.h @@ -28,7 +28,7 @@ class MODULES_EXPORT MediaControlOverlayPlayButtonElement final void SetIsDisplayed(bool); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: const char* GetNameForHistograms() const override; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc index 246c9188059..4b296242c83 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc @@ -72,7 +72,7 @@ void MediaControlPanelElement::RemovedFrom(ContainerNode& insertion_point) { DetachTransitionEventListener(); } -void MediaControlPanelElement::Trace(Visitor* visitor) { +void MediaControlPanelElement::Trace(Visitor* visitor) const { MediaControlDivElement::Trace(visitor); visitor->Trace(event_listener_); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h index ef7fade2a71..7153c81f780 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h @@ -33,7 +33,7 @@ class MODULES_EXPORT MediaControlPanelElement final // Node override; void RemovedFrom(ContainerNode&) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: friend class MediaControlPanelElementTest; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc index 40f4b7deda3..2bee34eb4ba 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc @@ -55,7 +55,7 @@ class MediaControlPopupMenuElement::EventListener final } } - void Trace(Visitor* visitor) final { + void Trace(Visitor* visitor) const final { NativeEventListener::Trace(visitor); visitor->Trace(popup_menu_); } @@ -165,7 +165,7 @@ void MediaControlPopupMenuElement::RemovedFrom(ContainerNode& container) { MediaControlDivElement::RemovedFrom(container); } -void MediaControlPopupMenuElement::Trace(Visitor* visitor) { +void MediaControlPopupMenuElement::Trace(Visitor* visitor) const { MediaControlDivElement::Trace(visitor); visitor->Trace(event_listener_); visitor->Trace(last_focused_element_); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h index 97e0fdd4f30..ed101d02924 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.h @@ -25,7 +25,7 @@ class MediaControlPopupMenuElement : public MediaControlDivElement { bool KeepEventInNode(const Event&) const override; void RemovedFrom(ContainerNode&) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // When clicking the scroll bar, chrome will find its first focusable parent // and focus on it. In order to prevent popup menu from losing focus (which diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc index cbdab823179..fdd66cfb18d 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.cc @@ -69,7 +69,7 @@ class MediaControlSliderElement::MediaControlSliderElementResizeObserverDelegate element_->NotifyElementSizeChanged(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(element_); ResizeObserver::Delegate::Trace(visitor); } @@ -163,7 +163,7 @@ void MediaControlSliderElement::NotifyElementSizeChanged() { TrackWidth(), ZoomFactor()); } -void MediaControlSliderElement::Trace(Visitor* visitor) { +void MediaControlSliderElement::Trace(Visitor* visitor) const { visitor->Trace(segment_highlight_before_); visitor->Trace(segment_highlight_after_); visitor->Trace(resize_observer_); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.h index 195b27fa0a3..c2bf1366899 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_slider_element.h @@ -20,7 +20,7 @@ class MODULES_EXPORT MediaControlSliderElement USING_GARBAGE_COLLECTED_MIXIN(MediaControlSliderElement); public: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Stores the position of the segment in proportion from 0.0 to 1.0. struct Position { 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 5f9f0e47d12..b9a431fb687 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 @@ -236,7 +236,7 @@ void MediaControlTimelineElement::RenderBarSegments() { SetAfterSegmentPosition(after_segment); } -void MediaControlTimelineElement::Trace(Visitor* visitor) { +void MediaControlTimelineElement::Trace(Visitor* visitor) const { MediaControlSliderElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h index ba1d15b0f45..cd33fc5d5ab 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h @@ -35,7 +35,7 @@ class MediaControlTimelineElement : public MediaControlSliderElement { void OnControlsShown(); void OnControlsHidden(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: const char* GetNameForHistograms() const override; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.cc b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.cc index 53dadc860c1..25b7001c57c 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_metrics.cc @@ -8,6 +8,7 @@ #include <cmath> #include <limits> +#include "base/notreached.h" #include "base/numerics/safe_conversions.h" #include "base/stl_util.h" #include "third_party/blink/renderer/platform/instrumentation/histogram.h" diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc index ffde7478b7a..592c70604e5 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.cc @@ -57,7 +57,7 @@ void MediaControlsDisplayCutoutDelegate::Detach() { this, true); } -void MediaControlsDisplayCutoutDelegate::Trace(Visitor* visitor) { +void MediaControlsDisplayCutoutDelegate::Trace(Visitor* visitor) const { NativeEventListener::Trace(visitor); visitor->Trace(video_element_); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.h index 3ea9997debc..8a275c89be1 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate.h @@ -37,7 +37,7 @@ class MODULES_EXPORT MediaControlsDisplayCutoutDelegate final // EventListener implementation. void Invoke(ExecutionContext*, Event*) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class MediaControlsDisplayCutoutDelegateTest; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc index 94f261dd5e7..847af5e792d 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc @@ -289,7 +289,11 @@ TEST_F(MediaControlsDisplayCutoutDelegateTest, SingleTouchGesture_Noop) { // Simulate a single touch gesture and make sure it had no effect. SimulateEnterFullscreen(); SimulateSingleTouchGesture(); - EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit()); + mojom::ViewportFit expected = + RuntimeEnabledFeatures::MediaControlsUseCutOutByDefaultEnabled() + ? mojom::ViewportFit::kCoverForcedByUserAgent + : mojom::ViewportFit::kAuto; + EXPECT_EQ(expected, CurrentViewportFit()); } TEST_F(MediaControlsDisplayCutoutDelegateTest, TouchCancelShouldClearState) { @@ -304,7 +308,11 @@ TEST_F(MediaControlsDisplayCutoutDelegateTest, TouchCancelShouldClearState) { list = CreateTouchListWithTwoPoints(1, 1, -1, -1); SimulateEvent(CreateTouchEventWithList(event_type_names::kTouchcancel, list)); EXPECT_FALSE(HasGestureState()); - EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit()); + mojom::ViewportFit expected = + RuntimeEnabledFeatures::MediaControlsUseCutOutByDefaultEnabled() + ? mojom::ViewportFit::kCoverForcedByUserAgent + : mojom::ViewportFit::kAuto; + EXPECT_EQ(expected, CurrentViewportFit()); } TEST_F(MediaControlsDisplayCutoutDelegateTest, TouchEndShouldClearState) { @@ -319,7 +327,12 @@ TEST_F(MediaControlsDisplayCutoutDelegateTest, TouchEndShouldClearState) { list = CreateTouchListWithTwoPoints(1, 1, -1, -1); SimulateEvent(CreateTouchEventWithList(event_type_names::kTouchend, list)); EXPECT_FALSE(HasGestureState()); - EXPECT_EQ(mojom::ViewportFit::kAuto, CurrentViewportFit()); + + mojom::ViewportFit expected = + RuntimeEnabledFeatures::MediaControlsUseCutOutByDefaultEnabled() + ? mojom::ViewportFit::kCoverForcedByUserAgent + : mojom::ViewportFit::kAuto; + EXPECT_EQ(expected, CurrentViewportFit()); } TEST_F(MediaControlsDisplayCutoutDelegateTest, DefaultExpand) { 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 53069e02b73..4869190f90e 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 @@ -237,7 +237,7 @@ class MediaControlsImpl::MediaControlsResizeObserverDelegate final controls_->NotifyElementSizeChanged(entries[0]->contentRect()); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(controls_); ResizeObserver::Delegate::Trace(visitor); } @@ -297,7 +297,7 @@ class MediaControlsImpl::MediaElementMutationCallback void Disconnect() { observer_->disconnect(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(controls_); visitor->Trace(observer_); MutationObserver::Delegate::Trace(visitor); @@ -2128,7 +2128,7 @@ HTMLVideoElement& MediaControlsImpl::VideoElement() { return *To<HTMLVideoElement>(&MediaElement()); } -void MediaControlsImpl::Trace(Visitor* visitor) { +void MediaControlsImpl::Trace(Visitor* visitor) const { visitor->Trace(element_mutation_callback_); visitor->Trace(resize_observer_); visitor->Trace(panel_); 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 b7595eb9cd2..13304bcb5c0 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 @@ -158,7 +158,7 @@ class MODULES_EXPORT MediaControlsImpl final : public HTMLDivElement, const MediaControlRemainingTimeDisplayElement& RemainingTimeDisplay() const; MediaControlToggleClosedCaptionsButtonElement& ToggleClosedCaptions(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Track the state of the controls. enum ControlsState { diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc index 0ffea25cc10..f7eaf58d17d 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc @@ -252,7 +252,7 @@ void MediaControlsMediaEventListener::OnRemotePlaybackAvailabilityChanged() { media_controls_->RefreshCastButtonVisibility(); } -void MediaControlsMediaEventListener::Trace(Visitor* visitor) { +void MediaControlsMediaEventListener::Trace(Visitor* visitor) const { NativeEventListener::Trace(visitor); visitor->Trace(media_controls_); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.h index 89a7ec4a942..06e3558bcaf 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.h @@ -26,7 +26,7 @@ class MediaControlsMediaEventListener final : public NativeEventListener { // object to be garbage collected. void Detach(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void Invoke(ExecutionContext*, Event*) override; 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 ee8c09a561f..feff64fa883 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 @@ -6,7 +6,6 @@ #include <memory> -#include "base/metrics/histogram_functions.h" #include "build/build_config.h" #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/task_type.h" @@ -39,22 +38,6 @@ namespace blink { namespace { -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -enum class MetadataAvailabilityMetrics { - kAvailable = 0, // Available when lock was attempted. - kMissing = 1, // Missing when lock was attempted. - kReceived = 2, // Received after being missing in order to lock. - - // Keep at the end. - kMaxValue = kReceived, -}; - -void RecordMetadataAvailability(MetadataAvailabilityMetrics metrics) { - base::UmaHistogramEnumeration( - "Media.Video.FullscreenOrientationLock.MetadataAvailability", metrics); -} - // WebLockOrientationCallback implementation that will not react to a success // nor a failure. class DummyScreenOrientationCallback : public WebLockOrientationCallback { @@ -100,16 +83,10 @@ void MediaControlsOrientationLockDelegate::MaybeLockOrientation() { DCHECK(state_ != State::kMaybeLockedFullscreen); if (VideoElement().getReadyState() == HTMLMediaElement::kHaveNothing) { - RecordMetadataAvailability(MetadataAvailabilityMetrics::kMissing); state_ = State::kPendingMetadata; return; } - if (state_ == State::kPendingMetadata) - RecordMetadataAvailability(MetadataAvailabilityMetrics::kReceived); - else - RecordMetadataAvailability(MetadataAvailabilityMetrics::kAvailable); - state_ = State::kMaybeLockedFullscreen; if (!GetDocument().domWindow()) @@ -435,7 +412,7 @@ void MediaControlsOrientationLockDelegate:: kLockToAnyDelay); } -void MediaControlsOrientationLockDelegate::Trace(Visitor* visitor) { +void MediaControlsOrientationLockDelegate::Trace(Visitor* visitor) const { NativeEventListener::Trace(visitor); visitor->Trace(monitor_); visitor->Trace(video_element_); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h index 541a1f8b16c..668f7936b72 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h @@ -68,7 +68,7 @@ class MediaControlsOrientationLockDelegate final : public NativeEventListener { // NativeEventListener implementation. void Invoke(ExecutionContext*, Event*) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class MediaControlsOrientationLockDelegateTest; 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 b29bff47259..69e43a6c4c7 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 @@ -286,7 +286,7 @@ MediaControlsRotateToFullscreenDelegate::ComputeScreenOrientation() const { return SimpleOrientation::kUnknown; } -void MediaControlsRotateToFullscreenDelegate::Trace(Visitor* visitor) { +void MediaControlsRotateToFullscreenDelegate::Trace(Visitor* visitor) const { NativeEventListener::Trace(visitor); visitor->Trace(video_element_); visitor->Trace(intersection_observer_); diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.h index 299ccbf56cc..babd54c86ac 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.h @@ -37,7 +37,7 @@ class MediaControlsRotateToFullscreenDelegate final // EventListener implementation. void Invoke(ExecutionContext*, Event*) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class MediaControlsRotateToFullscreenDelegateTest; diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.cc b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.cc index 1cda95d45bc..48a68a74df2 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.cc +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.cc @@ -65,7 +65,7 @@ void MediaControlsSharedHelpers::TransitionEventListener::Invoke( } void MediaControlsSharedHelpers::TransitionEventListener::Trace( - blink::Visitor* visitor) { + blink::Visitor* visitor) const { NativeEventListener::Trace(visitor); visitor->Trace(element_); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h index 255a451ef8d..c3fdb3a0ae2 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h @@ -29,7 +29,7 @@ class MediaControlsSharedHelpers final { void Detach(); bool IsAttached() const; void Invoke(ExecutionContext* context, Event* event) override; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: bool attached_ = false; 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 40978603e6c..64291f875c4 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 @@ -54,7 +54,7 @@ void MediaControlsTextTrackManager::DisableShowingTextTracks() { } } -void MediaControlsTextTrackManager::Trace(Visitor* visitor) { +void MediaControlsTextTrackManager::Trace(Visitor* visitor) const { visitor->Trace(media_element_); } diff --git a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h index ebb7e305767..b2b48f3ce73 100644 --- a/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h +++ b/chromium/third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h @@ -26,7 +26,7 @@ class MODULES_EXPORT MediaControlsTextTrackManager void ShowTextTrackAtIndex(unsigned); void DisableShowingTextTracks(); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; private: Member<HTMLMediaElement> media_element_; 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 d459f85adae..36d3067ee49 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 @@ -1446,12 +1446,10 @@ video::-webkit-media-controls.immersive-mode input[pseudo="-internal-media-contr display: none; } -@media (-webkit-min-device-pixel-ratio: 2) { - video::-webkit-media-controls.immersive-mode div[pseudo="-webkit-media-controls-panel" i] { - background: - -webkit-image-set(url('default_200_percent/vr_gradient_bg.png') 1x) - repeat-x bottom left auto 198px; - } +video::-webkit-media-controls.immersive-mode div[pseudo="-webkit-media-controls-panel" i] { + background: + -webkit-image-set(url('default_200_percent/vr_gradient_bg.png') 1x) + repeat-x bottom left auto 198px; } /** 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 771b8ea19c2..8f7e58de886 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 @@ -26,7 +26,7 @@ class AutoCanvasDrawListener : public GarbageCollected<AutoCanvasDrawListener>, bool NeedsNewFrame() const final; void RequestFrame() final; - void Trace(Visitor*) override {} + void Trace(Visitor*) const override {} protected: std::unique_ptr<CanvasCaptureHandler> handler_; 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 ddd73e34730..70f27208b99 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 @@ -23,6 +23,7 @@ #include "third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/text/base64.h" @@ -142,12 +143,12 @@ CanvasCaptureHandler::CanvasCaptureHandler( const blink::WebSize& size, double frame_rate, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - blink::WebMediaStreamTrack* track) + MediaStreamComponent** component) : ask_for_new_frame_(false), io_task_runner_(std::move(io_task_runner)) { std::unique_ptr<media::VideoCapturerSource> video_source( new VideoCapturerSource(weak_ptr_factory_.GetWeakPtr(), size, frame_rate)); - AddVideoCapturerSourceToVideoTrack(frame, std::move(video_source), track); + AddVideoCapturerSourceToVideoTrack(frame, std::move(video_source), component); } CanvasCaptureHandler::~CanvasCaptureHandler() { @@ -163,13 +164,13 @@ CanvasCaptureHandler::CreateCanvasCaptureHandler( const blink::WebSize& size, double frame_rate, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - blink::WebMediaStreamTrack* track) { + MediaStreamComponent** component) { // Save histogram data so we can see how much CanvasCapture is used. // The histogram counts the number of calls to the JS API. UpdateWebRTCMethodCount(RTCAPIName::kCanvasCaptureStream); return std::unique_ptr<CanvasCaptureHandler>(new CanvasCaptureHandler( - frame, size, frame_rate, std::move(io_task_runner), track)); + frame, size, frame_rate, std::move(io_task_runner), component)); } void CanvasCaptureHandler::SendNewFrame( @@ -507,7 +508,7 @@ void CanvasCaptureHandler::SendFrame(scoped_refptr<VideoFrame> video_frame, void CanvasCaptureHandler::AddVideoCapturerSourceToVideoTrack( LocalFrame* frame, std::unique_ptr<media::VideoCapturerSource> source, - blink::WebMediaStreamTrack* web_track) { + MediaStreamComponent** component) { uint8_t track_id_bytes[64]; base::RandBytes(track_id_bytes, sizeof(track_id_bytes)); WebString track_id = Base64Encode(track_id_bytes); @@ -525,10 +526,11 @@ void CanvasCaptureHandler::AddVideoCapturerSourceToVideoTrack( media::VideoFacingMode::MEDIA_VIDEO_FACING_NONE, false /* is_device_capture */)); - web_track->Initialize(webkit_source); - web_track->SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>( - media_stream_source, - blink::MediaStreamVideoSource::ConstraintsOnceCallback(), true)); + *component = MakeGarbageCollected<MediaStreamComponent>(webkit_source); + (*component) + ->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>( + media_stream_source, + MediaStreamVideoSource::ConstraintsOnceCallback(), true)); } void CanvasCaptureHandler::IncrementOngoingAsyncPixelReadouts() { 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 ba2d60a1810..ed7df7c3126 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 @@ -18,7 +18,6 @@ #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" #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/skia/include/core/SkImageInfo.h" @@ -28,6 +27,7 @@ class SkImage; namespace blink { class LocalFrame; +class MediaStreamComponent; class StaticBitmapImage; class WebGraphicsContext3DProvider; class WebGraphicsContext3DProviderWrapper; @@ -51,7 +51,7 @@ class MODULES_EXPORT CanvasCaptureHandler { const blink::WebSize& size, double frame_rate, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - blink::WebMediaStreamTrack* track); + MediaStreamComponent** component); void SendNewFrame(scoped_refptr<StaticBitmapImage> image, base::WeakPtr<blink::WebGraphicsContext3DProviderWrapper> @@ -77,7 +77,7 @@ class MODULES_EXPORT CanvasCaptureHandler { const blink::WebSize& size, double frame_rate, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - blink::WebMediaStreamTrack* track); + MediaStreamComponent** component); // Helper functions to read pixel content. void ReadARGBPixelsSync(scoped_refptr<StaticBitmapImage> image); @@ -112,7 +112,7 @@ class MODULES_EXPORT CanvasCaptureHandler { void AddVideoCapturerSourceToVideoTrack( LocalFrame* frame, std::unique_ptr<media::VideoCapturerSource> source, - blink::WebMediaStreamTrack* web_track); + MediaStreamComponent** component); // Helper methods to increment/decrement the number of ongoing async pixel // readouts currently happening. diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc index bec1d7931b1..bc6e3df7d8e 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler_unittest.cc @@ -12,11 +12,12 @@ #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_media_stream_source.h" -#include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/public/web/web_heap.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h" #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h" #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkRefCnt.h" @@ -50,15 +51,17 @@ class CanvasCaptureHandlerTest CanvasCaptureHandlerTest() = default; void SetUp() override { + MediaStreamComponent* component = nullptr; canvas_capture_handler_ = CanvasCaptureHandler::CreateCanvasCaptureHandler( /*LocalFrame =*/nullptr, blink::WebSize(kTestCanvasCaptureWidth, kTestCanvasCaptureHeight), kTestCanvasCaptureFramesPerSecond, - blink::scheduler::GetSingleThreadTaskRunnerForTesting(), &track_); + blink::scheduler::GetSingleThreadTaskRunnerForTesting(), &component); + component_ = component; } void TearDown() override { - track_.Reset(); + component_ = nullptr; blink::WebHeap::CollectAllGarbageForTesting(); canvas_capture_handler_.reset(); @@ -120,7 +123,7 @@ class CanvasCaptureHandlerTest } } - blink::WebMediaStreamTrack track_; + Persistent<MediaStreamComponent> component_; // The Class under test. Needs to be scoped_ptr to force its destruction. std::unique_ptr<CanvasCaptureHandler> canvas_capture_handler_; @@ -145,7 +148,7 @@ TEST_F(CanvasCaptureHandlerTest, ConstructAndDestruct) { // Checks that the destruction sequence works fine. TEST_F(CanvasCaptureHandlerTest, DestructTrack) { EXPECT_TRUE(canvas_capture_handler_->NeedsNewFrame()); - track_.Reset(); + component_ = nullptr; base::RunLoop().RunUntilIdle(); } @@ -159,7 +162,7 @@ TEST_F(CanvasCaptureHandlerTest, DestructHandler) { // Checks that VideoCapturerSource call sequence works fine. TEST_P(CanvasCaptureHandlerTest, GetFormatsStartAndStop) { InSequence s; - const blink::WebMediaStreamSource& web_media_stream_source = track_.Source(); + const WebMediaStreamSource& web_media_stream_source = component_->Source(); EXPECT_FALSE(web_media_stream_source.IsNull()); blink::MediaStreamVideoCapturerSource* const ms_source = static_cast<blink::MediaStreamVideoCapturerSource*>( @@ -205,7 +208,7 @@ TEST_P(CanvasCaptureHandlerTest, VerifyFrame) { InSequence s; media::VideoCapturerSource* const source = GetVideoCapturerSource( static_cast<blink::MediaStreamVideoCapturerSource*>( - track_.Source().GetPlatformSource())); + component_->Source()->GetPlatformSource())); EXPECT_TRUE(source); base::RunLoop run_loop; @@ -227,7 +230,7 @@ TEST_F(CanvasCaptureHandlerTest, CheckNeedsNewFrame) { InSequence s; media::VideoCapturerSource* source = GetVideoCapturerSource( static_cast<blink::MediaStreamVideoCapturerSource*>( - track_.Source().GetPlatformSource())); + component_->Source()->GetPlatformSource())); EXPECT_TRUE(source); EXPECT_TRUE(canvas_capture_handler_->NeedsNewFrame()); source->StopCapture(); diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc index ce10ffb1f97..583d5b87cab 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.cc @@ -31,7 +31,7 @@ CanvasCaptureMediaStreamTrack* CanvasCaptureMediaStreamTrack::clone( return cloned_track; } -void CanvasCaptureMediaStreamTrack::Trace(Visitor* visitor) { +void CanvasCaptureMediaStreamTrack::Trace(Visitor* visitor) const { visitor->Trace(canvas_element_); visitor->Trace(draw_listener_); MediaStreamTrack::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.h b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.h index 88ff785c474..832be9fb9ee 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.h +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.h @@ -37,7 +37,7 @@ class CanvasCaptureMediaStreamTrack final : public MediaStreamTrack { CanvasCaptureMediaStreamTrack* clone(ScriptState*) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<HTMLCanvasElement> canvas_element_; diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc index db18d7463e5..48092cc0914 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_audio_element_capturer_source_unittest.cc @@ -18,6 +18,8 @@ #include "third_party/blink/public/platform/webaudiosourceprovider_impl.h" #include "third_party/blink/public/web/web_heap.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h" namespace blink { @@ -46,8 +48,8 @@ class MockMediaStreamAudioSink final : public blink::WebMediaStreamAudioSink { // - a WebAudioSourceProviderImpl, which in turn needs an Audio Sink, in this // case a NullAudioSink. This is needed to plug HTMLAudioElementCapturerSource // and inject audio. -// - a WebMediaStreamSource, that owns the HTMLAudioElementCapturerSource under -// test, and a WebMediaStreamAudioTrack, that the class under test needs to +// - a MediaStreamSource, that owns the HTMLAudioElementCapturerSource under +// test, and a MediaStreamComponent, that the class under test needs to // connect to in order to operate correctly. This class has an inner content // MediaStreamAudioTrack. // - finally, a MockMediaStreamAudioSink to observe captured audio frames, and @@ -67,18 +69,18 @@ class HTMLAudioElementCapturerSourceTest : public testing::Test { } void TearDown() override { - blink_audio_track_.Reset(); - blink_audio_source_.Reset(); + media_stream_component_ = nullptr; + media_stream_source_ = nullptr; blink::WebHeap::CollectAllGarbageForTesting(); } HtmlAudioElementCapturerSource* source() const { return static_cast<HtmlAudioElementCapturerSource*>( - blink::MediaStreamAudioSource::From(blink_audio_source_)); + MediaStreamAudioSource::From(media_stream_source_.Get())); } blink::MediaStreamAudioTrack* track() const { - return blink::MediaStreamAudioTrack::From(blink_audio_track_); + return blink::MediaStreamAudioTrack::From(media_stream_component_); } int InjectAudio(media::AudioBus* audio_bus) { @@ -94,23 +96,23 @@ class HTMLAudioElementCapturerSourceTest : public testing::Test { kAudioTrackSamplesPerBuffer /* frames_per_buffer */); audio_source_->Initialize(params, &fake_callback_); - blink_audio_source_.Initialize(blink::WebString::FromUTF8("audio_id"), - blink::WebMediaStreamSource::kTypeAudio, - blink::WebString::FromUTF8("audio_track"), - false /* remote */); - blink_audio_track_.Initialize(blink_audio_source_.Id(), - blink_audio_source_); - - // |blink_audio_source_| takes ownership of HtmlAudioElementCapturerSource. - blink_audio_source_.SetPlatformSource( - std::make_unique<HtmlAudioElementCapturerSource>( - audio_source_.get(), - blink::scheduler::GetSingleThreadTaskRunnerForTesting())); - ASSERT_TRUE(source()->ConnectToTrack(blink_audio_track_)); + media_stream_source_ = MakeGarbageCollected<MediaStreamSource>( + String::FromUTF8("audio_id"), MediaStreamSource::kTypeAudio, + String::FromUTF8("audio_track"), false /* remote */); + media_stream_component_ = MakeGarbageCollected<MediaStreamComponent>( + media_stream_source_->Id(), media_stream_source_); + + // |media_stream_source_| takes wnership of + // HtmlAudioElementCapturerSource. + auto capture_source = std::make_unique<HtmlAudioElementCapturerSource>( + audio_source_, blink::scheduler::GetSingleThreadTaskRunnerForTesting()); + capture_source->SetOwner(media_stream_source_.Get()); + media_stream_source_->SetPlatformSource(std::move(capture_source)); + ASSERT_TRUE(source()->ConnectToTrack(media_stream_component_.Get())); } - blink::WebMediaStreamSource blink_audio_source_; - blink::WebMediaStreamTrack blink_audio_track_; + Persistent<MediaStreamSource> media_stream_source_; + Persistent<MediaStreamComponent> media_stream_component_; media::NullMediaLog media_log_; media::FakeAudioRenderCallback fake_callback_; diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.cc index 057be6f0854..98e3056fd5e 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.cc +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.cc @@ -7,13 +7,13 @@ #include <memory> #include "third_party/blink/public/platform/platform.h" #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/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h" #include "third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_handler.h" #include "third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.h" #include "third_party/blink/renderer/modules/mediastream/media_stream.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" namespace { const double kDefaultFrameRate = 60.0; @@ -56,17 +56,17 @@ MediaStream* HTMLCanvasElementCapture::captureStream( } LocalFrame* frame = ToLocalFrameIfNotDetached(script_state->GetContext()); - WebMediaStreamTrack track; + MediaStreamComponent* component = nullptr; const WebSize size(element.width(), element.height()); std::unique_ptr<CanvasCaptureHandler> handler; if (given_frame_rate) { handler = CanvasCaptureHandler::CreateCanvasCaptureHandler( frame, size, frame_rate, Platform::Current()->GetIOTaskRunner(), - &track); + &component); } else { handler = CanvasCaptureHandler::CreateCanvasCaptureHandler( frame, size, kDefaultFrameRate, Platform::Current()->GetIOTaskRunner(), - &track); + &component); } if (!handler) { @@ -81,10 +81,10 @@ MediaStream* HTMLCanvasElementCapture::captureStream( CanvasCaptureMediaStreamTrack* canvas_track; if (given_frame_rate) { canvas_track = MakeGarbageCollected<CanvasCaptureMediaStreamTrack>( - track, &element, context, std::move(handler), frame_rate); + component, &element, context, std::move(handler), frame_rate); } else { canvas_track = MakeGarbageCollected<CanvasCaptureMediaStreamTrack>( - track, &element, context, std::move(handler)); + component, &element, context, std::move(handler)); } // We want to capture a frame in the beginning. canvas_track->requestFrame(); diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc index 9cad18a1db2..a6e1e91e793 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc @@ -8,7 +8,6 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" #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/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/renderer/bindings/core/v8/v8_binding_for_core.h" @@ -26,6 +25,8 @@ #include "third_party/blink/renderer/modules/mediastream/media_stream_utils.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.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/uuid.h" namespace blink { @@ -101,24 +102,24 @@ void CreateHTMLAudioElementCapturer( DCHECK(web_media_stream); DCHECK(web_media_player); - blink::WebMediaStreamSource web_media_stream_source; - blink::WebMediaStreamTrack web_media_stream_track; - const WebString track_id(WTF::CreateCanonicalUUIDString()); + const String track_id = WTF::CreateCanonicalUUIDString(); - web_media_stream_source.Initialize(track_id, - blink::WebMediaStreamSource::kTypeAudio, - track_id, false /* is_remote */); - web_media_stream_track.Initialize(web_media_stream_source); + auto* media_stream_source = MakeGarbageCollected<MediaStreamSource>( + track_id, MediaStreamSource::StreamType::kTypeAudio, track_id, + false /* is_remote */); + auto* media_stream_component = + MakeGarbageCollected<MediaStreamComponent>(media_stream_source); - blink::MediaStreamAudioSource* const media_stream_source = + MediaStreamAudioSource* const media_stream_audio_source = HtmlAudioElementCapturerSource::CreateFromWebMediaPlayerImpl( web_media_player, std::move(task_runner)); - // Takes ownership of |media_stream_source|. - web_media_stream_source.SetPlatformSource( - base::WrapUnique(media_stream_source)); + // |media_stream_source| takes ownership of |media_stream_audio_source|. + media_stream_audio_source->SetOwner(media_stream_source); + media_stream_source->SetPlatformSource( + base::WrapUnique(media_stream_audio_source)); - blink::WebMediaStreamSource::Capabilities capabilities; + WebMediaStreamSource::Capabilities capabilities; capabilities.device_id = track_id; capabilities.echo_cancellation.emplace_back(false); capabilities.auto_gain_control.emplace_back(false); @@ -127,10 +128,10 @@ void CreateHTMLAudioElementCapturer( media::SampleFormatToBitsPerChannel(media::kSampleFormatS16), // min media::SampleFormatToBitsPerChannel(media::kSampleFormatS16) // max }; - web_media_stream_source.SetCapabilities(capabilities); + media_stream_source->SetCapabilities(capabilities); - media_stream_source->ConnectToTrack(web_media_stream_track); - web_media_stream->AddTrack(web_media_stream_track); + media_stream_audio_source->ConnectToTrack(media_stream_component); + web_media_stream->AddTrack(media_stream_component); } // Class to register to the events of |m_mediaElement|, acting accordingly on @@ -140,7 +141,7 @@ class MediaElementEventListener final : public NativeEventListener { MediaElementEventListener(HTMLMediaElement*, MediaStream*); void UpdateSources(ExecutionContext*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // EventListener implementation. void Invoke(ExecutionContext*, Event*) override; @@ -196,9 +197,10 @@ void MediaElementEventListener::Invoke(ExecutionContext* context, return; } - WebMediaStream web_stream; - web_stream.Initialize(WebVector<WebMediaStreamTrack>(), - WebVector<WebMediaStreamTrack>()); + auto* descriptor = MakeGarbageCollected<MediaStreamDescriptor>( + WTF::CreateCanonicalUUIDString(), MediaStreamComponentVector(), + MediaStreamComponentVector()); + WebMediaStream web_stream(descriptor); if (media_element_->HasVideo()) { CreateHTMLVideoElementCapturer( @@ -215,16 +217,16 @@ void MediaElementEventListener::Invoke(ExecutionContext* context, TaskType::kInternalMediaRealTime)); } - WebVector<WebMediaStreamTrack> video_tracks = web_stream.VideoTracks(); - for (const auto& track : video_tracks) - media_stream_->AddTrackByComponentAndFireEvents(track); + MediaStreamComponentVector video_components = descriptor->VideoComponents(); + for (auto component : video_components) + media_stream_->AddTrackByComponentAndFireEvents(component); - WebVector<WebMediaStreamTrack> audio_tracks = web_stream.AudioTracks(); - for (const auto& track : audio_tracks) - media_stream_->AddTrackByComponentAndFireEvents(track); + MediaStreamComponentVector audio_components = descriptor->AudioComponents(); + for (auto component : audio_components) + media_stream_->AddTrackByComponentAndFireEvents(component); - DVLOG(2) << "#videotracks: " << video_tracks.size() - << " #audiotracks: " << audio_tracks.size(); + DVLOG(2) << "#videotracks: " << video_components.size() + << " #audiotracks: " << audio_components.size(); UpdateSources(context); } @@ -254,7 +256,7 @@ void MediaElementEventListener::UpdateSources(ExecutionContext* context) { } } -void MediaElementEventListener::Trace(Visitor* visitor) { +void MediaElementEventListener::Trace(Visitor* visitor) const { visitor->Trace(media_element_); visitor->Trace(media_stream_); visitor->Trace(sources_); @@ -290,12 +292,12 @@ MediaStream* HTMLMediaElementCapture::captureStream( return nullptr; } - WebMediaStream web_stream; - web_stream.Initialize(WebVector<WebMediaStreamTrack>(), - WebVector<WebMediaStreamTrack>()); + auto* descriptor = MakeGarbageCollected<MediaStreamDescriptor>( + WTF::CreateCanonicalUUIDString(), MediaStreamComponentVector(), + MediaStreamComponentVector()); - // Create() duplicates the MediaStreamTracks inside |webStream|. - MediaStream* stream = MediaStream::Create(context, web_stream); + // Create() duplicates the MediaStreamTracks inside |descriptor|. + MediaStream* stream = MediaStream::Create(context, descriptor); MediaElementEventListener* listener = MakeGarbageCollected<MediaElementEventListener>(&element, stream); @@ -309,6 +311,8 @@ MediaStream* HTMLMediaElementCapture::captureStream( return MediaStream::Create(context, descriptor); } + WebMediaStream web_stream(descriptor); + LocalFrame* frame = ToLocalFrameIfNotDetached(script_state->GetContext()); DCHECK(frame); if (element.HasVideo()) { 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 900d4534bc2..a712281d527 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 @@ -116,8 +116,10 @@ void HtmlVideoElementCapturerSource::sendNewFrame() { TRACE_EVENT0("media", "HtmlVideoElementCapturerSource::sendNewFrame"); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (!web_media_player_ || new_frame_callback_.is_null()) + if (!web_media_player_ || new_frame_callback_.is_null() || + web_media_player_->WouldTaintOrigin()) { return; + } const base::TimeTicks current_time = base::TimeTicks::Now(); if (start_capture_time_.is_null()) 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 4d24f214880..13c693f8e07 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 @@ -48,6 +48,7 @@ class MockWebMediaPlayer : public WebMediaPlayer { void SetRate(double) override {} void SetVolume(double) override {} void SetLatencyHint(double) override {} + void SetPreservesPitch(bool) override {} void OnRequestPictureInPicture() override {} void OnPictureInPictureAvailabilityChanged(bool available) override {} WebTimeRanges Buffered() const override { return WebTimeRanges(); } @@ -71,7 +72,7 @@ class MockWebMediaPlayer : public WebMediaPlayer { WebString GetErrorMessage() const override { return WebString(); } bool DidLoadingProgress() override { return true; } - bool WouldTaintOrigin() const override { return false; } + bool WouldTaintOrigin() const override { return would_taint_origin_; } double MediaTimeForTimeValue(double timeValue) const override { return 0.0; } unsigned DecodedFrameCount() const override { return 0; } unsigned DroppedFrameCount() const override { return 0; } @@ -79,6 +80,8 @@ class MockWebMediaPlayer : public WebMediaPlayer { uint64_t AudioDecodedByteCount() const override { return 0; } uint64_t VideoDecodedByteCount() const override { return 0; } + void SetWouldTaintOrigin(bool taint) { would_taint_origin_ = taint; } + void Paint(cc::PaintCanvas* canvas, const WebRect& rect, cc::PaintFlags&, @@ -98,6 +101,7 @@ class MockWebMediaPlayer : public WebMediaPlayer { bool is_video_opaque_ = true; gfx::Size size_ = gfx::Size(16, 10); + bool would_taint_origin_ = false; base::WeakPtrFactory<MockWebMediaPlayer> weak_factory_{this}; }; @@ -326,4 +330,36 @@ TEST_F(HTMLVideoElementCapturerSourceTest, SizeChange) { Mock::VerifyAndClearExpectations(this); } +// Checks that the usual sequence of GetPreferredFormats() -> +// StartCapture() -> StopCapture() works as expected and let it capture two +// frames, that are tested for format vs the expected source opacity. +TEST_F(HTMLVideoElementCapturerSourceTest, TaintedPlayerDoesNotDeliverFrames) { + InSequence s; + media::VideoCaptureFormats formats = + html_video_capturer_->GetPreferredFormats(); + ASSERT_EQ(1u, formats.size()); + EXPECT_EQ(web_media_player_->NaturalSize(), formats[0].frame_size); + web_media_player_->SetWouldTaintOrigin(true); + + media::VideoCaptureParams params; + params.requested_format = formats[0]; + + EXPECT_CALL(*this, DoOnRunning(true)).Times(1); + + // No frames should be delivered. + EXPECT_CALL(*this, DoOnDeliverFrame(_, _)).Times(0); + html_video_capturer_->StartCapture( + params, + WTF::BindRepeating(&HTMLVideoElementCapturerSourceTest::OnDeliverFrame, + base::Unretained(this)), + WTF::BindRepeating(&HTMLVideoElementCapturerSourceTest::OnRunning, + base::Unretained(this))); + + // Wait for frames to be potentially sent in a follow-up task. + base::RunLoop().RunUntilIdle(); + + html_video_capturer_->StopCapture(); + Mock::VerifyAndClearExpectations(this); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.cc index 57f87898277..00a76bef72f 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.cc +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.cc @@ -21,7 +21,7 @@ void OnRequestCanvasDrawListener::SendNewFrame( AutoCanvasDrawListener::SendNewFrame(image, context_provider); } -void OnRequestCanvasDrawListener::Trace(Visitor* visitor) { +void OnRequestCanvasDrawListener::Trace(Visitor* visitor) const { AutoCanvasDrawListener::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.h b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.h index 57fe0066d74..ab89980d6b2 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.h +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/on_request_canvas_draw_listener.h @@ -22,7 +22,7 @@ class OnRequestCanvasDrawListener : public AutoCanvasDrawListener { void SendNewFrame(scoped_refptr<StaticBitmapImage>, base::WeakPtr<WebGraphicsContext3DProviderWrapper>) final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.cc b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.cc index 83d2f40d27b..eafd759e225 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.cc +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.cc @@ -42,7 +42,7 @@ void TimedCanvasDrawListener::RequestFrameTimerFired(TimerBase*) { frame_capture_requested_ = true; } -void TimedCanvasDrawListener::Trace(Visitor* visitor) { +void TimedCanvasDrawListener::Trace(Visitor* visitor) const { OnRequestCanvasDrawListener::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.h b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.h index 6c3e58ae758..f3336d4a05b 100644 --- a/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.h +++ b/chromium/third_party/blink/renderer/modules/mediacapturefromelement/timed_canvas_draw_listener.h @@ -26,7 +26,7 @@ class TimedCanvasDrawListener final : public OnRequestCanvasDrawListener { static TimedCanvasDrawListener* Create(std::unique_ptr<CanvasCaptureHandler>, double frame_rate, ExecutionContext*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Implementation of TimerFiredFunction. diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc index ef217eb2a52..91959eac8a6 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder_unittest.cc @@ -16,9 +16,10 @@ #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" -#include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/web/web_heap.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -105,9 +106,9 @@ class AudioTrackRecorderTest : public testing::TestWithParam<ATRTestParams> { opus_decoder_(nullptr), first_source_cache_pos_(0) { ResetDecoder(first_params_); - PrepareBlinkTrack(); + PrepareTrack(); audio_track_recorder_ = std::make_unique<AudioTrackRecorder>( - codec_, blink_track_, + codec_, media_stream_component_, WTF::BindRepeating(&AudioTrackRecorderTest::OnEncodedAudio, WTF::Unretained(this)), ConvertToBaseOnceCallback(CrossThreadBindOnce([] {})), @@ -117,7 +118,7 @@ class AudioTrackRecorderTest : public testing::TestWithParam<ATRTestParams> { ~AudioTrackRecorderTest() { opus_decoder_destroy(opus_decoder_); opus_decoder_ = nullptr; - blink_track_.Reset(); + media_stream_component_ = nullptr; WebHeap::CollectAllGarbageForTesting(); audio_track_recorder_.reset(); // Let the message loop run to finish destroying the recorder properly. @@ -204,9 +205,9 @@ class AudioTrackRecorderTest : public testing::TestWithParam<ATRTestParams> { DoOnEncodedAudio(params, std::move(encoded_data), timestamp); } - // ATR and WebMediaStreamTrack for fooling it. + // AudioTrackRecorder and MediaStreamComponent for fooling it. std::unique_ptr<AudioTrackRecorder> audio_track_recorder_; - WebMediaStreamTrack blink_track_; + Persistent<MediaStreamComponent> media_stream_component_; // The codec we'll use for compression the audio. const AudioTrackRecorder::CodecId codec_; @@ -232,17 +233,18 @@ class AudioTrackRecorderTest : public testing::TestWithParam<ATRTestParams> { // Prepares a blink track of a given MediaStreamType and attaches the native // track, which can be used to capture audio data and pass it to the producer. // Adapted from media::WebRTCLocalAudioSourceProviderTest. - void PrepareBlinkTrack() { - WebMediaStreamSource audio_source; - audio_source.Initialize(WebString::FromUTF8("dummy_source_id"), - WebMediaStreamSource::kTypeAudio, - WebString::FromUTF8("dummy_source_name"), - false /* remote */); - audio_source.SetPlatformSource(std::make_unique<MediaStreamAudioSource>( - scheduler::GetSingleThreadTaskRunnerForTesting(), true)); - blink_track_.Initialize(WebString::FromUTF8("audio_track"), audio_source); - CHECK(MediaStreamAudioSource::From(audio_source) - ->ConnectToTrack(blink_track_)); + void PrepareTrack() { + auto* source = MakeGarbageCollected<MediaStreamSource>( + String::FromUTF8("dummy_source_id"), MediaStreamSource::kTypeAudio, + String::FromUTF8("dummy_source_name"), false /* remote */); + auto audio_source = std::make_unique<MediaStreamAudioSource>( + scheduler::GetSingleThreadTaskRunnerForTesting(), true); + audio_source->SetOwner(source); + source->SetPlatformSource(std::move(audio_source)); + media_stream_component_ = MakeGarbageCollected<MediaStreamComponent>( + String::FromUTF8("audio_track"), source); + CHECK(MediaStreamAudioSource::From(source)->ConnectToTrack( + media_stream_component_)); } DISALLOW_COPY_AND_ASSIGN(AudioTrackRecorderTest); 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 ed34cf77b0f..345c93a1528 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.cc @@ -20,7 +20,7 @@ const AtomicString& BlobEvent::InterfaceName() const { return event_interface_names::kBlobEvent; } -void BlobEvent::Trace(Visitor* visitor) { +void BlobEvent::Trace(Visitor* visitor) const { visitor->Trace(blob_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.h b/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.h index c02118390bb..7e4ae309387 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.h +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/blob_event.h @@ -34,7 +34,7 @@ class MODULES_EXPORT BlobEvent final : public Event { // Event const AtomicString& InterfaceName() const final; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<Blob> blob_; diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc index 47da141fed3..2d845f40ec2 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc @@ -448,7 +448,7 @@ void MediaRecorder::DispatchScheduledEvent() { DispatchEvent(*event); } -void MediaRecorder::Trace(Visitor* visitor) { +void MediaRecorder::Trace(Visitor* visitor) const { visitor->Trace(stream_); visitor->Trace(recorder_handler_); visitor->Trace(scheduled_events_); diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.h b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.h index f6194eed0f1..a8852a49670 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.h +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder.h @@ -87,7 +87,7 @@ class MODULES_EXPORT MediaRecorder // be sent, unless recording isn't active in which case nothing happens. void OnAllTracksEnded(); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: void CreateBlobEvent(Blob* blob, double timecode); 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 d364f59852a..1ac9e3cfc59 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 @@ -679,7 +679,7 @@ void MediaRecorderHandler::SetAudioFormatForTesting( recorder->OnSetFormat(params); } -void MediaRecorderHandler::Trace(Visitor* visitor) { +void MediaRecorderHandler::Trace(Visitor* visitor) const { visitor->Trace(media_stream_); visitor->Trace(video_tracks_); visitor->Trace(audio_tracks_); 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 34bc943424c..e1451983405 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 @@ -77,7 +77,7 @@ class MODULES_EXPORT MediaRecorderHandler final OnMediaCapabilitiesEncodingInfoCallback cb); String ActualMimeType(); - void Trace(Visitor*); + void Trace(Visitor*) const; private: friend class MediaRecorderHandlerTest; diff --git a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler_unittest.cc b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler_unittest.cc index 98c6416cc43..ab6398f857f 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler_unittest.cc +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler_unittest.cc @@ -192,7 +192,7 @@ class MediaRecorderHandlerTest : public TestWithParam<MediaRecorderTestParams>, // For generating test AudioBuses media::SineWaveAudioSource audio_source_; - MockMediaStreamVideoSource* video_source_ = 0; + MockMediaStreamVideoSource* video_source_ = nullptr; private: DISALLOW_COPY_AND_ASSIGN(MediaRecorderHandlerTest); 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 95e749732cd..0397c605efb 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 @@ -320,11 +320,10 @@ void VideoTrackRecorderImpl::Encoder::RetrieveFrameOnMainThread( const gfx::Size& old_visible_size = video_frame->visible_rect().size(); gfx::Size new_visible_size = old_visible_size; - media::VideoRotation video_rotation = media::VIDEO_ROTATION_0; - if (video_frame->metadata()->GetRotation( - media::VideoFrameMetadata::ROTATION, &video_rotation) && - (video_rotation == media::VIDEO_ROTATION_90 || - video_rotation == media::VIDEO_ROTATION_270)) { + media::VideoRotation video_rotation = + video_frame->metadata()->rotation.value_or(media::VIDEO_ROTATION_0); + if (video_rotation == media::VIDEO_ROTATION_90 || + video_rotation == media::VIDEO_ROTATION_270) { new_visible_size.SetSize(old_visible_size.height(), old_visible_size.width()); } 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 4d441913456..4650cf4e1a6 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 @@ -13,7 +13,6 @@ #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" -#include "third_party/blink/public/platform/web_string.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/web_heap.h" @@ -22,6 +21,8 @@ #include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/persistent.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.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" @@ -87,34 +88,35 @@ class VideoTrackRecorderTest media::VideoFrame::StorageType>> { public: VideoTrackRecorderTest() : mock_source_(new MockMediaStreamVideoSource()) { - const WebString webkit_track_id(WebString::FromASCII("dummy")); - blink_source_.Initialize(webkit_track_id, WebMediaStreamSource::kTypeVideo, - webkit_track_id, false /*remote*/); - blink_source_.SetPlatformSource(base::WrapUnique(mock_source_)); - blink_track_.Initialize(blink_source_); + const String track_id("dummy"); + source_ = MakeGarbageCollected<MediaStreamSource>( + track_id, MediaStreamSource::kTypeVideo, track_id, false /*remote*/); + mock_source_->SetOwner(source_); + source_->SetPlatformSource(base::WrapUnique(mock_source_)); + component_ = MakeGarbageCollected<MediaStreamComponent>(source_); track_ = new MediaStreamVideoTrack( mock_source_, WebPlatformMediaStreamSource::ConstraintsOnceCallback(), true /* enabled */); - blink_track_.SetPlatformTrack(base::WrapUnique(track_)); + component_->SetPlatformTrack(base::WrapUnique(track_)); // Paranoia checks. - EXPECT_EQ(blink_track_.Source().GetPlatformSource(), - blink_source_.GetPlatformSource()); + EXPECT_EQ(component_->Source()->GetPlatformSource(), + source_->GetPlatformSource()); EXPECT_TRUE(scheduler::GetSingleThreadTaskRunnerForTesting() ->BelongsToCurrentThread()); } ~VideoTrackRecorderTest() { - blink_track_.Reset(); - blink_source_.Reset(); - video_track_recorder_ = nullptr; + component_ = nullptr; + source_ = nullptr; + video_track_recorder_.reset(); WebHeap::CollectAllGarbageForTesting(); } void InitializeRecorder(VideoTrackRecorder::CodecId codec) { video_track_recorder_ = std::make_unique<VideoTrackRecorderImpl>( - codec, blink_track_, + codec, WebMediaStreamTrack(component_.Get()), ConvertToBaseRepeatingCallback( CrossThreadBindRepeating(&VideoTrackRecorderTest::OnEncodedVideo, CrossThreadUnretained(this))), @@ -156,11 +158,11 @@ class VideoTrackRecorderTest ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; // All members are non-const due to the series of initialize() calls needed. - // |mock_source_| is owned by |blink_source_|, |track_| by |blink_track_|. + // |mock_source_| is owned by |source_|, |track_| by |component_|. MockMediaStreamVideoSource* mock_source_; - WebMediaStreamSource blink_source_; + Persistent<MediaStreamSource> source_; MediaStreamVideoTrack* track_; - WebMediaStreamTrack blink_track_; + Persistent<MediaStreamComponent> component_; std::unique_ptr<VideoTrackRecorderImpl> video_track_recorder_; @@ -238,8 +240,7 @@ TEST_P(VideoTrackRecorderTest, VideoEncoding) { ASSERT_TRUE(!!video_frame); const double kFrameRate = 60.0f; - video_frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, - kFrameRate); + video_frame->metadata()->frame_rate = kFrameRate; InSequence s; const base::TimeTicks timeticks_now = base::TimeTicks::Now(); @@ -443,34 +444,35 @@ class VideoTrackRecorderPassthroughTest VideoTrackRecorderPassthroughTest() : mock_source_(new MockMediaStreamVideoSource()) { ON_CALL(*mock_source_, SupportsEncodedOutput).WillByDefault(Return(true)); - const WebString webkit_track_id(WebString::FromASCII("dummy")); - blink_source_.Initialize(webkit_track_id, WebMediaStreamSource::kTypeVideo, - webkit_track_id, false /*remote*/); - blink_source_.SetPlatformSource(base::WrapUnique(mock_source_)); - blink_track_.Initialize(blink_source_); + const String track_id("dummy"); + source_ = MakeGarbageCollected<MediaStreamSource>( + track_id, MediaStreamSource::kTypeVideo, track_id, false /*remote*/); + mock_source_->SetOwner(source_); + source_->SetPlatformSource(base::WrapUnique(mock_source_)); + component_ = MakeGarbageCollected<MediaStreamComponent>(source_); track_ = new MediaStreamVideoTrack( mock_source_, WebPlatformMediaStreamSource::ConstraintsOnceCallback(), true /* enabled */); - blink_track_.SetPlatformTrack(base::WrapUnique(track_)); + component_->SetPlatformTrack(base::WrapUnique(track_)); // Paranoia checks. - EXPECT_EQ(blink_track_.Source().GetPlatformSource(), - blink_source_.GetPlatformSource()); + EXPECT_EQ(component_->Source()->GetPlatformSource(), + source_->GetPlatformSource()); EXPECT_TRUE(scheduler::GetSingleThreadTaskRunnerForTesting() ->BelongsToCurrentThread()); } ~VideoTrackRecorderPassthroughTest() { - blink_track_.Reset(); - blink_source_.Reset(); + component_ = nullptr; + source_ = nullptr; video_track_recorder_.reset(); WebHeap::CollectAllGarbageForTesting(); } void InitializeRecorder() { video_track_recorder_ = std::make_unique<VideoTrackRecorderPassthrough>( - blink_track_, + WebMediaStreamTrack(component_.Get()), ConvertToBaseRepeatingCallback(CrossThreadBindRepeating( &VideoTrackRecorderPassthroughTest::OnEncodedVideo, CrossThreadUnretained(this))), @@ -488,11 +490,11 @@ class VideoTrackRecorderPassthroughTest ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; // All members are non-const due to the series of initialize() calls needed. - // |mock_source_| is owned by |blink_source_|, |track_| by |blink_track_|. + // |mock_source_| is owned by |source_|, |track_| by |component_|. MockMediaStreamVideoSource* mock_source_; - WebMediaStreamSource blink_source_; + Persistent<MediaStreamSource> source_; MediaStreamVideoTrack* track_; - WebMediaStreamTrack blink_track_; + Persistent<MediaStreamComponent> component_; std::unique_ptr<VideoTrackRecorderPassthrough> video_track_recorder_; }; 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 74807bfacc9..f76bc65b119 100644 --- a/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc +++ b/chromium/third_party/blink/renderer/modules/mediarecorder/vpx_encoder.cc @@ -296,26 +296,25 @@ base::TimeDelta VpxEncoder::EstimateFrameDuration(const VideoFrame& frame) { DCHECK(encoding_task_runner_->BelongsToCurrentThread()); using base::TimeDelta; - base::TimeDelta predicted_frame_duration; - if (!frame.metadata()->GetTimeDelta(VideoFrameMetadata::FRAME_DURATION, - &predicted_frame_duration) || - predicted_frame_duration <= base::TimeDelta()) { - // The source of the video frame did not provide the frame duration. Use - // the actual amount of time between the current and previous frame as a - // prediction for the next frame's duration. - // TODO(mcasas): This duration estimation could lead to artifacts if the - // cadence of the received stream is compromised (e.g. camera freeze, pause, - // remote packet loss). Investigate using GetFrameRate() in this case. - predicted_frame_duration = frame.timestamp() - last_frame_timestamp_; - } + + // If the source of the video frame did not provide the frame duration, use + // the actual amount of time between the current and previous frame as a + // prediction for the next frame's duration. + // TODO(mcasas): This duration estimation could lead to artifacts if the + // cadence of the received stream is compromised (e.g. camera freeze, pause, + // remote packet loss). Investigate using GetFrameRate() in this case. + base::TimeDelta predicted_frame_duration = + frame.timestamp() - last_frame_timestamp_; + base::TimeDelta frame_duration = + frame.metadata()->frame_duration.value_or(predicted_frame_duration); last_frame_timestamp_ = frame.timestamp(); - // Make sure |predicted_frame_duration| is in a safe range of values. + // Make sure |frame_duration| is in a safe range of values. const base::TimeDelta kMaxFrameDuration = base::TimeDelta::FromSecondsD(1.0 / 8); const base::TimeDelta kMinFrameDuration = base::TimeDelta::FromMilliseconds(1); return std::min(kMaxFrameDuration, - std::max(predicted_frame_duration, kMinFrameDuration)); + std::max(frame_duration, kMinFrameDuration)); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc index 902dc6d739b..918e2ad1d59 100644 --- a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc +++ b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.cc @@ -122,7 +122,7 @@ void MediaMetadata::SetArtworkInternal( artwork_.swap(processed_artwork); } -void MediaMetadata::Trace(Visitor* visitor) { +void MediaMetadata::Trace(Visitor* visitor) const { visitor->Trace(artwork_); visitor->Trace(session_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.h b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.h index 591a9fffc12..1f7306b8305 100644 --- a/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.h +++ b/chromium/third_party/blink/renderer/modules/mediasession/media_metadata.h @@ -54,7 +54,7 @@ class MODULES_EXPORT MediaMetadata final : public ScriptWrappable { // Called by MediaSession to associate or de-associate itself. void SetSession(MediaSession*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Called when one of the metadata fields is updated from script. It will 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 662ceac2e02..76705081a6c 100644 --- a/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc +++ b/chromium/third_party/blink/renderer/modules/mediasession/media_session.cc @@ -181,13 +181,6 @@ void MediaSession::setActionHandler(const String& action, } UseCounter::Count(GetExecutionContext(), WebFeature::kMediaSessionSkipAd); - } else if (action == "seekto" && - !RuntimeEnabledFeatures::MediaSessionSeekingEnabled( - GetExecutionContext())) { - exception_state.ThrowTypeError( - "The provided value 'seekto' is not a valid enum " - "value of type MediaSessionAction."); - return; } if (handler) { @@ -367,7 +360,7 @@ void MediaSession::DidReceiveAction( iter->value->InvokeAndReportException(this, blink_details); } -void MediaSession::Trace(Visitor* visitor) { +void MediaSession::Trace(Visitor* visitor) const { visitor->Trace(client_receiver_); visitor->Trace(metadata_); visitor->Trace(action_handlers_); diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_session.h b/chromium/third_party/blink/renderer/modules/mediasession/media_session.h index f357ea66a41..0a3e01ada80 100644 --- a/chromium/third_party/blink/renderer/modules/mediasession/media_session.h +++ b/chromium/third_party/blink/renderer/modules/mediasession/media_session.h @@ -54,7 +54,7 @@ class MODULES_EXPORT MediaSession final // internally when a new MediaMetadata object is set. void OnMetadataChanged(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class V8MediaSession; diff --git a/chromium/third_party/blink/renderer/modules/mediasession/media_session.idl b/chromium/third_party/blink/renderer/modules/mediasession/media_session.idl index b6f7aaa0ba1..3f9e8bafb9a 100644 --- a/chromium/third_party/blink/renderer/modules/mediasession/media_session.idl +++ b/chromium/third_party/blink/renderer/modules/mediasession/media_session.idl @@ -24,7 +24,7 @@ enum MediaSessionAction { "seekto" }; -callback MediaSessionActionHandler = void ([RuntimeEnabled=MediaSessionSeeking] MediaSessionActionDetails details); +callback MediaSessionActionHandler = void (MediaSessionActionDetails details); [ Exposed=Window, diff --git a/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.cc b/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.cc index cc4d23cbf92..f99065f3d12 100644 --- a/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.cc +++ b/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.cc @@ -14,7 +14,7 @@ namespace blink { NavigatorMediaSession::NavigatorMediaSession(Navigator& navigator) : Supplement<Navigator>(navigator) {} -void NavigatorMediaSession::Trace(Visitor* visitor) { +void NavigatorMediaSession::Trace(Visitor* visitor) const { visitor->Trace(session_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.h b/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.h index f55d6874f7a..12f7311fbb1 100644 --- a/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.h +++ b/chromium/third_party/blink/renderer/modules/mediasession/navigator_media_session.h @@ -28,7 +28,7 @@ class NavigatorMediaSession final explicit NavigatorMediaSession(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // The MediaSession instance of this Navigator. diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.cc b/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.cc index 2f8b01af3d1..0c1586c75a7 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.cc +++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.cc @@ -391,7 +391,7 @@ ExecutionContext* MediaSourceImpl::GetExecutionContext() const { return ExecutionContextLifecycleObserver::GetExecutionContext(); } -void MediaSourceImpl::Trace(Visitor* visitor) { +void MediaSourceImpl::Trace(Visitor* visitor) const { visitor->Trace(async_event_queue_); visitor->Trace(attached_element_); visitor->Trace(source_buffers_); @@ -625,7 +625,7 @@ void MediaSourceImpl::DurationChangeAlgorithm(double new_duration, } Deprecation::CountDeprecation( - attached_element_->GetDocument(), + attached_element_->GetExecutionContext(), WebFeature::kMediaSourceDurationTruncatingBuffered); // See also deprecated remove(new duration, old duration) behavior below. } diff --git a/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.h b/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.h index af950d136c8..770b121e865 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.h +++ b/chromium/third_party/blink/renderer/modules/mediasource/media_source_impl.h @@ -129,7 +129,7 @@ class MediaSourceImpl final : public EventTargetWithInlineData, void AddedToRegistry(); void RemovedFromRegistry(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void SetReadyState(const AtomicString&); 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 623bf778981..06d16615c9f 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc +++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.cc @@ -416,8 +416,9 @@ void SourceBuffer::abort(ExceptionState& exception_state) { return; } - Deprecation::CountDeprecation(source_->MediaElement()->GetDocument(), - WebFeature::kMediaSourceAbortRemove); + Deprecation::CountDeprecation( + source_->MediaElement()->GetExecutionContext(), + WebFeature::kMediaSourceAbortRemove); CancelRemove(); } @@ -1442,7 +1443,7 @@ void SourceBuffer::AppendError() { source_->EndOfStreamAlgorithm(WebMediaSource::kEndOfStreamStatusDecodeError); } -void SourceBuffer::Trace(Visitor* visitor) { +void SourceBuffer::Trace(Visitor* visitor) const { visitor->Trace(source_); visitor->Trace(track_defaults_); visitor->Trace(async_event_queue_); diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.h b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.h index 086fc82156e..92e444fc374 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.h +++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer.h @@ -114,7 +114,7 @@ class SourceBuffer final : public EventTargetWithInlineData, bool InitializationSegmentReceived(const WebVector<MediaTrackInfo>&) override; void NotifyParseWarning(const ParseWarning) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void Dispose(); diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.cc b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.cc index fc8f39dd9c3..d6dada303ce 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.cc +++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.cc @@ -78,7 +78,7 @@ const AtomicString& SourceBufferList::InterfaceName() const { return event_target_names::kSourceBufferList; } -void SourceBufferList::Trace(Visitor* visitor) { +void SourceBufferList::Trace(Visitor* visitor) const { visitor->Trace(async_event_queue_); visitor->Trace(list_); EventTargetWithInlineData::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.h b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.h index f7c05134444..12c5c03fda3 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.h +++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_list.h @@ -73,7 +73,7 @@ class SourceBufferList final : public EventTargetWithInlineData, return ExecutionContextClient::GetExecutionContext(); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void ScheduleEvent(const AtomicString&); diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.cc b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.cc index bc9f18752ac..8416de392d8 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.cc +++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.cc @@ -44,7 +44,7 @@ void SourceBufferTrackBaseSupplement::SetSourceBuffer( From(track).source_buffer_ = source_buffer; } -void SourceBufferTrackBaseSupplement::Trace(Visitor* visitor) { +void SourceBufferTrackBaseSupplement::Trace(Visitor* visitor) const { visitor->Trace(source_buffer_); Supplement<TrackBase>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h index 9f2ca92fa5b..539db5efb74 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h +++ b/chromium/third_party/blink/renderer/modules/mediasource/source_buffer_track_base_supplement.h @@ -24,7 +24,7 @@ class SourceBufferTrackBaseSupplement static SourceBuffer* sourceBuffer(TrackBase&); static void SetSourceBuffer(TrackBase&, SourceBuffer*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: static SourceBufferTrackBaseSupplement& From(TrackBase&); diff --git a/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.cc b/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.cc index 2c7dd45156d..4a4bb665659 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.cc +++ b/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.cc @@ -65,7 +65,7 @@ TrackDefaultList::TrackDefaultList( const HeapVector<Member<TrackDefault>>& track_defaults) : track_defaults_(track_defaults) {} -void TrackDefaultList::Trace(Visitor* visitor) { +void TrackDefaultList::Trace(Visitor* visitor) const { visitor->Trace(track_defaults_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.h b/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.h index fb727fa01a3..a3d7b4a0a14 100644 --- a/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.h +++ b/chromium/third_party/blink/renderer/modules/mediasource/track_default_list.h @@ -27,7 +27,7 @@ class TrackDefaultList final : public ScriptWrappable { unsigned length() const { return track_defaults_.size(); } TrackDefault* item(unsigned) const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: const HeapVector<Member<TrackDefault>> track_defaults_; diff --git a/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn b/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn index aca23b09e4c..50a762329a0 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/mediastream/BUILD.gn @@ -126,4 +126,6 @@ jumbo_source_set("test_support") { "//third_party/blink/public/mojom:mojom_platform_blink_headers", "//third_party/webrtc_overrides:webrtc_component", ] + + configs += [ "//third_party/blink/renderer:inside_blink" ] } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/DEPS b/chromium/third_party/blink/renderer/modules/mediastream/DEPS index fa70065c400..7902dc3c3e0 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/DEPS +++ b/chromium/third_party/blink/renderer/modules/mediastream/DEPS @@ -5,7 +5,6 @@ include_rules = [ "+base/strings/string_number_conversions.h", "+base/strings/stringprintf.h", "+base/containers/flat_map.h", - "+base/callback_helpers.h", # TODO(crbug.com/923394): Remove these dependencies once per-frame # task runners are used in all cases. 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 f7f6762041e..f2e97772016 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 @@ -18,6 +18,7 @@ #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -54,20 +55,20 @@ void ApplyConstraintsProcessor::ProcessRequest( DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(!request_completed_cb_); DCHECK(!current_request_); - DCHECK(!request->Track().IsNull()); - if (request->Track().Source().IsNull()) { + DCHECK(request->Track()); + if (!request->Track()->Source()) { CannotApplyConstraints( "Track has no source. ApplyConstraints not possible."); return; } request_completed_cb_ = std::move(callback); current_request_ = request; - if (current_request_->Track().Source().GetType() == - blink::WebMediaStreamSource::kTypeVideo) { + if (current_request_->Track()->Source()->GetType() == + MediaStreamSource::kTypeVideo) { ProcessVideoRequest(); } else { - DCHECK_EQ(current_request_->Track().Source().GetType(), - blink::WebMediaStreamSource::kTypeAudio); + DCHECK_EQ(current_request_->Track()->Source()->GetType(), + MediaStreamSource::kTypeAudio); ProcessAudioRequest(); } } @@ -75,8 +76,8 @@ void ApplyConstraintsProcessor::ProcessRequest( void ApplyConstraintsProcessor::ProcessAudioRequest() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(current_request_); - DCHECK_EQ(current_request_->Track().Source().GetType(), - blink::WebMediaStreamSource::kTypeAudio); + DCHECK_EQ(current_request_->Track()->Source()->GetType(), + MediaStreamSource::kTypeAudio); DCHECK(request_completed_cb_); blink::MediaStreamAudioSource* audio_source = GetCurrentAudioSource(); if (!audio_source) { @@ -96,8 +97,8 @@ void ApplyConstraintsProcessor::ProcessAudioRequest() { void ApplyConstraintsProcessor::ProcessVideoRequest() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(current_request_); - DCHECK_EQ(current_request_->Track().Source().GetType(), - blink::WebMediaStreamSource::kTypeVideo); + DCHECK_EQ(current_request_->Track()->Source()->GetType(), + MediaStreamSource::kTypeVideo); DCHECK(request_completed_cb_); video_source_ = GetCurrentVideoSource(); if (!video_source_) { @@ -236,14 +237,14 @@ blink::VideoCaptureSettings ApplyConstraintsProcessor::SelectVideoSettings( Vector<media::VideoCaptureFormat> formats) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(current_request_); - DCHECK_EQ(current_request_->Track().Source().GetType(), - blink::WebMediaStreamSource::kTypeVideo); + DCHECK_EQ(current_request_->Track()->Source()->GetType(), + MediaStreamSource::kTypeVideo); DCHECK(request_completed_cb_); DCHECK_GT(formats.size(), 0U); blink::VideoInputDeviceCapabilities device_capabilities; - device_capabilities.device_id = current_request_->Track().Source().Id(); - device_capabilities.group_id = current_request_->Track().Source().GroupId(); + device_capabilities.device_id = current_request_->Track()->Source()->Id(); + device_capabilities.group_id = current_request_->Track()->Source()->GroupId(); device_capabilities.facing_mode = GetCurrentVideoSource() ? GetCurrentVideoSource()->device().video_facing : media::MEDIA_VIDEO_FACING_NONE; @@ -274,9 +275,9 @@ blink::MediaStreamAudioSource* ApplyConstraintsProcessor::GetCurrentAudioSource() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(current_request_); - DCHECK(!current_request_->Track().IsNull()); + DCHECK(current_request_->Track()); return blink::MediaStreamAudioSource::From( - current_request_->Track().Source()); + current_request_->Track()->Source()); } blink::MediaStreamVideoTrack* @@ -297,8 +298,8 @@ ApplyConstraintsProcessor::GetCurrentVideoSource() { bool ApplyConstraintsProcessor::AbortIfVideoRequestStateInvalid() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(current_request_); - DCHECK_EQ(current_request_->Track().Source().GetType(), - blink::WebMediaStreamSource::kTypeVideo); + DCHECK_EQ(current_request_->Track()->Source()->GetType(), + MediaStreamSource::kTypeVideo); DCHECK(request_completed_cb_); if (GetCurrentVideoSource() != video_source_) { CannotApplyConstraints( 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 26ed5c8c207..fdfe859a24e 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 @@ -44,7 +44,7 @@ class MODULES_EXPORT ApplyConstraintsProcessor final void ProcessRequest(blink::ApplyConstraintsRequest* request, base::OnceClosure callback); - void Trace(Visitor* visitor) { visitor->Trace(current_request_); } + void Trace(Visitor* visitor) const { visitor->Trace(current_request_); } private: // Helpers for video device-capture requests. diff --git a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.cc b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.cc index 7ae4f625641..f61f2e20f54 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/apply_constraints_request.cc @@ -12,13 +12,13 @@ namespace blink { ApplyConstraintsRequest::ApplyConstraintsRequest( - const WebMediaStreamTrack& track, + MediaStreamComponent* component, const MediaConstraints& constraints, ScriptPromiseResolver* resolver) - : track_(track), constraints_(constraints), resolver_(resolver) {} + : component_(component), constraints_(constraints), resolver_(resolver) {} -WebMediaStreamTrack ApplyConstraintsRequest::Track() const { - return track_; +MediaStreamComponent* ApplyConstraintsRequest::Track() const { + return component_; } MediaConstraints ApplyConstraintsRequest::Constraints() const { @@ -26,10 +26,10 @@ MediaConstraints ApplyConstraintsRequest::Constraints() const { } void ApplyConstraintsRequest::RequestSucceeded() { - track_.SetConstraints(constraints_); + component_->SetConstraints(constraints_); if (resolver_) resolver_->Resolve(); - track_.Reset(); + component_ = nullptr; } void ApplyConstraintsRequest::RequestFailed(const String& constraint, @@ -38,10 +38,11 @@ void ApplyConstraintsRequest::RequestFailed(const String& constraint, resolver_->Reject( MakeGarbageCollected<OverconstrainedError>(constraint, message)); } - track_.Reset(); + component_ = nullptr; } -void ApplyConstraintsRequest::Trace(Visitor* visitor) { +void ApplyConstraintsRequest::Trace(Visitor* visitor) const { + visitor->Trace(component_); visitor->Trace(resolver_); } 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 aaeda6f6554..88edca62424 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 @@ -5,11 +5,11 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_APPLY_CONSTRAINTS_REQUEST_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_APPLY_CONSTRAINTS_REQUEST_H_ -#include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/blink/renderer/platform/mediastream/media_constraints.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" namespace blink { @@ -18,20 +18,20 @@ class ScriptPromiseResolver; class MODULES_EXPORT ApplyConstraintsRequest final : public GarbageCollected<ApplyConstraintsRequest> { public: - ApplyConstraintsRequest(const WebMediaStreamTrack&, + ApplyConstraintsRequest(MediaStreamComponent*, const MediaConstraints&, ScriptPromiseResolver*); - WebMediaStreamTrack Track() const; + MediaStreamComponent* Track() const; MediaConstraints Constraints() const; void RequestSucceeded(); void RequestFailed(const String& constraint, const String& message); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; private: - WebMediaStreamTrack track_; + Member<MediaStreamComponent> component_; MediaConstraints constraints_; Member<ScriptPromiseResolver> resolver_; }; diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc index 1ef736cb077..9cc7a7d34a0 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc @@ -497,6 +497,7 @@ MediaConstraints Create(ExecutionContext* context, void CopyLongConstraint(const LongOrConstrainLongRange& blink_union_form, NakedValueDisposition naked_treatment, LongConstraint& web_form) { + web_form.SetIsPresent(true); if (blink_union_form.IsLong()) { switch (naked_treatment) { case NakedValueDisposition::kTreatAsIdeal: @@ -526,6 +527,7 @@ void CopyLongConstraint(const LongOrConstrainLongRange& blink_union_form, void CopyDoubleConstraint(const DoubleOrConstrainDoubleRange& blink_union_form, NakedValueDisposition naked_treatment, DoubleConstraint& web_form) { + web_form.SetIsPresent(true); if (blink_union_form.IsDouble()) { switch (naked_treatment) { case NakedValueDisposition::kTreatAsIdeal: @@ -552,11 +554,31 @@ void CopyDoubleConstraint(const DoubleOrConstrainDoubleRange& blink_union_form, } } +void CopyBooleanOrDoubleConstraint( + const BooleanOrDoubleOrConstrainDoubleRange& blink_union_form, + NakedValueDisposition naked_treatment, + DoubleConstraint& web_form) { + if (blink_union_form.IsBoolean()) { + web_form.SetIsPresent(blink_union_form.GetAsBoolean()); + return; + } + DoubleOrConstrainDoubleRange double_constraint; + if (blink_union_form.IsDouble()) { + double_constraint.SetDouble(blink_union_form.GetAsDouble()); + } else { + DCHECK(blink_union_form.IsConstrainDoubleRange()); + double_constraint.SetConstrainDoubleRange( + blink_union_form.GetAsConstrainDoubleRange()); + } + CopyDoubleConstraint(double_constraint, naked_treatment, web_form); +} + void CopyStringConstraint( const StringOrStringSequenceOrConstrainDOMStringParameters& blink_union_form, NakedValueDisposition naked_treatment, StringConstraint& web_form) { + web_form.SetIsPresent(true); if (blink_union_form.IsString()) { switch (naked_treatment) { case NakedValueDisposition::kTreatAsIdeal: @@ -601,6 +623,7 @@ void CopyBooleanConstraint( const BooleanOrConstrainBooleanParameters& blink_union_form, NakedValueDisposition naked_treatment, BooleanConstraint& web_form) { + web_form.SetIsPresent(true); if (blink_union_form.IsBoolean()) { switch (naked_treatment) { case NakedValueDisposition::kTreatAsIdeal: @@ -689,16 +712,16 @@ void CopyConstraintSet(const MediaTrackConstraintSet* constraints_in, constraint_buffer.video_kind); } if (constraints_in->hasPan()) { - CopyDoubleConstraint(constraints_in->pan(), naked_treatment, - constraint_buffer.pan); + CopyBooleanOrDoubleConstraint(constraints_in->pan(), naked_treatment, + constraint_buffer.pan); } if (constraints_in->hasTilt()) { - CopyDoubleConstraint(constraints_in->tilt(), naked_treatment, - constraint_buffer.tilt); + CopyBooleanOrDoubleConstraint(constraints_in->tilt(), naked_treatment, + constraint_buffer.tilt); } if (constraints_in->hasZoom()) { - CopyDoubleConstraint(constraints_in->zoom(), naked_treatment, - constraint_buffer.zoom); + CopyBooleanOrDoubleConstraint(constraints_in->zoom(), naked_treatment, + constraint_buffer.zoom); } } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_test.cc index b7b29c300cf..a8a25d7e13a 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_test.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_constraints_test.cc @@ -116,6 +116,32 @@ TEST(MediaTrackConstraintsTest, ConstraintsToString) { MediaConstraints null_constraints; EXPECT_EQ("", null_constraints.ToString().Utf8()); + + MediaConstraints pan_constraints; + MediaTrackConstraintSetPlatform pan_basic; + Vector<MediaTrackConstraintSetPlatform> pan_advanced(static_cast<size_t>(1)); + pan_basic.pan.SetIsPresent(false); + pan_advanced[0].pan.SetIsPresent(true); + pan_constraints.Initialize(pan_basic, pan_advanced); + EXPECT_EQ("{advanced: [{pan: {}}]}", pan_constraints.ToString().Utf8()); + + MediaConstraints tilt_constraints; + MediaTrackConstraintSetPlatform tilt_basic; + Vector<MediaTrackConstraintSetPlatform> tilt_advanced(static_cast<size_t>(1)); + tilt_basic.tilt.SetIsPresent(false); + tilt_advanced[0].tilt.SetIsPresent(true); + tilt_constraints.Initialize(tilt_basic, tilt_advanced); + EXPECT_EQ("{advanced: [{tilt: {}}]}", tilt_constraints.ToString().Utf8()); + + MediaConstraints zoom_constraints; + MediaTrackConstraintSetPlatform zoom_basic; + Vector<MediaTrackConstraintSetPlatform> zoom_advanced(static_cast<size_t>(1)); + zoom_basic.zoom.SetIsPresent(false); + zoom_advanced[0].zoom.SetIsPresent(true); + zoom_constraints.Initialize(zoom_basic, zoom_advanced); + EXPECT_EQ("{advanced: [{zoom: {}}]}", zoom_constraints.ToString().Utf8()); + + // TODO(crbug.com/1086338): Test other constraints with IsPresent. } TEST(MediaTrackConstraintsTest, ConvertWebConstraintsBasic) { 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 323c7e42421..68c45c08f75 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.cc @@ -48,7 +48,7 @@ class PromiseResolverCallbacks final : public UserMediaRequest::Callbacks { resolver_->Reject(error); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(resolver_); UserMediaRequest::Callbacks::Trace(visitor); } @@ -363,7 +363,7 @@ void MediaDevices::SetDispatcherHostForTesting( WrapWeakPersistent(this))); } -void MediaDevices::Trace(Visitor* visitor) { +void MediaDevices::Trace(Visitor* visitor) const { visitor->Trace(receiver_); visitor->Trace(scheduled_events_); visitor->Trace(requests_); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.h b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.h index 212f6efa977..3e4467dde81 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_devices.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_devices.h @@ -90,7 +90,7 @@ class MODULES_EXPORT MediaDevices final device_change_test_callback_ = std::move(test_callback); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; DEFINE_ATTRIBUTE_EVENT_LISTENER(devicechange, kDevicechange) diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc index ae185e43611..a5e1b9d82e1 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.cc @@ -92,7 +92,15 @@ MediaStream* MediaStream::Create(ExecutionContext* context, MediaStream* MediaStream::Create(ExecutionContext* context, MediaStreamDescriptor* stream_descriptor) { - return MakeGarbageCollected<MediaStream>(context, stream_descriptor); + return MakeGarbageCollected<MediaStream>(context, stream_descriptor, + /*pan_tilt_zoom_allowed=*/false); +} + +MediaStream* MediaStream::Create(ExecutionContext* context, + MediaStreamDescriptor* stream_descriptor, + bool pan_tilt_zoom_allowed) { + return MakeGarbageCollected<MediaStream>(context, stream_descriptor, + pan_tilt_zoom_allowed); } MediaStream* MediaStream::Create(ExecutionContext* context, @@ -104,7 +112,8 @@ MediaStream* MediaStream::Create(ExecutionContext* context, } MediaStream::MediaStream(ExecutionContext* context, - MediaStreamDescriptor* stream_descriptor) + MediaStreamDescriptor* stream_descriptor, + bool pan_tilt_zoom_allowed) : ExecutionContextClient(context), descriptor_(stream_descriptor), scheduled_event_timer_( @@ -126,7 +135,7 @@ MediaStream::MediaStream(ExecutionContext* context, video_tracks_.ReserveCapacity(number_of_video_tracks); for (uint32_t i = 0; i < number_of_video_tracks; i++) { auto* new_track = MakeGarbageCollected<MediaStreamTrack>( - context, descriptor_->VideoComponent(i)); + context, descriptor_->VideoComponent(i), pan_tilt_zoom_allowed); new_track->RegisterMediaStream(this); video_tracks_.push_back(new_track); } @@ -498,7 +507,7 @@ void MediaStream::ScheduledEventTimerFired(TimerBase*) { events.clear(); } -void MediaStream::Trace(Visitor* visitor) { +void MediaStream::Trace(Visitor* visitor) const { visitor->Trace(audio_tracks_); visitor->Trace(video_tracks_); visitor->Trace(descriptor_); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.h index 00ce4749510..27b5301b6b0 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream.h @@ -49,7 +49,7 @@ class MODULES_EXPORT MediaStreamObserver : public GarbageCollectedMixin { // Invoked when |MediaStream::removeTrack| is called. virtual void OnStreamRemoveTrack(MediaStream*, MediaStreamTrack*) = 0; - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} }; class MODULES_EXPORT MediaStream final @@ -67,6 +67,9 @@ class MODULES_EXPORT MediaStream final // Creates a MediaStream matching the MediaStreamDescriptor. MediaStreamTracks // are created for any MediaStreamComponents attached to the descriptor. static MediaStream* Create(ExecutionContext*, MediaStreamDescriptor*); + static MediaStream* Create(ExecutionContext*, + MediaStreamDescriptor*, + bool pan_tilt_zoom_allowed); // Creates a MediaStream with the specified MediaStreamDescriptor and // MediaStreamTracks. The tracks must match the MediaStreamComponents attached // to the descriptor (or else a DCHECK fails). This allows you to create @@ -81,7 +84,9 @@ class MODULES_EXPORT MediaStream final const MediaStreamTrackVector& audio_tracks, const MediaStreamTrackVector& video_tracks); - MediaStream(ExecutionContext*, MediaStreamDescriptor*); + MediaStream(ExecutionContext*, + MediaStreamDescriptor*, + bool pan_tilt_zoom_allowed); MediaStream(ExecutionContext*, MediaStreamDescriptor*, const MediaStreamTrackVector& audio_tracks, @@ -141,7 +146,7 @@ class MODULES_EXPORT MediaStream final // ActiveScriptWrappable bool HasPendingActivity() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: bool AddEventListenerInternal( 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 fe29538cde1..28ad2a82a4e 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 @@ -114,14 +114,20 @@ VideoCaptureSettings::VideoCaptureSettings( base::Optional<bool> noise_reduction, const VideoTrackAdapterSettings& track_adapter_settings, base::Optional<double> min_frame_rate, - base::Optional<double> max_frame_rate) + base::Optional<double> max_frame_rate, + base::Optional<double> pan, + base::Optional<double> tilt, + base::Optional<double> zoom) : failed_constraint_name_(nullptr), device_id_(std::move(device_id)), capture_params_(capture_params), noise_reduction_(noise_reduction), track_adapter_settings_(track_adapter_settings), min_frame_rate_(min_frame_rate), - max_frame_rate_(max_frame_rate) { + max_frame_rate_(max_frame_rate), + pan_(pan), + tilt_(tilt), + zoom_(zoom) { DCHECK(!min_frame_rate || *min_frame_rate_ <= capture_params.requested_format.frame_rate); DCHECK(!track_adapter_settings.target_size() || diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h index 2424b7a8f45..d5977197773 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h @@ -69,7 +69,10 @@ class MODULES_EXPORT VideoCaptureSettings { base::Optional<bool> noise_reduction_, const VideoTrackAdapterSettings& track_adapter_settings, base::Optional<double> min_frame_rate, - base::Optional<double> max_frame_rate); + base::Optional<double> max_frame_rate, + base::Optional<double> pan = base::nullopt, + base::Optional<double> tilt = base::nullopt, + base::Optional<double> zoom = base::nullopt); VideoCaptureSettings(const VideoCaptureSettings& other); VideoCaptureSettings& operator=(const VideoCaptureSettings& other); @@ -127,6 +130,18 @@ class MODULES_EXPORT VideoCaptureSettings { DCHECK(HasValue()); return max_frame_rate_; } + const base::Optional<double>& pan() const { + DCHECK(HasValue()); + return pan_; + } + const base::Optional<double>& tilt() const { + DCHECK(HasValue()); + return tilt_; + } + const base::Optional<double>& zoom() const { + DCHECK(HasValue()); + return zoom_; + } private: const char* failed_constraint_name_; @@ -136,6 +151,9 @@ class MODULES_EXPORT VideoCaptureSettings { VideoTrackAdapterSettings track_adapter_settings_; base::Optional<double> min_frame_rate_; base::Optional<double> max_frame_rate_; + base::Optional<double> pan_; + base::Optional<double> tilt_; + base::Optional<double> zoom_; }; // This class represents the output the SelectSettings algorithm for audio diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h index 955b20a1e2b..ad388e2094a 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_sets.h @@ -11,8 +11,8 @@ #include <utility> #include <vector> +#include "base/check_op.h" #include "base/gtest_prod_util.h" -#include "base/logging.h" #include "base/optional.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/mediastream/media_constraints.h" 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 c3dbb578e7a..37708d98373 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 @@ -52,9 +52,9 @@ WebString ToWebString(media::VideoFacingMode facing_mode) { } } -// Returns the fitness distance between the ideal value of |constraint| and the -// closest value to it in the range [min, max]. -// Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. +// Returns the fitness distance between the ideal value of |constraint| and +// |value|. Based on +// https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. template <typename NumericConstraint> double NumericValueFitness(const NumericConstraint& constraint, decltype(constraint.Min()) value) { @@ -63,6 +63,29 @@ double NumericValueFitness(const NumericConstraint& constraint, : 0.0; } +// Returns the fitness distance between the ideal value of |constraint| and the +// closest value to it in the range [min, max]. +// If the ideal value is contained in the range, returns 1. +// If there is no ideal value, returns 0; +// Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. +template <typename NumericConstraint> +double NumericRangeFitness( + const NumericConstraint& constraint, + const media_constraints::NumericRangeSet<decltype(constraint.Min())>& + range) { + DCHECK(!range.IsEmpty()); + if (!constraint.HasIdeal()) + return 0.0; + + auto ideal = constraint.Ideal(); + if (range.Max().has_value() && ideal > *range.Max()) + return NumericConstraintFitnessDistance(ideal, *range.Max()); + else if (range.Min().has_value() && ideal < *range.Min()) + return NumericConstraintFitnessDistance(ideal, *range.Min()); + + return 1.0; +} + // Returns a custom distance between |native_value| and the ideal value and // allowed range for a constrainable property. The ideal value is obtained from // |constraint| and the allowed range is specified by |min| and |max|. @@ -402,6 +425,112 @@ bool FacingModeSatisfiesConstraint(media::VideoFacingMode value, return constraint.Matches(string_value); } +class PTZDeviceState { + public: + explicit PTZDeviceState(const MediaTrackConstraintSetPlatform& constraint_set) + : pan_set_(DoubleRangeSet::FromConstraint(constraint_set.pan)), + tilt_set_(DoubleRangeSet::FromConstraint(constraint_set.tilt)), + zoom_set_(DoubleRangeSet::FromConstraint(constraint_set.zoom)) {} + + PTZDeviceState(const DoubleRangeSet& pan_set, + const DoubleRangeSet& tilt_set, + const DoubleRangeSet& zoom_set) + : pan_set_(pan_set), tilt_set_(tilt_set), zoom_set_(zoom_set) {} + + PTZDeviceState(const PTZDeviceState& other) = default; + PTZDeviceState& operator=(const PTZDeviceState& other) = default; + + PTZDeviceState Intersection( + const MediaTrackConstraintSetPlatform& constraint_set) const { + DoubleRangeSet pan_intersection = pan_set_.Intersection( + DoubleRangeSet::FromConstraint(constraint_set.pan)); + DoubleRangeSet tilt_intersection = tilt_set_.Intersection( + DoubleRangeSet::FromConstraint(constraint_set.tilt)); + DoubleRangeSet zoom_intersection = zoom_set_.Intersection( + DoubleRangeSet::FromConstraint(constraint_set.zoom)); + + return PTZDeviceState(pan_intersection, tilt_intersection, + zoom_intersection); + } + + bool IsEmpty() const { + return pan_set_.IsEmpty() || tilt_set_.IsEmpty() || zoom_set_.IsEmpty(); + } + + double Fitness(const MediaTrackConstraintSetPlatform& basic_set) const { + return NumericRangeFitness(basic_set.pan, pan_set_) + + NumericRangeFitness(basic_set.tilt, tilt_set_) + + NumericRangeFitness(basic_set.zoom, zoom_set_); + } + + const char* FailedConstraintName() const { + MediaTrackConstraintSetPlatform dummy; + if (!pan_set_.IsEmpty()) + return dummy.pan.GetName(); + if (!tilt_set_.IsEmpty()) + return dummy.tilt.GetName(); + if (!zoom_set_.IsEmpty()) + return dummy.zoom.GetName(); + + // No failed constraint. + return nullptr; + } + + base::Optional<double> SelectPan( + const MediaTrackConstraintSetPlatform& basic_set) const { + return SelectProperty(&PTZDeviceState::pan_set_, basic_set, + &MediaTrackConstraintSetPlatform::pan); + } + + base::Optional<double> SelectTilt( + const MediaTrackConstraintSetPlatform& basic_set) const { + return SelectProperty(&PTZDeviceState::tilt_set_, basic_set, + &MediaTrackConstraintSetPlatform::tilt); + } + + base::Optional<double> SelectZoom( + const MediaTrackConstraintSetPlatform& basic_set) const { + return SelectProperty(&PTZDeviceState::zoom_set_, basic_set, + &MediaTrackConstraintSetPlatform::zoom); + } + + private: + // Select the target value of a property based on the ideal value in + // |basic_set| as follows: + // If an ideal value is provided, return the value in the range closest to + // ideal. + // If no ideal value is provided: + // * If minimum is provided, return minimum. + // * Otherwise, if maximum is provided, return maximum. + // * Otherwise, return nullopt. + base::Optional<double> SelectProperty( + DoubleRangeSet PTZDeviceState::*ptz_field, + const MediaTrackConstraintSetPlatform& basic_set, + DoubleConstraint MediaTrackConstraintSetPlatform::*basic_set_field) + const { + if (!(basic_set.*basic_set_field).HasIdeal()) { + return (this->*ptz_field).Min().has_value() ? (this->*ptz_field).Min() + : (this->*ptz_field).Max(); + } + + auto ideal = (basic_set.*basic_set_field).Ideal(); + if ((this->*ptz_field).Min().has_value() && + ideal < (this->*ptz_field).Min().value()) { + return (this->*ptz_field).Min(); + } + if ((this->*ptz_field).Max().has_value() && + ideal > (this->*ptz_field).Max().value()) { + return (this->*ptz_field).Max(); + } + + return ideal; + } + + DoubleRangeSet pan_set_; + DoubleRangeSet tilt_set_; + DoubleRangeSet zoom_set_; +}; + // Returns true if |constraint_set| can be satisfied by |device|. Otherwise, // returns false and, if |failed_constraint_name| is not null, updates // |failed_constraint_name| with the name of a constraint that could not be @@ -428,6 +557,21 @@ bool DeviceSatisfiesConstraintSet( return false; } + if (constraint_set.pan.IsPresent() && !device.pan_tilt_zoom_supported) { + UpdateFailedConstraintName(constraint_set.pan, failed_constraint_name); + return false; + } + + if (constraint_set.tilt.IsPresent() && !device.pan_tilt_zoom_supported) { + UpdateFailedConstraintName(constraint_set.tilt, failed_constraint_name); + return false; + } + + if (constraint_set.zoom.IsPresent() && !device.pan_tilt_zoom_supported) { + UpdateFailedConstraintName(constraint_set.zoom, failed_constraint_name); + return false; + } + return true; } @@ -464,11 +608,13 @@ double DeviceFitness(const DeviceInfo& device, // The track settings for |candidate| that correspond to the returned fitness // are returned in |track_settings|. double CandidateFitness(const DeviceInfo& device, + const PTZDeviceState& ptz_state, const CandidateFormat& candidate_format, const base::Optional<bool>& noise_reduction, const MediaTrackConstraintSetPlatform& constraint_set, VideoTrackAdapterSettings* track_settings) { return DeviceFitness(device, constraint_set) + + ptz_state.Fitness(constraint_set) + candidate_format.Fitness(constraint_set, track_settings) + OptionalBoolFitness(noise_reduction, constraint_set.goog_noise_reduction); @@ -524,11 +670,13 @@ VideoInputDeviceCapabilities::VideoInputDeviceCapabilities( String device_id, String group_id, Vector<media::VideoCaptureFormat> formats, - media::VideoFacingMode facing_mode) + media::VideoFacingMode facing_mode, + bool pan_tilt_zoom_supported) : device_id(std::move(device_id)), group_id(std::move(group_id)), formats(std::move(formats)), - facing_mode(facing_mode) {} + facing_mode(facing_mode), + pan_tilt_zoom_supported(pan_tilt_zoom_supported) {} VideoInputDeviceCapabilities::VideoInputDeviceCapabilities( VideoInputDeviceCapabilities&& other) = default; @@ -600,7 +748,14 @@ VideoCaptureSettings SelectSettingsVideoDeviceCapture( continue; } + PTZDeviceState ptz_device_state(constraints.Basic()); + if (ptz_device_state.IsEmpty()) { + failed_constraint_name = ptz_device_state.FailedConstraintName(); + continue; + } + for (auto& format : device.formats) { + PTZDeviceState ptz_state_for_format = ptz_device_state; CandidateFormat candidate_format(format); if (!candidate_format.ApplyConstraintSet(constraints.Basic(), &failed_constraint_name)) { @@ -622,8 +777,11 @@ VideoCaptureSettings SelectSettingsVideoDeviceCapture( // First criteria for valid candidates is satisfaction of advanced // constraint sets. for (const auto& advanced_set : constraints.Advanced()) { + PTZDeviceState ptz_advanced_state = + ptz_state_for_format.Intersection(advanced_set); bool satisfies_advanced_set = DeviceSatisfiesConstraintSet(device, advanced_set) && + !ptz_advanced_state.IsEmpty() && OptionalBoolSatisfiesConstraint( noise_reduction, advanced_set.goog_noise_reduction) && // This must be the last in the condition since it is the only @@ -631,15 +789,18 @@ VideoCaptureSettings SelectSettingsVideoDeviceCapture( // previous two are true. candidate_format.ApplyConstraintSet(advanced_set); + if (satisfies_advanced_set) + ptz_state_for_format = ptz_advanced_state; + candidate_distance_vector.push_back( satisfies_advanced_set ? 0 : HUGE_VAL); } VideoTrackAdapterSettings track_settings; // Second criterion is fitness distance. - candidate_distance_vector.push_back( - CandidateFitness(device, candidate_format, noise_reduction, - constraints.Basic(), &track_settings)); + candidate_distance_vector.push_back(CandidateFitness( + device, ptz_state_for_format, candidate_format, noise_reduction, + constraints.Basic(), &track_settings)); // Third criterion is native fitness distance. candidate_distance_vector.push_back( @@ -660,7 +821,10 @@ VideoCaptureSettings SelectSettingsVideoDeviceCapture( result = VideoCaptureSettings( device.device_id.Utf8(), capture_params, noise_reduction, track_settings, candidate_format.constrained_frame_rate().Min(), - candidate_format.constrained_frame_rate().Max()); + candidate_format.constrained_frame_rate().Max(), + ptz_state_for_format.SelectPan(constraints.Basic()), + ptz_state_for_format.SelectTilt(constraints.Basic()), + ptz_state_for_format.SelectZoom(constraints.Basic())); } } } 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 4bbaa2f2362..9ab76221342 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 @@ -32,7 +32,8 @@ struct MODULES_EXPORT VideoInputDeviceCapabilities { VideoInputDeviceCapabilities(String device_id, String group_id, Vector<media::VideoCaptureFormat> formats, - media::VideoFacingMode facing_mode); + media::VideoFacingMode facing_mode, + bool pan_tilt_zoom_supported); VideoInputDeviceCapabilities(); VideoInputDeviceCapabilities(VideoInputDeviceCapabilities&& other); VideoInputDeviceCapabilities& operator=(VideoInputDeviceCapabilities&& other); @@ -42,6 +43,7 @@ struct MODULES_EXPORT VideoInputDeviceCapabilities { String group_id; Vector<media::VideoCaptureFormat> formats; media::VideoFacingMode facing_mode; + bool pan_tilt_zoom_supported; }; struct MODULES_EXPORT VideoDeviceCaptureCapabilities { diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc index 326b787b176..ae5108b0729 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device_test.cc @@ -23,12 +23,21 @@ const char kDeviceID2[] = "fake_device_2"; const char kDeviceID3[] = "fake_device_3"; const char kDeviceID4[] = "fake_device_4"; const char kDeviceID5[] = "fake_device_5"; +const char kDeviceID6[] = "fake_device_6"; const char kGroupID1[] = "fake_group_1"; const char kGroupID2[] = "fake_group_2"; const char kGroupID3[] = "fake_group_3"; const char kGroupID4[] = "fake_group_4"; const char kGroupID5[] = "fake_group_5"; +const char kGroupID6[] = "fake_group_6"; + +const std::vector<DoubleConstraint MediaTrackConstraintSetPlatform::*> + kPanTiltZoomConstraints = { + &MediaTrackConstraintSetPlatform::pan, + &MediaTrackConstraintSetPlatform::tilt, + &MediaTrackConstraintSetPlatform::zoom, +}; void CheckTrackAdapterSettingsEqualsResolution( const VideoCaptureSettings& settings) { @@ -86,6 +95,7 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test { media::VideoCaptureFormat(gfx::Size(1000, 1000), 20.0f, media::PIXEL_FORMAT_I420), }; + device.pan_tilt_zoom_supported = true; capabilities_.device_capabilities.push_back(std::move(device)); // A low-resolution device. @@ -106,6 +116,7 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test { media::VideoCaptureFormat(gfx::Size(800, 600), 20.0f, media::PIXEL_FORMAT_I420), }; + device.pan_tilt_zoom_supported = true; capabilities_.device_capabilities.push_back(std::move(device)); // A high-resolution device. @@ -137,6 +148,7 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test { media::VideoCaptureFormat(gfx::Size(2304, 1536), 10.0f, media::PIXEL_FORMAT_I420), }; + device.pan_tilt_zoom_supported = true; capabilities_.device_capabilities.push_back(std::move(device)); // A depth capture device. @@ -160,6 +172,16 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test { media::VideoCaptureFormat(gfx::Size(500, 500), 0.1f, media::PIXEL_FORMAT_I420), }; + device.pan_tilt_zoom_supported = true; + capabilities_.device_capabilities.push_back(std::move(device)); + + // A camera device without PTZ. + device.device_id = kDeviceID6; + device.group_id = kGroupID6; + device.facing_mode = media::MEDIA_VIDEO_FACING_NONE; + device.formats = {media::VideoCaptureFormat(gfx::Size(640, 480), 30.0f, + media::PIXEL_FORMAT_I420)}; + device.pan_tilt_zoom_supported = false; capabilities_.device_capabilities.push_back(std::move(device)); capabilities_.noise_reduction_capabilities = { @@ -172,6 +194,7 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test { low_res_device_ = &capabilities_.device_capabilities[1]; high_res_device_ = &capabilities_.device_capabilities[2]; invalid_frame_rate_device_ = &capabilities_.device_capabilities[4]; + no_ptz_device_ = &capabilities_.device_capabilities[5]; default_closest_format_ = &default_device_->formats[1]; low_res_closest_format_ = &low_res_device_->formats[2]; high_res_closest_format_ = &high_res_device_->formats[3]; @@ -189,6 +212,7 @@ class MediaStreamConstraintsUtilVideoDeviceTest : public testing::Test { const VideoInputDeviceCapabilities* low_res_device_; const VideoInputDeviceCapabilities* high_res_device_; const VideoInputDeviceCapabilities* invalid_frame_rate_device_; + const VideoInputDeviceCapabilities* no_ptz_device_; // Closest formats to the default settings. const media::VideoCaptureFormat* default_closest_format_; const media::VideoCaptureFormat* low_res_closest_format_; @@ -401,6 +425,43 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, result.failed_constraint_name()); } +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, + OverconstrainedOnPanTiltZoom) { + for (auto& constraint : kPanTiltZoomConstraints) { + constraint_factory_.Reset(); + constraint_factory_.basic().device_id.SetExact(no_ptz_device_->device_id); + (constraint_factory_.basic().*constraint).SetIdeal(1); + auto result = SelectSettings(); + EXPECT_FALSE(result.HasValue()); + EXPECT_EQ((constraint_factory_.basic().*constraint).GetName(), + result.failed_constraint_name()); + + constraint_factory_.Reset(); + constraint_factory_.basic().device_id.SetExact(no_ptz_device_->device_id); + (constraint_factory_.basic().*constraint).SetMin(1); + result = SelectSettings(); + EXPECT_FALSE(result.HasValue()); + EXPECT_EQ((constraint_factory_.basic().*constraint).GetName(), + result.failed_constraint_name()); + + constraint_factory_.Reset(); + constraint_factory_.basic().device_id.SetExact(no_ptz_device_->device_id); + (constraint_factory_.basic().*constraint).SetMax(1); + result = SelectSettings(); + EXPECT_FALSE(result.HasValue()); + EXPECT_EQ((constraint_factory_.basic().*constraint).GetName(), + result.failed_constraint_name()); + + constraint_factory_.Reset(); + constraint_factory_.basic().device_id.SetExact(no_ptz_device_->device_id); + (constraint_factory_.basic().*constraint).SetExact(1); + result = SelectSettings(); + EXPECT_FALSE(result.HasValue()); + EXPECT_EQ((constraint_factory_.basic().*constraint).GetName(), + result.failed_constraint_name()); + } +} + // The "Mandatory" and "Ideal" tests check that various selection criteria work // for each individual constraint in the basic constraint set. TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryDeviceID) { @@ -1827,6 +1888,97 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, TwoIdealResizeValues) { EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); } +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryExactPanTiltZoom) { + for (auto& constraint : kPanTiltZoomConstraints) { + constraint_factory_.Reset(); + (constraint_factory_.basic().*constraint).SetExact(3); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // The algorithm should prefer the first device that supports PTZ natively, + // which is the default device. + EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id()); + if (constraint == &MediaTrackConstraintSetPlatform::pan) + EXPECT_EQ(3, result.pan().value()); + else if (constraint == &MediaTrackConstraintSetPlatform::tilt) + EXPECT_EQ(3, result.tilt().value()); + else if (constraint == &MediaTrackConstraintSetPlatform::zoom) + EXPECT_EQ(3, result.zoom().value()); + } +} + +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryMinPanTiltZoom) { + for (auto& constraint : kPanTiltZoomConstraints) { + constraint_factory_.Reset(); + (constraint_factory_.basic().*constraint).SetMin(2); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // The algorithm should prefer the first device that supports PTZ + // natively, which is the default device. + EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id()); + if (constraint == &MediaTrackConstraintSetPlatform::pan) + EXPECT_EQ(2, result.pan().value()); + else if (constraint == &MediaTrackConstraintSetPlatform::tilt) + EXPECT_EQ(2, result.tilt().value()); + else if (constraint == &MediaTrackConstraintSetPlatform::zoom) + EXPECT_EQ(2, result.zoom().value()); + } +} + +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryMaxPanTiltZoom) { + for (auto& constraint : kPanTiltZoomConstraints) { + constraint_factory_.Reset(); + (constraint_factory_.basic().*constraint).SetMax(4); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // The algorithm should prefer the first device that supports PTZ + // natively, which is the default device. + EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id()); + if (constraint == &MediaTrackConstraintSetPlatform::pan) + EXPECT_EQ(4, result.pan().value()); + else if (constraint == &MediaTrackConstraintSetPlatform::tilt) + EXPECT_EQ(4, result.tilt().value()); + else if (constraint == &MediaTrackConstraintSetPlatform::zoom) + EXPECT_EQ(4, result.zoom().value()); + } +} + +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryPanTiltZoomRange) { + for (auto& constraint : kPanTiltZoomConstraints) { + constraint_factory_.Reset(); + (constraint_factory_.basic().*constraint).SetMin(2); + (constraint_factory_.basic().*constraint).SetMax(4); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // The algorithm should prefer the first device that supports PTZ + // natively, which is the default device. + EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id()); + if (constraint == &MediaTrackConstraintSetPlatform::pan) + EXPECT_EQ(2, result.pan().value()); + else if (constraint == &MediaTrackConstraintSetPlatform::tilt) + EXPECT_EQ(2, result.tilt().value()); + else if (constraint == &MediaTrackConstraintSetPlatform::zoom) + EXPECT_EQ(2, result.zoom().value()); + } +} + +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, IdealPanTiltZoom) { + for (auto& constraint : kPanTiltZoomConstraints) { + constraint_factory_.Reset(); + (constraint_factory_.basic().*constraint).SetIdeal(3); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // The algorithm should select the first device that supports the ideal PTZ + // constraint natively, which is the default device. + EXPECT_EQ(default_device_->device_id.Utf8(), result.device_id()); + if (constraint == &MediaTrackConstraintSetPlatform::pan) + EXPECT_EQ(3, result.pan().value()); + else if (constraint == &MediaTrackConstraintSetPlatform::tilt) + EXPECT_EQ(3, result.tilt().value()); + else if (constraint == &MediaTrackConstraintSetPlatform::zoom) + EXPECT_EQ(3, result.zoom().value()); + } +} + // The "Advanced" tests check selection criteria involving advanced constraint // sets. TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, @@ -2393,6 +2545,44 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, } } +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, + AdvancedContradictoryPanTiltZoom) { + for (auto& constraint : kPanTiltZoomConstraints) { + constraint_factory_.Reset(); + + MediaTrackConstraintSetPlatform& advanced1 = + constraint_factory_.AddAdvanced(); + advanced1.device_id.SetExact({low_res_device_->device_id}); + + MediaTrackConstraintSetPlatform& advanced2 = + constraint_factory_.AddAdvanced(); + advanced2.device_id.SetExact({no_ptz_device_->device_id}); + (advanced2.*constraint).SetExact(4); + + MediaTrackConstraintSetPlatform& advanced3 = + constraint_factory_.AddAdvanced(); + (advanced3.*constraint).SetMin(4); + (advanced3.*constraint).SetMax(2); + + MediaTrackConstraintSetPlatform& advanced4 = + constraint_factory_.AddAdvanced(); + (advanced4.*constraint).SetExact(3); + + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + EXPECT_EQ(low_res_device_->device_id.Utf8(), result.device_id()); + // The second advanced set must be ignored because it contradicts the first + // set. The third advanced must be ignored because it is invalid. The fourth + // advanced set must be applied. + if (constraint == &MediaTrackConstraintSetPlatform::pan) + EXPECT_EQ(3, result.pan().value()); + else if (constraint == &MediaTrackConstraintSetPlatform::tilt) + EXPECT_EQ(3, result.tilt().value()); + else if (constraint == &MediaTrackConstraintSetPlatform::zoom) + EXPECT_EQ(3, result.zoom().value()); + } +} + TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedResize) { constraint_factory_.Reset(); constraint_factory_.basic().width.SetIdeal(1); @@ -2439,6 +2629,26 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, EXPECT_EQ(result.FrameRate(), 30.0); } +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedPanTiltZoom) { + for (auto& constraint : kPanTiltZoomConstraints) { + constraint_factory_.Reset(); + constraint_factory_.basic().device_id.SetExact(no_ptz_device_->device_id); + MediaTrackConstraintSetPlatform& advanced = + constraint_factory_.AddAdvanced(); + (advanced.*constraint).SetExact(3); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + EXPECT_EQ(no_ptz_device_->device_id.Utf8(), result.device_id()); + // The advanced set must be ignored because the device does not support PTZ. + if (constraint == &MediaTrackConstraintSetPlatform::pan) + EXPECT_FALSE(result.pan().has_value()); + else if (constraint == &MediaTrackConstraintSetPlatform::tilt) + EXPECT_FALSE(result.tilt().has_value()); + else if (constraint == &MediaTrackConstraintSetPlatform::zoom) + EXPECT_FALSE(result.zoom().has_value()); + } +} + TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, BasicContradictoryWidth) { constraint_factory_.Reset(); constraint_factory_.basic().width.SetMin(10); @@ -2460,6 +2670,19 @@ TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, result.failed_constraint_name()); } +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, + BasicContradictoryPanTiltZoom) { + for (auto& constraint : kPanTiltZoomConstraints) { + constraint_factory_.Reset(); + (constraint_factory_.basic().*constraint).SetMin(4); + (constraint_factory_.basic().*constraint).SetMax(2); + auto result = SelectSettings(); + EXPECT_FALSE(result.HasValue()); + EXPECT_EQ((constraint_factory_.basic().*constraint).GetName(), + result.failed_constraint_name()); + } +} + // The "NoDevices" tests verify that the algorithm returns the expected result // when there are no candidates to choose from. TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, NoDevicesNoConstraints) { 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 6ef3e5b0c43..c188707b875 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 @@ -132,6 +132,7 @@ void MediaStreamDeviceObserver::OnDeviceChanged( void MediaStreamDeviceObserver::BindMediaStreamDeviceObserverReceiver( mojo::PendingReceiver<mojom::blink::MediaStreamDeviceObserver> receiver) { + receiver_.reset(); 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 3e844ab1a70..46d1a50d176 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 @@ -64,6 +64,8 @@ class MODULES_EXPORT MediaStreamDeviceObserver GetNonScreenCaptureDevices); FRIEND_TEST_ALL_PREFIXES(MediaStreamDeviceObserverTest, OnDeviceStopped); FRIEND_TEST_ALL_PREFIXES(MediaStreamDeviceObserverTest, OnDeviceChanged); + FRIEND_TEST_ALL_PREFIXES(MediaStreamDeviceObserverTest, + OnDeviceChangedChangesDeviceAfterRebind); // Private class for keeping track of opened devices and who have // opened it. diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer_test.cc index cecfcb2b035..7a8e309c778 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer_test.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_device_observer_test.cc @@ -11,8 +11,10 @@ #include "base/bind.h" #include "base/run_loop.h" +#include "mojo/public/cpp/bindings/remote.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/mediastream/media_stream_request.h" +#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h" #include "third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.h" namespace blink { @@ -157,4 +159,49 @@ TEST_F(MediaStreamDeviceObserverTest, OnDeviceChanged) { EXPECT_EQ(observer_->label_stream_map_.size(), 0u); } +TEST_F(MediaStreamDeviceObserverTest, OnDeviceChangedChangesDeviceAfterRebind) { + const String kStreamLabel = "stream_label"; + const std::string kDeviceName = "Video Device"; + const blink::mojom::MediaStreamType kDeviceType = + blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE; + + // Add a device to the |observer_|, to be changed using OnChangedDevice(). + blink::MediaStreamDevice initial_device(kDeviceType, "initial_device", + kDeviceName); + observer_->AddStream(kStreamLabel, initial_device); + + // Call the |observer_|'s bind callback and check that its internal + // |receiver_| is bound. + mojo::Remote<mojom::blink::MediaStreamDeviceObserver> remote_observer; + EXPECT_FALSE(observer_->receiver_.is_bound()); + observer_->BindMediaStreamDeviceObserverReceiver( + remote_observer.BindNewPipeAndPassReceiver()); + EXPECT_TRUE(observer_->receiver_.is_bound()); + + // Send an OnDeviceChanged() message using the remote mojo pipe, and verify + // that the device is changed. + blink::MediaStreamDevice changed_device = + blink::MediaStreamDevice(kDeviceType, "video_device-123", kDeviceName); + remote_observer->OnDeviceChanged(kStreamLabel, initial_device, + changed_device); + base::RunLoop().RunUntilIdle(); + blink::MediaStreamDevices video_devices = + observer_->GetNonScreenCaptureDevices(); + ASSERT_EQ(video_devices.size(), 1u); + EXPECT_EQ(video_devices[0].id, "video_device-123"); + + // Reset the remote end of the mojo pipe, then rebind it, and verify that + // OnDeviceChanged() changes the device after rebind. + remote_observer.reset(); + observer_->BindMediaStreamDeviceObserverReceiver( + remote_observer.BindNewPipeAndPassReceiver()); + remote_observer->OnDeviceChanged( + kStreamLabel, changed_device, + blink::MediaStreamDevice(kDeviceType, "video_device-456", kDeviceName)); + base::RunLoop().RunUntilIdle(); + video_devices = observer_->GetNonScreenCaptureDevices(); + ASSERT_EQ(video_devices.size(), 1u); + EXPECT_EQ(video_devices[0].id, "video_device-456"); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.cc index f7f7d15d361..cff093d87cf 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.cc @@ -58,7 +58,7 @@ const AtomicString& MediaStreamEvent::InterfaceName() const { return event_interface_names::kMediaStreamEvent; } -void MediaStreamEvent::Trace(Visitor* visitor) { +void MediaStreamEvent::Trace(Visitor* visitor) const { visitor->Trace(stream_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.h index f07e7876b68..423800a5e01 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_event.h @@ -48,7 +48,7 @@ class MediaStreamEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<MediaStream> stream_; 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 5f69944b4ea..e5c9a44512d 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,12 +11,14 @@ #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/web_local_frame.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.h" #include "third_party/blink/renderer/modules/mediastream/track_audio_renderer.h" #include "third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h" #include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h" #include "third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h" #include "third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/webrtc/api/media_stream_interface.h" @@ -65,13 +67,14 @@ MediaStreamRendererFactoryImpl::GetVideoRenderer( DVLOG(1) << "MediaStreamRendererFactoryImpl::GetVideoRenderer stream:" << web_stream.Id().Utf8(); - WebVector<WebMediaStreamTrack> video_tracks = web_stream.VideoTracks(); - if (video_tracks.empty() || - !MediaStreamVideoTrack::GetTrack(video_tracks[0])) { + MediaStreamDescriptor& descriptor = *web_stream; + auto video_components = descriptor.VideoComponents(); + if (video_components.IsEmpty() || + !MediaStreamVideoTrack::GetTrack(video_components[0].Get())) { return nullptr; } - return new MediaStreamVideoRendererSink(video_tracks[0], repaint_cb, + return new MediaStreamVideoRendererSink(video_components[0].Get(), repaint_cb, std::move(io_task_runner), std::move(main_render_task_runner)); } @@ -86,14 +89,16 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer( SendLogMessage(String::Format("%s({web_stream_id=%s}, {device_id=%s})", __func__, web_stream.Id().Utf8().c_str(), device_id.Utf8().c_str())); - WebVector<WebMediaStreamTrack> audio_tracks = web_stream.AudioTracks(); - if (audio_tracks.empty()) { + + MediaStreamDescriptor& descriptor = *web_stream; + auto audio_components = descriptor.AudioComponents(); + if (audio_components.IsEmpty()) { // The stream contains no audio tracks. Log error message if the stream // contains no video tracks either. Without this extra check, video-only // streams would generate error messages at this stage and we want to // avoid that. - WebVector<WebMediaStreamTrack> video_tracks = web_stream.VideoTracks(); - if (video_tracks.empty()) { + auto video_tracks = descriptor.VideoComponents(); + if (video_tracks.IsEmpty()) { SendLogMessage(String::Format( "%s => (ERROR: no audio tracks in media stream)", __func__)); } @@ -108,7 +113,7 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer( // For now, we have separate renderers depending on if the first audio track // in the stream is local or remote. MediaStreamAudioTrack* audio_track = - MediaStreamAudioTrack::From(audio_tracks[0]); + MediaStreamAudioTrack::From(audio_components[0].Get()); if (!audio_track) { // This can happen if the track was cloned. // TODO(tommi, perkj): Fix cloning of tracks to handle extra data too. @@ -126,7 +131,11 @@ MediaStreamRendererFactoryImpl::GetAudioRenderer( "%s => (creating TrackAudioRenderer for %s audio track)", __func__, audio_track->is_local_track() ? "local" : "remote")); - return new TrackAudioRenderer(audio_tracks[0], web_frame, + auto* frame = + web_frame + ? static_cast<LocalFrame*>(WebLocalFrame::ToCoreFrame(*web_frame)) + : nullptr; + return new TrackAudioRenderer(audio_components[0].Get(), frame, /*session_id=*/base::UnguessableToken(), String(device_id), std::move(on_render_error_callback)); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc index 16da5aa1972..9c4aa3aa3b1 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.cc @@ -155,59 +155,59 @@ bool ConstraintsHaveImageCapture(const MediaTrackConstraints* constraints) { // Caller must take the ownership of the returned |WebAudioSourceProvider| // object. std::unique_ptr<WebAudioSourceProvider> -CreateWebAudioSourceFromMediaStreamTrack(const WebMediaStreamTrack& track, +CreateWebAudioSourceFromMediaStreamTrack(MediaStreamComponent* component, int context_sample_rate) { - WebPlatformMediaStreamTrack* media_stream_track = track.GetPlatformTrack(); + WebPlatformMediaStreamTrack* media_stream_track = + component->GetPlatformTrack(); if (!media_stream_track) { DLOG(ERROR) << "Native track missing for webaudio source."; return nullptr; } - WebMediaStreamSource source = track.Source(); - DCHECK_EQ(source.GetType(), WebMediaStreamSource::kTypeAudio); + MediaStreamSource* source = component->Source(); + DCHECK_EQ(source->GetType(), MediaStreamSource::kTypeAudio); - return std::make_unique<WebAudioMediaStreamAudioSink>(track, + return std::make_unique<WebAudioMediaStreamAudioSink>(component, context_sample_rate); } -void CloneNativeVideoMediaStreamTrack(const WebMediaStreamTrack& original, - WebMediaStreamTrack clone) { - DCHECK(!clone.GetPlatformTrack()); - WebMediaStreamSource source = clone.Source(); - DCHECK_EQ(source.GetType(), WebMediaStreamSource::kTypeVideo); +void CloneNativeVideoMediaStreamTrack(MediaStreamComponent* original, + MediaStreamComponent* clone) { + DCHECK(!clone->GetPlatformTrack()); + MediaStreamSource* source = clone->Source(); + DCHECK_EQ(source->GetType(), MediaStreamSource::kTypeVideo); MediaStreamVideoSource* native_source = MediaStreamVideoSource::GetVideoSource(source); DCHECK(native_source); MediaStreamVideoTrack* original_track = MediaStreamVideoTrack::GetVideoTrack(original); DCHECK(original_track); - clone.SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>( + clone->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>( native_source, original_track->adapter_settings(), original_track->noise_reduction(), original_track->is_screencast(), original_track->min_frame_rate(), - MediaStreamVideoSource::ConstraintsOnceCallback(), clone.IsEnabled())); + MediaStreamVideoSource::ConstraintsOnceCallback(), clone->Enabled())); } void DidSetMediaStreamTrackEnabled(MediaStreamComponent* component) { - const WebMediaStreamTrack track(component); - auto* native_track = WebPlatformMediaStreamTrack::GetTrack(track); + auto* native_track = WebPlatformMediaStreamTrack::GetTrack(component); if (native_track) native_track->SetEnabled(component->Enabled()); } -void DidCloneMediaStreamTrack(const WebMediaStreamTrack& original, - const WebMediaStreamTrack& clone) { - DCHECK(!clone.IsNull()); - DCHECK(!clone.GetPlatformTrack()); - DCHECK(!clone.Source().IsNull()); +void DidCloneMediaStreamTrack(MediaStreamComponent* original, + MediaStreamComponent* clone) { + DCHECK(clone); + DCHECK(!clone->GetPlatformTrack()); + DCHECK(clone->Source()); - switch (clone.Source().GetType()) { - case WebMediaStreamSource::kTypeAudio: + switch (clone->Source()->GetType()) { + case MediaStreamSource::kTypeAudio: // TODO(crbug.com/704136): Use per thread task runner. MediaStreamUtils::CreateNativeAudioMediaStreamTrack( clone, Thread::MainThread()->GetTaskRunner()); break; - case WebMediaStreamSource::kTypeVideo: + case MediaStreamSource::kTypeVideo: CloneNativeVideoMediaStreamTrack(original, clone); break; } @@ -219,11 +219,21 @@ MediaStreamTrack::MediaStreamTrack(ExecutionContext* context, MediaStreamComponent* component) : MediaStreamTrack(context, component, - component->Source()->GetReadyState()) {} + component->Source()->GetReadyState(), + /*pan_tilt_zoom_allowed=*/false) {} + +MediaStreamTrack::MediaStreamTrack(ExecutionContext* context, + MediaStreamComponent* component, + bool pan_tilt_zoom_allowed) + : MediaStreamTrack(context, + component, + component->Source()->GetReadyState(), + pan_tilt_zoom_allowed) {} MediaStreamTrack::MediaStreamTrack(ExecutionContext* context, MediaStreamComponent* component, - MediaStreamSource::ReadyState ready_state) + MediaStreamSource::ReadyState ready_state, + bool pan_tilt_zoom_allowed) : ready_state_(ready_state), component_(component), execution_context_(context) { @@ -236,9 +246,8 @@ MediaStreamTrack::MediaStreamTrack(ExecutionContext* context, if (component_->Source() && component_->Source()->GetType() == MediaStreamSource::kTypeVideo) { - // ImageCapture::create() only throws if |this| track is not of video type. - NonThrowableExceptionState exception_state; - image_capture_ = ImageCapture::Create(context, this, exception_state); + image_capture_ = MakeGarbageCollected<ImageCapture>(context, this, + pan_tilt_zoom_allowed); } } @@ -393,8 +402,12 @@ void MediaStreamTrack::stopTrack(ExecutionContext* execution_context) { MediaStreamTrack* MediaStreamTrack::clone(ScriptState* script_state) { MediaStreamComponent* cloned_component = Component()->Clone(); + bool pan_tilt_zoom_allowed = + image_capture_ ? image_capture_->HasPanTiltZoomPermissionGranted() + : false; MediaStreamTrack* cloned_track = MakeGarbageCollected<MediaStreamTrack>( - ExecutionContext::From(script_state), cloned_component, ready_state_); + ExecutionContext::From(script_state), cloned_component, ready_state_, + pan_tilt_zoom_allowed); DidCloneMediaStreamTrack(Component(), cloned_component); return cloned_track; } @@ -406,7 +419,7 @@ void MediaStreamTrack::SetConstraints(const MediaConstraints& constraints) { MediaTrackCapabilities* MediaStreamTrack::getCapabilities() const { MediaTrackCapabilities* capabilities = MediaTrackCapabilities::Create(); if (image_capture_) - capabilities = image_capture_->GetMediaTrackCapabilities(); + image_capture_->GetMediaTrackCapabilities(capabilities); auto platform_capabilities = component_->Source()->GetCapabilities(); capabilities->setDeviceId(platform_capabilities.device_id); @@ -803,7 +816,7 @@ ExecutionContext* MediaStreamTrack::GetExecutionContext() const { return execution_context_.Get(); } -void MediaStreamTrack::Trace(Visitor* visitor) { +void MediaStreamTrack::Trace(Visitor* visitor) const { visitor->Trace(registered_media_streams_); visitor->Trace(component_); visitor->Trace(image_capture_); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.h index 5652168de8f..cc011f37f94 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track.h @@ -57,7 +57,11 @@ class MODULES_EXPORT MediaStreamTrack MediaStreamTrack(ExecutionContext*, MediaStreamComponent*); MediaStreamTrack(ExecutionContext*, MediaStreamComponent*, - MediaStreamSource::ReadyState); + bool pan_tilt_zoom_allowed); + MediaStreamTrack(ExecutionContext*, + MediaStreamComponent*, + MediaStreamSource::ReadyState, + bool pan_tilt_zoom_allowed); ~MediaStreamTrack() override; String kind() const; @@ -106,7 +110,9 @@ class MODULES_EXPORT MediaStreamTrack std::unique_ptr<AudioSourceProvider> CreateWebAudioSource( int context_sample_rate); - void Trace(Visitor*) override; + ImageCapture* GetImageCapture() { return image_capture_; } + + void Trace(Visitor*) const override; private: friend class CanvasCaptureMediaStreamTrack; diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.cc index 115f3981d52..da3327aebfe 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.cc @@ -57,7 +57,7 @@ const AtomicString& MediaStreamTrackEvent::InterfaceName() const { return event_interface_names::kMediaStreamTrackEvent; } -void MediaStreamTrackEvent::Trace(Visitor* visitor) { +void MediaStreamTrackEvent::Trace(Visitor* visitor) const { visitor->Trace(track_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.h index 152deed005d..6d8350d32cd 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_track_event.h @@ -51,7 +51,7 @@ class MediaStreamTrackEvent final : public Event { // Event const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<MediaStreamTrack> track_; diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc index 52957ccf554..e82b8a22e00 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc @@ -18,26 +18,25 @@ namespace blink { namespace { -void CreateNativeVideoMediaStreamTrack(blink::WebMediaStreamTrack track) { - DCHECK(!track.GetPlatformTrack()); - blink::WebMediaStreamSource source = track.Source(); - DCHECK_EQ(source.GetType(), blink::WebMediaStreamSource::kTypeVideo); - blink::MediaStreamVideoSource* native_source = - blink::MediaStreamVideoSource::GetVideoSource(source); +void CreateNativeVideoMediaStreamTrack(MediaStreamComponent* component) { + DCHECK(!component->GetPlatformTrack()); + MediaStreamSource* source = component->Source(); + DCHECK_EQ(source->GetType(), MediaStreamSource::kTypeVideo); + MediaStreamVideoSource* native_source = + MediaStreamVideoSource::GetVideoSource(source); DCHECK(native_source); - track.SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>( + component->SetPlatformTrack(std::make_unique<blink::MediaStreamVideoTrack>( native_source, blink::MediaStreamVideoSource::ConstraintsOnceCallback(), - track.IsEnabled())); + component->Enabled())); } } // namespace void MediaStreamUtils::CreateNativeAudioMediaStreamTrack( - const blink::WebMediaStreamTrack& track, + MediaStreamComponent* component, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { - WebMediaStreamSource source = track.Source(); - MediaStreamAudioSource* media_stream_source = - blink::MediaStreamAudioSource::From(source); + MediaStreamSource* source = component->Source(); + MediaStreamAudioSource* audio_source = MediaStreamAudioSource::From(source); // At this point, a MediaStreamAudioSource instance must exist. The one // exception is when a WebAudio destination node is acting as a source of @@ -46,15 +45,16 @@ void MediaStreamUtils::CreateNativeAudioMediaStreamTrack( // TODO(miu): This needs to be moved to an appropriate location. A WebAudio // source should have been created before this method was called so that this // special case code isn't needed here. - if (!media_stream_source && source.RequiresAudioConsumer()) { + if (!audio_source && source->RequiresAudioConsumer()) { DVLOG(1) << "Creating WebAudio media stream source."; - media_stream_source = - new blink::WebAudioMediaStreamSource(&source, task_runner); - source.SetPlatformSource( - base::WrapUnique(media_stream_source)); // Takes ownership. + audio_source = new WebAudioMediaStreamSource(source, task_runner); + // |source| takes ownership of |audio_source|. + audio_source->SetOwner(source); + source->SetPlatformSource( + base::WrapUnique(audio_source)); // Takes ownership. - blink::WebMediaStreamSource::Capabilities capabilities; - capabilities.device_id = source.Id(); + WebMediaStreamSource::Capabilities capabilities; + capabilities.device_id = source->Id(); // TODO(crbug.com/704136): Switch away from std::vector. capabilities.echo_cancellation = std::vector<bool>({false}); capabilities.auto_gain_control = std::vector<bool>({false}); @@ -63,7 +63,7 @@ void MediaStreamUtils::CreateNativeAudioMediaStreamTrack( media::SampleFormatToBitsPerChannel(media::kSampleFormatS16), // min media::SampleFormatToBitsPerChannel(media::kSampleFormatS16) // max }; - auto parameters = media_stream_source->GetAudioParameters(); + auto parameters = audio_source->GetAudioParameters(); if (parameters.IsValid()) { capabilities.channel_count = {1, parameters.channels()}; capabilities.sample_rate = {parameters.sample_rate(), @@ -71,30 +71,30 @@ void MediaStreamUtils::CreateNativeAudioMediaStreamTrack( capabilities.latency = {parameters.GetBufferDuration().InSecondsF(), parameters.GetBufferDuration().InSecondsF()}; } - source.SetCapabilities(capabilities); + source->SetCapabilities(capabilities); } - if (media_stream_source) - media_stream_source->ConnectToTrack(track); + if (audio_source) + audio_source->ConnectToTrack(component); else - LOG(DFATAL) << "WebMediaStreamSource missing its MediaStreamAudioSource."; + LOG(DFATAL) << "MediaStreamSource missing its MediaStreamAudioSource."; } // TODO(crbug.com/704136): Change this method to take the task // runner instance, and use per thread task runner on the call site. void MediaStreamUtils::DidCreateMediaStreamTrack( MediaStreamComponent* component) { - WebMediaStreamTrack track(component); - DCHECK(!track.IsNull() && !track.GetPlatformTrack()); - DCHECK(!track.Source().IsNull()); + DCHECK(component); + DCHECK(!component->GetPlatformTrack()); + DCHECK(component->Source()); - switch (track.Source().GetType()) { - case blink::WebMediaStreamSource::kTypeAudio: - CreateNativeAudioMediaStreamTrack(track, + switch (component->Source()->GetType()) { + case MediaStreamSource::kTypeAudio: + CreateNativeAudioMediaStreamTrack(component, Thread::MainThread()->GetTaskRunner()); break; - case blink::WebMediaStreamSource::kTypeVideo: - CreateNativeVideoMediaStreamTrack(track); + case MediaStreamSource::kTypeVideo: + CreateNativeVideoMediaStreamTrack(component); break; } } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.h index 38b365b708a..60974aa56de 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_utils.h @@ -15,14 +15,13 @@ class SingleThreadTaskRunner; namespace blink { class MediaStreamComponent; -class WebMediaStreamTrack; class MediaStreamUtils { STATIC_ONLY(MediaStreamUtils); public: static void CreateNativeAudioMediaStreamTrack( - const WebMediaStreamTrack&, + MediaStreamComponent*, scoped_refptr<base::SingleThreadTaskRunner>); static void DidCreateMediaStreamTrack(MediaStreamComponent*); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source_test.cc index 87fab684cfc..4f1da326910 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source_test.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_capturer_source_test.cc @@ -90,8 +90,7 @@ class FakeMediaStreamVideoSink : public MediaStreamVideoSink { void OnVideoFrame(scoped_refptr<media::VideoFrame> frame, base::TimeTicks capture_time) { *capture_time_ = capture_time; - metadata_->Clear(); - metadata_->MergeMetadataFrom(frame->metadata()); + *metadata_ = *frame->metadata(); std::move(got_frame_cb_).Run(); } @@ -245,17 +244,14 @@ TEST_F(MediaStreamVideoCapturerSourceTest, CaptureTimeAndMetadataPlumbing) { fake_sink.ConnectToTrack(track); const scoped_refptr<media::VideoFrame> frame = media::VideoFrame::CreateBlackFrame(gfx::Size(2, 2)); - frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, 30.0); + frame->metadata()->frame_rate = 30.0; PostCrossThreadTask( *Platform::Current()->GetIOTaskRunner(), FROM_HERE, CrossThreadBindOnce(deliver_frame_cb, frame, reference_capture_time)); run_loop.Run(); fake_sink.DisconnectFromTrack(); EXPECT_EQ(reference_capture_time, capture_time); - double metadata_value; - EXPECT_TRUE(metadata.GetDouble(media::VideoFrameMetadata::FRAME_RATE, - &metadata_value)); - EXPECT_EQ(30.0, metadata_value); + EXPECT_EQ(30.0, *metadata.frame_rate); } TEST_F(MediaStreamVideoCapturerSourceTest, Restart) { 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 c778a33803d..8a9f2155257 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 @@ -12,6 +12,7 @@ #include "media/base/video_frame.h" #include "media/base/video_frame_metadata.h" #include "media/base/video_util.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.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" @@ -86,10 +87,8 @@ class MediaStreamVideoRendererSink::FrameDeliverer { if (!video_frame) return; - video_frame->metadata()->SetBoolean( - media::VideoFrameMetadata::END_OF_STREAM, true); - video_frame->metadata()->SetTimeTicks( - media::VideoFrameMetadata::REFERENCE_TIME, base::TimeTicks::Now()); + video_frame->metadata()->end_of_stream = true; + video_frame->metadata()->reference_time = base::TimeTicks::Now(); OnVideoFrame(video_frame, base::TimeTicks()); } @@ -133,12 +132,12 @@ class MediaStreamVideoRendererSink::FrameDeliverer { }; MediaStreamVideoRendererSink::MediaStreamVideoRendererSink( - const WebMediaStreamTrack& video_track, + MediaStreamComponent* video_component, const RepaintCB& repaint_cb, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner) : repaint_cb_(repaint_cb), - video_track_(video_track), + video_component_(video_component), io_task_runner_(std::move(io_task_runner)), main_render_task_runner_(std::move(main_render_task_runner)) {} @@ -157,7 +156,7 @@ void MediaStreamVideoRendererSink::Start() { WTF::CrossThreadUnretained(frame_deliverer_.get()))); MediaStreamVideoSink::ConnectToTrack( - video_track_, + WebMediaStreamTrack(video_component_.Get()), // This callback is run on IO thread. It is safe to use base::Unretained // here because |frame_receiver_| will be destroyed on IO thread after // sink is disconnected from track. @@ -167,9 +166,9 @@ void MediaStreamVideoRendererSink::Start() { // Local display video rendering is considered a secure link. true); - if (video_track_.Source().GetReadyState() == - WebMediaStreamSource::kReadyStateEnded || - !video_track_.IsEnabled()) { + if (video_component_->Source()->GetReadyState() == + MediaStreamSource::kReadyStateEnded || + !video_component_->Enabled()) { PostCrossThreadTask( *io_task_runner_, FROM_HERE, CrossThreadBindOnce(&FrameDeliverer::RenderEndOfStream, diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.h b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.h index eedf02271c4..c8b8f1363f5 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.h @@ -11,9 +11,9 @@ #include "base/threading/thread_checker.h" #include "third_party/blink/public/common/media/video_capture.h" #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_video_renderer.h" -#include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_sink.h" #include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "ui/gfx/geometry/size.h" namespace base { @@ -39,7 +39,7 @@ class MODULES_EXPORT MediaStreamVideoRendererSink public MediaStreamVideoSink { public: MediaStreamVideoRendererSink( - const WebMediaStreamTrack& video_track, + MediaStreamComponent* video_component, const WebMediaStreamVideoRenderer::RepaintCB& repaint_cb, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, scoped_refptr<base::SingleThreadTaskRunner> main_render_task_runner); @@ -69,7 +69,7 @@ class MODULES_EXPORT MediaStreamVideoRendererSink State GetStateForTesting(); const RepaintCB repaint_cb_; - const WebMediaStreamTrack video_track_; + Persistent<MediaStreamComponent> video_component_; // Inner class used for transfering frames on compositor thread and running // |repaint_cb_|. diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink_test.cc index ce9215d3568..87fd93576e7 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink_test.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink_test.cc @@ -16,11 +16,12 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.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/web_heap.h" #include "third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h" #include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h" #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" @@ -36,19 +37,20 @@ class MediaStreamVideoRendererSinkTest : public testing::Test { public: MediaStreamVideoRendererSinkTest() : mock_source_(new MockMediaStreamVideoSource()) { - blink_source_.Initialize(WebString::FromASCII("dummy_source_id"), - WebMediaStreamSource::kTypeVideo, - WebString::FromASCII("dummy_source_name"), - false /* remote */); - blink_source_.SetPlatformSource(base::WrapUnique(mock_source_)); - blink_track_ = MediaStreamVideoTrack::CreateVideoTrack( + media_stream_source_ = MakeGarbageCollected<MediaStreamSource>( + String::FromUTF8("dummy_source_id"), MediaStreamSource::kTypeVideo, + String::FromUTF8("dummy_source_name"), false /* remote */); + mock_source_->SetOwner(media_stream_source_.Get()); + media_stream_source_->SetPlatformSource(base::WrapUnique(mock_source_)); + WebMediaStreamTrack web_track = MediaStreamVideoTrack::CreateVideoTrack( mock_source_, WebPlatformMediaStreamSource::ConstraintsOnceCallback(), true); + media_stream_component_ = *web_track; mock_source_->StartMockedSource(); base::RunLoop().RunUntilIdle(); media_stream_video_renderer_sink_ = new MediaStreamVideoRendererSink( - blink_track_, + media_stream_component_, ConvertToBaseRepeatingCallback(CrossThreadBindRepeating( &MediaStreamVideoRendererSinkTest::RepaintCallback, CrossThreadUnretained(this))), @@ -61,8 +63,8 @@ class MediaStreamVideoRendererSinkTest : public testing::Test { void TearDown() override { media_stream_video_renderer_sink_ = nullptr; - blink_source_.Reset(); - blink_track_.Reset(); + media_stream_source_ = nullptr; + media_stream_component_ = nullptr; WebHeap::CollectAllGarbageForTesting(); // Let the message loop run to finish destroying the pool. @@ -99,12 +101,12 @@ class MediaStreamVideoRendererSinkTest : public testing::Test { protected: ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; - WebMediaStreamTrack blink_track_; + Persistent<MediaStreamComponent> media_stream_component_; private: void RunIOUntilIdle() const { - // |blink_track_| uses IO thread to send frames to sinks. Make sure that - // tasks on IO thread are completed before moving on. + // |media_stream_component_| uses IO thread to send frames to sinks. Make + // sure that tasks on IO thread are completed before moving on. base::RunLoop run_loop; Platform::Current()->GetIOTaskRunner()->PostTaskAndReply( FROM_HERE, base::BindOnce([] {}), run_loop.QuitClosure()); @@ -112,7 +114,7 @@ class MediaStreamVideoRendererSinkTest : public testing::Test { base::RunLoop().RunUntilIdle(); } - WebMediaStreamSource blink_source_; + Persistent<MediaStreamSource> media_stream_source_; MockMediaStreamVideoSource* mock_source_; DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoRendererSinkTest); @@ -154,7 +156,7 @@ class MediaStreamVideoRendererSinkTransparencyTest public: MediaStreamVideoRendererSinkTransparencyTest() { media_stream_video_renderer_sink_ = new MediaStreamVideoRendererSink( - blink_track_, + media_stream_component_, ConvertToBaseRepeatingCallback(CrossThreadBindRepeating( &MediaStreamVideoRendererSinkTransparencyTest:: VerifyTransparentFrame, 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 344b42e6def..56ffe913378 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 @@ -18,6 +18,7 @@ #include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_device.h" #include "third_party/blink/renderer/modules/mediastream/video_track_adapter.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.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" @@ -33,6 +34,15 @@ MediaStreamVideoSource* MediaStreamVideoSource::GetVideoSource( return static_cast<MediaStreamVideoSource*>(source.GetPlatformSource()); } +// static +MediaStreamVideoSource* MediaStreamVideoSource::GetVideoSource( + MediaStreamSource* source) { + if (!source || source->GetType() != MediaStreamSource::kTypeVideo) { + return nullptr; + } + return static_cast<MediaStreamVideoSource*>(source->GetPlatformSource()); +} + MediaStreamVideoSource::MediaStreamVideoSource() : state_(NEW) { track_adapter_ = base::MakeRefCounted<VideoTrackAdapter>( Platform::Current()->GetIOTaskRunner(), GetWeakPtr()); 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 2d8308c9c13..3bf854fbfc4 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 @@ -326,12 +326,8 @@ MediaStreamVideoTrack::FrameDeliverer::GetBlackFrame( return nullptr; wrapped_black_frame->set_timestamp(reference_frame.timestamp()); - base::TimeTicks reference_time; - if (reference_frame.metadata()->GetTimeTicks( - media::VideoFrameMetadata::REFERENCE_TIME, &reference_time)) { - wrapped_black_frame->metadata()->SetTimeTicks( - media::VideoFrameMetadata::REFERENCE_TIME, reference_time); - } + wrapped_black_frame->metadata()->reference_time = + reference_frame.metadata()->reference_time; return wrapped_black_frame; } @@ -350,19 +346,6 @@ WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack( // static WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack( - const WebString& id, - MediaStreamVideoSource* source, - MediaStreamVideoSource::ConstraintsOnceCallback callback, - bool enabled) { - WebMediaStreamTrack track; - track.Initialize(id, source->Owner()); - track.SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>( - source, std::move(callback), enabled)); - return track; -} - -// static -WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack( MediaStreamVideoSource* source, const VideoTrackAdapterSettings& adapter_settings, const base::Optional<bool>& noise_reduction, diff --git a/chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl b/chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl index 3368c0a8254..069e6913cfb 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl +++ b/chromium/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl @@ -48,9 +48,9 @@ dictionary MediaTrackConstraintSet { ConstrainDouble saturation; ConstrainDouble sharpness; ConstrainDouble focusDistance; - [RuntimeEnabled=MediaCapturePanTilt] ConstrainDouble pan; - [RuntimeEnabled=MediaCapturePanTilt] ConstrainDouble tilt; - ConstrainDouble zoom; + [RuntimeEnabled=MediaCapturePanTilt] (boolean or ConstrainDouble) pan; + [RuntimeEnabled=MediaCapturePanTilt] (boolean or ConstrainDouble) tilt; + (boolean or ConstrainDouble) zoom; ConstrainBoolean torch; // The "mandatory" and "_optional" members are retained for conformance // with https://www.w3.org/TR/2013/WD-mediacapture-streams-20130903/ diff --git a/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.cc b/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.cc index 1d451a6d42c..b850dff7753 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.cc @@ -9,14 +9,14 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.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/platform/web_vector.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" #include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h" #include "third_party/blink/renderer/modules/mediastream/video_track_adapter_settings.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h" namespace blink { @@ -50,10 +50,10 @@ class MockCDQualityAudioSource : public MediaStreamAudioSource { MockMediaStreamRegistry::MockMediaStreamRegistry() {} void MockMediaStreamRegistry::Init() { - const WebVector<WebMediaStreamTrack> webkit_audio_tracks; - const WebVector<WebMediaStreamTrack> webkit_video_tracks; - const WebString label(kTestStreamLabel); - test_stream_.Initialize(label, webkit_audio_tracks, webkit_video_tracks); + MediaStreamComponentVector audio_descriptions, video_descriptions; + String label(kTestStreamLabel); + descriptor_ = MakeGarbageCollected<MediaStreamDescriptor>( + label, audio_descriptions, video_descriptions); } MockMediaStreamVideoSource* MockMediaStreamRegistry::AddVideoTrack( @@ -62,21 +62,22 @@ MockMediaStreamVideoSource* MockMediaStreamRegistry::AddVideoTrack( const base::Optional<bool>& noise_reduction, bool is_screencast, double min_frame_rate) { - WebMediaStreamSource blink_source; - blink_source.Initialize("mock video source id", - WebMediaStreamSource::kTypeVideo, - "mock video source name", false /* remote */); - MockMediaStreamVideoSource* native_source = new MockMediaStreamVideoSource(); - blink_source.SetPlatformSource(base::WrapUnique(native_source)); - WebMediaStreamTrack blink_track; - blink_track.Initialize(WebString::FromUTF8(track_id), blink_source); - - blink_track.SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>( - native_source, adapter_settings, noise_reduction, is_screencast, + auto* source = MakeGarbageCollected<MediaStreamSource>( + "mock video source id", MediaStreamSource::kTypeVideo, + "mock video source name", false /* remote */); + auto native_source = std::make_unique<MockMediaStreamVideoSource>(); + auto* native_source_ptr = native_source.get(); + native_source->SetOwner(source); + source->SetPlatformSource(std::move(native_source)); + + auto* component = MakeGarbageCollected<MediaStreamComponent>( + String::FromUTF8(track_id), source); + component->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>( + native_source_ptr, adapter_settings, noise_reduction, is_screencast, min_frame_rate, MediaStreamVideoSource::ConstraintsOnceCallback(), true /* enabled */)); - test_stream_.AddTrack(blink_track); - return native_source; + descriptor_->AddRemoteTrack(component); + return native_source_ptr; } MockMediaStreamVideoSource* MockMediaStreamRegistry::AddVideoTrack( @@ -87,18 +88,18 @@ MockMediaStreamVideoSource* MockMediaStreamRegistry::AddVideoTrack( } void MockMediaStreamRegistry::AddAudioTrack(const std::string& track_id) { - WebMediaStreamSource blink_source; - blink_source.Initialize("mock audio source id", - WebMediaStreamSource::kTypeAudio, - "mock audio source name", false /* remote */); - MediaStreamAudioSource* const source = new MockCDQualityAudioSource(); - blink_source.SetPlatformSource(base::WrapUnique(source)); // Takes ownership. - - WebMediaStreamTrack blink_track; - blink_track.Initialize(blink_source); - CHECK(source->ConnectToTrack(blink_track)); - - test_stream_.AddTrack(blink_track); + auto* source = MakeGarbageCollected<MediaStreamSource>( + "mock audio source id", MediaStreamSource::kTypeAudio, + "mock audio source name", false /* remote */); + auto audio_source = std::make_unique<MockCDQualityAudioSource>(); + auto* audio_source_ptr = audio_source.get(); + audio_source->SetOwner(source); + source->SetPlatformSource(std::move(audio_source)); + + auto* component = MakeGarbageCollected<MediaStreamComponent>(source); + CHECK(audio_source_ptr->ConnectToTrack(component)); + + descriptor_->AddRemoteTrack(component); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h b/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h index fb1827086b8..7d1d8eb1329 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h @@ -8,8 +8,8 @@ #include <string> #include "base/optional.h" -#include "third_party/blink/public/platform/web_media_stream.h" #include "third_party/blink/renderer/modules/mediastream/mock_media_stream_video_source.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h" namespace blink { @@ -34,12 +34,12 @@ class MockMediaStreamRegistry final { MockMediaStreamVideoSource* AddVideoTrack(const std::string& track_id); void AddAudioTrack(const std::string& track_id); - const WebMediaStream test_stream() const { return test_stream_; } + MediaStreamDescriptor* test_stream() const { return descriptor_.Get(); } - void reset() { test_stream_.Reset(); } + void reset() { descriptor_ = nullptr; } private: - WebMediaStream test_stream_; + Persistent<MediaStreamDescriptor> descriptor_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.cc b/chromium/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.cc index eb24eafb284..949a0c89b6c 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/mock_mojo_media_stream_dispatcher_host.cc @@ -60,7 +60,8 @@ void MockMojoMediaStreamDispatcherHost::GenerateStream( } else { std::move(callback).Run(mojom::blink::MediaStreamRequestResult::OK, String("dummy") + String::Number(request_id_), - audio_devices_, video_devices_); + audio_devices_, video_devices_, + /*pan_tilt_zoom_allowed=*/false); } } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.cc b/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.cc index 560919ee120..2d086564ab8 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.cc @@ -37,7 +37,7 @@ MediaDevices* NavigatorUserMedia::mediaDevices(Navigator& navigator) { return NavigatorUserMedia::From(navigator).GetMediaDevices(); } -void NavigatorUserMedia::Trace(Visitor* visitor) { +void NavigatorUserMedia::Trace(Visitor* visitor) const { visitor->Trace(media_devices_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.h b/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.h index 1c81f3619a1..131a491834a 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/navigator_user_media.h @@ -25,7 +25,7 @@ class NavigatorUserMedia final : public GarbageCollected<NavigatorUserMedia>, explicit NavigatorUserMedia(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: MediaDevices* GetMediaDevices(); 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 600aa8103e0..ea44df69e44 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 @@ -12,6 +12,7 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" +#include "build/chromecast_buildflags.h" #include "media/audio/audio_source_parameters.h" #include "media/base/channel_layout.h" #include "media/base/sample_rates.h" @@ -475,7 +476,7 @@ void ProcessedLocalAudioSource::CaptureUsingProcessor( int ProcessedLocalAudioSource::GetBufferSize(int sample_rate) const { DCHECK(GetTaskRunner()->BelongsToCurrentThread()); -#if defined(OS_ANDROID) +#if defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMECAST) // TODO(henrika): Re-evaluate whether to use same logic as other platforms. // https://crbug.com/638081 return (2 * sample_rate / 100); 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 63c7a255d01..21eb4db6e7b 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 @@ -20,6 +20,8 @@ #include "third_party/blink/renderer/platform/mediastream/media_constraints.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_processor_options.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h" using ::testing::_; using ::testing::AtLeast; @@ -81,17 +83,16 @@ class ProcessedLocalAudioSourceTest : public testing::Test { ~ProcessedLocalAudioSourceTest() override {} void SetUp() override { - blink_audio_source_.Initialize(blink::WebString::FromUTF8("audio_label"), - WebMediaStreamSource::kTypeAudio, - WebString::FromUTF8("audio_track"), - false /* remote */); - blink_audio_track_.Initialize(blink_audio_source_.Id(), - blink_audio_source_); + audio_source_ = MakeGarbageCollected<MediaStreamSource>( + String::FromUTF8("audio_label"), MediaStreamSource::kTypeAudio, + String::FromUTF8("audio_track"), false /* remote */); + audio_component_ = MakeGarbageCollected<MediaStreamComponent>( + audio_source_->Id(), audio_source_); } void TearDown() override { - blink_audio_track_.Reset(); - blink_audio_source_.Reset(); + audio_source_ = nullptr; + audio_component_ = nullptr; WebHeap::CollectAllGarbageForTesting(); } @@ -107,8 +108,8 @@ class ProcessedLocalAudioSourceTest : public testing::Test { false /* disable_local_echo */, properties, base::DoNothing(), scheduler::GetSingleThreadTaskRunnerForTesting()); source->SetAllowInvalidRenderFrameIdForTesting(true); - blink_audio_source_.SetPlatformSource( - std::move(source)); // Takes ownership. + source->SetOwner(audio_source_.Get()); + audio_source_->SetPlatformSource(std::move(source)); } void CheckSourceFormatMatches(const media::AudioParameters& params) { @@ -129,10 +130,11 @@ class ProcessedLocalAudioSourceTest : public testing::Test { } MediaStreamAudioSource* audio_source() const { - return MediaStreamAudioSource::From(blink_audio_source_); + return MediaStreamAudioSource::From( + WebMediaStreamSource(audio_source_.Get())); } - const WebMediaStreamTrack& blink_audio_track() { return blink_audio_track_; } + MediaStreamComponent* audio_track() { return audio_component_; } MockAudioCapturerSource* mock_audio_capturer_source() { return webrtc_audio_device_platform_support_->mock_audio_capturer_source(); @@ -141,8 +143,8 @@ class ProcessedLocalAudioSourceTest : public testing::Test { private: ScopedTestingPlatformSupport<AudioCapturerSourceTestingPlatformSupport> webrtc_audio_device_platform_support_; - WebMediaStreamSource blink_audio_source_; - WebMediaStreamTrack blink_audio_track_; + Persistent<MediaStreamSource> audio_source_; + Persistent<MediaStreamComponent> audio_component_; }; // Tests a basic end-to-end start-up, track+sink connections, audio flow, and @@ -169,7 +171,7 @@ TEST_F(ProcessedLocalAudioSourceTest, VerifyAudioFlowWithoutAudioProcessing) { .WillOnce(Invoke( capture_source_callback(), &media::AudioCapturerSource::CaptureCallback::OnCaptureStarted)); - ASSERT_TRUE(audio_source()->ConnectToTrack(blink_audio_track())); + ASSERT_TRUE(audio_source()->ConnectToTrack(audio_track())); CheckOutputFormatMatches(audio_source()->GetAudioParameters()); // Connect a sink to the track. @@ -177,7 +179,7 @@ TEST_F(ProcessedLocalAudioSourceTest, VerifyAudioFlowWithoutAudioProcessing) { new MockMediaStreamAudioSink()); EXPECT_CALL(*sink, FormatIsSet(_)) .WillOnce(Invoke(this, &ThisTest::CheckOutputFormatMatches)); - MediaStreamAudioTrack::From(blink_audio_track())->AddSink(sink.get()); + MediaStreamAudioTrack::From(audio_track())->AddSink(sink.get()); // Feed audio data into the ProcessedLocalAudioSource and expect it to reach // the sink. @@ -196,7 +198,7 @@ TEST_F(ProcessedLocalAudioSourceTest, VerifyAudioFlowWithoutAudioProcessing) { // Expect the ProcessedLocalAudioSource to auto-stop the MockCapturerSource // when the track is stopped. EXPECT_CALL(*mock_audio_capturer_source(), Stop()); - MediaStreamAudioTrack::From(blink_audio_track())->Stop(); + MediaStreamAudioTrack::From(audio_track())->Stop(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.cc b/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.cc index 61e734e638a..902074d9ba2 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.cc @@ -35,9 +35,9 @@ RemoteVideoTrackAdapter::~RemoteVideoTrackAdapter() { if (initialized()) { // TODO(crbug.com/704136): When moving RemoteVideoTrackAdapter out of the // public API, make this managed by Oilpan. Note that, the destructor will - // not allowed to touch other on-heap objects like web_track(). + // not allowed to touch other on-heap objects like track(). static_cast<MediaStreamRemoteVideoSource*>( - web_track()->Source().GetPlatformSource()) + track()->Source()->GetPlatformSource()) ->OnSourceTerminated(); } } @@ -49,14 +49,15 @@ void RemoteVideoTrackAdapter::InitializeWebVideoTrack( auto video_source_ptr = std::make_unique<MediaStreamRemoteVideoSource>(std::move(observer)); MediaStreamRemoteVideoSource* video_source = video_source_ptr.get(); - InitializeWebTrack(WebMediaStreamSource::kTypeVideo); - web_track()->Source().SetPlatformSource(std::move(video_source_ptr)); + InitializeTrack(MediaStreamSource::kTypeVideo); + video_source_ptr->SetOwner(track()->Source()); + track()->Source()->SetPlatformSource(std::move(video_source_ptr)); WebMediaStreamSource::Capabilities capabilities; capabilities.device_id = id(); - web_track()->Source().SetCapabilities(capabilities); + track()->Source()->SetCapabilities(capabilities); - web_track()->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>( + track()->SetPlatformTrack(std::make_unique<MediaStreamVideoTrack>( video_source, MediaStreamVideoSource::ConstraintsOnceCallback(), enabled)); } @@ -93,13 +94,13 @@ void RemoteAudioTrackAdapter::Unregister() { void RemoteAudioTrackAdapter::InitializeWebAudioTrack( const scoped_refptr<base::SingleThreadTaskRunner>& main_thread) { - InitializeWebTrack(WebMediaStreamSource::kTypeAudio); + InitializeTrack(MediaStreamSource::kTypeAudio); auto source = std::make_unique<PeerConnectionRemoteAudioSource>( observed_track().get(), main_thread); auto* source_ptr = source.get(); - web_track()->Source().SetPlatformSource( - std::move(source)); // Takes ownership. + source_ptr->SetOwner(track()->Source()); + track()->Source()->SetPlatformSource(std::move(source)); // Takes ownership. WebMediaStreamSource::Capabilities capabilities; capabilities.device_id = id(); @@ -111,9 +112,9 @@ void RemoteAudioTrackAdapter::InitializeWebAudioTrack( media::SampleFormatToBitsPerChannel(media::kSampleFormatS16), // min media::SampleFormatToBitsPerChannel(media::kSampleFormatS16) // max }; - web_track()->Source().SetCapabilities(capabilities); + track()->Source()->SetCapabilities(capabilities); - source_ptr->ConnectToTrack(*(web_track())); + source_ptr->ConnectToTrack(track()); } void RemoteAudioTrackAdapter::OnChanged() { @@ -134,12 +135,10 @@ void RemoteAudioTrackAdapter::OnChangedOnMainThread( switch (state) { case webrtc::MediaStreamTrackInterface::kLive: - web_track()->Source().SetReadyState( - WebMediaStreamSource::kReadyStateLive); + track()->Source()->SetReadyState(MediaStreamSource::kReadyStateLive); break; case webrtc::MediaStreamTrackInterface::kEnded: - web_track()->Source().SetReadyState( - WebMediaStreamSource::kReadyStateEnded); + track()->Source()->SetReadyState(MediaStreamSource::kReadyStateEnded); break; default: NOTREACHED(); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.h b/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.h index 20401c01b89..b9f3e69bfc6 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/remote_media_stream_track_adapter.h @@ -5,11 +5,12 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_REMOTE_MEDIA_STREAM_TRACK_ADAPTER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_REMOTE_MEDIA_STREAM_TRACK_ADAPTER_H_ -#include "base/logging.h" +#include "base/check_op.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/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" #include "third_party/webrtc/api/media_stream_interface.h" @@ -35,23 +36,23 @@ class MODULES_EXPORT RemoteMediaStreamTrackAdapter WebRtcMediaStreamTrackType* webrtc_track) : main_thread_(main_thread), webrtc_track_(webrtc_track), - id_(WebString::FromUTF8(webrtc_track->id())) {} + id_(String::FromUTF8(webrtc_track->id())) {} const scoped_refptr<WebRtcMediaStreamTrackType>& observed_track() { return webrtc_track_; } - WebMediaStreamTrack* web_track() { + MediaStreamComponent* track() { DCHECK(main_thread_->BelongsToCurrentThread()); - DCHECK(!web_track_.IsNull()); - return &web_track_; + DCHECK(component_); + return component_; } - WebString id() const { return id_; } + String id() const { return id_; } bool initialized() const { DCHECK(main_thread_->BelongsToCurrentThread()); - return !web_track_.IsNull(); + return !!component_; } void Initialize() { @@ -69,14 +70,14 @@ class MODULES_EXPORT RemoteMediaStreamTrackAdapter DCHECK(main_thread_->BelongsToCurrentThread()); } - void InitializeWebTrack(WebMediaStreamSource::Type type) { + void InitializeTrack(MediaStreamSource::StreamType type) { DCHECK(main_thread_->BelongsToCurrentThread()); - DCHECK(web_track_.IsNull()); + DCHECK(!component_); - WebMediaStreamSource web_source; - web_source.Initialize(id_, type, id_, true /* remote */); - web_track_.Initialize(id_, web_source); - DCHECK(!web_track_.IsNull()); + auto* source = MakeGarbageCollected<MediaStreamSource>(id_, type, id_, + true /*remote*/); + component_ = MakeGarbageCollected<MediaStreamComponent>(id_, source); + DCHECK(component_); } const scoped_refptr<base::SingleThreadTaskRunner> main_thread_; @@ -88,10 +89,10 @@ class MODULES_EXPORT RemoteMediaStreamTrackAdapter private: const scoped_refptr<WebRtcMediaStreamTrackType> webrtc_track_; - WebMediaStreamTrack web_track_; + CrossThreadPersistent<MediaStreamComponent> component_; // const copy of the webrtc track id that allows us to check it from both the // main and signaling threads without incurring a synchronous thread hop. - const WebString id_; + const String id_; DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackAdapter); }; diff --git a/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.cc b/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.cc index ea9c3333d7f..6b7af3e05a4 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.cc @@ -17,9 +17,9 @@ #include "media/base/audio_latency.h" #include "media/base/audio_shifter.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/modules/mediastream/media_stream_local_frame_wrapper.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.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" @@ -57,6 +57,13 @@ base::TimeDelta ComputeTotalElapsedRenderTime( sample_rate); } +WebLocalFrame* ToWebLocalFrame(LocalFrame* frame) { + if (!frame) + return nullptr; + + return static_cast<WebLocalFrame*>(WebFrame::FromFrame(frame)); +} + } // namespace // media::AudioRendererSink::RenderCallback implementation @@ -146,24 +153,23 @@ void TrackAudioRenderer::OnSetFormat(const media::AudioParameters& params) { } TrackAudioRenderer::TrackAudioRenderer( - const WebMediaStreamTrack& audio_track, - WebLocalFrame* playout_web_frame, + MediaStreamComponent* audio_component, + LocalFrame* playout_frame, const base::UnguessableToken& session_id, const String& device_id, base::RepeatingCallback<void()> on_render_error_callback) - : audio_track_(audio_track), - internal_playout_frame_( - std::make_unique<MediaStreamInternalFrameWrapper>(playout_web_frame)), + : audio_component_(audio_component), + playout_frame_(playout_frame), session_id_(session_id), task_runner_( - playout_web_frame->GetTaskRunner(blink::TaskType::kInternalMedia)), + playout_frame->GetTaskRunner(blink::TaskType::kInternalMedia)), num_samples_rendered_(0), on_render_error_callback_(std::move(on_render_error_callback)), playing_(false), output_device_id_(device_id), volume_(0.0), sink_started_(false) { - DCHECK(MediaStreamAudioTrack::From(audio_track_)); + DCHECK(MediaStreamAudioTrack::From(audio_component_.Get())); DCHECK(task_runner_->BelongsToCurrentThread()); DVLOG(1) << "TrackAudioRenderer::TrackAudioRenderer()"; } @@ -179,14 +185,14 @@ void TrackAudioRenderer::Start() { DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK_EQ(playing_, false); - // We get audio data from |audio_track_|... - WebMediaStreamAudioSink::AddToAudioTrack(this, audio_track_); + // We get audio data from |audio_component_|... + WebMediaStreamAudioSink::AddToAudioTrack( + this, WebMediaStreamTrack(audio_component_.Get())); // ...and |sink_| will get audio data from us. DCHECK(!sink_); sink_ = Platform::Current()->NewAudioRendererSink( WebAudioDeviceSourceType::kNonRtcAudioTrack, - internal_playout_frame_->web_frame(), - {session_id_, output_device_id_.Utf8()}); + ToWebLocalFrame(playout_frame_), {session_id_, output_device_id_.Utf8()}); base::AutoLock auto_lock(thread_lock_); prior_elapsed_render_time_ = base::TimeDelta(); @@ -214,7 +220,8 @@ void TrackAudioRenderer::Stop() { sink_started_ = false; // Ensure that the capturer stops feeding us with captured audio. - WebMediaStreamAudioSink::RemoveFromAudioTrack(this, audio_track_); + WebMediaStreamAudioSink::RemoveFromAudioTrack( + this, WebMediaStreamTrack(audio_component_.Get())); } void TrackAudioRenderer::Play() { @@ -266,7 +273,7 @@ base::TimeDelta TrackAudioRenderer::GetCurrentRenderTime() { bool TrackAudioRenderer::IsLocalRenderer() { DCHECK(task_runner_->BelongsToCurrentThread()); - return MediaStreamAudioTrack::From(audio_track_)->is_local_track(); + return MediaStreamAudioTrack::From(audio_component_.Get())->is_local_track(); } void TrackAudioRenderer::SwitchOutputDevice( @@ -283,7 +290,7 @@ void TrackAudioRenderer::SwitchOutputDevice( scoped_refptr<media::AudioRendererSink> new_sink = Platform::Current()->NewAudioRendererSink( WebAudioDeviceSourceType::kNonRtcAudioTrack, - internal_playout_frame_->web_frame(), {session_id_, device_id}); + ToWebLocalFrame(playout_frame_), {session_id_, device_id}); media::OutputDeviceStatus new_sink_status = new_sink->GetOutputDeviceInfo().device_status(); @@ -383,8 +390,7 @@ void TrackAudioRenderer::ReconfigureSink(const media::AudioParameters& params) { sink_started_ = false; sink_ = Platform::Current()->NewAudioRendererSink( WebAudioDeviceSourceType::kNonRtcAudioTrack, - internal_playout_frame_->web_frame(), - {session_id_, output_device_id_.Utf8()}); + ToWebLocalFrame(playout_frame_), {session_id_, output_device_id_.Utf8()}); MaybeStartSink(); } diff --git a/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.h b/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.h index e61743cd8e3..5f5532cb75f 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/track_audio_renderer.h @@ -18,7 +18,7 @@ #include "media/base/audio_renderer_sink.h" #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_renderer.h" #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h" -#include "third_party/blink/public/platform/web_media_stream_track.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace media { @@ -29,8 +29,7 @@ class AudioParameters; namespace blink { -class WebLocalFrame; -class MediaStreamInternalFrameWrapper; +class LocalFrame; // TrackAudioRenderer is a WebMediaStreamAudioRenderer for plumbing audio // data generated from either local or remote (but not @@ -62,8 +61,8 @@ class TrackAudioRenderer : public WebMediaStreamAudioRenderer, // otherwise, audio is output to the default device for the system. // // Called on the main thread. - TrackAudioRenderer(const WebMediaStreamTrack& audio_track, - WebLocalFrame* playout_web_frame, + TrackAudioRenderer(MediaStreamComponent* audio_component, + LocalFrame* playout_web_frame, const base::UnguessableToken& session_id, const String& device_id, base::RepeatingCallback<void()> on_render_error_callback); @@ -127,10 +126,10 @@ class TrackAudioRenderer : public WebMediaStreamAudioRenderer, // This class is calling WebMediaStreamAudioSink::AddToAudioTrack() and // WebMediaStreamAudioSink::RemoveFromAudioTrack() to connect and // disconnect with the audio track. - WebMediaStreamTrack audio_track_; + Persistent<MediaStreamComponent> audio_component_; - // The WebLocalFrame in which the audio is rendered into |sink_|. - std::unique_ptr<MediaStreamInternalFrameWrapper> internal_playout_frame_; + // The LocalFrame in which the audio is rendered into |sink_|. + WeakPersistent<LocalFrame> playout_frame_; const base::UnguessableToken session_id_; // MessageLoop associated with the single thread that performs all control 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 f5c874ee3d0..c8dbef8fba8 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 @@ -50,20 +50,19 @@ UserMediaClient::Request::Request(UserMediaRequest* user_media_request) : user_media_request_(user_media_request) { DCHECK(user_media_request_); DCHECK(!apply_constraints_request_); - DCHECK(web_track_to_stop_.IsNull()); + DCHECK(!track_to_stop_); } UserMediaClient::Request::Request(blink::ApplyConstraintsRequest* request) : apply_constraints_request_(request) { DCHECK(apply_constraints_request_); DCHECK(!user_media_request_); - DCHECK(web_track_to_stop_.IsNull()); + DCHECK(!track_to_stop_); } -UserMediaClient::Request::Request( - const blink::WebMediaStreamTrack& web_track_to_stop) - : web_track_to_stop_(web_track_to_stop) { - DCHECK(!web_track_to_stop_.IsNull()); +UserMediaClient::Request::Request(MediaStreamComponent* track_to_stop) + : track_to_stop_(track_to_stop) { + DCHECK(track_to_stop_); DCHECK(!user_media_request_); DCHECK(!apply_constraints_request_); } @@ -93,7 +92,8 @@ UserMediaClient::UserMediaClient( return client->GetMediaDevicesDispatcher(); }, WrapWeakPersistent(this)), - std::move(task_runner))) { + std::move(task_runner))), + media_devices_dispatcher_(frame->DomWindow()) { if (frame_) { // WrapWeakPersistent is safe because the |frame_| owns UserMediaClient. frame_->SetIsCapturingMediaCallback(WTF::BindRepeating( @@ -183,8 +183,8 @@ void UserMediaClient::ApplyConstraints( MaybeProcessNextRequestInfo(); } -void UserMediaClient::StopTrack(const blink::WebMediaStreamTrack& web_track) { - pending_request_infos_.push_back(MakeGarbageCollected<Request>(web_track)); +void UserMediaClient::StopTrack(MediaStreamComponent* track) { + pending_request_infos_.push_back(MakeGarbageCollected<Request>(track)); if (!is_processing_request_) MaybeProcessNextRequestInfo(); } @@ -216,7 +216,7 @@ void UserMediaClient::MaybeProcessNextRequestInfo() { DCHECK(current_request->IsStopTrack()); blink::WebPlatformMediaStreamTrack* track = blink::WebPlatformMediaStreamTrack::GetTrack( - current_request->web_track_to_stop()); + current_request->track_to_stop()); if (track) { track->StopAndNotify(WTF::Bind(&UserMediaClient::CurrentRequestCompleted, WrapWeakPersistent(this))); @@ -289,24 +289,28 @@ void UserMediaClient::ContextDestroyed() { DeleteAllUserMediaRequests(); } -void UserMediaClient::Trace(Visitor* visitor) { +void UserMediaClient::Trace(Visitor* visitor) const { visitor->Trace(frame_); visitor->Trace(user_media_processor_); visitor->Trace(apply_constraints_processor_); + visitor->Trace(media_devices_dispatcher_); visitor->Trace(pending_request_infos_); } void UserMediaClient::SetMediaDevicesDispatcherForTesting( mojo::PendingRemote<blink::mojom::blink::MediaDevicesDispatcherHost> media_devices_dispatcher) { - media_devices_dispatcher_.Bind(std::move(media_devices_dispatcher)); + media_devices_dispatcher_.Bind( + std::move(media_devices_dispatcher), + frame_->GetTaskRunner(blink::TaskType::kInternalMedia)); } blink::mojom::blink::MediaDevicesDispatcherHost* UserMediaClient::GetMediaDevicesDispatcher() { - if (!media_devices_dispatcher_) { + if (!media_devices_dispatcher_.is_bound()) { frame_->GetBrowserInterfaceBroker().GetInterface( - media_devices_dispatcher_.BindNewPipeAndPassReceiver()); + media_devices_dispatcher_.BindNewPipeAndPassReceiver( + frame_->GetTaskRunner(blink::TaskType::kInternalMedia))); } return media_devices_dispatcher_.get(); 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 2f528b7307d..f56f66e73fc 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 @@ -11,7 +11,6 @@ #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-forward.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" @@ -19,6 +18,9 @@ #include "third_party/blink/renderer/modules/mediastream/user_media_processor.h" #include "third_party/blink/renderer/modules/mediastream/user_media_request.h" #include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" #include "third_party/blink/renderer/platform/wtf/deque.h" namespace base { @@ -50,12 +52,12 @@ class MODULES_EXPORT UserMediaClient void RequestUserMedia(UserMediaRequest* user_media_request); void CancelUserMediaRequest(UserMediaRequest* user_media_request); void ApplyConstraints(blink::ApplyConstraintsRequest* user_media_request); - void StopTrack(const blink::WebMediaStreamTrack& web_track); + void StopTrack(MediaStreamComponent* track); void ContextDestroyed(); bool IsCapturing(); - void Trace(Visitor*); + void Trace(Visitor*) const; void SetMediaDevicesDispatcherForTesting( mojo::PendingRemote<blink::mojom::blink::MediaDevicesDispatcherHost> @@ -66,7 +68,7 @@ class MODULES_EXPORT UserMediaClient public: explicit Request(UserMediaRequest* request); explicit Request(blink::ApplyConstraintsRequest* request); - explicit Request(const blink::WebMediaStreamTrack& request); + explicit Request(MediaStreamComponent* request); ~Request(); UserMediaRequest* MoveUserMediaRequest(); @@ -75,23 +77,22 @@ class MODULES_EXPORT UserMediaClient blink::ApplyConstraintsRequest* apply_constraints_request() const { return apply_constraints_request_; } - const blink::WebMediaStreamTrack& web_track_to_stop() const { - return web_track_to_stop_; - } + MediaStreamComponent* track_to_stop() const { return track_to_stop_; } bool IsUserMedia() const { return !!user_media_request_; } - bool IsApplyConstraints() const { return apply_constraints_request_; } - bool IsStopTrack() const { return !web_track_to_stop_.IsNull(); } + bool IsApplyConstraints() const { return !!apply_constraints_request_; } + bool IsStopTrack() const { return !!track_to_stop_; } - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(user_media_request_); visitor->Trace(apply_constraints_request_); + visitor->Trace(track_to_stop_); } private: Member<UserMediaRequest> user_media_request_; Member<blink::ApplyConstraintsRequest> apply_constraints_request_; - blink::WebMediaStreamTrack web_track_to_stop_; + Member<MediaStreamComponent> track_to_stop_; DISALLOW_COPY_AND_ASSIGN(Request); }; @@ -114,7 +115,8 @@ class MODULES_EXPORT UserMediaClient // problems in builds that do not include WebRTC. Member<ApplyConstraintsProcessor> apply_constraints_processor_; - mojo::Remote<blink::mojom::blink::MediaDevicesDispatcherHost> + HeapMojoRemote<blink::mojom::blink::MediaDevicesDispatcherHost, + HeapMojoWrapperMode::kWithoutContextObserver> media_devices_dispatcher_; // UserMedia requests are processed sequentially. |is_processing_request_| 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 70bd5ff795a..db165b26d33 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 @@ -26,11 +26,14 @@ #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_screen_info.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_vector.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_device_observer.h" #include "third_party/blink/public/web/web_heap.h" +#include "third_party/blink/renderer/core/loader/empty_clients.h" +#include "third_party/blink/renderer/core/testing/dummy_page_holder.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_video_content.h" #include "third_party/blink/renderer/modules/mediastream/mock_constraint_factory.h" @@ -302,13 +305,14 @@ enum RequestState { class UserMediaProcessorUnderTest : public UserMediaProcessor { public: UserMediaProcessorUnderTest( + LocalFrame* frame, std::unique_ptr<blink::WebMediaStreamDeviceObserver> media_stream_device_observer, mojo::PendingRemote<blink::mojom::blink::MediaDevicesDispatcherHost> media_devices_dispatcher, RequestState* state) : UserMediaProcessor( - nullptr, + frame, base::BindRepeating( &UserMediaProcessorUnderTest::media_devices_dispatcher, base::Unretained(this)), @@ -402,7 +406,8 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor { } void GetUserMediaRequestSucceeded(const blink::WebMediaStream& stream, - UserMediaRequest* request_info) override { + UserMediaRequest* request_info, + bool pan_tilt_zoom_allowed) override { last_generated_stream_ = stream; *state_ = REQUEST_SUCCEEDED; } @@ -439,10 +444,11 @@ class UserMediaProcessorUnderTest : public UserMediaProcessor { class UserMediaClientUnderTest : public UserMediaClient { public: - UserMediaClientUnderTest(UserMediaProcessor* user_media_processor, + UserMediaClientUnderTest(LocalFrame* frame, + UserMediaProcessor* user_media_processor, RequestState* state) : UserMediaClient( - nullptr, + frame, user_media_processor, blink::scheduler::GetSingleThreadTaskRunnerForTesting()), state_(state) {} @@ -463,6 +469,16 @@ class UserMediaClientUnderTest : public UserMediaClient { RequestState* state_; }; +class UserMediaChromeClient : public EmptyChromeClient { + public: + WebScreenInfo GetScreenInfo(LocalFrame&) const override { + WebScreenInfo info; + info.rect.width = blink::kDefaultScreenCastWidth; + info.rect.height = blink::kDefaultScreenCastHeight; + return info; + } +}; + } // namespace class UserMediaClientTest : public ::testing::Test { @@ -475,14 +491,20 @@ class UserMediaClientTest : public ::testing::Test { // Create our test object. auto* msd_observer = new blink::WebMediaStreamDeviceObserver(nullptr); + ChromeClient* client = MakeGarbageCollected<UserMediaChromeClient>(); + Page::PageClients page_clients; + page_clients.chrome_client = client; + dummy_page_holder_ = + std::make_unique<DummyPageHolder>(IntSize(1, 1), &page_clients); + user_media_processor_ = MakeGarbageCollected<UserMediaProcessorUnderTest>( - base::WrapUnique(msd_observer), + &(dummy_page_holder_->GetFrame()), base::WrapUnique(msd_observer), 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_); + &(dummy_page_holder_->GetFrame()), user_media_processor_, &state_); user_media_client_impl_->SetMediaDevicesDispatcherForTesting( user_media_client_receiver_.BindNewPipeAndPassRemote()); @@ -631,6 +653,7 @@ class UserMediaClientTest : public ::testing::Test { mojo::Receiver<blink::mojom::blink::MediaDevicesDispatcherHost> user_media_client_receiver_; + std::unique_ptr<DummyPageHolder> dummy_page_holder_; WeakPersistent<UserMediaProcessorUnderTest> user_media_processor_; Persistent<UserMediaClientUnderTest> user_media_client_impl_; RequestState state_ = REQUEST_NOT_STARTED; @@ -1437,81 +1460,48 @@ TEST_F(UserMediaClientTest, PanConstraintRequestPanTiltZoomPermission) { EXPECT_FALSE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( CreateDefaultConstraints())); - blink::MockConstraintFactory exact_basic_factory; - exact_basic_factory.basic().pan.SetExact(1); - EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( - exact_basic_factory.CreateMediaConstraints())); - - blink::MockConstraintFactory ideal_basic_factory; - ideal_basic_factory.basic().pan.SetIdeal(1); - EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( - ideal_basic_factory.CreateMediaConstraints())); - - blink::MockConstraintFactory exact_advanced_factory; - auto& exact_advanced = exact_advanced_factory.AddAdvanced(); - exact_advanced.pan.SetExact(1); + blink::MockConstraintFactory basic_factory; + basic_factory.basic().pan.SetIsPresent(true); EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( - exact_advanced_factory.CreateMediaConstraints())); + basic_factory.CreateMediaConstraints())); - blink::MockConstraintFactory ideal_advanced_factory; - auto& ideal_advanced = ideal_advanced_factory.AddAdvanced(); - ideal_advanced.pan.SetIdeal(1); + blink::MockConstraintFactory advanced_factory; + auto& exact_advanced = advanced_factory.AddAdvanced(); + exact_advanced.pan.SetIsPresent(true); EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( - ideal_advanced_factory.CreateMediaConstraints())); + advanced_factory.CreateMediaConstraints())); } TEST_F(UserMediaClientTest, TiltConstraintRequestPanTiltZoomPermission) { EXPECT_FALSE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( CreateDefaultConstraints())); - blink::MockConstraintFactory exact_basic_factory; - exact_basic_factory.basic().tilt.SetExact(1); + blink::MockConstraintFactory basic_factory; + basic_factory.basic().tilt.SetIsPresent(true); EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( - exact_basic_factory.CreateMediaConstraints())); + basic_factory.CreateMediaConstraints())); - blink::MockConstraintFactory ideal_basic_factory; - ideal_basic_factory.basic().tilt.SetIdeal(1); + blink::MockConstraintFactory advanced_factory; + auto& exact_advanced = advanced_factory.AddAdvanced(); + exact_advanced.tilt.SetIsPresent(true); EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( - ideal_basic_factory.CreateMediaConstraints())); - - blink::MockConstraintFactory exact_advanced_factory; - auto& exact_advanced = exact_advanced_factory.AddAdvanced(); - exact_advanced.tilt.SetExact(1); - EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( - exact_advanced_factory.CreateMediaConstraints())); - - blink::MockConstraintFactory ideal_advanced_factory; - auto& ideal_advanced = ideal_advanced_factory.AddAdvanced(); - ideal_advanced.tilt.SetIdeal(1); - EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( - ideal_advanced_factory.CreateMediaConstraints())); + advanced_factory.CreateMediaConstraints())); } TEST_F(UserMediaClientTest, ZoomConstraintRequestPanTiltZoomPermission) { EXPECT_FALSE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( CreateDefaultConstraints())); - blink::MockConstraintFactory exact_basic_factory; - exact_basic_factory.basic().zoom.SetExact(1); - EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( - exact_basic_factory.CreateMediaConstraints())); - - blink::MockConstraintFactory ideal_basic_factory; - ideal_basic_factory.basic().zoom.SetIdeal(1); - EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( - ideal_basic_factory.CreateMediaConstraints())); - - blink::MockConstraintFactory exact_advanced_factory; - auto& exact_advanced = exact_advanced_factory.AddAdvanced(); - exact_advanced.zoom.SetExact(1); + blink::MockConstraintFactory basic_factory; + basic_factory.basic().zoom.SetIsPresent(true); EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( - exact_advanced_factory.CreateMediaConstraints())); + basic_factory.CreateMediaConstraints())); - blink::MockConstraintFactory ideal_advanced_factory; - auto& ideal_advanced = ideal_advanced_factory.AddAdvanced(); - ideal_advanced.zoom.SetIdeal(1); + blink::MockConstraintFactory advanced_factory; + auto& exact_advanced = advanced_factory.AddAdvanced(); + exact_advanced.zoom.SetIsPresent(true); EXPECT_TRUE(UserMediaProcessor::IsPanTiltZoomPermissionRequested( - ideal_advanced_factory.CreateMediaConstraints())); + advanced_factory.CreateMediaConstraints())); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.cc b/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.cc index 63f721fe8ce..db8c30c0ac2 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_controller.cc @@ -42,7 +42,7 @@ UserMediaController::UserMediaController(LocalDOMWindow* window) : Supplement<LocalDOMWindow>(*window), ExecutionContextLifecycleObserver(window) {} -void UserMediaController::Trace(Visitor* visitor) { +void UserMediaController::Trace(Visitor* visitor) const { Supplement<LocalDOMWindow>::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); visitor->Trace(client_); @@ -51,6 +51,7 @@ void UserMediaController::Trace(Visitor* visitor) { UserMediaClient* UserMediaController::Client() { auto* window = To<LocalDOMWindow>(GetExecutionContext()); if (!client_ && window) { + DCHECK(window->GetFrame()); client_ = MakeGarbageCollected<UserMediaClient>( window->GetFrame(), window->GetTaskRunner(TaskType::kInternalMedia)); } 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 74c5283ac9b..c919757ce48 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 @@ -46,7 +46,7 @@ class UserMediaController final : public GarbageCollected<UserMediaController>, static const char kSupplementName[]; explicit UserMediaController(LocalDOMWindow*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; UserMediaClient* Client(); @@ -82,7 +82,7 @@ inline void UserMediaController::ApplyConstraints( } inline void UserMediaController::StopTrack(MediaStreamComponent* track) { - Client()->StopTrack(WebMediaStreamTrack(track)); + Client()->StopTrack(track); } inline bool UserMediaController::HasRequestedUserMedia() { 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 9764a6cc7d0..685bb569727 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 @@ -31,6 +31,7 @@ #include "third_party/blink/public/web/modules/mediastream/web_media_stream_device_observer.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_local_frame_client.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/core/page/chrome_client.h" #include "third_party/blink/renderer/modules/mediastream/local_media_stream_audio_source.h" @@ -44,6 +45,8 @@ #include "third_party/blink/renderer/modules/mediastream/user_media_client.h" #include "third_party/blink/renderer/platform/mediastream/media_constraints.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.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/mediastream/webrtc_uma_histograms.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" @@ -119,12 +122,12 @@ void SendLogMessage(const std::string& message) { blink::WebRtcLogMessage("UMP::" + message); } -std::string GetTrackLogString(const blink::WebMediaStreamTrack& track, +std::string GetTrackLogString(MediaStreamComponent* component, bool is_pending) { String str = String::Format( "StartAudioTrack({track=[id: %s, enabled: %d, muted: %d]}, " "{is_pending=%d})", - track.Id().Utf8().c_str(), track.IsEnabled(), track.IsMuted(), + component->Id().Utf8().c_str(), component->Enabled(), component->Muted(), is_pending); return str.Utf8(); } @@ -301,7 +304,8 @@ Vector<blink::VideoInputDeviceCapabilities> ToVideoInputDeviceCapabilities( Vector<blink::VideoInputDeviceCapabilities> capabilities; for (const auto& capability : input_capabilities) { capabilities.emplace_back(capability->device_id, capability->group_id, - capability->formats, capability->facing_mode); + capability->formats, capability->facing_mode, + capability->pan_tilt_zoom_supported); } return capabilities; @@ -325,10 +329,9 @@ class UserMediaProcessor::RequestInfo final explicit RequestInfo(UserMediaRequest* request); - void StartAudioTrack(const blink::WebMediaStreamTrack& track, - bool is_pending); - blink::WebMediaStreamTrack CreateAndStartVideoTrack( - const blink::WebMediaStreamSource& source); + void StartAudioTrack(MediaStreamComponent* component, bool is_pending); + MediaStreamComponent* CreateAndStartVideoTrack( + const WebMediaStreamSource& source); // Triggers |callback| when all sources used in this request have either // successfully started, or a source has failed to start. @@ -389,6 +392,14 @@ class UserMediaProcessor::RequestInfo final return &it->value; } + void InitializeWebStream(const String& label, + const MediaStreamComponentVector& audios, + const MediaStreamComponentVector& videos) { + auto* media_stream_descriptor = + MakeGarbageCollected<MediaStreamDescriptor>(label, audios, videos); + web_stream_ = WebMediaStream(media_stream_descriptor); + } + const Vector<MediaStreamDevice>& audio_devices() const { return audio_devices_; } @@ -400,7 +411,10 @@ class UserMediaProcessor::RequestInfo final return video_formats_map_.size() == video_devices_.size(); } - blink::WebMediaStream* web_stream() { return &web_stream_; } + blink::WebMediaStream* web_stream() { + DCHECK(!web_stream_.IsNull()); + return &web_stream_; + } StreamControls* stream_controls() { return &stream_controls_; } @@ -408,7 +422,12 @@ class UserMediaProcessor::RequestInfo final return request_->has_transient_user_activation(); } - void Trace(Visitor* visitor) { visitor->Trace(request_); } + bool pan_tilt_zoom_allowed() const { return pan_tilt_zoom_allowed_; } + void set_pan_tilt_zoom_allowed(bool pan_tilt_zoom_allowed) { + pan_tilt_zoom_allowed_ = pan_tilt_zoom_allowed; + } + + void Trace(Visitor* visitor) const { visitor->Trace(request_); } private: void OnTrackStarted(blink::WebPlatformMediaStreamSource* source, @@ -437,6 +456,7 @@ class UserMediaProcessor::RequestInfo final HashMap<String, Vector<media::VideoCaptureFormat>> video_formats_map_; Vector<MediaStreamDevice> audio_devices_; Vector<MediaStreamDevice> video_devices_; + bool pan_tilt_zoom_allowed_ = false; }; // TODO(guidou): Initialize request_result_name_ as a null WTF::String. @@ -445,22 +465,21 @@ UserMediaProcessor::RequestInfo::RequestInfo(UserMediaRequest* request) : request_(request), request_result_name_("") {} void UserMediaProcessor::RequestInfo::StartAudioTrack( - const blink::WebMediaStreamTrack& track, + MediaStreamComponent* component, bool is_pending) { - DCHECK(track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio); + DCHECK(component->Source()->GetType() == MediaStreamSource::kTypeAudio); DCHECK(request()->Audio()); #if DCHECK_IS_ON() DCHECK(audio_capture_settings_.HasValue()); #endif - SendLogMessage(GetTrackLogString(track, is_pending)); - blink::MediaStreamAudioSource* native_source = - blink::MediaStreamAudioSource::From(track.Source()); + SendLogMessage(GetTrackLogString(component, is_pending)); + auto* native_source = MediaStreamAudioSource::From(component->Source()); SendLogMessage(GetTrackSourceLogString(native_source)); // Add the source as pending since OnTrackStarted will expect it to be there. sources_waiting_for_callback_.push_back(native_source); - sources_.push_back(track.Source()); - bool connected = native_source->ConnectToTrack(track); + sources_.push_back(component->Source()); + bool connected = native_source->ConnectToTrack(component); if (!is_pending) { OnTrackStarted(native_source, connected @@ -470,21 +489,20 @@ void UserMediaProcessor::RequestInfo::StartAudioTrack( } } -blink::WebMediaStreamTrack -UserMediaProcessor::RequestInfo::CreateAndStartVideoTrack( - const blink::WebMediaStreamSource& source) { - DCHECK(source.GetType() == blink::WebMediaStreamSource::kTypeVideo); +MediaStreamComponent* UserMediaProcessor::RequestInfo::CreateAndStartVideoTrack( + const WebMediaStreamSource& source) { + DCHECK(source.GetType() == WebMediaStreamSource::kTypeVideo); DCHECK(request()->Video()); DCHECK(video_capture_settings_.HasValue()); SendLogMessage(base::StringPrintf( "UMP::RI::CreateAndStartVideoTrack({request_id=%d})", request_id())); - blink::MediaStreamVideoSource* native_source = - blink::MediaStreamVideoSource::GetVideoSource(source); + MediaStreamVideoSource* native_source = + MediaStreamVideoSource::GetVideoSource(source); DCHECK(native_source); sources_.push_back(source); sources_waiting_for_callback_.push_back(native_source); - return blink::MediaStreamVideoTrack::CreateVideoTrack( + return MediaStreamVideoTrack::CreateVideoTrack( native_source, video_capture_settings_.track_adapter_settings(), video_capture_settings_.noise_reduction(), is_video_content_capture_, video_capture_settings_.min_frame_rate(), @@ -540,7 +558,8 @@ UserMediaProcessor::UserMediaProcessor( LocalFrame* frame, MediaDevicesDispatcherCallback media_devices_dispatcher_cb, scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : media_devices_dispatcher_cb_(std::move(media_devices_dispatcher_cb)), + : dispatcher_host_(frame->DomWindow()), + media_devices_dispatcher_cb_(std::move(media_devices_dispatcher_cb)), frame_(frame), task_runner_(std::move(task_runner)) {} @@ -794,15 +813,15 @@ bool UserMediaProcessor::IsPanTiltZoomPermissionRequested( if (!RuntimeEnabledFeatures::MediaCapturePanTiltEnabled()) return false; - if (!constraints.Basic().pan.IsEmpty() || - !constraints.Basic().tilt.IsEmpty() || - !constraints.Basic().zoom.IsEmpty()) { + if (constraints.Basic().pan.IsPresent() || + constraints.Basic().tilt.IsPresent() || + constraints.Basic().zoom.IsPresent()) { return true; } for (const auto& advanced_set : constraints.Advanced()) { - if (!advanced_set.pan.IsEmpty() || !advanced_set.tilt.IsEmpty() || - !advanced_set.zoom.IsEmpty()) { + if (advanced_set.pan.IsPresent() || advanced_set.tilt.IsPresent() || + advanced_set.zoom.IsPresent()) { return true; } } @@ -943,8 +962,12 @@ void UserMediaProcessor::OnStreamGenerated( MediaStreamRequestResult result, const String& label, const Vector<MediaStreamDevice>& audio_devices, - const Vector<MediaStreamDevice>& video_devices) { + const Vector<MediaStreamDevice>& video_devices, + bool pan_tilt_zoom_allowed) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // TODO(crbug.com/934063): Reject the request if the PTZ permission is denied + // and the request requires it. if (result != MediaStreamRequestResult::OK) { OnStreamGenerationFailed(request_id, result); return; @@ -961,6 +984,7 @@ void UserMediaProcessor::OnStreamGenerated( } current_request_info_->set_state(RequestInfo::State::GENERATED); + current_request_info_->set_pan_tilt_zoom_allowed(pan_tilt_zoom_allowed); for (const auto* devices : {&audio_devices, &video_devices}) { for (const auto& device : *devices) { @@ -1182,7 +1206,8 @@ void UserMediaProcessor::OnDeviceChanged(const MediaStreamDevice& old_device, source_impl->ChangeSource(new_device); } -void UserMediaProcessor::Trace(Visitor* visitor) { +void UserMediaProcessor::Trace(Visitor* visitor) const { + visitor->Trace(dispatcher_host_); visitor->Trace(frame_); visitor->Trace(current_request_info_); } @@ -1376,19 +1401,17 @@ void UserMediaProcessor::StartTracks(const String& label) { WrapWeakPersistent(this))); } - Vector<blink::WebMediaStreamTrack> audio_tracks( + HeapVector<Member<MediaStreamComponent>> audio_tracks( current_request_info_->audio_devices().size()); CreateAudioTracks(current_request_info_->audio_devices(), &audio_tracks); - Vector<blink::WebMediaStreamTrack> video_tracks( + HeapVector<Member<MediaStreamComponent>> video_tracks( current_request_info_->video_devices().size()); CreateVideoTracks(current_request_info_->video_devices(), &video_tracks); String blink_id = label; - current_request_info_->web_stream()->Initialize( - blink_id, - WebVector<WebMediaStreamTrack>(audio_tracks.data(), audio_tracks.size()), - WebVector<WebMediaStreamTrack>(video_tracks.data(), video_tracks.size())); + current_request_info_->InitializeWebStream(blink_id, audio_tracks, + video_tracks); // Wait for the tracks to be started successfully or to fail. current_request_info_->CallbackOnTracksStarted( @@ -1398,27 +1421,26 @@ void UserMediaProcessor::StartTracks(const String& label) { void UserMediaProcessor::CreateVideoTracks( const Vector<MediaStreamDevice>& devices, - Vector<blink::WebMediaStreamTrack>* webkit_tracks) { + HeapVector<Member<MediaStreamComponent>>* components) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(current_request_info_); - DCHECK_EQ(devices.size(), webkit_tracks->size()); + DCHECK_EQ(devices.size(), components->size()); SendLogMessage(base::StringPrintf("UMP::CreateVideoTracks({request_id=%d})", current_request_info_->request_id())); for (WTF::wtf_size_t i = 0; i < devices.size(); ++i) { blink::WebMediaStreamSource source = InitializeVideoSourceObject(devices[i]); - (*webkit_tracks)[i] = - current_request_info_->CreateAndStartVideoTrack(source); + (*components)[i] = current_request_info_->CreateAndStartVideoTrack(source); } } void UserMediaProcessor::CreateAudioTracks( const Vector<MediaStreamDevice>& devices, - Vector<blink::WebMediaStreamTrack>* webkit_tracks) { + HeapVector<Member<MediaStreamComponent>>* components) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(current_request_info_); - DCHECK_EQ(devices.size(), webkit_tracks->size()); + DCHECK_EQ(devices.size(), components->size()); Vector<MediaStreamDevice> overridden_audio_devices = devices; bool render_to_associated_sink = @@ -1438,10 +1460,10 @@ void UserMediaProcessor::CreateAudioTracks( for (WTF::wtf_size_t i = 0; i < overridden_audio_devices.size(); ++i) { bool is_pending = false; - blink::WebMediaStreamSource source = + WebMediaStreamSource source = InitializeAudioSourceObject(overridden_audio_devices[i], &is_pending); - (*webkit_tracks)[i].Initialize(source); - current_request_info_->StartAudioTrack((*webkit_tracks)[i], is_pending); + (*components)[i] = MakeGarbageCollected<MediaStreamComponent>(source); + current_request_info_->StartAudioTrack((*components)[i], is_pending); // At this point the source has started, and its audio parameters have been // set. Thus, all audio processing properties are known and can be surfaced // to |source|. @@ -1460,7 +1482,8 @@ void UserMediaProcessor::OnCreateNativeTracksCompleted( request_info->request_id(), label.Utf8().c_str())); if (result == MediaStreamRequestResult::OK) { GetUserMediaRequestSucceeded(*request_info->web_stream(), - request_info->request()); + request_info->request(), + request_info->pan_tilt_zoom_allowed()); GetMediaStreamDispatcherHost()->OnStreamStarted(label); } else { GetUserMediaRequestFailed(result, constraint_name); @@ -1485,7 +1508,8 @@ void UserMediaProcessor::OnCreateNativeTracksCompleted( void UserMediaProcessor::GetUserMediaRequestSucceeded( const blink::WebMediaStream& stream, - UserMediaRequest* user_media_request) { + UserMediaRequest* user_media_request, + bool pan_tilt_zoom_allowed) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(IsCurrentRequestInfo(user_media_request)); SendLogMessage( @@ -1500,13 +1524,15 @@ void UserMediaProcessor::GetUserMediaRequestSucceeded( FROM_HERE, WTF::Bind(&UserMediaProcessor::DelayedGetUserMediaRequestSucceeded, WrapWeakPersistent(this), current_request_info_->request_id(), - stream, WrapPersistent(user_media_request))); + stream, WrapPersistent(user_media_request), + pan_tilt_zoom_allowed)); } void UserMediaProcessor::DelayedGetUserMediaRequestSucceeded( int request_id, const blink::WebMediaStream& stream, - UserMediaRequest* user_media_request) { + UserMediaRequest* user_media_request, + bool pan_tilt_zoom_allowed) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); SendLogMessage(base::StringPrintf( "DelayedGetUserMediaRequestSucceeded({request_id=%d}, {result=%s})", @@ -1514,7 +1540,7 @@ void UserMediaProcessor::DelayedGetUserMediaRequestSucceeded( MediaStreamRequestResultToString(MediaStreamRequestResult::OK))); blink::LogUserMediaRequestResult(MediaStreamRequestResult::OK); DeleteUserMediaRequest(user_media_request); - user_media_request->Succeed(stream); + user_media_request->Succeed(stream, pan_tilt_zoom_allowed); } void UserMediaProcessor::GetUserMediaRequestFailed( @@ -1795,9 +1821,9 @@ bool UserMediaProcessor::HasActiveSources() const { blink::mojom::blink::MediaStreamDispatcherHost* UserMediaProcessor::GetMediaStreamDispatcherHost() { - if (!dispatcher_host_) { + if (!dispatcher_host_.is_bound()) { frame_->GetBrowserInterfaceBroker().GetInterface( - dispatcher_host_.BindNewPipeAndPassReceiver()); + dispatcher_host_.BindNewPipeAndPassReceiver(task_runner_)); } return dispatcher_host_.get(); } 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 63c61032cfa..1066e271468 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 @@ -12,7 +12,6 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/threading/thread_checker.h" -#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/common/mediastream/media_stream_request.h" #include "third_party/blink/public/mojom/mediastream/media_devices.mojom-blink.h" #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h" @@ -20,6 +19,8 @@ #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util_audio.h" #include "third_party/blink/renderer/modules/mediastream/user_media_request.h" #include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -90,10 +91,10 @@ class MODULES_EXPORT UserMediaProcessor void set_media_stream_dispatcher_host_for_testing( mojo::PendingRemote<blink::mojom::blink::MediaStreamDispatcherHost> dispatcher_host) { - dispatcher_host_.Bind(std::move(dispatcher_host)); + dispatcher_host_.Bind(std::move(dispatcher_host), task_runner_); } - void Trace(Visitor*); + void Trace(Visitor*) const; protected: // These methods are virtual for test purposes. A test can override them to @@ -101,7 +102,8 @@ class MODULES_EXPORT UserMediaProcessor // |request| have completed. virtual void GetUserMediaRequestSucceeded( const blink::WebMediaStream& stream, - UserMediaRequest* user_media_request); + UserMediaRequest* user_media_request, + bool pan_tilt_zoom_allowed); virtual void GetUserMediaRequestFailed( blink::mojom::blink::MediaStreamRequestResult result, const String& constraint_name = String()); @@ -137,7 +139,8 @@ class MODULES_EXPORT UserMediaProcessor blink::mojom::blink::MediaStreamRequestResult result, const String& label, const Vector<blink::MediaStreamDevice>& audio_devices, - const Vector<blink::MediaStreamDevice>& video_devices); + const Vector<blink::MediaStreamDevice>& video_devices, + bool pan_tilt_zoom_allowed); void GotAllVideoInputFormatsForDevice( UserMediaRequest* user_media_request, @@ -153,10 +156,10 @@ class MODULES_EXPORT UserMediaProcessor bool IsCurrentRequestInfo(int request_id) const; bool IsCurrentRequestInfo(UserMediaRequest* user_media_request) const; - void DelayedGetUserMediaRequestSucceeded( - int request_id, - const blink::WebMediaStream& stream, - UserMediaRequest* user_media_request); + void DelayedGetUserMediaRequestSucceeded(int request_id, + const blink::WebMediaStream& stream, + UserMediaRequest* user_media_request, + bool pan_tilt_zoom_allowed); void DelayedGetUserMediaRequestFailed( int request_id, UserMediaRequest* user_media_request, @@ -178,10 +181,10 @@ class MODULES_EXPORT UserMediaProcessor void StartTracks(const String& label); void CreateVideoTracks(const Vector<blink::MediaStreamDevice>& devices, - Vector<blink::WebMediaStreamTrack>* webkit_tracks); + HeapVector<Member<MediaStreamComponent>>* components); void CreateAudioTracks(const Vector<blink::MediaStreamDevice>& devices, - Vector<blink::WebMediaStreamTrack>* webkit_tracks); + HeapVector<Member<MediaStreamComponent>>* components); // Callback function triggered when all native versions of the // underlying media sources and tracks have been created and started. @@ -283,7 +286,9 @@ class MODULES_EXPORT UserMediaProcessor LocalStreamSources local_sources_; LocalStreamSources pending_local_sources_; - mojo::Remote<blink::mojom::blink::MediaStreamDispatcherHost> dispatcher_host_; + HeapMojoRemote<blink::mojom::blink::MediaStreamDispatcherHost, + HeapMojoWrapperMode::kWithoutContextObserver> + dispatcher_host_; // UserMedia requests are processed sequentially. |current_request_info_| // contains the request currently being processed. diff --git a/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc b/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc index 782e99dfd93..817910fd08a 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/user_media_request.cc @@ -40,7 +40,6 @@ #include "third_party/blink/renderer/bindings/core/v8/dictionary.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_constraints.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_media_track_constraints.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/space_split_string.h" #include "third_party/blink/renderer/core/frame/deprecation.h" @@ -305,7 +304,7 @@ class UserMediaRequest::V8Callbacks final : public UserMediaRequest::Callbacks { : success_callback_(success_callback), error_callback_(error_callback) {} ~V8Callbacks() override = default; - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(success_callback_); visitor->Trace(error_callback_); UserMediaRequest::Callbacks::Trace(visitor); @@ -472,7 +471,7 @@ bool UserMediaRequest::IsSecureContextUse(String& error_message) { if (window->IsSecureContext(error_message)) { UseCounter::Count(window, WebFeature::kGetUserMediaSecureOrigin); - window->document()->CountUseOnlyInCrossOriginIframe( + window->CountUseOnlyInCrossOriginIframe( WebFeature::kGetUserMediaSecureOriginIframe); // Feature policy deprecation messages. @@ -500,7 +499,7 @@ bool UserMediaRequest::IsSecureContextUse(String& error_message) { Deprecation::CountDeprecation(window, WebFeature::kGetUserMediaInsecureOrigin); Deprecation::CountDeprecationCrossOriginIframe( - *window->document(), WebFeature::kGetUserMediaInsecureOriginIframe); + window, WebFeature::kGetUserMediaInsecureOriginIframe); return false; } @@ -513,13 +512,14 @@ void UserMediaRequest::Start() { controller_->RequestUserMedia(this); } -void UserMediaRequest::Succeed(MediaStreamDescriptor* stream_descriptor) { +void UserMediaRequest::Succeed(MediaStreamDescriptor* stream_descriptor, + bool pan_tilt_zoom_allowed) { DCHECK(!is_resolved_); if (!GetExecutionContext()) return; - MediaStream* stream = - MediaStream::Create(GetExecutionContext(), stream_descriptor); + MediaStream* stream = MediaStream::Create( + GetExecutionContext(), stream_descriptor, pan_tilt_zoom_allowed); MediaStreamTrackVector audio_tracks = stream->getAudioTracks(); for (MediaStreamTrackVector::iterator iter = audio_tracks.begin(); @@ -612,7 +612,7 @@ void UserMediaRequest::ContextDestroyed() { } } -void UserMediaRequest::Trace(Visitor* visitor) { +void UserMediaRequest::Trace(Visitor* visitor) const { visitor->Trace(controller_); visitor->Trace(callbacks_); ExecutionContextLifecycleObserver::Trace(visitor); 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 fb0191dbdee..35bbbbeeacb 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 @@ -83,7 +83,7 @@ class MODULES_EXPORT UserMediaRequest final virtual void OnError(ScriptWrappable* callback_this_value, DOMExceptionOrOverconstrainedError) = 0; - virtual void Trace(Visitor*) {} + virtual void Trace(Visitor*) const {} protected: Callbacks() = default; @@ -118,7 +118,7 @@ class MODULES_EXPORT UserMediaRequest final void Start(); - void Succeed(MediaStreamDescriptor*); + void Succeed(MediaStreamDescriptor*, bool pan_tilt_zoom_allowed); void FailConstraint(const String& constraint_name, const String& message); void Fail(Error name, const String& message); @@ -149,7 +149,7 @@ class MODULES_EXPORT UserMediaRequest final return has_transient_user_activation_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: MediaType media_type_; 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 41f288cd370..1e02b4ac6a9 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 @@ -308,11 +308,8 @@ void VideoTrackAdapter::VideoFrameResolutionAdapter::DeliverFrame( &source_format_settings_.prev_frame_timestamp); MaybeUpdateTracksFormat(*frame); - double frame_rate; - if (!frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE, - &frame_rate)) { - frame_rate = MediaStreamVideoSource::kUnknownFrameRate; - } + double frame_rate = frame->metadata()->frame_rate.value_or( + MediaStreamVideoSource::kUnknownFrameRate); auto frame_drop_reason = media::VideoCaptureFrameDropReason::kNone; if (MaybeDropFrame(*frame, frame_rate, &frame_drop_reason)) { diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc b/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc index 87413a96f9c..74bfc6a4b14 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.cc @@ -24,9 +24,9 @@ namespace blink { const size_t WebAudioMediaStreamAudioSink::kWebAudioRenderBufferSize = 128; WebAudioMediaStreamAudioSink::WebAudioMediaStreamAudioSink( - const WebMediaStreamTrack& track, + MediaStreamComponent* component, int context_sample_rate) - : is_enabled_(false), track_(track), track_stopped_(false) { + : is_enabled_(false), component_(component), track_stopped_(false) { // Get the native audio output hardware sample-rate for the sink. // We need to check if there is a valid frame since the unittests // do not have one and they will inject their own |sink_params_| for testing. @@ -37,7 +37,8 @@ WebAudioMediaStreamAudioSink::WebAudioMediaStreamAudioSink( kWebAudioRenderBufferSize); } // Connect the source provider to the track as a sink. - WebMediaStreamAudioSink::AddToAudioTrack(this, track_); + WebMediaStreamAudioSink::AddToAudioTrack( + this, WebMediaStreamTrack(component_.Get())); } WebAudioMediaStreamAudioSink::~WebAudioMediaStreamAudioSink() { @@ -46,8 +47,10 @@ WebAudioMediaStreamAudioSink::~WebAudioMediaStreamAudioSink() { // If the track is still active, it is necessary to notify the track before // the source provider goes away. - if (!track_stopped_) - WebMediaStreamAudioSink::RemoveFromAudioTrack(this, track_); + if (!track_stopped_) { + WebMediaStreamAudioSink::RemoveFromAudioTrack( + this, WebMediaStreamTrack(component_.Get())); + } } void WebAudioMediaStreamAudioSink::OnSetFormat( diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h b/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h index 40633bd79f6..ef1f148aab5 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink.h @@ -16,9 +16,9 @@ #include "media/base/reentrancy_checker.h" #include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h" #include "third_party/blink/public/platform/web_audio_source_provider.h" -#include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" namespace media { class AudioBus; @@ -48,7 +48,7 @@ class MODULES_EXPORT WebAudioMediaStreamAudioSink public: static const size_t kWebAudioRenderBufferSize; - explicit WebAudioMediaStreamAudioSink(const WebMediaStreamTrack& track, + explicit WebAudioMediaStreamAudioSink(MediaStreamComponent* component, int context_sample_rate); ~WebAudioMediaStreamAudioSink() override; @@ -95,7 +95,7 @@ class MODULES_EXPORT WebAudioMediaStreamAudioSink // The audio track that this source provider is connected to. // No lock protection needed since only accessed in constructor and // destructor. - WebMediaStreamTrack track_; + Persistent<MediaStreamComponent> component_; // Flag to tell if the track has been stopped or not. // No lock protection needed since only accessed in constructor, destructor diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc b/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc index c99260d757e..f0da86b6d4d 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/webaudio_media_stream_audio_sink_test.cc @@ -9,10 +9,10 @@ #include "media/base/audio_bus.h" #include "media/base/audio_parameters.h" #include "testing/gtest/include/gtest/gtest.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/web_heap.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h" namespace blink { @@ -26,30 +26,28 @@ class WebAudioMediaStreamAudioSinkTest : public testing::Test { media::CHANNEL_LAYOUT_STEREO, context_sample_rate, WebAudioMediaStreamAudioSink::kWebAudioRenderBufferSize); sink_bus_ = media::AudioBus::Create(sink_params_); - WebMediaStreamSource audio_source; - audio_source.Initialize(WebString::FromUTF8("dummy_source_id"), - WebMediaStreamSource::kTypeAudio, - WebString::FromUTF8("dummy_source_name"), - false /* remote */); - blink_track_.Initialize(WebString::FromUTF8("audio_track"), audio_source); - blink_track_.SetPlatformTrack( - std::make_unique<MediaStreamAudioTrack>(true)); + auto* audio_source = MakeGarbageCollected<MediaStreamSource>( + String::FromUTF8("dummy_source_id"), MediaStreamSource::kTypeAudio, + String::FromUTF8("dummy_source_name"), false /* remote */); + component_ = MakeGarbageCollected<MediaStreamComponent>( + String::FromUTF8("audio_track"), audio_source); + component_->SetPlatformTrack(std::make_unique<MediaStreamAudioTrack>(true)); source_provider_.reset( - new WebAudioMediaStreamAudioSink(blink_track_, context_sample_rate)); + new WebAudioMediaStreamAudioSink(component_, context_sample_rate)); source_provider_->SetSinkParamsForTesting(sink_params_); source_provider_->OnSetFormat(source_params_); } void TearDown() override { source_provider_.reset(); - blink_track_.Reset(); + component_ = nullptr; WebHeap::CollectAllGarbageForTesting(); } media::AudioParameters source_params_; media::AudioParameters sink_params_; std::unique_ptr<media::AudioBus> sink_bus_; - WebMediaStreamTrack blink_track_; + Persistent<MediaStreamComponent> component_; std::unique_ptr<WebAudioMediaStreamAudioSink> source_provider_; }; @@ -117,13 +115,13 @@ TEST_F(WebAudioMediaStreamAudioSinkTest, source_provider_.reset(); // Stop the audio track. - MediaStreamAudioTrack::From(blink_track_)->Stop(); + MediaStreamAudioTrack::From(component_.Get())->Stop(); } TEST_F(WebAudioMediaStreamAudioSinkTest, StopTrackBeforeDeletingSourceProvider) { // Stop the audio track. - MediaStreamAudioTrack::From(blink_track_)->Stop(); + MediaStreamAudioTrack::From(component_.Get())->Stop(); // Delete the source provider. source_provider_.reset(); diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc index 4ea24dc8e4f..39a84a893e5 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc @@ -40,10 +40,31 @@ #include "third_party/blink/renderer/modules/mediastream/media_stream_local_frame_wrapper.h" #include "third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.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/mediastream/media_stream_source.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" +namespace WTF { + +template <> +struct CrossThreadCopier<viz::SurfaceId> + : public CrossThreadCopierPassThrough<viz::SurfaceId> { + STATIC_ONLY(CrossThreadCopier); +}; + +template <> +struct CrossThreadCopier<media::VideoTransformation> + : public CrossThreadCopierPassThrough<media::VideoTransformation> { + STATIC_ONLY(CrossThreadCopier); +}; + +} // namespace WTF + +namespace blink { + namespace { enum class RendererReloadAction { @@ -52,53 +73,53 @@ enum class RendererReloadAction { NEW_RENDERER }; -bool IsPlayableTrack(const blink::WebMediaStreamTrack& track) { - return !track.IsNull() && !track.Source().IsNull() && - track.Source().GetReadyState() != - blink::WebMediaStreamSource::kReadyStateEnded; +bool IsPlayableTrack(MediaStreamComponent* component) { + return component && component->Source() && + component->Source()->GetReadyState() != + MediaStreamSource::kReadyStateEnded; } -const char* LoadTypeToString(blink::WebMediaPlayer::LoadType type) { +const char* LoadTypeToString(WebMediaPlayer::LoadType type) { switch (type) { - case blink::WebMediaPlayer::kLoadTypeURL: + case WebMediaPlayer::kLoadTypeURL: return "URL"; - case blink::WebMediaPlayer::kLoadTypeMediaSource: + case WebMediaPlayer::kLoadTypeMediaSource: return "MediaSource"; - case blink::WebMediaPlayer::kLoadTypeMediaStream: + case WebMediaPlayer::kLoadTypeMediaStream: return "MediaStream"; } } -const char* ReadyStateToString(blink::WebMediaPlayer::ReadyState state) { +const char* ReadyStateToString(WebMediaPlayer::ReadyState state) { switch (state) { - case blink::WebMediaPlayer::kReadyStateHaveNothing: + case WebMediaPlayer::kReadyStateHaveNothing: return "HaveNothing"; - case blink::WebMediaPlayer::kReadyStateHaveMetadata: + case WebMediaPlayer::kReadyStateHaveMetadata: return "HaveMetadata"; - case blink::WebMediaPlayer::kReadyStateHaveCurrentData: + case WebMediaPlayer::kReadyStateHaveCurrentData: return "HaveCurrentData"; - case blink::WebMediaPlayer::kReadyStateHaveFutureData: + case WebMediaPlayer::kReadyStateHaveFutureData: return "HaveFutureData"; - case blink::WebMediaPlayer::kReadyStateHaveEnoughData: + case WebMediaPlayer::kReadyStateHaveEnoughData: return "HaveEnoughData"; } } -const char* NetworkStateToString(blink::WebMediaPlayer::NetworkState state) { +const char* NetworkStateToString(WebMediaPlayer::NetworkState state) { switch (state) { - case blink::WebMediaPlayer::kNetworkStateEmpty: + case WebMediaPlayer::kNetworkStateEmpty: return "Empty"; - case blink::WebMediaPlayer::kNetworkStateIdle: + case WebMediaPlayer::kNetworkStateIdle: return "Idle"; - case blink::WebMediaPlayer::kNetworkStateLoading: + case WebMediaPlayer::kNetworkStateLoading: return "Loading"; - case blink::WebMediaPlayer::kNetworkStateLoaded: + case WebMediaPlayer::kNetworkStateLoaded: return "Loaded"; - case blink::WebMediaPlayer::kNetworkStateFormatError: + case WebMediaPlayer::kNetworkStateFormatError: return "FormatError"; - case blink::WebMediaPlayer::kNetworkStateNetworkError: + case WebMediaPlayer::kNetworkStateNetworkError: return "NetworkError"; - case blink::WebMediaPlayer::kNetworkStateDecodeError: + case WebMediaPlayer::kNetworkStateDecodeError: return "DecodeError"; } } @@ -107,24 +128,6 @@ constexpr base::TimeDelta kForceBeginFramesTimeout = base::TimeDelta::FromSeconds(1); } // namespace -namespace WTF { - -template <> -struct CrossThreadCopier<viz::SurfaceId> - : public CrossThreadCopierPassThrough<viz::SurfaceId> { - STATIC_ONLY(CrossThreadCopier); -}; - -template <> -struct CrossThreadCopier<media::VideoTransformation> - : public CrossThreadCopierPassThrough<media::VideoTransformation> { - STATIC_ONLY(CrossThreadCopier); -}; - -} // namespace WTF - -namespace blink { - #if defined(OS_WIN) // Since we do not have native GMB support in Windows, using GMBs can cause a // CPU regression. This is more apparent and can have adverse affects in lower @@ -244,11 +247,9 @@ class WebMediaPlayerMS::FrameDeliverer { bool tracing_enabled = false; TRACE_EVENT_CATEGORY_GROUP_ENABLED("media", &tracing_enabled); if (tracing_enabled) { - base::TimeTicks render_time; - if (frame->metadata()->GetTimeTicks( - media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) { + if (frame->metadata()->reference_time.has_value()) { TRACE_EVENT1("media", "EnqueueFrame", "Ideal Render Instant", - render_time.ToInternalValue()); + frame->metadata()->reference_time->ToInternalValue()); } else { TRACE_EVENT0("media", "EnqueueFrame"); } @@ -467,9 +468,10 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load( // Store the ID of audio track being played in |current_audio_track_id_|. if (!web_stream_.IsNull()) { - WebVector<WebMediaStreamTrack> audio_tracks = web_stream_.AudioTracks(); - DCHECK_GT(audio_tracks.size(), 0U); - current_audio_track_id_ = audio_tracks[0].Id(); + MediaStreamDescriptor& descriptor = *web_stream_; + auto audio_components = descriptor.AudioComponents(); + DCHECK_GT(audio_components.size(), 0U); + current_audio_track_id_ = WebString(audio_components[0]->Id()); SendLogMessage(String::Format("%s => (audio_track_id=%s)", __func__, current_audio_track_id_.Utf8().c_str())); } @@ -480,9 +482,10 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load( // Store the ID of video track being played in |current_video_track_id_|. if (!web_stream_.IsNull()) { - WebVector<WebMediaStreamTrack> video_tracks = web_stream_.VideoTracks(); - DCHECK_GT(video_tracks.size(), 0U); - current_video_track_id_ = video_tracks[0].Id(); + MediaStreamDescriptor& descriptor = *web_stream_; + auto video_components = descriptor.VideoComponents(); + DCHECK_GT(video_components.size(), 0U); + current_video_track_id_ = WebString(video_components[0]->Id()); SendLogMessage(String::Format("%s => (video_track_id=%s)", __func__, current_video_track_id_.Utf8().c_str())); } @@ -586,17 +589,18 @@ void WebMediaPlayerMS::Reload() { void WebMediaPlayerMS::ReloadVideo() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(!web_stream_.IsNull()); - WebVector<WebMediaStreamTrack> video_tracks = web_stream_.VideoTracks(); + MediaStreamDescriptor& descriptor = *web_stream_; + auto video_components = descriptor.VideoComponents(); RendererReloadAction renderer_action = RendererReloadAction::KEEP_RENDERER; - if (video_tracks.empty()) { + if (video_components.IsEmpty()) { if (video_frame_provider_) renderer_action = RendererReloadAction::REMOVE_RENDERER; current_video_track_id_ = WebString(); - } else if (video_tracks[0].Id() != current_video_track_id_ && - IsPlayableTrack(video_tracks[0])) { + } else if (WebString(video_components[0]->Id()) != current_video_track_id_ && + IsPlayableTrack(video_components[0])) { renderer_action = RendererReloadAction::NEW_RENDERER; - current_video_track_id_ = video_tracks[0].Id(); + current_video_track_id_ = video_components[0]->Id(); } switch (renderer_action) { @@ -635,17 +639,18 @@ void WebMediaPlayerMS::ReloadAudio() { return; SendLogMessage(String::Format("%s()", __func__)); - WebVector<WebMediaStreamTrack> audio_tracks = web_stream_.AudioTracks(); + MediaStreamDescriptor& descriptor = *web_stream_; + auto audio_components = descriptor.AudioComponents(); RendererReloadAction renderer_action = RendererReloadAction::KEEP_RENDERER; - if (audio_tracks.empty()) { + if (audio_components.IsEmpty()) { if (audio_renderer_) renderer_action = RendererReloadAction::REMOVE_RENDERER; current_audio_track_id_ = WebString(); - } else if (audio_tracks[0].Id() != current_audio_track_id_ && - IsPlayableTrack(audio_tracks[0])) { + } else if (WebString(audio_components[0]->Id()) != current_audio_track_id_ && + IsPlayableTrack(audio_components[0])) { renderer_action = RendererReloadAction::NEW_RENDERER; - current_audio_track_id_ = audio_tracks[0].Id(); + current_audio_track_id_ = audio_components[0]->Id(); } switch (renderer_action) { @@ -761,6 +766,12 @@ void WebMediaPlayerMS::SetLatencyHint(double seconds) { // https://henbos.github.io/webrtc-timing/#dom-rtcrtpreceiver-playoutdelayhint } +void WebMediaPlayerMS::SetPreservesPitch(bool preserves_pitch) { + // Since WebMediaPlayerMS::SetRate() is a no-op, it doesn't make sense to + // handle pitch preservation flags. The playback rate should always be 1.0, + // and thus there should be no pitch-shifting. +} + void WebMediaPlayerMS::OnRequestPictureInPicture() { if (!bridge_) ActivateSurfaceLayerForVideo(); @@ -1329,9 +1340,8 @@ void WebMediaPlayerMS::OnNewFramePresentedCallback() { } void WebMediaPlayerMS::SendLogMessage(const WTF::String& message) const { - blink::WebRtcLogMessage( - "WMPMS::" + message.Utf8() + - String::Format(" [delegate_id=%d]", delegate_id_).Utf8()); + WebRtcLogMessage("WMPMS::" + message.Utf8() + + String::Format(" [delegate_id=%d]", delegate_id_).Utf8()); } std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata> 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 43eb8b63b58..7ac8c1ed1dd 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 @@ -21,11 +21,10 @@ #include "media/renderers/paint_canvas_video_renderer.h" #include "services/viz/public/cpp/gpu/context_provider_command_buffer.h" #include "skia/ext/platform_canvas.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_video_frame_submitter.h" #include "third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.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/scheduler/public/post_cross_thread_task.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/libyuv/include/libyuv/convert.h" @@ -141,7 +140,7 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor( scoped_refptr<base::SingleThreadTaskRunner> video_frame_compositor_task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - const WebMediaStream& web_stream, + MediaStreamDescriptor* media_stream_descriptor, std::unique_ptr<WebVideoFrameSubmitter> submitter, WebMediaPlayer::SurfaceLayerMode surface_layer_mode, const base::WeakPtr<WebMediaPlayerMS>& player) @@ -170,12 +169,12 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor( weak_ptr_factory_.GetWeakPtr()))); } - WebVector<WebMediaStreamTrack> video_tracks; - if (!web_stream.IsNull()) - video_tracks = web_stream.VideoTracks(); + HeapVector<Member<MediaStreamComponent>> video_components; + if (media_stream_descriptor) + video_components = media_stream_descriptor->VideoComponents(); const bool remote_video = - video_tracks.size() && video_tracks[0].Source().Remote(); + video_components.size() && video_components[0]->Source()->Remote(); if (remote_video && Platform::Current()->RTCSmoothnessAlgorithmEnabled()) { base::AutoLock auto_lock(current_frame_lock_); @@ -187,8 +186,9 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor( } // Just for logging purpose. - std::string stream_id = - web_stream.IsNull() ? std::string() : web_stream.Id().Utf8(); + std::string stream_id = media_stream_descriptor + ? media_stream_descriptor->Id().Utf8() + : std::string(); const uint32_t hash_value = base::Hash(stream_id); serial_ = (hash_value << 1) | (remote_video ? 1 : 0); } @@ -333,10 +333,7 @@ void WebMediaPlayerMSCompositor::EnqueueFrame( } // This is a signal frame saying that the stream is stopped. - bool end_of_stream = false; - if (frame->metadata()->GetBoolean(media::VideoFrameMetadata::END_OF_STREAM, - &end_of_stream) && - end_of_stream) { + if (frame->metadata()->end_of_stream) { rendering_frame_buffer_.reset(); RenderWithoutAlgorithm(std::move(frame)); return; @@ -345,16 +342,15 @@ void WebMediaPlayerMSCompositor::EnqueueFrame( // If we detect a bad frame without |render_time|, we switch off algorithm, // because without |render_time|, algorithm cannot work. // In general, this should not happen. - base::TimeTicks render_time; - if (!frame->metadata()->GetTimeTicks( - media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) { + if (!frame->metadata()->reference_time.has_value()) { DLOG(WARNING) - << "Incoming VideoFrames have no REFERENCE_TIME, switching off super " + << "Incoming VideoFrames have no reference_time, switching off super " "sophisticated rendering algorithm"; rendering_frame_buffer_.reset(); RenderWithoutAlgorithm(std::move(frame)); return; } + base::TimeTicks render_time = *frame->metadata()->reference_time; // The code below handles the case where UpdateCurrentFrame() callbacks stop. // These callbacks can stop when the tab is hidden or the page area containing @@ -400,9 +396,10 @@ bool WebMediaPlayerMSCompositor::UpdateCurrentFrame( tracing_or_dcheck_enabled = true; #endif // DCHECK_IS_ON() if (tracing_or_dcheck_enabled) { - base::TimeTicks render_time; - if (!current_frame_->metadata()->GetTimeTicks( - media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) { + base::TimeTicks render_time = + current_frame_->metadata()->reference_time.value_or( + base::TimeTicks()); + if (!current_frame_->metadata()->reference_time.has_value()) { DCHECK(!rendering_frame_buffer_) << "VideoFrames need REFERENCE_TIME to use " "sophisticated video rendering algorithm."; @@ -573,25 +570,20 @@ void WebMediaPlayerMSCompositor::SetCurrentFrame( // current frame. bool is_first_frame = true; bool has_frame_size_changed = false; - base::Optional<media::VideoRotation> new_rotation = media::VIDEO_ROTATION_0; - base::Optional<bool> new_opacity; + base::Optional<media::VideoRotation> new_rotation = + frame->metadata()->rotation.value_or(media::VIDEO_ROTATION_0); + + base::Optional<bool> new_opacity; new_opacity = media::IsOpaque(frame->format()); - media::VideoRotation current_video_rotation; - if (frame->metadata()->GetRotation(media::VideoFrameMetadata::ROTATION, - ¤t_video_rotation)) { - new_rotation = current_video_rotation; - } if (current_frame_) { // We have a current frame, so determine what has changed. is_first_frame = false; - if (!current_frame_->metadata()->GetRotation( - media::VideoFrameMetadata::ROTATION, ¤t_video_rotation)) { - // Assume VIDEO_ROTATION_0 for current frame without video rotation. - current_video_rotation = media::VIDEO_ROTATION_0; - } + media::VideoRotation current_video_rotation = + current_frame_->metadata()->rotation.value_or(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_compositor.h b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h index 33f5898f2cb..7ef0b61d982 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h @@ -41,8 +41,8 @@ class SurfaceId; } namespace blink { +class MediaStreamDescriptor; class WebMediaPlayerMS; -class WebMediaStream; struct WebMediaPlayerMSCompositorTraits; // This class is designed to handle the work load on compositor thread for @@ -64,7 +64,7 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor WebMediaPlayerMSCompositor( scoped_refptr<base::SingleThreadTaskRunner> task_runner, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, - const WebMediaStream& web_stream, + MediaStreamDescriptor* media_stream_descriptor, std::unique_ptr<WebVideoFrameSubmitter> submitter, WebMediaPlayer::SurfaceLayerMode surface_layer_mode, const base::WeakPtr<WebMediaPlayerMS>& player); @@ -120,8 +120,8 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor void SetOnFramePresentedCallback(OnNewFramePresentedCB presented_cb); // Gets the metadata for the last frame that was presented to the compositor. - // Used to populate the VideoFrameMetadata of video.requestAnimationFrame() - // callbacks. See https://wicg.github.io/video-raf/. + // Used to populate the VideoFrameMetadata of video.requestVideoFrameCallback + // callbacks. See https://wicg.github.io/video-rvfc/. // Can be called on any thread. std::unique_ptr<WebMediaPlayer::VideoFramePresentationMetadata> GetLastPresentedFrameMetadata(); 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 ddd53c58709..5c80f8c73b4 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 @@ -127,6 +127,10 @@ class FakeWebMediaPlayerDelegate EXPECT_EQ(delegate_id_, delegate_id); } + void DidBufferUnderflow(int delegate_id) override { + EXPECT_EQ(delegate_id_, delegate_id); + } + void PlayerGone(int delegate_id) override { EXPECT_EQ(delegate_id_, delegate_id); is_gone_ = true; @@ -354,13 +358,11 @@ void MockMediaStreamVideoRenderer::QueueFrames( // 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)); + if (rotation != media::VIDEO_ROTATION_0) + frame->metadata()->rotation = rotation; + + frame->metadata()->reference_time = + base::TimeTicks::Now() + base::TimeDelta::FromMilliseconds(token); AddFrame(FrameType::NORMAL_FRAME, frame); continue; 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 49501396fc5..84425b1612b 100644 --- a/chromium/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/chromium/third_party/blink/renderer/modules/modules_idl_files.gni @@ -96,6 +96,7 @@ _idl_imports = [ "//third_party/blink/renderer/modules/nfc/idls.gni", "//third_party/blink/renderer/modules/notifications/idls.gni", "//third_party/blink/renderer/modules/payments/idls.gni", + "//third_party/blink/renderer/modules/payments/goods/idls.gni", "//third_party/blink/renderer/modules/peerconnection/idls.gni", "//third_party/blink/renderer/modules/permissions/idls.gni", "//third_party/blink/renderer/modules/picture_in_picture/idls.gni", 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 c248e70eba5..77de97c110f 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 @@ -6,6 +6,8 @@ import("//third_party/blink/renderer/modules/modules.gni") blink_modules_sources("native_file_system") { sources = [ + "global_native_file_system.cc", + "global_native_file_system.h", "native_file_system_directory_handle.cc", "native_file_system_directory_handle.h", "native_file_system_directory_iterator.cc", @@ -20,10 +22,6 @@ blink_modules_sources("native_file_system") { "native_file_system_underlying_sink.h", "native_file_system_writable_file_stream.cc", "native_file_system_writable_file_stream.h", - "native_file_system_writer.cc", - "native_file_system_writer.h", - "window_native_file_system.cc", - "window_native_file_system.h", ] deps = [ "//third_party/blink/renderer/platform" ] @@ -31,7 +29,7 @@ blink_modules_sources("native_file_system") { jumbo_source_set("unit_tests") { testonly = true - sources = [ "window_native_file_system_test.cc" ] + sources = [ "global_native_file_system_test.cc" ] configs += [ "//third_party/blink/renderer:config", diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/README.md b/chromium/third_party/blink/renderer/modules/native_file_system/README.md index 8be6bc87056..4787d052cd1 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/README.md +++ b/chromium/third_party/blink/renderer/modules/native_file_system/README.md @@ -13,7 +13,7 @@ contains the mojom interfaces for these APIs. ## APIs In this directory This directory contains the implementation of the new and still under -development [Native File System API](https://github.com/WICG/native-file-system/blob/master/EXPLAINER.md). +development [Native File System API](https://wicg.github.io/native-file-system/). It consists of the following parts: @@ -21,17 +21,15 @@ It consists of the following parts: these interfaces mimic the old `Entry` interfaces, but expose a more modern promisified API. - * `getSystemDirectory`: An entry point (exposed via `FileSystemDirectoryHandle`) - that today only gives access to the same sandboxed filesystem as what was - available through the old API. In the future this could get extended to add - support for other directories as well. + * ` getOriginPrivateDirectory`: An entry point that gives access to the same + sandboxed filesystem as what is available through the old API. - * `FileSystemWriter`: a more modern API with similar functionality to the + * `FileSystemWritableFileStream`: a more modern API with similar functionality to the old `FileWriter` API. The implementation of this actually does make use of a different mojom interface than the old API. But since the functionality is mostly the same, hopefully we will be able to migrate the old implementation to the new mojom API as well. - * `chooseFileSystemEntries`: An entry point, currently on `window`, that lets - a website pop-up a file picker, prompting the user to select one or more - files or directories, to which the website than gets access. + * `showOpenFilePicker`, `showSaveFilePicker` and `showDirectorPicker`: Entry points + on `window`, that let a website pop-up a file or directory picker, prompting the + user to select one or more files or directories, to which the website than gets access. diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/directory_picker_options.idl b/chromium/third_party/blink/renderer/modules/native_file_system/directory_picker_options.idl new file mode 100644 index 00000000000..3ebc626cee2 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/native_file_system/directory_picker_options.idl @@ -0,0 +1,7 @@ +// Copyright 2020 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/native-file-system/#dictdef-directorypickeroptions +dictionary DirectoryPickerOptions { +}; diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/file_picker_accept_type.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_picker_accept_type.idl new file mode 100644 index 00000000000..661a17d1811 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/native_file_system/file_picker_accept_type.idl @@ -0,0 +1,9 @@ +// Copyright 2020 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/native-file-system/#dictdef-filepickeraccepttype +dictionary FilePickerAcceptType { + USVString description; + record<USVString, sequence<USVString>> accept; +}; diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/file_picker_options.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_picker_options.idl new file mode 100644 index 00000000000..7bb6d45d657 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/native_file_system/file_picker_options.idl @@ -0,0 +1,9 @@ +// Copyright 2020 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/native-file-system/#dictdef-filepickeroptions +dictionary FilePickerOptions { + sequence<FilePickerAcceptType> types; + boolean excludeAcceptAllOption = false; +}; diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_directory_handle.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_directory_handle.idl index bf4d4deda7b..9ce1f889755 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_directory_handle.idl +++ b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_directory_handle.idl @@ -18,6 +18,6 @@ [CallWith=ScriptState, Measure] Promise<sequence<USVString>?> resolve(FileSystemHandle possibleChild); - [CallWith=ScriptState, Measure, RaisesException] + [CallWith=ScriptState, Measure, RaisesException, RuntimeEnabled=LegacyNativeFileSystem] static Promise<FileSystemDirectoryHandle> getSystemDirectory(GetSystemDirectoryOptions options); }; diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_file_handle.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_file_handle.idl index c725cb9ae72..b24362e53ef 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_file_handle.idl +++ b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_file_handle.idl @@ -10,6 +10,6 @@ RuntimeEnabled=NativeFileSystem, ImplementedAs=NativeFileSystemFileHandle ] interface FileSystemFileHandle : FileSystemHandle { - [CallWith=ScriptState, RuntimeEnabled=WritableFileStream, RaisesException] Promise<FileSystemWritableFileStream> createWritable(optional FileSystemCreateWriterOptions options = {}); + [CallWith=ScriptState, RaisesException] Promise<FileSystemWritableFileStream> createWritable(optional FileSystemCreateWriterOptions options = {}); [CallWith=ScriptState, RaisesException] Promise<File> getFile(); }; diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl index 8fd21015f1e..e09e63d9cfa 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl +++ b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl @@ -7,7 +7,7 @@ Exposed=(Window,Worker), SecureContext, ImplementedAs=NativeFileSystemWritableFileStream, - RuntimeEnabled=WritableFileStream + RuntimeEnabled=NativeFileSystem ] interface FileSystemWritableFileStream : WritableStream { [CallWith=ScriptState, RaisesException] Promise<void> write((BufferSource or Blob or USVString or WriteParams) data); [CallWith=ScriptState, RaisesException] Promise<void> truncate(unsigned long long size); diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writer.idl b/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writer.idl deleted file mode 100644 index 5f8787b38ce..00000000000 --- a/chromium/third_party/blink/renderer/modules/native_file_system/file_system_writer.idl +++ /dev/null @@ -1,16 +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. - -// https://wicg.github.io/native-file-system/#filesystemwriter -[ - Exposed=(Window,Worker), - SecureContext, - ImplementedAs=NativeFileSystemWriter, - RuntimeEnabled=NativeFileSystem -] interface FileSystemWriter { - [CallWith=ScriptState, RaisesException] Promise<void> write(unsigned long long position, (BufferSource or Blob or USVString) data); - [CallWith=ScriptState, RaisesException] Promise<void> truncate(unsigned long long size); - - [CallWith=ScriptState, RaisesException] Promise<void> close(); -}; diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.cc b/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.cc new file mode 100644 index 00000000000..3ee55ea558c --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.cc @@ -0,0 +1,379 @@ +// 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/global_native_file_system.h" + +#include <utility> + +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.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_promise_resolver.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_choose_file_system_entries_options.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_choose_file_system_entries_options_accepts.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_file_picker_accept_type.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_open_file_picker_options.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_save_file_picker_options.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/security_context.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/core/workers/worker_global_scope.h" +#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/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/network/http_parsers.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" + +namespace blink { + +namespace { +// The name to use for the root directory of a sandboxed file system. +constexpr const char kSandboxRootDirectoryName[] = ""; + +mojom::blink::ChooseFileSystemEntryType ConvertChooserType(const String& input, + bool multiple) { + if (input == "open-file" || input == "openFile") { + return multiple + ? mojom::blink::ChooseFileSystemEntryType::kOpenMultipleFiles + : mojom::blink::ChooseFileSystemEntryType::kOpenFile; + } + if (input == "save-file" || input == "saveFile") + return mojom::blink::ChooseFileSystemEntryType::kSaveFile; + if (input == "open-directory" || input == "openDirectory") + return mojom::blink::ChooseFileSystemEntryType::kOpenDirectory; + NOTREACHED(); + return mojom::blink::ChooseFileSystemEntryType::kOpenFile; +} + +Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> ConvertAccepts( + const HeapVector<Member<ChooseFileSystemEntriesOptionsAccepts>>& accepts) { + Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> result; + result.ReserveInitialCapacity(accepts.size()); + for (const auto& a : accepts) { + result.emplace_back( + blink::mojom::blink::ChooseFileSystemEntryAcceptsOption::New( + a->hasDescription() ? a->description() : g_empty_string, + a->hasMimeTypes() ? a->mimeTypes() : Vector<String>(), + a->hasExtensions() ? a->extensions() : Vector<String>())); + } + return result; +} + +constexpr bool IsHTTPWhitespace(UChar chr) { + return chr == ' ' || chr == '\n' || chr == '\t' || chr == '\r'; +} + +Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> ConvertAccepts( + const HeapVector<Member<FilePickerAcceptType>>& types, + ExceptionState& exception_state) { + Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> result; + result.ReserveInitialCapacity(types.size()); + for (const auto& t : types) { + Vector<String> mimeTypes; + mimeTypes.ReserveInitialCapacity(t->accept().size()); + Vector<String> extensions; + for (const auto& a : t->accept()) { + String type = a.first.StripWhiteSpace(IsHTTPWhitespace); + if (type.IsEmpty()) { + exception_state.ThrowTypeError("Invalid type: " + a.first); + return {}; + } + Vector<String> parsed_type; + type.Split('/', true, parsed_type); + if (parsed_type.size() != 2) { + exception_state.ThrowTypeError("Invalid type: " + a.first); + return {}; + } + if (!IsValidHTTPToken(parsed_type[0])) { + exception_state.ThrowTypeError("Invalid type: " + a.first); + return {}; + } + if (!IsValidHTTPToken(parsed_type[1])) { + exception_state.ThrowTypeError("Invalid type: " + a.first); + return {}; + } + + mimeTypes.push_back(type); + extensions.AppendVector(a.second); + } + result.emplace_back( + blink::mojom::blink::ChooseFileSystemEntryAcceptsOption::New( + t->hasDescription() ? t->description() : g_empty_string, + std::move(mimeTypes), std::move(extensions))); + } + return result; +} + +ScriptPromise GetOriginPrivateDirectoryImpl(ScriptState* script_state, + ExceptionState& exception_state) { + ExecutionContext* context = ExecutionContext::From(script_state); + if (!context->GetSecurityOrigin()->CanAccessNativeFileSystem()) { + if (context->GetSecurityContext().IsSandboxed( + network::mojom::blink::WebSandboxFlags::kOrigin)) { + exception_state.ThrowSecurityError( + "System directory access is denied because the context is " + "sandboxed and lacks the 'allow-same-origin' flag."); + return ScriptPromise(); + } else { + exception_state.ThrowSecurityError("System directory access is denied."); + return ScriptPromise(); + } + } + + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise result = resolver->Promise(); + + mojo::Remote<mojom::blink::NativeFileSystemManager> manager; + context->GetBrowserInterfaceBroker().GetInterface( + manager.BindNewPipeAndPassReceiver()); + + auto* raw_manager = manager.get(); + raw_manager->GetSandboxedFileSystem(WTF::Bind( + [](ScriptPromiseResolver* resolver, + mojo::Remote<mojom::blink::NativeFileSystemManager>, + mojom::blink::NativeFileSystemErrorPtr result, + mojo::PendingRemote<mojom::blink::NativeFileSystemDirectoryHandle> + handle) { + ExecutionContext* context = resolver->GetExecutionContext(); + if (!context) + return; + if (result->status != mojom::blink::NativeFileSystemStatus::kOk) { + native_file_system_error::Reject(resolver, *result); + return; + } + resolver->Resolve(MakeGarbageCollected<NativeFileSystemDirectoryHandle>( + context, kSandboxRootDirectoryName, std::move(handle))); + }, + WrapPersistent(resolver), std::move(manager))); + + return result; +} + +void VerifyIsAllowedToShowFilePicker(const LocalDOMWindow& window, + ExceptionState& exception_state) { + if (!window.IsCurrentlyDisplayedInFrame()) { + exception_state.ThrowDOMException(DOMExceptionCode::kAbortError, ""); + return; + } + + Document* document = window.document(); + if (!document) { + exception_state.ThrowDOMException(DOMExceptionCode::kAbortError, ""); + return; + } + + if (!document->GetSecurityOrigin()->CanAccessNativeFileSystem()) { + if (document->IsSandboxed( + network::mojom::blink::WebSandboxFlags::kOrigin)) { + exception_state.ThrowSecurityError( + "Sandboxed documents aren't allowed to show a file picker."); + return; + } else { + exception_state.ThrowSecurityError( + "This document isn't allowed to show a file picker."); + return; + } + } + + LocalFrame* local_frame = window.GetFrame(); + if (!local_frame || local_frame->IsCrossOriginToMainFrame()) { + exception_state.ThrowSecurityError( + "Cross origin sub frames aren't allowed to show a file picker."); + return; + } + + if (!LocalFrame::HasTransientUserActivation(local_frame)) { + exception_state.ThrowSecurityError( + "Must be handling a user gesture to show a file picker."); + return; + } +} + +ScriptPromise ShowFilePickerImpl( + ScriptState* script_state, + LocalDOMWindow& window, + mojom::blink::ChooseFileSystemEntryType chooser_type, + Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts, + bool accept_all, + bool return_as_sequence) { + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise resolver_result = resolver->Promise(); + + // TODO(mek): Cache mojo::Remote<mojom::blink::NativeFileSystemManager> + // associated with an ExecutionContext, so we don't have to request a new one + // for each operation, and can avoid code duplication between here and other + // uses. + mojo::Remote<mojom::blink::NativeFileSystemManager> manager; + window.GetBrowserInterfaceBroker().GetInterface( + manager.BindNewPipeAndPassReceiver()); + + auto* raw_manager = manager.get(); + raw_manager->ChooseEntries( + chooser_type, std::move(accepts), accept_all, + WTF::Bind( + [](ScriptPromiseResolver* resolver, + mojo::Remote<mojom::blink::NativeFileSystemManager>, + bool return_as_sequence, LocalFrame* local_frame, + mojom::blink::NativeFileSystemErrorPtr file_operation_result, + Vector<mojom::blink::NativeFileSystemEntryPtr> entries) { + ExecutionContext* context = resolver->GetExecutionContext(); + if (!context) + return; + if (file_operation_result->status != + mojom::blink::NativeFileSystemStatus::kOk) { + native_file_system_error::Reject(resolver, + *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); + + if (return_as_sequence) { + HeapVector<Member<NativeFileSystemHandle>> results; + results.ReserveInitialCapacity(entries.size()); + for (auto& entry : entries) { + results.push_back(NativeFileSystemHandle::CreateFromMojoEntry( + std::move(entry), context)); + } + resolver->Resolve(results); + } else { + DCHECK_EQ(1u, entries.size()); + resolver->Resolve(NativeFileSystemHandle::CreateFromMojoEntry( + std::move(entries[0]), context)); + } + }, + WrapPersistent(resolver), std::move(manager), return_as_sequence, + WrapPersistent(window.GetFrame()))); + return resolver_result; +} + +} // namespace + +// static +ScriptPromise GlobalNativeFileSystem::chooseFileSystemEntries( + ScriptState* script_state, + LocalDOMWindow& window, + const ChooseFileSystemEntriesOptions* options, + ExceptionState& exception_state) { + VerifyIsAllowedToShowFilePicker(window, exception_state); + if (exception_state.HadException()) + return ScriptPromise(); + + Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts; + if (options->hasAccepts()) + accepts = ConvertAccepts(options->accepts()); + + return ShowFilePickerImpl( + script_state, window, + ConvertChooserType(options->type(), options->multiple()), + std::move(accepts), !options->excludeAcceptAllOption(), + options->multiple()); +} + +// static +ScriptPromise GlobalNativeFileSystem::showOpenFilePicker( + ScriptState* script_state, + LocalDOMWindow& window, + const OpenFilePickerOptions* options, + ExceptionState& exception_state) { + Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts; + if (options->hasTypes()) + accepts = ConvertAccepts(options->types(), exception_state); + if (exception_state.HadException()) + return ScriptPromise(); + + if (accepts.IsEmpty() && options->excludeAcceptAllOption()) { + exception_state.ThrowTypeError("Need at least one accepted type"); + return ScriptPromise(); + } + + VerifyIsAllowedToShowFilePicker(window, exception_state); + if (exception_state.HadException()) + return ScriptPromise(); + + return ShowFilePickerImpl( + script_state, window, + options->multiple() + ? mojom::blink::ChooseFileSystemEntryType::kOpenMultipleFiles + : mojom::blink::ChooseFileSystemEntryType::kOpenFile, + std::move(accepts), !options->excludeAcceptAllOption(), + /*return_as_sequence=*/true); +} + +// static +ScriptPromise GlobalNativeFileSystem::showSaveFilePicker( + ScriptState* script_state, + LocalDOMWindow& window, + const SaveFilePickerOptions* options, + ExceptionState& exception_state) { + Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts; + if (options->hasTypes()) + accepts = ConvertAccepts(options->types(), exception_state); + if (exception_state.HadException()) + return ScriptPromise(); + + if (accepts.IsEmpty() && options->excludeAcceptAllOption()) { + exception_state.ThrowTypeError("Need at least one accepted type"); + return ScriptPromise(); + } + + VerifyIsAllowedToShowFilePicker(window, exception_state); + if (exception_state.HadException()) + return ScriptPromise(); + + return ShowFilePickerImpl( + script_state, window, mojom::blink::ChooseFileSystemEntryType::kSaveFile, + std::move(accepts), !options->excludeAcceptAllOption(), + /*return_as_sequence=*/false); +} + +// static +ScriptPromise GlobalNativeFileSystem::showDirectoryPicker( + ScriptState* script_state, + LocalDOMWindow& window, + const DirectoryPickerOptions* options, + ExceptionState& exception_state) { + VerifyIsAllowedToShowFilePicker(window, exception_state); + if (exception_state.HadException()) + return ScriptPromise(); + + return ShowFilePickerImpl( + script_state, window, + mojom::blink::ChooseFileSystemEntryType::kOpenDirectory, {}, + /*accept_all=*/true, + /*return_as_sequence=*/false); +} + +// static +ScriptPromise GlobalNativeFileSystem::getOriginPrivateDirectory( + ScriptState* script_state, + const LocalDOMWindow& window, + ExceptionState& exception_state) { + return GetOriginPrivateDirectoryImpl(script_state, exception_state); +} + +// static +ScriptPromise GlobalNativeFileSystem::getOriginPrivateDirectory( + ScriptState* script_state, + const WorkerGlobalScope& workerGlobalScope, + ExceptionState& exception_state) { + return GetOriginPrivateDirectoryImpl(script_state, exception_state); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.h b/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.h new file mode 100644 index 00000000000..7f1037e3d7f --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/native_file_system/global_native_file_system.h @@ -0,0 +1,56 @@ +// 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_NATIVE_FILE_SYSTEM_GLOBAL_NATIVE_FILE_SYSTEM_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_GLOBAL_NATIVE_FILE_SYSTEM_H_ + +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" + +namespace blink { + +class ChooseFileSystemEntriesOptions; +class OpenFilePickerOptions; +class SaveFilePickerOptions; +class DirectoryPickerOptions; +class ExceptionState; +class LocalDOMWindow; +class ScriptPromise; +class ScriptState; +class WorkerGlobalScope; + +class GlobalNativeFileSystem { + STATIC_ONLY(GlobalNativeFileSystem); + + public: + static ScriptPromise chooseFileSystemEntries( + ScriptState*, + LocalDOMWindow&, + const ChooseFileSystemEntriesOptions*, + ExceptionState&); + + static ScriptPromise showOpenFilePicker(ScriptState*, + LocalDOMWindow&, + const OpenFilePickerOptions*, + ExceptionState&); + static ScriptPromise showSaveFilePicker(ScriptState*, + LocalDOMWindow&, + const SaveFilePickerOptions*, + ExceptionState&); + static ScriptPromise showDirectoryPicker(ScriptState*, + LocalDOMWindow&, + const DirectoryPickerOptions*, + ExceptionState&); + + static ScriptPromise getOriginPrivateDirectory(ScriptState*, + const LocalDOMWindow&, + ExceptionState&); + static ScriptPromise getOriginPrivateDirectory(ScriptState*, + const WorkerGlobalScope&, + ExceptionState&); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_GLOBAL_NATIVE_FILE_SYSTEM_H_ 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/global_native_file_system_test.cc index 476b6549e17..aedf47decc9 100644 --- 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/global_native_file_system_test.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/native_file_system/window_native_file_system.h" +#include "third_party/blink/renderer/modules/native_file_system/global_native_file_system.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h" @@ -97,7 +97,7 @@ class MockNativeFileSystemManager BrowserInterfaceBrokerProxy& broker_; }; -class WindowNativeFileSystemTest : public PageTestBase { +class GlobalNativeFileSystemTest : public PageTestBase { public: void SetUp() override { PageTestBase::SetUp(); @@ -116,7 +116,7 @@ class WindowNativeFileSystemTest : public PageTestBase { } }; -TEST_F(WindowNativeFileSystemTest, UserActivationRequiredOtherwiseDenied) { +TEST_F(GlobalNativeFileSystemTest, UserActivationRequiredOtherwiseDenied) { LocalFrame* frame = &GetFrame(); EXPECT_FALSE(frame->HasStickyUserActivation()); @@ -131,7 +131,7 @@ TEST_F(WindowNativeFileSystemTest, UserActivationRequiredOtherwiseDenied) { EXPECT_FALSE(frame->HasStickyUserActivation()); } -TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesSuccessful) { +TEST_F(GlobalNativeFileSystemTest, UserActivationChooseEntriesSuccessful) { LocalFrame* frame = &GetFrame(); EXPECT_FALSE(frame->HasStickyUserActivation()); @@ -174,7 +174,7 @@ TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesSuccessful) { EXPECT_TRUE(frame->HasStickyUserActivation()); } -TEST_F(WindowNativeFileSystemTest, UserActivationChooseEntriesErrors) { +TEST_F(GlobalNativeFileSystemTest, UserActivationChooseEntriesErrors) { LocalFrame* frame = &GetFrame(); EXPECT_FALSE(frame->HasStickyUserActivation()); diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/idls.gni b/chromium/third_party/blink/renderer/modules/native_file_system/idls.gni index 490d4ad43aa..6e11fe1cebc 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/idls.gni +++ b/chromium/third_party/blink/renderer/modules/native_file_system/idls.gni @@ -8,20 +8,27 @@ modules_idl_files = [ "file_system_file_handle.idl", "file_system_handle.idl", "file_system_writable_file_stream.idl", - "file_system_writer.idl", ] modules_dictionary_idl_files = [ "choose_file_system_entries_options.idl", "choose_file_system_entries_options_accepts.idl", + "directory_picker_options.idl", + "file_picker_accept_type.idl", + "file_picker_options.idl", "file_system_create_writer_options.idl", "file_system_get_directory_options.idl", "file_system_get_file_options.idl", "file_system_handle_permission_descriptor.idl", "file_system_remove_options.idl", "get_system_directory_options.idl", + "open_file_picker_options.idl", "native_file_system_directory_iterator_entry.idl", + "save_file_picker_options.idl", "write_params.idl", ] -modules_dependency_idl_files = [ "window_native_file_system.idl" ] +modules_dependency_idl_files = [ + "window_native_file_system.idl", + "worker_global_scope_native_file_system.idl", +] 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 8894b4005bc..27403aaac53 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 @@ -250,7 +250,7 @@ NativeFileSystemDirectoryHandle::Transfer() { return result; } -void NativeFileSystemDirectoryHandle::Trace(Visitor* visitor) { +void NativeFileSystemDirectoryHandle::Trace(Visitor* visitor) const { visitor->Trace(mojo_ptr_); NativeFileSystemHandle::Trace(visitor); } 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 9997033c91b..0474d916291 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 @@ -51,7 +51,7 @@ class NativeFileSystemDirectoryHandle final : public NativeFileSystemHandle { return mojo_ptr_.get(); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void QueryPermissionImpl( diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.cc index b25417e3ac2..b665fa8ed46 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.cc +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.cc @@ -53,7 +53,7 @@ ScriptPromise NativeFileSystemDirectoryIterator::next( return ScriptPromise::Cast(script_state, ToV8(result, script_state)); } -void NativeFileSystemDirectoryIterator::Trace(Visitor* visitor) { +void NativeFileSystemDirectoryIterator::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); ExecutionContextClient::Trace(visitor); visitor->Trace(receiver_); 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 4480443ac9e..b265f53746e 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 @@ -33,7 +33,7 @@ class NativeFileSystemDirectoryIterator final ScriptPromise next(ScriptState*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void DidReadDirectory(mojom::blink::NativeFileSystemErrorPtr result, 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 39f4929462f..9419f3b555b 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 @@ -14,7 +14,6 @@ #include "third_party/blink/renderer/core/fileapi/file_error.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_writable_file_stream.h" -#include "third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/file_metadata.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -33,40 +32,6 @@ NativeFileSystemFileHandle::NativeFileSystemFileHandle( DCHECK(mojo_ptr_.is_bound()); } -ScriptPromise NativeFileSystemFileHandle::createWriter( - ScriptState* script_state, - const FileSystemCreateWriterOptions* options) { - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise result = resolver->Promise(); - - if (!mojo_ptr_.is_bound()) { - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kInvalidStateError)); - return result; - } - - mojo_ptr_->CreateFileWriter( - options->keepExistingData(), - WTF::Bind( - [](ScriptPromiseResolver* resolver, - mojom::blink::NativeFileSystemErrorPtr result, - mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter> - writer) { - ExecutionContext* context = resolver->GetExecutionContext(); - if (!context) - return; - if (result->status != mojom::blink::NativeFileSystemStatus::kOk) { - native_file_system_error::Reject(resolver, *result); - return; - } - resolver->Resolve(MakeGarbageCollected<NativeFileSystemWriter>( - context, std::move(writer))); - }, - WrapPersistent(resolver))); - - return result; -} - ScriptPromise NativeFileSystemFileHandle::createWritable( ScriptState* script_state, const FileSystemCreateWriterOptions* options, @@ -137,7 +102,7 @@ NativeFileSystemFileHandle::Transfer() { return result; } -void NativeFileSystemFileHandle::Trace(Visitor* visitor) { +void NativeFileSystemFileHandle::Trace(Visitor* visitor) const { visitor->Trace(mojo_ptr_); NativeFileSystemHandle::Trace(visitor); } 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 e0fc8d3df89..47fbd767254 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 @@ -24,8 +24,6 @@ class NativeFileSystemFileHandle final : public NativeFileSystemHandle { bool isFile() const override { return true; } - ScriptPromise createWriter(ScriptState*, - const FileSystemCreateWriterOptions* options); ScriptPromise createWritable(ScriptState*, const FileSystemCreateWriterOptions* options, ExceptionState&); @@ -38,7 +36,7 @@ class NativeFileSystemFileHandle final : public NativeFileSystemHandle { return mojo_ptr_.get(); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void QueryPermissionImpl( 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 ed7e9edc502..c759bf521bc 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 @@ -112,7 +112,7 @@ ScriptPromise NativeFileSystemHandle::isSameEntry( return result; } -void NativeFileSystemHandle::Trace(Visitor* visitor) { +void NativeFileSystemHandle::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); ExecutionContextClient::Trace(visitor); } 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 cc2804f245d..8bb5147ef57 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 @@ -49,7 +49,7 @@ class NativeFileSystemHandle : public ScriptWrappable, virtual mojo::PendingRemote<mojom::blink::NativeFileSystemTransferToken> Transfer() = 0; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: virtual void QueryPermissionImpl( diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.cc index 7ff83a0f659..49ae32fef81 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.cc +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.cc @@ -104,27 +104,28 @@ ScriptPromise NativeFileSystemUnderlyingSink::HandleParams( const WriteParams& params, ExceptionState& exception_state) { if (params.type() == "truncate") { - if (!params.hasSize()) { + if (!params.hasSizeNonNull()) { exception_state.ThrowDOMException( DOMExceptionCode::kSyntaxError, "Invalid params passed. truncate requires a size argument"); return ScriptPromise(); } - return Truncate(script_state, params.size(), exception_state); + return Truncate(script_state, params.sizeNonNull(), exception_state); } if (params.type() == "seek") { - if (!params.hasPosition()) { + if (!params.hasPositionNonNull()) { exception_state.ThrowDOMException( DOMExceptionCode::kSyntaxError, "Invalid params passed. seek requires a position argument"); return ScriptPromise(); } - return Seek(script_state, params.position(), exception_state); + return Seek(script_state, params.positionNonNull(), exception_state); } if (params.type() == "write") { - uint64_t position = params.hasPosition() ? params.position() : offset_; + uint64_t position = + params.hasPositionNonNull() ? params.positionNonNull() : offset_; if (!params.hasData()) { exception_state.ThrowDOMException( DOMExceptionCode::kSyntaxError, @@ -261,7 +262,7 @@ void NativeFileSystemUnderlyingSink::CloseComplete( writer_remote_.reset(); } -void NativeFileSystemUnderlyingSink::Trace(Visitor* visitor) { +void NativeFileSystemUnderlyingSink::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); UnderlyingSinkBase::Trace(visitor); visitor->Trace(writer_remote_); diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.h index e4b1b89ed70..cac18d80062 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.h +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_underlying_sink.h @@ -37,7 +37,7 @@ class NativeFileSystemUnderlyingSink final : public UnderlyingSinkBase { ScriptValue reason, ExceptionState&) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ScriptPromise HandleParams(ScriptState*, const WriteParams&, ExceptionState&); diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.cc b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.cc index 9eb16481ea4..56d5db3f1bf 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.cc +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.cc @@ -123,7 +123,7 @@ ScriptPromise NativeFileSystemWritableFileStream::seek( return promise; } -void NativeFileSystemWritableFileStream::Trace(Visitor* visitor) { +void NativeFileSystemWritableFileStream::Trace(Visitor* visitor) const { WritableStream::Trace(visitor); visitor->Trace(underlying_sink_); } diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.h b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.h index 3eb79e89f89..3a037f3e34f 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.h +++ b/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writable_file_stream.h @@ -27,7 +27,7 @@ class NativeFileSystemWritableFileStream final : public WritableStream { ScriptState*, mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter>); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // IDL defined functions specific to NativeFileSystemWritableFileStream. ScriptPromise write( 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 deleted file mode 100644 index 7ec053fac3f..00000000000 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.cc +++ /dev/null @@ -1,243 +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/native_file_system/native_file_system_writer.h" - -#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" -#include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h" -#include "third_party/blink/renderer/core/dom/dom_exception.h" -#include "third_party/blink/renderer/core/fetch/fetch_data_loader.h" -#include "third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h" -#include "third_party/blink/renderer/core/fileapi/blob.h" -#include "third_party/blink/renderer/core/fileapi/file_error.h" -#include "third_party/blink/renderer/core/streams/readable_stream.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/blob/blob_data.h" -#include "third_party/blink/renderer/platform/heap/heap.h" -#include "third_party/blink/renderer/platform/wtf/functional.h" - -namespace blink { - -NativeFileSystemWriter::NativeFileSystemWriter( - ExecutionContext* context, - mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter> - writer_pending_remote) - : writer_remote_(context) { - writer_remote_.Bind(std::move(writer_pending_remote), - context->GetTaskRunner(TaskType::kMiscPlatformAPI)); - DCHECK(writer_remote_.is_bound()); -} - -ScriptPromise NativeFileSystemWriter::write( - ScriptState* script_state, - uint64_t position, - const ArrayBufferOrArrayBufferViewOrBlobOrUSVString& data, - ExceptionState& exception_state) { - DCHECK(!data.IsNull()); - - auto blob_data = std::make_unique<BlobData>(); - Blob* blob = nullptr; - if (data.IsArrayBuffer()) { - DOMArrayBuffer* array_buffer = data.GetAsArrayBuffer(); - blob_data->AppendBytes(array_buffer->Data(), - array_buffer->ByteLengthAsSizeT()); - } else if (data.IsArrayBufferView()) { - DOMArrayBufferView* array_buffer_view = data.GetAsArrayBufferView().View(); - blob_data->AppendBytes(array_buffer_view->BaseAddress(), - array_buffer_view->byteLengthAsSizeT()); - } else if (data.IsBlob()) { - blob = data.GetAsBlob(); - } else if (data.IsUSVString()) { - // Let the developer be explicit about line endings. - blob_data->AppendText(data.GetAsUSVString(), - /*normalize_line_endings_to_native=*/false); - } - - if (!blob) { - uint64_t size = blob_data->length(); - blob = MakeGarbageCollected<Blob>( - BlobDataHandle::Create(std::move(blob_data), size)); - } - - return WriteBlob(script_state, position, blob, exception_state); -} - -ScriptPromise NativeFileSystemWriter::WriteBlob( - ScriptState* script_state, - uint64_t position, - Blob* blob, - ExceptionState& exception_state) { - if (!writer_remote_.is_bound() || pending_operation_) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, ""); - return ScriptPromise(); - } - pending_operation_ = - MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise result = pending_operation_->Promise(); - writer_remote_->Write( - position, blob->AsMojoBlob(), - WTF::Bind(&NativeFileSystemWriter::WriteComplete, WrapPersistent(this))); - return result; -} - -class NativeFileSystemWriter::StreamWriterClient - : public GarbageCollected<StreamWriterClient>, - public FetchDataLoader::Client { - USING_GARBAGE_COLLECTED_MIXIN(StreamWriterClient); - - public: - explicit StreamWriterClient(NativeFileSystemWriter* writer) - : writer_(writer) {} - - void DidFetchDataStartedDataPipe( - mojo::ScopedDataPipeConsumerHandle data_pipe) override { - data_pipe_ = std::move(data_pipe); - } - - mojo::ScopedDataPipeConsumerHandle TakeDataPipe() { - DCHECK(data_pipe_); - return std::move(data_pipe_); - } - - void DidFetchDataLoadedDataPipe() override { - // WriteComplete could have been called with an error before we reach this - // point, in that case just return. - if (did_complete_) - return; - DCHECK(!did_finish_writing_to_pipe_); - DCHECK(writer_->pending_operation_); - did_finish_writing_to_pipe_ = true; - } - - void DidFetchDataLoadFailed() override { - // WriteComplete could have been called with an error before we reach this - // point, in that case just return. - if (did_complete_) - return; - DCHECK(writer_->pending_operation_); - did_complete_ = true; - writer_->pending_operation_->Reject( - file_error::CreateDOMException(base::File::FILE_ERROR_FAILED)); - Reset(); - } - - void Abort() override { - // WriteComplete could have been called with an error before we reach this - // point, in that case just return. - if (did_complete_) - return; - DCHECK(writer_->pending_operation_); - did_complete_ = true; - writer_->pending_operation_->Reject( - file_error::CreateDOMException(base::File::FILE_ERROR_ABORT)); - Reset(); - } - - void WriteComplete(mojom::blink::NativeFileSystemErrorPtr result, - uint64_t bytes_written) { - // Early return if we already completed (with an error) before. - if (did_complete_) - return; - DCHECK(writer_->pending_operation_); - did_complete_ = true; - if (result->status != mojom::blink::NativeFileSystemStatus::kOk) { - native_file_system_error::Reject(writer_->pending_operation_, *result); - } else { - DCHECK(did_finish_writing_to_pipe_); - writer_->pending_operation_->Resolve(); - } - Reset(); - } - - void Trace(Visitor* visitor) override { - Client::Trace(visitor); - visitor->Trace(writer_); - } - - private: - void Reset() { - writer_->pending_operation_ = nullptr; - writer_->stream_loader_ = nullptr; - } - - Member<NativeFileSystemWriter> writer_; - mojo::ScopedDataPipeConsumerHandle data_pipe_; - bool did_finish_writing_to_pipe_ = false; - bool did_complete_ = false; -}; - -ScriptPromise NativeFileSystemWriter::truncate( - ScriptState* script_state, - uint64_t size, - ExceptionState& exception_state) { - if (!writer_remote_.is_bound() || pending_operation_) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, ""); - return ScriptPromise(); - } - pending_operation_ = - MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise result = pending_operation_->Promise(); - writer_remote_->Truncate(size, - WTF::Bind(&NativeFileSystemWriter::TruncateComplete, - WrapPersistent(this))); - return result; -} - -ScriptPromise NativeFileSystemWriter::close(ScriptState* script_state, - ExceptionState& exception_state) { - if (!writer_remote_.is_bound() || pending_operation_) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, ""); - return ScriptPromise(); - } - pending_operation_ = - MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise result = pending_operation_->Promise(); - writer_remote_->Close( - WTF::Bind(&NativeFileSystemWriter::CloseComplete, WrapPersistent(this))); - - return result; -} - -void NativeFileSystemWriter::Trace(Visitor* visitor) { - ScriptWrappable::Trace(visitor); - visitor->Trace(writer_remote_); - visitor->Trace(file_); - visitor->Trace(pending_operation_); - visitor->Trace(stream_loader_); -} - -void NativeFileSystemWriter::WriteComplete( - mojom::blink::NativeFileSystemErrorPtr result, - uint64_t bytes_written) { - DCHECK(pending_operation_); - native_file_system_error::ResolveOrReject(pending_operation_, *result); - pending_operation_ = nullptr; -} - -void NativeFileSystemWriter::TruncateComplete( - mojom::blink::NativeFileSystemErrorPtr result) { - DCHECK(pending_operation_); - native_file_system_error::ResolveOrReject(pending_operation_, *result); - pending_operation_ = nullptr; -} - -void NativeFileSystemWriter::CloseComplete( - mojom::blink::NativeFileSystemErrorPtr result) { - DCHECK(pending_operation_); - native_file_system_error::ResolveOrReject(pending_operation_, *result); - file_ = nullptr; - pending_operation_ = nullptr; - // We close the mojo pipe because we intend this writer to be discarded after - // close. Subsequent operations will fail. - 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 deleted file mode 100644 index f5936ff6c53..00000000000 --- a/chromium/third_party/blink/renderer/modules/native_file_system/native_file_system_writer.h +++ /dev/null @@ -1,64 +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_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-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/execution_context.h" -#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" -#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" - -namespace blink { - -class Blob; -class ExceptionState; -class FetchDataLoader; -class ScriptPromise; -class ScriptPromiseResolver; -class ScriptState; -class NativeFileSystemFileHandle; - -class NativeFileSystemWriter final : public ScriptWrappable { - DEFINE_WRAPPERTYPEINFO(); - - public: - NativeFileSystemWriter( - ExecutionContext* context, - mojo::PendingRemote<mojom::blink::NativeFileSystemFileWriter>); - - ScriptPromise write(ScriptState*, - uint64_t position, - const ArrayBufferOrArrayBufferViewOrBlobOrUSVString& data, - ExceptionState&); - ScriptPromise truncate(ScriptState*, uint64_t size, ExceptionState&); - ScriptPromise close(ScriptState*, ExceptionState&); - - void Trace(Visitor*) override; - - private: - class StreamWriterClient; - - ScriptPromise WriteBlob(ScriptState*, - uint64_t position, - Blob*, - ExceptionState&); - - void WriteComplete(mojom::blink::NativeFileSystemErrorPtr result, - uint64_t bytes_written); - void TruncateComplete(mojom::blink::NativeFileSystemErrorPtr result); - void CloseComplete(mojom::blink::NativeFileSystemErrorPtr result); - - HeapMojoRemote<mojom::blink::NativeFileSystemFileWriter> writer_remote_; - Member<NativeFileSystemFileHandle> file_; - - Member<ScriptPromiseResolver> pending_operation_; - Member<FetchDataLoader> stream_loader_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_NATIVE_FILE_SYSTEM_WRITER_H_ diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/open_file_picker_options.idl b/chromium/third_party/blink/renderer/modules/native_file_system/open_file_picker_options.idl new file mode 100644 index 00000000000..96456f757a8 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/native_file_system/open_file_picker_options.idl @@ -0,0 +1,8 @@ +// Copyright 2020 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/native-file-system/#dictdef-openfilepickeroptions +dictionary OpenFilePickerOptions : FilePickerOptions { + boolean multiple = false; +}; diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/save_file_picker_options.idl b/chromium/third_party/blink/renderer/modules/native_file_system/save_file_picker_options.idl new file mode 100644 index 00000000000..d18f9d01f73 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/native_file_system/save_file_picker_options.idl @@ -0,0 +1,7 @@ +// Copyright 2020 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/native-file-system/#dictdef-savefilepickeroptions +dictionary SaveFilePickerOptions : FilePickerOptions { +}; 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 deleted file mode 100644 index 664309feae0..00000000000 --- a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.cc +++ /dev/null @@ -1,170 +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/native_file_system/window_native_file_system.h" - -#include <utility> - -#include "mojo/public/cpp/bindings/remote.h" -#include "services/network/public/mojom/web_sandbox_flags.mojom-blink.h" -#include "third_party/blink/public/common/browser_interface_broker_proxy.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_promise_resolver.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_choose_file_system_entries_options.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_choose_file_system_entries_options_accepts.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/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/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/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/heap/heap.h" -#include "third_party/blink/renderer/platform/wtf/functional.h" - -namespace blink { - -namespace { - -mojom::blink::ChooseFileSystemEntryType ConvertChooserType(const String& input, - bool multiple) { - if (input == "open-file" || input == "openFile") { - return multiple - ? mojom::blink::ChooseFileSystemEntryType::kOpenMultipleFiles - : mojom::blink::ChooseFileSystemEntryType::kOpenFile; - } - if (input == "save-file" || input == "saveFile") - return mojom::blink::ChooseFileSystemEntryType::kSaveFile; - if (input == "open-directory" || input == "openDirectory") - return mojom::blink::ChooseFileSystemEntryType::kOpenDirectory; - NOTREACHED(); - return mojom::blink::ChooseFileSystemEntryType::kOpenFile; -} - -Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> ConvertAccepts( - const HeapVector<Member<ChooseFileSystemEntriesOptionsAccepts>>& accepts) { - Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> result; - result.ReserveInitialCapacity(accepts.size()); - for (const auto& a : accepts) { - result.emplace_back( - blink::mojom::blink::ChooseFileSystemEntryAcceptsOption::New( - a->hasDescription() ? a->description() : g_empty_string, - a->hasMimeTypes() ? a->mimeTypes() : Vector<String>(), - a->hasExtensions() ? a->extensions() : Vector<String>())); - } - return result; -} - -} // namespace - -// static -ScriptPromise WindowNativeFileSystem::chooseFileSystemEntries( - ScriptState* script_state, - LocalDOMWindow& window, - const ChooseFileSystemEntriesOptions* options, - ExceptionState& exception_state) { - if (!window.IsCurrentlyDisplayedInFrame()) { - exception_state.ThrowDOMException(DOMExceptionCode::kAbortError, ""); - return ScriptPromise(); - } - - Document* document = window.document(); - if (!document) { - exception_state.ThrowDOMException(DOMExceptionCode::kAbortError, ""); - return ScriptPromise(); - } - - if (!document->GetSecurityOrigin()->CanAccessNativeFileSystem()) { - if (document->IsSandboxed( - network::mojom::blink::WebSandboxFlags::kOrigin)) { - exception_state.ThrowSecurityError( - "Sandboxed documents aren't allowed to show a file picker."); - return ScriptPromise(); - } else { - exception_state.ThrowSecurityError( - "This document isn't allowed to show a file picker."); - return ScriptPromise(); - } - } - - LocalFrame* local_frame = window.GetFrame(); - if (!local_frame || local_frame->IsCrossOriginToMainFrame()) { - exception_state.ThrowSecurityError( - "Cross origin sub frames aren't allowed to show a file picker."); - return ScriptPromise(); - } - - if (!LocalFrame::HasTransientUserActivation(local_frame)) { - exception_state.ThrowSecurityError( - "Must be handling a user gesture to show a file picker."); - return ScriptPromise(); - } - - Vector<mojom::blink::ChooseFileSystemEntryAcceptsOptionPtr> accepts; - if (options->hasAccepts()) - accepts = ConvertAccepts(options->accepts()); - - auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); - ScriptPromise resolver_result = resolver->Promise(); - - // TODO(mek): Cache mojo::Remote<mojom::blink::NativeFileSystemManager> - // associated with an ExecutionContext, so we don't have to request a new one - // for each operation, and can avoid code duplication between here and other - // uses. - mojo::Remote<mojom::blink::NativeFileSystemManager> manager; - document->GetBrowserInterfaceBroker().GetInterface( - manager.BindNewPipeAndPassReceiver()); - - auto* raw_manager = manager.get(); - raw_manager->ChooseEntries( - ConvertChooserType(options->type(), options->multiple()), - std::move(accepts), !options->excludeAcceptAllOption(), - WTF::Bind( - [](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(); - if (!context) - return; - if (file_operation_result->status != - mojom::blink::NativeFileSystemStatus::kOk) { - native_file_system_error::Reject(resolver, - *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); - - if (options->multiple()) { - HeapVector<Member<NativeFileSystemHandle>> results; - results.ReserveInitialCapacity(entries.size()); - for (auto& entry : entries) { - results.push_back(NativeFileSystemHandle::CreateFromMojoEntry( - std::move(entry), context)); - } - resolver->Resolve(results); - } else { - DCHECK_EQ(1u, entries.size()); - resolver->Resolve(NativeFileSystemHandle::CreateFromMojoEntry( - std::move(entries[0]), context)); - } - }, - WrapPersistent(resolver), std::move(manager), WrapPersistent(options), - WrapPersistent(local_frame))); - return resolver_result; -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.h b/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.h deleted file mode 100644 index 8f4926ab0d6..00000000000 --- a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.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_NATIVE_FILE_SYSTEM_WINDOW_NATIVE_FILE_SYSTEM_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_WINDOW_NATIVE_FILE_SYSTEM_H_ - -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -class ChooseFileSystemEntriesOptions; -class ExceptionState; -class LocalDOMWindow; -class ScriptPromise; -class ScriptState; - -class WindowNativeFileSystem { - STATIC_ONLY(WindowNativeFileSystem); - - public: - static ScriptPromise chooseFileSystemEntries( - ScriptState*, - LocalDOMWindow&, - const ChooseFileSystemEntriesOptions*, - ExceptionState&); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_NATIVE_FILE_SYSTEM_WINDOW_NATIVE_FILE_SYSTEM_H_ diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl b/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl index fae73c8984d..df7c4473a89 100644 --- a/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl +++ b/chromium/third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl @@ -2,13 +2,27 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://wicg.github.io/native-file-system/#api-choosefilesystementries +// https://wicg.github.io/native-file-system/#native-filesystem +// https://wicg.github.io/native-file-system/#api-getoriginprivatefilesystem [ SecureContext, RuntimeEnabled=NativeFileSystem, - ImplementedAs=WindowNativeFileSystem + ImplementedAs=GlobalNativeFileSystem ] partial interface Window { - [CallWith=ScriptState, Measure, RaisesException] + [CallWith=ScriptState, Measure, RaisesException, RuntimeEnabled=LegacyNativeFileSystem] Promise<(FileSystemHandle or sequence<FileSystemHandle>)> chooseFileSystemEntries(optional ChooseFileSystemEntriesOptions options = {}); + + [CallWith=ScriptState, RaisesException] + Promise<sequence<FileSystemFileHandle>> showOpenFilePicker( + optional OpenFilePickerOptions options = {}); + [CallWith=ScriptState, RaisesException] + Promise<FileSystemFileHandle> showSaveFilePicker( + optional SaveFilePickerOptions options = {}); + [CallWith=ScriptState, RaisesException] + Promise<FileSystemDirectoryHandle> showDirectoryPicker( + optional DirectoryPickerOptions options = {}); + + [CallWith=ScriptState, RaisesException] + Promise<FileSystemDirectoryHandle> getOriginPrivateDirectory(); }; diff --git a/chromium/third_party/blink/renderer/modules/native_file_system/worker_global_scope_native_file_system.idl b/chromium/third_party/blink/renderer/modules/native_file_system/worker_global_scope_native_file_system.idl new file mode 100644 index 00000000000..eaf542b453a --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/native_file_system/worker_global_scope_native_file_system.idl @@ -0,0 +1,13 @@ +// 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/native-file-system/#api-getoriginprivatefilesystem +[ + SecureContext, + RuntimeEnabled=NativeFileSystem, + ImplementedAs=GlobalNativeFileSystem +] partial interface WorkerGlobalScope { + [CallWith=ScriptState, RaisesException] + Promise<FileSystemDirectoryHandle> getOriginPrivateDirectory(); +}; diff --git a/chromium/third_party/blink/renderer/modules/native_io/global_native_io.cc b/chromium/third_party/blink/renderer/modules/native_io/global_native_io.cc index 1c4ff4afcd2..604c36afdbf 100644 --- a/chromium/third_party/blink/renderer/modules/native_io/global_native_io.cc +++ b/chromium/third_party/blink/renderer/modules/native_io/global_native_io.cc @@ -61,7 +61,7 @@ class GlobalNativeIOImpl final : public GarbageCollected<GlobalNativeIOImpl<T>>, return native_io_manager_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(native_io_manager_); Supplement<T>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_file.cc b/chromium/third_party/blink/renderer/modules/native_io/native_io_file.cc index 1adc7944222..3214540b8ff 100644 --- a/chromium/third_party/blink/renderer/modules/native_io/native_io_file.cc +++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file.cc @@ -202,7 +202,7 @@ ScriptPromise NativeIOFile::write(ScriptState* script_state, return resolver->Promise(); } -void NativeIOFile::Trace(Visitor* visitor) { +void NativeIOFile::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); visitor->Trace(queued_close_resolver_); visitor->Trace(backend_file_); diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_file.h b/chromium/third_party/blink/renderer/modules/native_io/native_io_file.h index 5424f1ed056..db236c543bf 100644 --- a/chromium/third_party/blink/renderer/modules/native_io/native_io_file.h +++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file.h @@ -57,7 +57,7 @@ class NativeIOFile final : public ScriptWrappable { ExceptionState&); // GarbageCollected - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: // Data accessed on the threads that do file I/O. diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.cc b/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.cc index 5655c50ff85..931ec9444e5 100644 --- a/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.cc +++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.cc @@ -86,7 +86,7 @@ int NativeIOFileSync::write(MaybeShared<DOMArrayBufferView> buffer, return written_bytes; } -void NativeIOFileSync::Trace(Visitor* visitor) { +void NativeIOFileSync::Trace(Visitor* visitor) const { visitor->Trace(backend_file_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.h b/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.h index c3d2c16671f..8e78b40cb78 100644 --- a/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.h +++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_file_sync.h @@ -46,7 +46,7 @@ class NativeIOFileSync final : public ScriptWrappable { ExceptionState&); // GarbageCollected - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: // Called when the mojo backend disconnects. diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.cc b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.cc index 739e62d2740..5be455a2bbf 100644 --- a/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.cc +++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.cc @@ -104,6 +104,21 @@ void OnGetAllResult(ScriptPromiseResolver* resolver, resolver->Resolve(file_names); } +void OnRenameResult(ScriptPromiseResolver* resolver, bool backend_success) { + ScriptState* script_state = resolver->GetScriptState(); + if (!script_state->ContextIsValid()) + return; + ScriptState::Scope scope(script_state); + + if (!backend_success) { + resolver->Reject(V8ThrowDOMException::CreateOrEmpty( + script_state->GetIsolate(), DOMExceptionCode::kUnknownError, + "rename() failed")); + return; + } + resolver->Resolve(); +} + } // namespace NativeIOManager::NativeIOManager( @@ -184,6 +199,27 @@ ScriptPromise NativeIOManager::getAll(ScriptState* script_state, return resolver->Promise(); } +ScriptPromise NativeIOManager::rename(ScriptState* script_state, + String old_name, + String new_name, + ExceptionState& exception_state) { + if (!IsValidNativeIOName(old_name) || !IsValidNativeIOName(new_name)) { + exception_state.ThrowTypeError("Invalid file name"); + return ScriptPromise(); + } + + if (!backend_.is_bound()) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "NativeIOHost backend went away"); + return ScriptPromise(); + } + + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + backend_->RenameFile(old_name, new_name, + WTF::Bind(&OnRenameResult, WrapPersistent(resolver))); + return resolver->Promise(); +} + NativeIOFileSync* NativeIOManager::openSync(String name, ExceptionState& exception_state) { if (!IsValidNativeIOName(name)) { @@ -258,7 +294,31 @@ Vector<String> NativeIOManager::getAllSync(ExceptionState& exception_state) { return result; } -void NativeIOManager::Trace(Visitor* visitor) { +void NativeIOManager::renameSync(String old_name, + String new_name, + ExceptionState& exception_state) { + if (!IsValidNativeIOName(old_name) || !IsValidNativeIOName(new_name)) { + exception_state.ThrowTypeError("Invalid file name"); + return; + } + + if (!backend_.is_bound()) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "NativeIOHost backend went away"); + return; + } + + bool backend_success = false; + bool call_succeeded = + backend_->RenameFile(old_name, new_name, &backend_success); + + if (!call_succeeded || !backend_success) { + exception_state.ThrowDOMException(DOMExceptionCode::kUnknownError, + "renameSync() failed"); + } +} + +void NativeIOManager::Trace(Visitor* visitor) const { visitor->Trace(backend_); ScriptWrappable::Trace(visitor); ExecutionContextClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.h b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.h index 85c439fec1c..060bd016075 100644 --- a/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.h +++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.h @@ -40,13 +40,18 @@ class NativeIOManager final : public ScriptWrappable, ScriptPromise open(ScriptState*, String name, ExceptionState&); ScriptPromise Delete(ScriptState*, String name, ExceptionState&); ScriptPromise getAll(ScriptState*, ExceptionState&); + ScriptPromise rename(ScriptState*, + String old_name, + String new_name, + ExceptionState&); NativeIOFileSync* openSync(String name, ExceptionState&); void deleteSync(String name, ExceptionState&); Vector<String> getAllSync(ExceptionState&); + void renameSync(String old_name, String new_name, ExceptionState&); // GarbageCollected - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: // Called when the mojo backend disconnects. diff --git a/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.idl b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.idl index c2317ff73d5..860eff12c84 100644 --- a/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.idl +++ b/chromium/third_party/blink/renderer/modules/native_io/native_io_manager.idl @@ -25,4 +25,9 @@ CallWith=ScriptState, RaisesException ] Promise<sequence<DOMString>> getAll(); [Exposed=DedicatedWorker, RaisesException] sequence<DOMString> getAllSync(); + + [ + CallWith=ScriptState, RaisesException + ] Promise<void> rename(DOMString old_name, DOMString new_name); + [Exposed=DedicatedWorker, RaisesException] void renameSync(DOMString old_name, DOMString new_name); }; diff --git a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc index 42936722ae8..f83ba5add07 100644 --- a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc +++ b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.cc @@ -28,6 +28,7 @@ #include "base/stl_util.h" #include "third_party/blink/renderer/core/dom/document.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/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.h" @@ -41,6 +42,10 @@ namespace blink { const char NavigatorContentUtils::kSupplementName[] = "NavigatorContentUtils"; +namespace { + +const char kToken[] = "%s"; + // Changes to this list must be kept in sync with the browser-side checks in // /chrome/common/custom_handlers/protocol_handler.cc. static const HashSet<String>& SupportedSchemes() { @@ -54,50 +59,50 @@ static const HashSet<String>& SupportedSchemes() { return supported_schemes; } -static bool VerifyCustomHandlerURL(const Document& document, - const String& url, - ExceptionState& exception_state) { - // The specification requires that it is a SyntaxError if the "%s" token is - // not present. - static const char kToken[] = "%s"; - int index = url.Find(kToken); - if (-1 == index) { - exception_state.ThrowDOMException( - DOMExceptionCode::kSyntaxError, - "The url provided ('" + url + "') does not contain '%s'."); - return false; - } - - // It is also a SyntaxError if the custom handler URL, as created by removing - // the "%s" token and prepending the base url, does not resolve. - String new_url = url; - new_url.Remove(index, base::size(kToken) - 1); - KURL kurl = document.CompleteURL(new_url); - - if (kurl.IsEmpty() || !kurl.IsValid()) { - exception_state.ThrowDOMException( - DOMExceptionCode::kSyntaxError, - "The custom handler URL created by removing '%s' and prepending '" + - document.BaseURL().GetString() + "' is invalid."); - return false; - } - +static bool VerifyCustomHandlerURLSecurity(const Document& document, + const KURL& full_url, + String& error_message) { // Although not required by the spec, the spec allows additional security // checks. Bugs have arisen from allowing non-http/https URLs, e.g. // https://crbug.com/971917 and it doesn't make a lot of sense to support // them. We do need to allow extensions to continue using the API. - if (!kurl.ProtocolIsInHTTPFamily() && !kurl.ProtocolIs("chrome-extension")) { - exception_state.ThrowSecurityError( + if (!full_url.ProtocolIsInHTTPFamily() && + !full_url.ProtocolIs("chrome-extension")) { + error_message = "The scheme of the url provided must be 'https' or " - "'chrome-extension'."); + "'chrome-extension'."; return false; } // The specification says that the API throws SecurityError exception if the // URL's origin differs from the document's origin. - if (!document.GetSecurityOrigin()->CanRequest(kurl)) { - exception_state.ThrowSecurityError( - "Can only register custom handler in the document's origin."); + if (!document.GetSecurityOrigin()->CanRequest(full_url)) { + error_message = + "Can only register custom handler in the document's origin."; + return false; + } + + return true; +} + +static bool VerifyCustomHandlerURL(const Document& document, + const String& user_url, + ExceptionState& exception_state) { + String new_url = user_url; + new_url.Remove(user_url.Find(kToken), base::size(kToken) - 1); + KURL full_url = document.CompleteURL(new_url); + KURL base_url = document.BaseURL(); + String error_message; + + if (!VerifyCustomHandlerURLSyntax(full_url, base_url, user_url, + error_message)) { + exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, + error_message); + return false; + } + + if (!VerifyCustomHandlerURLSecurity(document, full_url, error_message)) { + exception_state.ThrowSecurityError(error_message); return false; } @@ -120,36 +125,60 @@ static bool IsValidWebSchemeName(const String& protocol) { return true; } -static bool VerifyCustomHandlerScheme(const String& scheme, - ExceptionState& exception_state) { +} // namespace + +bool VerifyCustomHandlerScheme(const String& scheme, String& error_string) { if (!IsValidProtocol(scheme)) { - exception_state.ThrowSecurityError( - "The scheme name '" + scheme + - "' is not allowed by URI syntax (RFC3986)."); + error_string = "The scheme name '" + scheme + + "' is not allowed by URI syntax (RFC3986)."; return false; } if (scheme.StartsWithIgnoringASCIICase("web+")) { if (IsValidWebSchemeName(scheme)) return true; - exception_state.ThrowSecurityError( + error_string = "The scheme name '" + scheme + "' is not allowed. Schemes starting with 'web+' must be followed by " - "one or more ASCII letters."); + "one or more ASCII letters."; return false; } if (SupportedSchemes().Contains(scheme.LowerASCII())) return true; - exception_state.ThrowSecurityError( - "The scheme '" + scheme + - "' doesn't belong to the scheme allowlist. " - "Please prefix non-allowlisted schemes " - "with the string 'web+'."); + error_string = "The scheme '" + scheme + + "' doesn't belong to the scheme allowlist. " + "Please prefix non-allowlisted schemes " + "with the string 'web+'."; return false; } +bool VerifyCustomHandlerURLSyntax(const KURL& full_url, + const KURL& base_url, + const String& user_url, + String& error_message) { + // The specification requires that it is a SyntaxError if the "%s" token is + // not present. + int index = user_url.Find(kToken); + if (-1 == index) { + error_message = + "The url provided ('" + user_url + "') does not contain '%s'."; + return false; + } + + // It is also a SyntaxError if the custom handler URL, as created by removing + // the "%s" token and prepending the base url, does not resolve. + if (full_url.IsEmpty() || !full_url.IsValid()) { + error_message = + "The custom handler URL created by removing '%s' and prepending '" + + base_url.GetString() + "' is invalid."; + return false; + } + + return true; +} + NavigatorContentUtils& NavigatorContentUtils::From(Navigator& navigator, LocalFrame& frame) { NavigatorContentUtils* navigator_content_utils = @@ -170,36 +199,37 @@ void NavigatorContentUtils::registerProtocolHandler( const String& url, const String& title, ExceptionState& exception_state) { - LocalFrame* frame = navigator.GetFrame(); - if (!frame) + LocalDOMWindow* window = navigator.DomWindow(); + if (!window) return; - Document* document = frame->GetDocument(); - DCHECK(document); // Per the HTML specification, exceptions for arguments must be surfaced in // the order of the arguments. - if (!VerifyCustomHandlerScheme(scheme, exception_state)) + String error_message; + if (!VerifyCustomHandlerScheme(scheme, error_message)) { + exception_state.ThrowSecurityError(error_message); return; + } - if (!VerifyCustomHandlerURL(*document, url, exception_state)) + if (!VerifyCustomHandlerURL(*window->document(), url, exception_state)) return; // Count usage; perhaps we can forbid this from cross-origin subframes as // proposed in https://crbug.com/977083. UseCounter::Count( - *document, frame->IsCrossOriginToMainFrame() - ? WebFeature::kRegisterProtocolHandlerCrossOriginSubframe - : WebFeature::kRegisterProtocolHandlerSameOriginAsTop); + window, window->GetFrame()->IsCrossOriginToMainFrame() + ? WebFeature::kRegisterProtocolHandlerCrossOriginSubframe + : WebFeature::kRegisterProtocolHandlerSameOriginAsTop); // Count usage. Context should now always be secure due to the same-origin // check and the requirement that the calling context be secure. - UseCounter::Count(*document, - document->IsSecureContext() + UseCounter::Count(window, + window->IsSecureContext() ? WebFeature::kRegisterProtocolHandlerSecureOrigin : WebFeature::kRegisterProtocolHandlerInsecureOrigin); - NavigatorContentUtils::From(navigator, *frame) + NavigatorContentUtils::From(navigator, *window->GetFrame()) .Client() - ->RegisterProtocolHandler(scheme, document->CompleteURL(url), title); + ->RegisterProtocolHandler(scheme, window->CompleteURL(url), title); } void NavigatorContentUtils::unregisterProtocolHandler( @@ -213,8 +243,11 @@ void NavigatorContentUtils::unregisterProtocolHandler( Document* document = frame->GetDocument(); DCHECK(document); - if (!VerifyCustomHandlerScheme(scheme, exception_state)) + String error_message; + if (!VerifyCustomHandlerScheme(scheme, error_message)) { + exception_state.ThrowSecurityError(error_message); return; + } if (!VerifyCustomHandlerURL(*document, url, exception_state)) return; @@ -224,7 +257,7 @@ void NavigatorContentUtils::unregisterProtocolHandler( ->UnregisterProtocolHandler(scheme, document->CompleteURL(url)); } -void NavigatorContentUtils::Trace(Visitor* visitor) { +void NavigatorContentUtils::Trace(Visitor* visitor) const { visitor->Trace(client_); Supplement<Navigator>::Trace(visitor); } 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 cf4ae1bab3f..ac19e36c978 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 @@ -38,6 +38,22 @@ namespace blink { class ExceptionState; class NavigatorContentUtilsClient; +// Verify custom handler schemes for errors as described in +// https://html.spec.whatwg.org/multipage/system-state.html#custom-handlers. +// Callers should surface an error with |error_message| if it returns false. +bool VerifyCustomHandlerScheme(const String& scheme, String& error_message); + +// Verify custom handler URLs for syntax errors as described in +// https://html.spec.whatwg.org/multipage/system-state.html#custom-handlers. +// Callers should surface an error with |error_message| if it returns false. +// |full_url| is calculated URL that needs to resolve to a valid URL. +// |base_url| is used for the error message and is generally the Document URL. +// |user_url| is the URL provided by the user, which may be relative. +bool VerifyCustomHandlerURLSyntax(const KURL& full_url, + const KURL& base_url, + const String& user_url, + String& error_message); + // It is owned by Navigator, and an instance is created lazily by calling // NavigatorContentUtils::From() via [register/unregister]ProtocolHandler. class MODULES_EXPORT NavigatorContentUtils final @@ -63,7 +79,7 @@ class MODULES_EXPORT NavigatorContentUtils final const String& url, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void SetClientForTest(NavigatorContentUtilsClient* client) { client_ = client; diff --git a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.cc b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.cc index a358d4dfe0e..af8baeab807 100644 --- a/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.cc +++ b/chromium/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils_client.cc @@ -12,7 +12,7 @@ namespace blink { NavigatorContentUtilsClient::NavigatorContentUtilsClient(LocalFrame* frame) : frame_(frame) {} -void NavigatorContentUtilsClient::Trace(Visitor* visitor) { +void NavigatorContentUtilsClient::Trace(Visitor* visitor) const { visitor->Trace(frame_); } 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 f7f0d906067..7e7a9d2a363 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 @@ -26,7 +26,7 @@ class MODULES_EXPORT NavigatorContentUtilsClient virtual void UnregisterProtocolHandler(const String& scheme, const KURL&); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; private: Member<LocalFrame> frame_; diff --git a/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.cc b/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.cc index 86df6beed3f..0e382dd2fa0 100644 --- a/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.cc +++ b/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.cc @@ -48,7 +48,7 @@ NetworkInformation* NavigatorNetworkInformation::connection() { return connection_.Get(); } -void NavigatorNetworkInformation::Trace(Visitor* visitor) { +void NavigatorNetworkInformation::Trace(Visitor* visitor) const { visitor->Trace(connection_); Supplement<Navigator>::Trace(visitor); ExecutionContextClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.h b/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.h index 0945246caad..670d30a9ef9 100644 --- a/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.h +++ b/chromium/third_party/blink/renderer/modules/netinfo/navigator_network_information.h @@ -29,7 +29,7 @@ class NavigatorNetworkInformation final explicit NavigatorNetworkInformation(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: NetworkInformation* connection(); diff --git a/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc b/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc index 044c88fcb24..44fb0589cb9 100644 --- a/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc +++ b/chromium/third_party/blink/renderer/modules/netinfo/network_information.cc @@ -290,7 +290,7 @@ NetworkInformation::NetworkInformation(ExecutionContext* context) DCHECK_GE(20u, GetNetworkStateNotifier().RandomizationSalt()); } -void NetworkInformation::Trace(Visitor* visitor) { +void NetworkInformation::Trace(Visitor* visitor) const { EventTargetWithInlineData::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/netinfo/network_information.h b/chromium/third_party/blink/renderer/modules/netinfo/network_information.h index 2797435c7a9..4649fae42a8 100644 --- a/chromium/third_party/blink/renderer/modules/netinfo/network_information.h +++ b/chromium/third_party/blink/renderer/modules/netinfo/network_information.h @@ -56,7 +56,7 @@ class NetworkInformation final // ExecutionContextLifecycleObserver overrides. void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange) DEFINE_ATTRIBUTE_EVENT_LISTENER(typechange, kTypechange) // Deprecated diff --git a/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.cc b/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.cc index f0086c7f52b..abb3bdcc058 100644 --- a/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.cc +++ b/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.cc @@ -48,7 +48,7 @@ NetworkInformation* WorkerNavigatorNetworkInformation::connection( .connection(context); } -void WorkerNavigatorNetworkInformation::Trace(Visitor* visitor) { +void WorkerNavigatorNetworkInformation::Trace(Visitor* visitor) const { visitor->Trace(connection_); Supplement<WorkerNavigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.h b/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.h index 89d7c479367..5f3b0d34ac8 100644 --- a/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.h +++ b/chromium/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.h @@ -33,7 +33,7 @@ class WorkerNavigatorNetworkInformation final WorkerNavigatorNetworkInformation(WorkerNavigator&, ExecutionContext*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: NetworkInformation* connection(ExecutionContext*); 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 52b9f214c13..227006efc6c 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.cc @@ -194,7 +194,7 @@ const HeapVector<Member<NDEFRecord>>& NDEFMessage::records() const { return records_; } -void NDEFMessage::Trace(Visitor* visitor) { +void NDEFMessage::Trace(Visitor* visitor) const { visitor->Trace(records_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.h b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.h index 9a5f485e24c..c6183f076ac 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_message.h +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_message.h @@ -42,7 +42,7 @@ class MODULES_EXPORT NDEFMessage final : public ScriptWrappable { const HeapVector<Member<NDEFRecord>>& records() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: HeapVector<Member<NDEFRecord>> records_; diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.cc b/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.cc index 898f26dc31b..b83d27aa791 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.cc @@ -170,7 +170,7 @@ void NDEFReader::OnScanRequestCompleted( resolver_.Clear(); } -void NDEFReader::Trace(Visitor* visitor) { +void NDEFReader::Trace(Visitor* visitor) const { visitor->Trace(permission_service_); visitor->Trace(resolver_); visitor->Trace(signal_); diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.h b/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.h index c53a124c951..cfb0aa6df34 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.h +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_reader.h @@ -47,7 +47,7 @@ class MODULES_EXPORT NDEFReader : public EventTargetWithInlineData, DEFINE_ATTRIBUTE_EVENT_LISTENER(reading, kReading) ScriptPromise scan(ScriptState*, const NDEFScanOptions*, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Called by NFCProxy for dispatching events. virtual void OnReading(const String& serial_number, diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.cc b/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.cc index 2035d5628d6..9561458d230 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.cc @@ -42,7 +42,7 @@ const AtomicString& NDEFReadingEvent::InterfaceName() const { return event_interface_names::kNDEFReadingEvent; } -void NDEFReadingEvent::Trace(Visitor* visitor) { +void NDEFReadingEvent::Trace(Visitor* visitor) const { visitor->Trace(message_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.h b/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.h index 6f7e5f8f463..87146a59446 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.h +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_reading_event.h @@ -31,7 +31,7 @@ class NDEFReadingEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const String& serialNumber() const; NDEFMessage* message() const; 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 a7c45e9fbbc..5888d7d9ec2 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.cc @@ -134,27 +134,27 @@ bool IsValidLocalType(const String& input) { } String getDocumentLanguage(const ExecutionContext* execution_context) { - DCHECK(execution_context); String document_language; - Element* document_element = - To<LocalDOMWindow>(execution_context)->document()->documentElement(); - if (document_element) { - document_language = document_element->getAttribute(html_names::kLangAttr); - } - if (document_language.IsEmpty()) { - document_language = "en"; + if (execution_context) { + Element* document_element = + To<LocalDOMWindow>(execution_context)->document()->documentElement(); + if (document_element) { + document_language = document_element->getAttribute(html_names::kLangAttr); + } + if (document_language.IsEmpty()) { + document_language = "en"; + } } return document_language; } -static NDEFRecord* CreateTextRecord(const String& id, - const ExecutionContext* execution_context, - const String& encoding, - const String& lang, - const NDEFRecordDataSource& data, +static NDEFRecord* CreateTextRecord(const ExecutionContext* execution_context, + const String& id, + const NDEFRecordInit& record, ExceptionState& exception_state) { // https://w3c.github.io/web-nfc/#mapping-string-to-ndef - if (!(data.IsString() || IsBufferSource(data))) { + if (!record.hasData() || + !(record.data().IsString() || IsBufferSource(record.data()))) { exception_state.ThrowTypeError( "The data for 'text' NDEFRecords must be a String or a BufferSource."); return nullptr; @@ -162,8 +162,10 @@ static NDEFRecord* CreateTextRecord(const String& id, // Set language to lang if it exists, or the document element's lang // attribute, or 'en'. - String language = lang; - if (execution_context && language.IsEmpty()) { + String language; + if (record.hasLang()) { + language = record.lang(); + } else { language = getDocumentLanguage(execution_context); } @@ -175,7 +177,9 @@ static NDEFRecord* CreateTextRecord(const String& id, return nullptr; } - String encoding_label = encoding.IsNull() ? "utf-8" : encoding; + auto& data = record.data(); + // TODO(crbug.com/1070871): Use encodingOr("utf-8"). + String encoding_label = record.hasEncoding() ? record.encoding() : "utf-8"; WTF::Vector<uint8_t> bytes; if (data.IsString()) { if (encoding_label != "utf-8") { @@ -205,67 +209,69 @@ static NDEFRecord* CreateTextRecord(const String& id, } // Create a 'url' record or an 'absolute-url' record. -static NDEFRecord* CreateUrlRecord(const String& record_type, - const String& id, - const NDEFRecordDataSource& data, +static NDEFRecord* CreateUrlRecord(const String& id, + const NDEFRecordInit& record, ExceptionState& exception_state) { // https://w3c.github.io/web-nfc/#mapping-url-to-ndef - if (!data.IsString()) { + if (!record.hasData() || !record.data().IsString()) { exception_state.ThrowTypeError( "The data for url NDEFRecord must be a String."); return nullptr; } // No need to check mediaType according to the spec. - String url = data.GetAsString(); + String url = record.data().GetAsString(); if (!KURL(NullURL(), url).IsValid()) { exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, "Cannot parse data for url record."); return nullptr; } + return MakeGarbageCollected<NDEFRecord>( - device::mojom::blink::NDEFRecordTypeCategory::kStandardized, record_type, - id, GetUTF8DataFromString(url)); + device::mojom::blink::NDEFRecordTypeCategory::kStandardized, + record.recordType(), id, GetUTF8DataFromString(url)); } static NDEFRecord* CreateMimeRecord(const String& id, - const NDEFRecordDataSource& data, - const String& media_type, + const NDEFRecordInit& record, ExceptionState& exception_state) { // https://w3c.github.io/web-nfc/#mapping-binary-data-to-ndef - if (!IsBufferSource(data)) { + if (!record.hasData() || !IsBufferSource(record.data())) { exception_state.ThrowTypeError( "The data for 'mime' NDEFRecord must be a BufferSource."); return nullptr; } - WTF::Vector<uint8_t> bytes; - if (!GetBytesOfBufferSource(data, &bytes, exception_state)) { - return nullptr; - } - // ExtractMIMETypeFromMediaType() ignores parameters of the MIME type. - String mime_type = ExtractMIMETypeFromMediaType(AtomicString(media_type)); - if (mime_type.IsEmpty()) { + String mime_type; + if (record.hasMediaType() && !record.mediaType().IsEmpty()) { + mime_type = ExtractMIMETypeFromMediaType(AtomicString(record.mediaType())); + } else { mime_type = "application/octet-stream"; } + WTF::Vector<uint8_t> bytes; + if (!GetBytesOfBufferSource(record.data(), &bytes, exception_state)) { + return nullptr; + } + return MakeGarbageCollected<NDEFRecord>(id, mime_type, bytes); } static NDEFRecord* CreateUnknownRecord(const String& id, - const NDEFRecordDataSource& data, + const NDEFRecordInit& record, ExceptionState& exception_state) { - if (!IsBufferSource(data)) { + if (!record.hasData() || !IsBufferSource(record.data())) { exception_state.ThrowTypeError( "The data for 'unknown' NDEFRecord must be a BufferSource."); return nullptr; } WTF::Vector<uint8_t> bytes; - if (!GetBytesOfBufferSource(data, &bytes, exception_state)) { + if (!GetBytesOfBufferSource(record.data(), &bytes, exception_state)) { return nullptr; } + return MakeGarbageCollected<NDEFRecord>( device::mojom::blink::NDEFRecordTypeCategory::kStandardized, "unknown", id, bytes); @@ -274,17 +280,17 @@ static NDEFRecord* CreateUnknownRecord(const String& id, static NDEFRecord* CreateSmartPosterRecord( const ExecutionContext* execution_context, const String& id, - const NDEFRecordDataSource& data, + const NDEFRecordInit& record, ExceptionState& exception_state) { // https://w3c.github.io/web-nfc/#dfn-map-smart-poster-to-ndef - if (!data.IsNDEFMessageInit()) { + if (!record.hasData() || !record.data().IsNDEFMessageInit()) { exception_state.ThrowTypeError( "The data for 'smart-poster' NDEFRecord must be an NDEFMessageInit."); return nullptr; } NDEFMessage* payload_message = NDEFMessage::CreateAsPayloadOfSmartPoster( - execution_context, data.GetAsNDEFMessageInit(), exception_state); + execution_context, record.data().GetAsNDEFMessageInit(), exception_state); if (exception_state.HadException()) return nullptr; DCHECK(payload_message); @@ -296,23 +302,24 @@ static NDEFRecord* CreateSmartPosterRecord( static NDEFRecord* CreateExternalRecord( const ExecutionContext* execution_context, - const String& record_type, const String& id, - const NDEFRecordDataSource& data, + const NDEFRecordInit& record, ExceptionState& exception_state) { + const String& record_type = record.recordType(); + // https://w3c.github.io/web-nfc/#dfn-map-external-data-to-ndef - if (IsBufferSource(data)) { + if (record.hasData() && IsBufferSource(record.data())) { WTF::Vector<uint8_t> bytes; - if (!GetBytesOfBufferSource(data, &bytes, exception_state)) { + if (!GetBytesOfBufferSource(record.data(), &bytes, exception_state)) { return nullptr; } return MakeGarbageCollected<NDEFRecord>( device::mojom::blink::NDEFRecordTypeCategory::kExternal, record_type, id, bytes); - } else if (data.IsNDEFMessageInit()) { - NDEFMessage* payload_message = - NDEFMessage::Create(execution_context, data.GetAsNDEFMessageInit(), - exception_state, /*is_embedded=*/true); + } else if (record.hasData() && record.data().IsNDEFMessageInit()) { + NDEFMessage* payload_message = NDEFMessage::Create( + execution_context, record.data().GetAsNDEFMessageInit(), + exception_state, /*is_embedded=*/true); if (exception_state.HadException()) return nullptr; DCHECK(payload_message); @@ -328,23 +335,24 @@ static NDEFRecord* CreateExternalRecord( } static NDEFRecord* CreateLocalRecord(const ExecutionContext* execution_context, - const String& record_type, const String& id, - const NDEFRecordDataSource& data, + const NDEFRecordInit& record, ExceptionState& exception_state) { + const String& record_type = record.recordType(); + // https://w3c.github.io/web-nfc/#dfn-map-local-type-to-ndef - if (IsBufferSource(data)) { + if (record.hasData() && IsBufferSource(record.data())) { WTF::Vector<uint8_t> bytes; - if (!GetBytesOfBufferSource(data, &bytes, exception_state)) { + if (!GetBytesOfBufferSource(record.data(), &bytes, exception_state)) { return nullptr; } return MakeGarbageCollected<NDEFRecord>( device::mojom::blink::NDEFRecordTypeCategory::kLocal, record_type, id, bytes); - } else if (data.IsNDEFMessageInit()) { - NDEFMessage* payload_message = - NDEFMessage::Create(execution_context, data.GetAsNDEFMessageInit(), - exception_state, /*is_embedded=*/true); + } else if (record.hasData() && record.data().IsNDEFMessageInit()) { + NDEFMessage* payload_message = NDEFMessage::Create( + execution_context, record.data().GetAsNDEFMessageInit(), + exception_state, /*is_embedded=*/true); if (exception_state.HadException()) return nullptr; DCHECK(payload_message); @@ -363,51 +371,50 @@ static NDEFRecord* CreateLocalRecord(const ExecutionContext* execution_context, // static NDEFRecord* NDEFRecord::Create(const ExecutionContext* execution_context, - const NDEFRecordInit* init, + const NDEFRecordInit* record, ExceptionState& exception_state, bool is_embedded) { // https://w3c.github.io/web-nfc/#creating-ndef-record - - // NDEFRecordInit#recordType is a required field. - DCHECK(init->hasRecordType()); - const String& record_type = init->recordType(); + const String& record_type = record->recordType(); // https://w3c.github.io/web-nfc/#dom-ndefrecordinit-mediatype - if (init->hasMediaType() && record_type != "mime") { + if (record->hasMediaType() && record_type != "mime") { exception_state.ThrowTypeError( "NDEFRecordInit#mediaType is only applicable for 'mime' records."); return nullptr; } // https://w3c.github.io/web-nfc/#dfn-map-empty-record-to-ndef - if (init->hasId() && record_type == "empty") { + if (record->hasId() && record_type == "empty") { exception_state.ThrowTypeError( "NDEFRecordInit#id is not applicable for 'empty' records."); return nullptr; } + // TODO(crbug.com/1070871): Use IdOr(String()). + String id; + if (record->hasId()) + id = record->id(); + if (record_type == "empty") { // https://w3c.github.io/web-nfc/#mapping-empty-record-to-ndef return MakeGarbageCollected<NDEFRecord>( device::mojom::blink::NDEFRecordTypeCategory::kStandardized, - record_type, init->id(), WTF::Vector<uint8_t>()); + record_type, /*id=*/String(), WTF::Vector<uint8_t>()); } else if (record_type == "text") { - return CreateTextRecord(init->id(), execution_context, init->encoding(), - init->lang(), init->data(), exception_state); + return CreateTextRecord(execution_context, id, *record, exception_state); } else if (record_type == "url" || record_type == "absolute-url") { - return CreateUrlRecord(record_type, init->id(), init->data(), - exception_state); + return CreateUrlRecord(id, *record, exception_state); } else if (record_type == "mime") { - return CreateMimeRecord(init->id(), init->data(), init->mediaType(), - exception_state); + return CreateMimeRecord(id, *record, exception_state); } else if (record_type == "unknown") { - return CreateUnknownRecord(init->id(), init->data(), exception_state); + return CreateUnknownRecord(id, *record, exception_state); } else if (record_type == "smart-poster") { - return CreateSmartPosterRecord(execution_context, init->id(), init->data(), + return CreateSmartPosterRecord(execution_context, id, *record, exception_state); } else if (IsValidExternalType(record_type)) { - return CreateExternalRecord(execution_context, record_type, init->id(), - init->data(), exception_state); + return CreateExternalRecord(execution_context, id, *record, + exception_state); } else if (IsValidLocalType(record_type)) { if (!is_embedded) { exception_state.ThrowTypeError( @@ -415,8 +422,7 @@ NDEFRecord* NDEFRecord::Create(const ExecutionContext* execution_context, "of another record (smart-poster, external, or local)."); return nullptr; } - return CreateLocalRecord(execution_context, record_type, init->id(), - init->data(), exception_state); + return CreateLocalRecord(execution_context, id, *record, exception_state); } exception_state.ThrowTypeError("Invalid NDEFRecord type."); @@ -541,7 +547,7 @@ base::Optional<HeapVector<Member<NDEFRecord>>> NDEFRecord::toRecords( return payload_message_->records(); } -void NDEFRecord::Trace(Visitor* visitor) { +void NDEFRecord::Trace(Visitor* visitor) const { visitor->Trace(payload_message_); ScriptWrappable::Trace(visitor); } 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 ab00de43d6b..cccc93dfade 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_record.h +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_record.h @@ -76,7 +76,7 @@ class MODULES_EXPORT NDEFRecord final : public ScriptWrappable { const WTF::Vector<uint8_t>& payloadData() const { return payload_data_; } const NDEFMessage* payload_message() const { return payload_message_.Get(); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: const device::mojom::NDEFRecordTypeCategory category_; diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.cc b/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.cc index 5867f1f73cf..56a731524a1 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.cc @@ -41,7 +41,7 @@ NDEFWriter* NDEFWriter::Create(ExecutionContext* context) { NDEFWriter::NDEFWriter(ExecutionContext* context) : ExecutionContextClient(context), permission_service_(context) {} -void NDEFWriter::Trace(Visitor* visitor) { +void NDEFWriter::Trace(Visitor* visitor) const { visitor->Trace(permission_service_); visitor->Trace(requests_); visitor->Trace(nfc_proxy_); diff --git a/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.h b/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.h index 89f12a7f2e5..7c768deebe4 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.h +++ b/chromium/third_party/blink/renderer/modules/nfc/ndef_writer.h @@ -34,7 +34,7 @@ class NDEFWriter : public ScriptWrappable, public ExecutionContextClient { explicit NDEFWriter(ExecutionContext*); ~NDEFWriter() override = default; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Write NDEFMessageSource asynchronously to NFC tag. ScriptPromise write(ScriptState*, 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 3da736ba804..08001abdd79 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.cc @@ -41,7 +41,7 @@ NFCProxy::NFCProxy(LocalDOMWindow& window) NFCProxy::~NFCProxy() = default; -void NFCProxy::Trace(Visitor* visitor) { +void NFCProxy::Trace(Visitor* visitor) const { visitor->Trace(client_receiver_); visitor->Trace(writers_); visitor->Trace(readers_); 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 06fbc7eb1af..a230f65aca3 100644 --- a/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h +++ b/chromium/third_party/blink/renderer/modules/nfc/nfc_proxy.h @@ -35,7 +35,7 @@ class MODULES_EXPORT NFCProxy final : public GarbageCollected<NFCProxy>, explicit NFCProxy(LocalDOMWindow&); ~NFCProxy() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // There is no matching RemoveWriter() method because writers are // automatically removed from the weak hash set when they are garbage diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification.cc b/chromium/third_party/blink/renderer/modules/notifications/notification.cc index 28def81e3b5..dd0bbbc7e62 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification.cc +++ b/chromium/third_party/blink/renderer/modules/notifications/notification.cc @@ -99,19 +99,18 @@ Notification* Notification::Create(ExecutionContext* context, } auto* window = DynamicTo<LocalDOMWindow>(context); - auto* document = window ? window->document() : nullptr; if (context->IsSecureContext()) { UseCounter::Count(context, WebFeature::kNotificationSecureOrigin); - if (document) { - document->CountUseOnlyInCrossOriginIframe( + if (window) { + window->CountUseOnlyInCrossOriginIframe( WebFeature::kNotificationAPISecureOriginIframe); } } else { Deprecation::CountDeprecation(context, WebFeature::kNotificationInsecureOrigin); - if (document) { + if (window) { Deprecation::CountDeprecationCrossOriginIframe( - *document, WebFeature::kNotificationAPIInsecureOriginIframe); + window, WebFeature::kNotificationAPIInsecureOriginIframe); } } @@ -139,9 +138,9 @@ Notification* Notification::Create(ExecutionContext* context, notification->SchedulePrepareShow(); - if (document) { + if (window) { if (auto* document_resource_coordinator = - document->GetResourceCoordinator()) { + window->document()->GetResourceCoordinator()) { document_resource_coordinator->OnNonPersistentNotificationCreated(); } } @@ -498,7 +497,7 @@ bool Notification::HasPendingActivity() const { return false; } -void Notification::Trace(Visitor* visitor) { +void Notification::Trace(Visitor* visitor) const { visitor->Trace(show_trigger_); visitor->Trace(loader_); visitor->Trace(listener_receiver_); diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification.h b/chromium/third_party/blink/renderer/modules/notifications/notification.h index b4175457705..01bc43a5381 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification.h +++ b/chromium/third_party/blink/renderer/modules/notifications/notification.h @@ -140,7 +140,7 @@ class MODULES_EXPORT Notification final // ScriptWrappable interface. bool HasPendingActivity() const final; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; protected: // EventTarget interface. diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc index 50288072b4f..8a3ebd584ad 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc +++ b/chromium/third_party/blink/renderer/modules/notifications/notification_data.cc @@ -22,13 +22,16 @@ namespace blink { namespace { +// TODO(crbug.com/1092328): Use V8NotificationDirection. mojom::blink::NotificationDirection ToDirectionEnumValue( const String& direction) { if (direction == "ltr") return mojom::blink::NotificationDirection::LEFT_TO_RIGHT; if (direction == "rtl") return mojom::blink::NotificationDirection::RIGHT_TO_LEFT; - + if (direction == "auto") + return mojom::blink::NotificationDirection::AUTO; + NOTREACHED() << "Unknown direction: " << direction; return mojom::blink::NotificationDirection::AUTO; } @@ -78,11 +81,15 @@ mojom::blink::NotificationDataPtr CreateNotificationData( if (options->hasBadge() && !options->badge().IsEmpty()) notification_data->badge = CompleteURL(context, options->badge()); - VibrationController::VibrationPattern vibration_pattern = - VibrationController::SanitizeVibrationPattern(options->vibrate()); + VibrationController::VibrationPattern vibration_pattern; + if (options->hasVibrate()) { + vibration_pattern = + VibrationController::SanitizeVibrationPattern(options->vibrate()); + } notification_data->vibration_pattern = Vector<int32_t>(); notification_data->vibration_pattern->Append(vibration_pattern.data(), vibration_pattern.size()); + notification_data->timestamp = options->hasTimestamp() ? static_cast<double>(options->timestamp()) : base::Time::Now().ToDoubleT() * 1000.0; @@ -90,7 +97,9 @@ mojom::blink::NotificationDataPtr CreateNotificationData( notification_data->silent = options->silent(); notification_data->require_interaction = options->requireInteraction(); - if (options->hasData()) { + // TODO(crbug.com/1070871, crbug.com/1070964): |data| member has a null value + // as a default value, and we don't need |hasData()| check actually. + if (options->hasData() && !options->data().IsNull()) { const ScriptValue& data = options->data(); v8::Isolate* isolate = data.GetIsolate(); DCHECK(isolate->InContext()); 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 8266bed7d98..b5680a964ca 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 @@ -7,9 +7,9 @@ #include "base/stl_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/notifications/notification_constants.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_notification_action.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_notification_options.h" -#include "third_party/blink/renderer/core/testing/null_execution_context.h" #include "third_party/blink/renderer/modules/notifications/notification.h" #include "third_party/blink/renderer/modules/notifications/timestamp_trigger.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -49,37 +49,10 @@ const char kNotificationActionPlaceholder[] = "Placeholder..."; const unsigned kNotificationVibrationUnnormalized[] = {10, 1000000, 50, 42}; const int kNotificationVibrationNormalized[] = {10, 10000, 50}; -// Execution context that implements the CompleteURL method to complete -// URLs that are assumed to be relative against a given base URL. -class CompleteUrlExecutionContext final : public NullExecutionContext { - public: - explicit CompleteUrlExecutionContext(const String& base) : base_(base) {} +TEST(NotificationDataTest, ReflectProperties) { + const KURL base_url(kNotificationBaseUrl); + V8TestingScope scope(base_url); - protected: - ~CompleteUrlExecutionContext() final = default; - - KURL CompleteURL(const String& url) const override { - return KURL(base_, url); - } - - private: - KURL base_; -}; - -class NotificationDataTest : public testing::Test { - public: - void SetUp() override { - execution_context_ = - MakeGarbageCollected<CompleteUrlExecutionContext>(kNotificationBaseUrl); - } - - ExecutionContext* GetExecutionContext() { return execution_context_.Get(); } - - private: - Persistent<ExecutionContext> execution_context_; -}; - -TEST_F(NotificationDataTest, ReflectProperties) { Vector<unsigned> vibration_pattern; for (size_t i = 0; i < base::size(kNotificationVibration); ++i) vibration_pattern.push_back(kNotificationVibration[i]); @@ -89,8 +62,7 @@ TEST_F(NotificationDataTest, ReflectProperties) { HeapVector<Member<NotificationAction>> actions; for (size_t i = 0; i < Notification::maxActions(); ++i) { - NotificationAction* action = - NotificationAction::Create(GetExecutionContext()->GetIsolate()); + NotificationAction* action = NotificationAction::Create(scope.GetIsolate()); action->setType(kNotificationActionType); action->setAction(kNotificationActionAction); action->setTitle(kNotificationActionTitle); @@ -104,7 +76,7 @@ TEST_F(NotificationDataTest, ReflectProperties) { TimestampTrigger* showTrigger = TimestampTrigger::Create(showTimestamp); NotificationOptions* options = - NotificationOptions::Create(GetExecutionContext()->GetIsolate()); + NotificationOptions::Create(scope.GetIsolate()); options->setDir(kNotificationDir); options->setLang(kNotificationLang); options->setBody(kNotificationBody); @@ -122,9 +94,10 @@ TEST_F(NotificationDataTest, ReflectProperties) { // TODO(peter): Test |options.data| and |notificationData.data|. - DummyExceptionStateForTesting exception_state; - mojom::blink::NotificationDataPtr notification_data = CreateNotificationData( - GetExecutionContext(), kNotificationTitle, options, exception_state); + ExceptionState& exception_state = scope.GetExceptionState(); + mojom::blink::NotificationDataPtr notification_data = + CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle, + options, exception_state); ASSERT_FALSE(exception_state.HadException()); EXPECT_EQ(kNotificationTitle, notification_data->title); @@ -137,12 +110,10 @@ TEST_F(NotificationDataTest, ReflectProperties) { EXPECT_EQ(base::Time::FromJsTime(showTimestamp), notification_data->show_trigger_timestamp); - KURL base(kNotificationBaseUrl); - // URLs should be resolved against the base URL of the execution context. - EXPECT_EQ(KURL(base, kNotificationImage), notification_data->image); - EXPECT_EQ(KURL(base, kNotificationIcon), notification_data->icon); - EXPECT_EQ(KURL(base, kNotificationBadge), notification_data->badge); + EXPECT_EQ(KURL(base_url, kNotificationImage), notification_data->image); + EXPECT_EQ(KURL(base_url, kNotificationIcon), notification_data->icon); + EXPECT_EQ(KURL(base_url, kNotificationBadge), notification_data->badge); ASSERT_EQ(vibration_pattern.size(), notification_data->vibration_pattern->size()); @@ -166,7 +137,9 @@ TEST_F(NotificationDataTest, ReflectProperties) { } } -TEST_F(NotificationDataTest, SilentNotificationWithVibration) { +TEST(NotificationDataTest, SilentNotificationWithVibration) { + V8TestingScope scope; + Vector<unsigned> vibration_pattern; for (size_t i = 0; i < base::size(kNotificationVibration); ++i) vibration_pattern.push_back(kNotificationVibration[i]); @@ -175,20 +148,23 @@ TEST_F(NotificationDataTest, SilentNotificationWithVibration) { vibration_sequence.SetUnsignedLongSequence(vibration_pattern); NotificationOptions* options = - NotificationOptions::Create(GetExecutionContext()->GetIsolate()); + NotificationOptions::Create(scope.GetIsolate()); options->setVibrate(vibration_sequence); options->setSilent(true); - DummyExceptionStateForTesting exception_state; - mojom::blink::NotificationDataPtr notification_data = CreateNotificationData( - GetExecutionContext(), kNotificationTitle, options, exception_state); + ExceptionState& exception_state = scope.GetExceptionState(); + mojom::blink::NotificationDataPtr notification_data = + CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle, + options, exception_state); ASSERT_TRUE(exception_state.HadException()); EXPECT_EQ("Silent notifications must not specify vibration patterns.", exception_state.Message()); } -TEST_F(NotificationDataTest, ActionTypeButtonWithPlaceholder) { +TEST(NotificationDataTest, ActionTypeButtonWithPlaceholder) { + V8TestingScope scope; + HeapVector<Member<NotificationAction>> actions; NotificationAction* action = NotificationAction::Create(); action->setType("button"); @@ -196,27 +172,31 @@ TEST_F(NotificationDataTest, ActionTypeButtonWithPlaceholder) { actions.push_back(action); NotificationOptions* options = - NotificationOptions::Create(GetExecutionContext()->GetIsolate()); + NotificationOptions::Create(scope.GetIsolate()); options->setActions(actions); - DummyExceptionStateForTesting exception_state; - mojom::blink::NotificationDataPtr notification_data = CreateNotificationData( - GetExecutionContext(), kNotificationTitle, options, exception_state); + ExceptionState& exception_state = scope.GetExceptionState(); + mojom::blink::NotificationDataPtr notification_data = + CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle, + options, exception_state); ASSERT_TRUE(exception_state.HadException()); EXPECT_EQ("Notifications of type \"button\" cannot specify a placeholder.", exception_state.Message()); } -TEST_F(NotificationDataTest, RenotifyWithEmptyTag) { +TEST(NotificationDataTest, RenotifyWithEmptyTag) { + V8TestingScope scope; + NotificationOptions* options = - NotificationOptions::Create(GetExecutionContext()->GetIsolate()); + NotificationOptions::Create(scope.GetIsolate()); options->setTag(kNotificationEmptyTag); options->setRenotify(true); - DummyExceptionStateForTesting exception_state; - mojom::blink::NotificationDataPtr notification_data = CreateNotificationData( - GetExecutionContext(), kNotificationTitle, options, exception_state); + ExceptionState& exception_state = scope.GetExceptionState(); + mojom::blink::NotificationDataPtr notification_data = + CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle, + options, exception_state); ASSERT_TRUE(exception_state.HadException()); EXPECT_EQ( @@ -224,7 +204,9 @@ TEST_F(NotificationDataTest, RenotifyWithEmptyTag) { exception_state.Message()); } -TEST_F(NotificationDataTest, InvalidIconUrls) { +TEST(NotificationDataTest, InvalidIconUrls) { + V8TestingScope scope; + HeapVector<Member<NotificationAction>> actions; for (size_t i = 0; i < Notification::maxActions(); ++i) { NotificationAction* action = NotificationAction::Create(); @@ -235,15 +217,16 @@ TEST_F(NotificationDataTest, InvalidIconUrls) { } NotificationOptions* options = - NotificationOptions::Create(GetExecutionContext()->GetIsolate()); + NotificationOptions::Create(scope.GetIsolate()); options->setImage(kNotificationIconInvalid); options->setIcon(kNotificationIconInvalid); options->setBadge(kNotificationIconInvalid); options->setActions(actions); - DummyExceptionStateForTesting exception_state; - mojom::blink::NotificationDataPtr notification_data = CreateNotificationData( - GetExecutionContext(), kNotificationTitle, options, exception_state); + ExceptionState& exception_state = scope.GetExceptionState(); + mojom::blink::NotificationDataPtr notification_data = + CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle, + options, exception_state); ASSERT_FALSE(exception_state.HadException()); EXPECT_TRUE(notification_data->image.IsEmpty()); @@ -253,7 +236,9 @@ TEST_F(NotificationDataTest, InvalidIconUrls) { EXPECT_TRUE(action->icon.IsEmpty()); } -TEST_F(NotificationDataTest, VibrationNormalization) { +TEST(NotificationDataTest, VibrationNormalization) { + V8TestingScope scope; + Vector<unsigned> unnormalized_pattern; for (size_t i = 0; i < base::size(kNotificationVibrationUnnormalized); ++i) unnormalized_pattern.push_back(kNotificationVibrationUnnormalized[i]); @@ -262,12 +247,13 @@ TEST_F(NotificationDataTest, VibrationNormalization) { vibration_sequence.SetUnsignedLongSequence(unnormalized_pattern); NotificationOptions* options = - NotificationOptions::Create(GetExecutionContext()->GetIsolate()); + NotificationOptions::Create(scope.GetIsolate()); options->setVibrate(vibration_sequence); - DummyExceptionStateForTesting exception_state; - mojom::blink::NotificationDataPtr notification_data = CreateNotificationData( - GetExecutionContext(), kNotificationTitle, options, exception_state); + ExceptionState& exception_state = scope.GetExceptionState(); + mojom::blink::NotificationDataPtr notification_data = + CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle, + options, exception_state); EXPECT_FALSE(exception_state.HadException()); Vector<int> normalized_pattern; @@ -282,13 +268,16 @@ TEST_F(NotificationDataTest, VibrationNormalization) { } } -TEST_F(NotificationDataTest, DefaultTimestampValue) { +TEST(NotificationDataTest, DefaultTimestampValue) { + V8TestingScope scope; + NotificationOptions* options = - NotificationOptions::Create(GetExecutionContext()->GetIsolate()); + NotificationOptions::Create(scope.GetIsolate()); - DummyExceptionStateForTesting exception_state; - mojom::blink::NotificationDataPtr notification_data = CreateNotificationData( - GetExecutionContext(), kNotificationTitle, options, exception_state); + ExceptionState& exception_state = scope.GetExceptionState(); + mojom::blink::NotificationDataPtr notification_data = + CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle, + options, exception_state); EXPECT_FALSE(exception_state.HadException()); // The timestamp should be set to the current time since the epoch if it @@ -298,23 +287,22 @@ TEST_F(NotificationDataTest, DefaultTimestampValue) { base::Time::Now().ToDoubleT() * 1000.0, 32); } -TEST_F(NotificationDataTest, DirectionValues) { +TEST(NotificationDataTest, DirectionValues) { + V8TestingScope scope; + WTF::HashMap<String, mojom::blink::NotificationDirection> mappings; mappings.insert("ltr", mojom::blink::NotificationDirection::LEFT_TO_RIGHT); mappings.insert("rtl", mojom::blink::NotificationDirection::RIGHT_TO_LEFT); mappings.insert("auto", mojom::blink::NotificationDirection::AUTO); - // Invalid values should default to "auto". - mappings.insert("peter", mojom::blink::NotificationDirection::AUTO); - for (const String& direction : mappings.Keys()) { NotificationOptions* options = - NotificationOptions::Create(GetExecutionContext()->GetIsolate()); + NotificationOptions::Create(scope.GetIsolate()); options->setDir(direction); - DummyExceptionStateForTesting exception_state; + ExceptionState& exception_state = scope.GetExceptionState(); mojom::blink::NotificationDataPtr notification_data = - CreateNotificationData(GetExecutionContext(), kNotificationTitle, + CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle, options, exception_state); ASSERT_FALSE(exception_state.HadException()); @@ -322,7 +310,9 @@ TEST_F(NotificationDataTest, DirectionValues) { } } -TEST_F(NotificationDataTest, MaximumActionCount) { +TEST(NotificationDataTest, MaximumActionCount) { + V8TestingScope scope; + HeapVector<Member<NotificationAction>> actions; for (size_t i = 0; i < Notification::maxActions() + 2; ++i) { NotificationAction* action = NotificationAction::Create(); @@ -333,12 +323,13 @@ TEST_F(NotificationDataTest, MaximumActionCount) { } NotificationOptions* options = - NotificationOptions::Create(GetExecutionContext()->GetIsolate()); + NotificationOptions::Create(scope.GetIsolate()); options->setActions(actions); - DummyExceptionStateForTesting exception_state; - mojom::blink::NotificationDataPtr notification_data = CreateNotificationData( - GetExecutionContext(), kNotificationTitle, options, exception_state); + ExceptionState& exception_state = scope.GetExceptionState(); + mojom::blink::NotificationDataPtr notification_data = + CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle, + options, exception_state); ASSERT_FALSE(exception_state.HadException()); // The stored actions will be capped to |maxActions| entries. @@ -350,7 +341,9 @@ TEST_F(NotificationDataTest, MaximumActionCount) { } } -TEST_F(NotificationDataTest, RejectsTriggerTimestampOverAYear) { +TEST(NotificationDataTest, RejectsTriggerTimestampOverAYear) { + V8TestingScope scope; + base::Time show_timestamp = base::Time::Now() + kMaxNotificationShowTriggerDelay + base::TimeDelta::FromDays(1); @@ -358,12 +351,13 @@ TEST_F(NotificationDataTest, RejectsTriggerTimestampOverAYear) { TimestampTrigger::Create(show_timestamp.ToJsTime()); NotificationOptions* options = - NotificationOptions::Create(GetExecutionContext()->GetIsolate()); + NotificationOptions::Create(scope.GetIsolate()); options->setShowTrigger(show_trigger); - DummyExceptionStateForTesting exception_state; - mojom::blink::NotificationDataPtr notification_data = CreateNotificationData( - GetExecutionContext(), kNotificationTitle, options, exception_state); + ExceptionState& exception_state = scope.GetExceptionState(); + mojom::blink::NotificationDataPtr notification_data = + CreateNotificationData(scope.GetExecutionContext(), kNotificationTitle, + options, exception_state); ASSERT_TRUE(exception_state.HadException()); EXPECT_EQ("Notification trigger timestamp too far ahead in the future.", diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_event.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_event.cc index cbb64ff9c7c..c9185029571 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification_event.cc +++ b/chromium/third_party/blink/renderer/modules/notifications/notification_event.cc @@ -34,7 +34,7 @@ const AtomicString& NotificationEvent::InterfaceName() const { return event_interface_names::kNotificationEvent; } -void NotificationEvent::Trace(Visitor* visitor) { +void NotificationEvent::Trace(Visitor* visitor) const { visitor->Trace(notification_); ExtendableEvent::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_event.h b/chromium/third_party/blink/renderer/modules/notifications/notification_event.h index 52442e1edaf..009cc6cff29 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification_event.h +++ b/chromium/third_party/blink/renderer/modules/notifications/notification_event.h @@ -43,7 +43,7 @@ class MODULES_EXPORT NotificationEvent final : public ExtendableEvent { // ExtendableEvent interface. const AtomicString& InterfaceName() const override; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<Notification> notification_; diff --git a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc index 9894ef23d30..edbec7abc11 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc +++ b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.cc @@ -246,7 +246,7 @@ NotificationManager::GetNotificationService() { return notification_service_.get(); } -void NotificationManager::Trace(Visitor* visitor) { +void NotificationManager::Trace(Visitor* visitor) const { visitor->Trace(notification_service_); visitor->Trace(permission_service_); Supplement<ExecutionContext>::Trace(visitor); 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 bb3d8d12fa2..ad0ee611829 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h +++ b/chromium/third_party/blink/renderer/modules/notifications/notification_manager.h @@ -80,7 +80,7 @@ class NotificationManager final : public GarbageCollected<NotificationManager>, bool include_triggered, ScriptPromiseResolver* resolver); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: void DidDisplayPersistentNotification( 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 3fb8d3c562e..5ef10d7b65c 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 @@ -102,7 +102,7 @@ void NotificationResourcesLoader::Stop() { icon_loader->Stop(); } -void NotificationResourcesLoader::Trace(Visitor* visitor) { +void NotificationResourcesLoader::Trace(Visitor* visitor) const { visitor->Trace(icon_loaders_); } 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 221d4961776..14370452928 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 @@ -54,7 +54,7 @@ class MODULES_EXPORT NotificationResourcesLoader final // pre-finalizer. void Stop(); - virtual void Trace(Visitor* visitor); + virtual void Trace(Visitor* visitor) const; private: void LoadIcon(ExecutionContext* context, 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 b2bc6c3f53c..0aec612f5da 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 @@ -42,7 +42,7 @@ class NotificationResourcesLoaderTest : public PageTestBase { ~NotificationResourcesLoaderTest() override { loader_->Stop(); - platform_->GetURLLoaderMockFactory() + WebURLLoaderMockFactory::GetSingletonInstance() ->UnregisterAllURLsAndClearMemoryCache(); } @@ -69,7 +69,8 @@ class NotificationResourcesLoaderTest : public PageTestBase { base::RunLoop run_loop; resources_loaded_closure_ = run_loop.QuitClosure(); Loader()->Start(GetExecutionContext(), notification_data); - platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests(); + WebURLLoaderMockFactory::GetSingletonInstance() + ->ServeAsynchronousRequests(); run_loop.Run(); } @@ -278,7 +279,7 @@ TEST_F(NotificationResourcesLoaderTest, StopYieldsNoResources) { // The loader would stop e.g. when the execution context is destroyed or // when the loader is about to be destroyed, as a pre-finalizer. Loader()->Stop(); - platform_->GetURLLoaderMockFactory()->ServeAsynchronousRequests(); + WebURLLoaderMockFactory::GetSingletonInstance()->ServeAsynchronousRequests(); // Loading should have been cancelled when |stop| was called so no resources // should have been received by the test even though diff --git a/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc b/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc index cb84c76e10e..64f3fd8862e 100644 --- a/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc +++ b/chromium/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc @@ -97,7 +97,7 @@ void ServiceWorkerRegistrationNotifications::ContextDestroyed() { loader->Stop(); } -void ServiceWorkerRegistrationNotifications::Trace(Visitor* visitor) { +void ServiceWorkerRegistrationNotifications::Trace(Visitor* visitor) const { visitor->Trace(registration_); visitor->Trace(loaders_); Supplement<ServiceWorkerRegistration>::Trace(visitor); 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 8af419240be..b0040e85efb 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 @@ -53,7 +53,7 @@ class ServiceWorkerRegistrationNotifications final // ExecutionContextLifecycleObserver interface. void ContextDestroyed() override; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: static ServiceWorkerRegistrationNotifications& From( diff --git a/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.cc b/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.cc index eccca7e5b28..29db2bdb341 100644 --- a/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.cc +++ b/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.cc @@ -47,7 +47,7 @@ void AbortPaymentEvent::respondWith(ScriptState* script_state, } } -void AbortPaymentEvent::Trace(Visitor* visitor) { +void AbortPaymentEvent::Trace(Visitor* visitor) const { visitor->Trace(observer_); ExtendableEvent::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.h b/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.h index 43716808d9e..43b7457905a 100644 --- a/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.h +++ b/chromium/third_party/blink/renderer/modules/payments/abort_payment_event.h @@ -42,7 +42,7 @@ class MODULES_EXPORT AbortPaymentEvent final : public ExtendableEvent { void respondWith(ScriptState*, ScriptPromise, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<RespondWithObserver> observer_; diff --git a/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.cc index 64212d5be81..f562bcf08d1 100644 --- a/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.cc +++ b/chromium/third_party/blink/renderer/modules/payments/abort_payment_respond_with_observer.cc @@ -57,7 +57,7 @@ void AbortPaymentRespondWithObserver::OnNoResponse() { ->RespondToAbortPaymentEvent(event_id_, false); } -void AbortPaymentRespondWithObserver::Trace(Visitor* visitor) { +void AbortPaymentRespondWithObserver::Trace(Visitor* visitor) const { RespondWithObserver::Trace(visitor); } 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 da44a5a0102..feac2f04a0d 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 @@ -33,7 +33,7 @@ class MODULES_EXPORT AbortPaymentRespondWithObserver final const char* property_name) override; void OnNoResponse() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc index f78a31117f9..5070dffa82c 100644 --- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc +++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.cc @@ -73,28 +73,33 @@ void CanMakePaymentEvent::respondWithMinimalUI( /*is_minimal_ui=*/true); } -void CanMakePaymentEvent::Trace(Visitor* visitor) { +void CanMakePaymentEvent::Trace(Visitor* visitor) const { visitor->Trace(method_data_); visitor->Trace(modifiers_); visitor->Trace(observer_); ExtendableEvent::Trace(visitor); } +// TODO(crbug.com/1070871): Use fooOr() in members' initializers. CanMakePaymentEvent::CanMakePaymentEvent( const AtomicString& type, const CanMakePaymentEventInit* initializer, CanMakePaymentRespondWithObserver* respond_with_observer, WaitUntilObserver* wait_until_observer) : ExtendableEvent(type, initializer, wait_until_observer), - top_origin_(initializer->topOrigin()), - payment_request_origin_(initializer->paymentRequestOrigin()), + top_origin_(initializer->hasTopOrigin() ? initializer->topOrigin() + : String()), + payment_request_origin_(initializer->hasPaymentRequestOrigin() + ? initializer->paymentRequestOrigin() + : String()), method_data_(initializer->hasMethodData() ? initializer->methodData() : HeapVector<Member<PaymentMethodData>>()), modifiers_(initializer->hasModifiers() ? initializer->modifiers() : HeapVector<Member<PaymentDetailsModifier>>()), - currency_(initializer->currency()), + currency_(initializer->hasCurrency() ? initializer->currency() + : String()), observer_(respond_with_observer) {} void CanMakePaymentEvent::RespondToCanMakePaymentEvent( diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.h b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.h index 42d84b9f54a..b20f4421841 100644 --- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.h +++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event.h @@ -52,7 +52,7 @@ class MODULES_EXPORT CanMakePaymentEvent final : public ExtendableEvent { const String& currency() const; void respondWithMinimalUI(ScriptState*, ScriptPromise, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void RespondToCanMakePaymentEvent(ScriptState*, diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl index e7d2240a6dd..5a01e49ccd4 100644 --- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl +++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://github.com/w3c/payment-handler/pull/170 +// https://w3c.github.io/payment-handler/#canmakepaymenteventinit-dictionary dictionary CanMakePaymentEventInit : ExtendableEventInit { USVString topOrigin; diff --git a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc index 0b11a249f30..1959cffb3e5 100644 --- a/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc +++ b/chromium/third_party/blink/renderer/modules/payments/can_make_payment_respond_with_observer.cc @@ -72,7 +72,7 @@ void CanMakePaymentRespondWithObserver::OnNoResponse() { RespondWithoutMinimalUI(ResponseType::NO_RESPONSE, true); } -void CanMakePaymentRespondWithObserver::Trace(Visitor* visitor) { +void CanMakePaymentRespondWithObserver::Trace(Visitor* visitor) const { RespondWithObserver::Trace(visitor); } 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 41a0b5ca480..54147ed8d20 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 @@ -35,7 +35,7 @@ class MODULES_EXPORT CanMakePaymentRespondWithObserver final const char* property_name) override; void OnNoResponse() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Observes the given promise and calls OnResponseRejected() or // OnResponseFulfilled(). diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/BUILD.gn b/chromium/third_party/blink/renderer/modules/payments/goods/BUILD.gn new file mode 100644 index 00000000000..e7c9f39fab4 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/BUILD.gn @@ -0,0 +1,16 @@ +# Copyright 2020 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("goods") { + sources = [ + "digital_goods_service.cc", + "digital_goods_service.h", + "digital_goods_type_converters.cc", + "digital_goods_type_converters.h", + "dom_window_digital_goods.cc", + "dom_window_digital_goods.h", + ] +} diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/OWNERS b/chromium/third_party/blink/renderer/modules/payments/goods/OWNERS new file mode 100644 index 00000000000..b4b867f7536 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/OWNERS @@ -0,0 +1,7 @@ +glenrob@chromium.org +mgiuca@chromium.org + +per-file *_type_converter*.*=set noparent +per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS + +# COMPONENT: UI>Browser>WebAppInstalls>ChromeOS diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.cc b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.cc new file mode 100644 index 00000000000..03dbd69a650 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.cc @@ -0,0 +1,45 @@ +// Copyright 2020 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/goods/digital_goods_service.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" + +namespace blink { + +DigitalGoodsService::DigitalGoodsService(ExecutionContext* context) {} + +DigitalGoodsService::~DigitalGoodsService() = default; + +ScriptPromise DigitalGoodsService::getDetails(ScriptState* script_state, + const Vector<String>& item_ids) { + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + + // TODO(crbug.com/1061503): This should call out to a mojo service. However, + // we can't land the mojo service until a browser side implementation is + // available (for security review). Until then, use this stub which never + // resolves. + + return promise; +} + +ScriptPromise DigitalGoodsService::acknowledge(ScriptState* script_state, + const String& purchase_token, + const String& purchase_type) { + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + + // TODO(crbug.com/1061503): This should call out to a mojo service. However, + // we can't land the mojo service until a browser side implementation is + // available (for security review). Until then, use this stub which never + // resolves. + + return promise; +} + +void DigitalGoodsService::Trace(Visitor* visitor) const { + ScriptWrappable::Trace(visitor); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.h b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.h new file mode 100644 index 00000000000..0e80c43a585 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.h @@ -0,0 +1,35 @@ +// Copyright 2020 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_PAYMENTS_GOODS_DIGITAL_GOODS_SERVICE_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_GOODS_DIGITAL_GOODS_SERVICE_H_ + +#include "mojo/public/cpp/bindings/remote.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" + +namespace blink { + +class ExecutionContext; +class ScriptState; +class Visitor; + +class DigitalGoodsService final : public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + + public: + explicit DigitalGoodsService(ExecutionContext* context); + ~DigitalGoodsService() override; + + // IDL Interface: + ScriptPromise getDetails(ScriptState*, const Vector<String>& item_ids); + ScriptPromise acknowledge(ScriptState*, + const String& purchase_token, + const String& purchase_type); + + void Trace(Visitor* visitor) const override; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_GOODS_DIGITAL_GOODS_SERVICE_H_ diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.idl b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.idl new file mode 100644 index 00000000000..48991860b58 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_service.idl @@ -0,0 +1,20 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://github.com/WICG/digital-goods/blob/master/explainer.md +[ + SecureContext, + RuntimeEnabled=DigitalGoods +] interface DigitalGoodsService { + [CallWith=ScriptState] + Promise<sequence<ItemDetails>> getDetails(sequence<DOMString> itemIds); + + [CallWith=ScriptState] + Promise<void> acknowledge(DOMString purchaseToken, PurchaseType purchaseType); +}; + +enum PurchaseType { + "repeatable", + "onetime", +}; diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.cc b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.cc new file mode 100644 index 00000000000..e9325de915f --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.cc @@ -0,0 +1,57 @@ +// Copyright 2020 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/goods/digital_goods_type_converters.h" + +#include "third_party/blink/public/mojom/digital_goods/digital_goods.mojom-blink.h" +#include "third_party/blink/renderer/modules/payments/payment_event_data_conversion.h" + +namespace mojo { + +blink::ItemDetails* +TypeConverter<blink::ItemDetails*, payments::mojom::blink::ItemDetailsPtr>:: + Convert(const payments::mojom::blink::ItemDetailsPtr& input) { + if (!input) + return nullptr; + blink::ItemDetails* output = blink::ItemDetails::Create(); + output->setItemId(input->item_id); + output->setTitle(input->title); + output->setDescription(input->description); + output->setPrice( + blink::PaymentEventDataConversion::ToPaymentCurrencyAmount(input->price)); + return output; +} + +WTF::String +TypeConverter<WTF::String, payments::mojom::blink::BillingResponseCode>:: + Convert(const payments::mojom::blink::BillingResponseCode& input) { + switch (input) { + case payments::mojom::blink::BillingResponseCode::kOk: + return "ok"; + case payments::mojom::blink::BillingResponseCode::kError: + return "error"; + case payments::mojom::blink::BillingResponseCode::kBillingUnavailable: + return "billingUnavailable"; + case payments::mojom::blink::BillingResponseCode::kDeveloperError: + return "developerError"; + case payments::mojom::blink::BillingResponseCode::kFeatureNotSupported: + return "featureNotSupported"; + case payments::mojom::blink::BillingResponseCode::kItemAlreadyOwned: + return "itemAlreadyOwned"; + case payments::mojom::blink::BillingResponseCode::kItemNotOwned: + return "itemNotOwned"; + case payments::mojom::blink::BillingResponseCode::kItemUnavailable: + return "itemUnavailable"; + case payments::mojom::blink::BillingResponseCode::kServiceDisconnected: + return "serviceDisconnected"; + case payments::mojom::blink::BillingResponseCode::kServiceUnavailable: + return "serviceUnavailable"; + case payments::mojom::blink::BillingResponseCode::kUserCancelled: + return "userCancelled"; + } + + NOTREACHED(); +} + +} // namespace mojo diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.h b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.h new file mode 100644 index 00000000000..cf0cdc18e34 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.h @@ -0,0 +1,35 @@ +// Copyright 2020 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_PAYMENTS_GOODS_DIGITAL_GOODS_TYPE_CONVERTERS_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_GOODS_DIGITAL_GOODS_TYPE_CONVERTERS_H_ + +#include <string> + +#include "mojo/public/cpp/bindings/type_converter.h" +#include "third_party/blink/public/mojom/digital_goods/digital_goods.mojom-blink-forward.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_item_details.h" +#include "third_party/blink/renderer/modules/modules_export.h" + +namespace mojo { + +// Converts a mojo ItemDetails into a WebIDL ItemDetails. +// Returns a null IDL struct when a null mojo struct is given as input. +template <> +struct MODULES_EXPORT + TypeConverter<blink::ItemDetails*, payments::mojom::blink::ItemDetailsPtr> { + static blink::ItemDetails* Convert( + const payments::mojom::blink::ItemDetailsPtr& input); +}; + +template <> +struct MODULES_EXPORT + TypeConverter<WTF::String, payments::mojom::blink::BillingResponseCode> { + static WTF::String Convert( + const payments::mojom::blink::BillingResponseCode& input); +}; + +} // namespace mojo + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_GOODS_DIGITAL_GOODS_TYPE_CONVERTERS_H_ diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters_unittest.cc b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters_unittest.cc new file mode 100644 index 00000000000..fca041df108 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters_unittest.cc @@ -0,0 +1,58 @@ +// Copyright 2020 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 <string> + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/digital_goods/digital_goods.mojom-blink.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_item_details.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_payment_currency_amount.h" +#include "third_party/blink/renderer/modules/payments/goods/digital_goods_type_converters.h" + +namespace blink { + +using payments::mojom::blink::BillingResponseCode; + +TEST(DigitalGoodsTypeConvertersTest, MojoBillingResponseOkToIdl) { + auto response_code = BillingResponseCode::kOk; + EXPECT_EQ(mojo::ConvertTo<String>(response_code), "ok"); +} + +TEST(DigitalGoodsTypeConvertersTest, MojoBillingResponseErrorToIdl) { + auto response_code = BillingResponseCode::kError; + EXPECT_EQ(mojo::ConvertTo<String>(response_code), "error"); +} + +TEST(DigitalGoodsTypeConvertersTest, MojoItemDetailsToIdl) { + auto mojo_item_details = payments::mojom::blink::ItemDetails::New(); + const String item_id = "shiny-sword-id"; + const String title = "Shiny Sword"; + const String description = "A sword that is shiny"; + const String currency = "AUD"; + const String value = "100.00"; + + mojo_item_details->item_id = item_id; + mojo_item_details->title = title; + mojo_item_details->description = description; + auto price = payments::mojom::blink::PaymentCurrencyAmount::New(); + price->currency = currency; + price->value = value; + mojo_item_details->price = std::move(price); + + auto* idl_item_details = mojo_item_details.To<ItemDetails*>(); + EXPECT_EQ(idl_item_details->itemId(), item_id); + EXPECT_EQ(idl_item_details->title(), title); + EXPECT_EQ(idl_item_details->description(), description); + EXPECT_EQ(idl_item_details->price()->currency(), currency); + EXPECT_EQ(idl_item_details->price()->value(), value); +} + +TEST(DigitalGoodsTypeConvertersTest, NullMojoItemDetailsToIdl) { + payments::mojom::blink::ItemDetailsPtr mojo_item_details; + + auto* idl_item_details = mojo_item_details.To<ItemDetails*>(); + EXPECT_EQ(idl_item_details, nullptr); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.cc b/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.cc new file mode 100644 index 00000000000..aea7dc00bfc --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.cc @@ -0,0 +1,71 @@ +// Copyright 2020 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/goods/dom_window_digital_goods.h" + +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/modules/payments/goods/digital_goods_service.h" + +namespace { + +// TODO (crbug.com/1061503): Point URL to Play payment request API once known. +const char known_payment_method_[] = "https://some.url/for/payment/request/api"; + +} // namespace + +namespace blink { + +const char DOMWindowDigitalGoods::kSupplementName[] = "DOMWindowDigitalGoods"; + +ScriptPromise DOMWindowDigitalGoods::getDigitalGoodsService( + ScriptState* script_state, + LocalDOMWindow& window, + const String& payment_method) { + return FromState(&window)->GetDigitalGoodsService(script_state, + payment_method); +} + +ScriptPromise DOMWindowDigitalGoods::GetDigitalGoodsService( + ScriptState* script_state, + const String& payment_method) { + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + auto promise = resolver->Promise(); + + // TODO (crbug.com/1061503): Enable JS to connect to various payment method + // backends. For now, just connect to one known backend and check the URL is + // correct for that payment method. + if (payment_method != known_payment_method_) { + resolver->Resolve(); + return promise; + } + + if (!digital_goods_service_) { + digital_goods_service_ = MakeGarbageCollected<DigitalGoodsService>( + ExecutionContext::From(script_state)); + } + + resolver->Resolve(digital_goods_service_); + return promise; +} + +void DOMWindowDigitalGoods::Trace(Visitor* visitor) const { + Supplement<LocalDOMWindow>::Trace(visitor); + visitor->Trace(digital_goods_service_); +} + +// static +DOMWindowDigitalGoods* DOMWindowDigitalGoods::FromState( + LocalDOMWindow* window) { + DOMWindowDigitalGoods* supplement = + Supplement<LocalDOMWindow>::From<DOMWindowDigitalGoods>(window); + if (!supplement) { + supplement = MakeGarbageCollected<DOMWindowDigitalGoods>(); + ProvideTo(*window, supplement); + } + + return supplement; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.h b/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.h new file mode 100644 index 00000000000..e32b8e3e863 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.h @@ -0,0 +1,43 @@ +// Copyright 2020 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_PAYMENTS_GOODS_DOM_WINDOW_DIGITAL_GOODS_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_GOODS_DOM_WINDOW_DIGITAL_GOODS_H_ + +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/platform/supplementable.h" + +namespace blink { + +class DigitalGoodsService; +class LocalDOMWindow; +class ScriptState; +class Visitor; + +class DOMWindowDigitalGoods final + : public GarbageCollected<DOMWindowDigitalGoods>, + public Supplement<LocalDOMWindow> { + USING_GARBAGE_COLLECTED_MIXIN(DOMWindowDigitalGoods); + + public: + static const char kSupplementName[]; + + // IDL Interface: + static ScriptPromise getDigitalGoodsService(ScriptState*, + LocalDOMWindow&, + const String& payment_method); + + ScriptPromise GetDigitalGoodsService(ScriptState*, + const String& payment_method); + void Trace(Visitor* visitor) const override; + + private: + Member<DigitalGoodsService> digital_goods_service_; + + static DOMWindowDigitalGoods* FromState(LocalDOMWindow*); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PAYMENTS_GOODS_DOM_WINDOW_DIGITAL_GOODS_H_ diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.idl b/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.idl new file mode 100644 index 00000000000..edc8fac867a --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.idl @@ -0,0 +1,13 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://github.com/WICG/digital-goods/blob/master/explainer.md +[ + SecureContext, + ImplementedAs=DOMWindowDigitalGoods, + RuntimeEnabled=DigitalGoods +] partial interface Window { + [CallWith=ScriptState] + Promise<DigitalGoodsService?> getDigitalGoodsService(DOMString paymentMethod); +}; diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/idls.gni b/chromium/third_party/blink/renderer/modules/payments/goods/idls.gni new file mode 100644 index 00000000000..f35497f186d --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/idls.gni @@ -0,0 +1,9 @@ +# Copyright 2020 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. + +modules_idl_files = [ "digital_goods_service.idl" ] + +modules_dictionary_idl_files = [ "item_details.idl" ] + +modules_dependency_idl_files = [ "dom_window_digital_goods.idl" ] diff --git a/chromium/third_party/blink/renderer/modules/payments/goods/item_details.idl b/chromium/third_party/blink/renderer/modules/payments/goods/item_details.idl new file mode 100644 index 00000000000..4393374ebaa --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/goods/item_details.idl @@ -0,0 +1,13 @@ +// Copyright 2020 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(crbug.com/1061503): Add more fields from +// https://github.com/WICG/digital-goods/blob/master/explainer.md +// as the discussions settle. +dictionary ItemDetails { + DOMString itemId; + DOMString title; + DOMString description; + PaymentCurrencyAmount price; +}; diff --git a/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.cc b/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.cc index 09752416771..154381ae683 100644 --- a/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.cc +++ b/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.cc @@ -51,7 +51,7 @@ bool HTMLIFrameElementPayments::AllowPaymentRequest( element.FastHasAttribute(html_names::kAllowpaymentrequestAttr); } -void HTMLIFrameElementPayments::Trace(Visitor* visitor) { +void HTMLIFrameElementPayments::Trace(Visitor* visitor) const { Supplement<HTMLIFrameElement>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.h b/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.h index 810d72a3148..ce290f292f4 100644 --- a/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.h +++ b/chromium/third_party/blink/renderer/modules/payments/html_iframe_element_payments.h @@ -31,7 +31,7 @@ class HTMLIFrameElementPayments final static HTMLIFrameElementPayments& From(HTMLIFrameElement&); static bool AllowPaymentRequest(HTMLIFrameElement&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/payments/idls.gni b/chromium/third_party/blink/renderer/modules/payments/idls.gni index f48bed77859..ea997922f5a 100644 --- a/chromium/third_party/blink/renderer/modules/payments/idls.gni +++ b/chromium/third_party/blink/renderer/modules/payments/idls.gni @@ -18,6 +18,7 @@ modules_idl_files = [ modules_dictionary_idl_files = [ "address_errors.idl", + "address_init.idl", "android_pay_method_data.idl", "basic_card_request.idl", "can_make_payment_event_init.idl", @@ -25,7 +26,6 @@ modules_dictionary_idl_files = [ "image_object.idl", "merchant_validation_event_init.idl", "payer_errors.idl", - "address_init.idl", "payment_currency_amount.idl", "payment_details_base.idl", "payment_details_init.idl", diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc b/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc index 70c052af16c..6282eaf121d 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.cc @@ -46,7 +46,7 @@ PaymentManager* PaymentAppServiceWorkerRegistration::paymentManager( return payment_manager_.Get(); } -void PaymentAppServiceWorkerRegistration::Trace(Visitor* visitor) { +void PaymentAppServiceWorkerRegistration::Trace(Visitor* visitor) const { visitor->Trace(registration_); visitor->Trace(payment_manager_); Supplement<ServiceWorkerRegistration>::Trace(visitor); 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 9a8a29ec407..e44716def24 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 @@ -33,7 +33,7 @@ class PaymentAppServiceWorkerRegistration final ServiceWorkerRegistration&); PaymentManager* paymentManager(ScriptState*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<ServiceWorkerRegistration> registration_; diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_details_init.idl b/chromium/third_party/blink/renderer/modules/payments/payment_details_init.idl index 9a784e3817b..1737da9b15e 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_details_init.idl +++ b/chromium/third_party/blink/renderer/modules/payments/payment_details_init.idl @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/browser-payment-api/#paymentdetailsinit-dictionary +// https://w3c.github.io/payment-request/#paymentdetailsinit-dictionary dictionary PaymentDetailsInit : PaymentDetailsBase { DOMString id; - required PaymentItem total; + PaymentItem total; }; 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 18816cf7913..a7c77c0673a 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 @@ -18,22 +18,13 @@ namespace blink { namespace { -PaymentCurrencyAmount* ToPaymentCurrencyAmount( - payments::mojom::blink::PaymentCurrencyAmountPtr data) { - PaymentCurrencyAmount* amount = PaymentCurrencyAmount::Create(); - if (!data) - return amount; - amount->setCurrency(data->currency); - amount->setValue(data->value); - return amount; -} - PaymentItem* ToPaymentItem(payments::mojom::blink::PaymentItemPtr data) { PaymentItem* item = PaymentItem::Create(); if (!data) return item; item->setLabel(data->label); - item->setAmount(ToPaymentCurrencyAmount(std::move(data->amount))); + item->setAmount( + PaymentEventDataConversion::ToPaymentCurrencyAmount(data->amount)); item->setPending(data->pending); return item; } @@ -109,7 +100,7 @@ PaymentShippingOption* ToShippingOption( PaymentShippingOption* shipping_option = PaymentShippingOption::Create(); shipping_option->setAmount( - ToPaymentCurrencyAmount(std::move(option->amount))); + PaymentEventDataConversion::ToPaymentCurrencyAmount(option->amount)); shipping_option->setLabel(option->label); shipping_option->setId(option->id); shipping_option->setSelected(option->selected); @@ -118,6 +109,16 @@ PaymentShippingOption* ToShippingOption( } // namespace +PaymentCurrencyAmount* PaymentEventDataConversion::ToPaymentCurrencyAmount( + payments::mojom::blink::PaymentCurrencyAmountPtr& input) { + PaymentCurrencyAmount* output = PaymentCurrencyAmount::Create(); + if (!input) + return output; + output->setCurrency(input->currency); + output->setValue(input->value); + return output; +} + PaymentRequestEventInit* PaymentEventDataConversion::ToPaymentRequestEventInit( ScriptState* script_state, payments::mojom::blink::PaymentRequestEventDataPtr event_data) { @@ -139,7 +140,7 @@ PaymentRequestEventInit* PaymentEventDataConversion::ToPaymentRequestEventInit( method_data.push_back(ToPaymentMethodData(script_state, std::move(md))); } event_init->setMethodData(method_data); - event_init->setTotal(ToPaymentCurrencyAmount(std::move(event_data->total))); + event_init->setTotal(ToPaymentCurrencyAmount(event_data->total)); HeapVector<Member<PaymentDetailsModifier>> modifiers; for (auto& modifier : event_data->modifiers) { modifiers.push_back( 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 b6ceee1454d..d5e436b0279 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,6 +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 "components/payments/mojom/payment_request_data.mojom-blink-forward.h" #include "third_party/blink/public/mojom/payments/payment_app.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_can_make_payment_event_init.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_payment_request_event_init.h" @@ -20,6 +21,8 @@ class MODULES_EXPORT PaymentEventDataConversion { STATIC_ONLY(PaymentEventDataConversion); public: + static PaymentCurrencyAmount* ToPaymentCurrencyAmount( + payments::mojom::blink::PaymentCurrencyAmountPtr&); static CanMakePaymentEventInit* ToCanMakePaymentEventInit( ScriptState*, payments::mojom::blink::CanMakePaymentEventDataPtr); 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 15d4dd93e05..fa8766848ce 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.cc @@ -96,55 +96,6 @@ ScriptPromise RejectNotAllowedToUsePaymentFeatures( } // namespace -// Class used to convert the placement only |PaymentInstrument| to -// GarbageCollected, so it can be used in WTF::Bind. Otherwise, on-heap objects -// 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 final - : public GarbageCollected<PaymentInstrumentParameter> { - public: - explicit PaymentInstrumentParameter(const PaymentInstrument* instrument) - : has_icons_(instrument->hasIcons()), - has_capabilities_(instrument->hasCapabilities()), - has_method_(instrument->hasMethod()), - has_name_(instrument->hasName()), - capabilities_(instrument->capabilities()), - method_(instrument->method()), - name_(instrument->name()) { - if (has_icons_) - icons_ = instrument->icons(); - } - - bool has_capabilities() const { return has_capabilities_; } - ScriptValue capabilities() const { return capabilities_; } - - bool has_icons() const { return has_icons_; } - const HeapVector<Member<ImageObject>>& icons() const { return icons_; } - - bool has_method() const { return has_method_; } - const String& method() const { return method_; } - - bool has_name() const { return has_name_; } - const String& name() const { return name_; } - - void Trace(Visitor* visitor) { - visitor->Trace(icons_); - visitor->Trace(capabilities_); - } - - private: - bool has_icons_; - bool has_capabilities_; - bool has_method_; - bool has_name_; - - ScriptValue capabilities_; - HeapVector<Member<ImageObject>> icons_; - String method_; - String name_; -}; - PaymentInstruments::PaymentInstruments( const HeapMojoRemote<payments::mojom::blink::PaymentManager, HeapMojoWrapperMode::kWithoutContextObserver>& manager, @@ -261,11 +212,9 @@ ScriptPromise PaymentInstruments::set(ScriptState* script_state, mojom::blink::PermissionName::PAYMENT_HANDLER), LocalFrame::HasTransientUserActivation( LocalDOMWindow::From(script_state)->GetFrame()), - WTF::Bind( - &PaymentInstruments::OnRequestPermission, WrapPersistent(this), - WrapPersistent(resolver), instrument_key, - WrapPersistent( - MakeGarbageCollected<PaymentInstrumentParameter>(details)))); + WTF::Bind(&PaymentInstruments::OnRequestPermission, + WrapPersistent(this), WrapPersistent(resolver), + instrument_key, WrapPersistent(details))); return resolver->Promise(); } @@ -289,7 +238,7 @@ ScriptPromise PaymentInstruments::clear(ScriptState* script_state, return promise; } -void PaymentInstruments::Trace(Visitor* visitor) { +void PaymentInstruments::Trace(Visitor* visitor) const { visitor->Trace(permission_service_); ScriptWrappable::Trace(visitor); } @@ -309,7 +258,7 @@ mojom::blink::PermissionService* PaymentInstruments::GetPermissionService( void PaymentInstruments::OnRequestPermission( ScriptPromiseResolver* resolver, const String& instrument_key, - PaymentInstrumentParameter* details, + const PaymentInstrument* details, mojom::blink::PermissionStatus status) { DCHECK(resolver); if (!resolver->GetExecutionContext() || @@ -327,9 +276,8 @@ void PaymentInstruments::OnRequestPermission( payments::mojom::blink::PaymentInstrumentPtr instrument = payments::mojom::blink::PaymentInstrument::New(); - instrument->name = - details->has_name() ? details->name() : WTF::g_empty_string; - if (details->has_icons()) { + instrument->name = details->hasName() ? details->name() : WTF::g_empty_string; + if (details->hasIcons()) { ExecutionContext* context = ExecutionContext::From(resolver->GetScriptState()); for (const ImageObject* image_object : details->icons()) { @@ -356,9 +304,9 @@ void PaymentInstruments::OnRequestPermission( } instrument->method = - details->has_method() ? details->method() : WTF::g_empty_string; + details->hasMethod() ? details->method() : WTF::g_empty_string; - if (details->has_capabilities()) { + if (details->hasCapabilities()) { v8::Local<v8::String> value; if (!v8::JSON::Stringify(resolver->GetScriptState()->GetContext(), details->capabilities().V8Value().As<v8::Object>()) diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.h b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.h index 58dff8efaa6..75ba6a99e63 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_instruments.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_instruments.h @@ -22,7 +22,6 @@ class PaymentInstrument; class ScriptPromise; class ScriptPromiseResolver; class ScriptState; -class PaymentInstrumentParameter; class MODULES_EXPORT PaymentInstruments final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); @@ -49,13 +48,13 @@ class MODULES_EXPORT PaymentInstruments final : public ScriptWrappable { ExceptionState&); ScriptPromise clear(ScriptState*, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: mojom::blink::PermissionService* GetPermissionService(ScriptState*); void OnRequestPermission(ScriptPromiseResolver*, const String&, - PaymentInstrumentParameter*, + const PaymentInstrument*, mojom::blink::PermissionStatus); void onDeletePaymentInstrument(ScriptPromiseResolver*, 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 64032484a14..7b97b724bdc 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_manager.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_manager.cc @@ -78,7 +78,7 @@ ScriptPromise PaymentManager::enableDelegations( return enable_delegations_resolver_->Promise(); } -void PaymentManager::Trace(Visitor* visitor) { +void PaymentManager::Trace(Visitor* visitor) const { visitor->Trace(registration_); visitor->Trace(manager_); visitor->Trace(instruments_); 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 d1c3f08f0d7..fda551f1d2b 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_manager.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_manager.h @@ -32,7 +32,7 @@ class MODULES_EXPORT PaymentManager final : public ScriptWrappable { const String& userHint(); void setUserHint(const String&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; ScriptPromise enableDelegations(ScriptState*, const Vector<String>& stringified_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 47c8e2dd397..7e9ac72adad 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 @@ -33,7 +33,7 @@ const ScriptValue PaymentMethodChangeEvent::methodDetails( method_details_.GetAcrossWorld(script_state)); } -void PaymentMethodChangeEvent::Trace(Visitor* visitor) { +void PaymentMethodChangeEvent::Trace(Visitor* visitor) const { visitor->Trace(method_details_); PaymentRequestUpdateEvent::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h index 27b560a6bbd..968954a8bce 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_method_change_event.h @@ -42,7 +42,7 @@ class MODULES_EXPORT PaymentMethodChangeEvent final const AtomicString& type, const PaymentMethodChangeEventInit*); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: String method_name_; 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 4567eba599c..3e20ff6c7a1 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.cc @@ -8,6 +8,7 @@ #include <utility> +#include "base/bind.h" #include "base/location.h" #include "base/stl_util.h" #include "build/build_config.h" @@ -93,6 +94,9 @@ using ::payments::mojom::blink::PaymentValidationErrorsPtr; const char kHasEnrolledInstrumentDebugName[] = "hasEnrolledInstrument"; const char kGooglePayMethod[] = "https://google.com/pay"; const char kAndroidPayMethod[] = "https://android.com/pay"; +const char kGooglePlayBillingMethod[] = "https://play.google.com/billing"; +const char kUnknownCurrency[] = "ZZZ"; +const char kAppStoreBillingLabelPlaceHolder[] = "AppStoreBillingPlaceHolder"; } // namespace @@ -266,6 +270,23 @@ void ValidateShippingOptionOrPaymentItem(const T* item, } } +const WTF::HashSet<String> GetAppStoreBillingMethods() { + static const WTF::HashSet<String> app_store_billing_methods = { + kGooglePlayBillingMethod}; + return app_store_billing_methods; +} + +bool RequestingOnlyAppStoreBillingMethods( + const Vector<payments::mojom::blink::PaymentMethodDataPtr>& method_data) { + DCHECK(!method_data.IsEmpty()); + const WTF::HashSet<String> billing_methods = GetAppStoreBillingMethods(); + for (const auto& method : method_data) { + if (!billing_methods.Contains(method->supported_method)) + return false; + } + return true; +} + void ValidateAndConvertDisplayItems( const HeapVector<Member<PaymentItem>>& input, const String& item_names, @@ -504,17 +525,50 @@ void ValidateAndConvertPaymentDetailsBase(const PaymentDetailsBase* input, } } +PaymentItemPtr CreateTotalPlaceHolderForAppStoreBilling( + ExecutionContext& execution_context) { + PaymentItemPtr total = payments::mojom::blink::PaymentItem::New(); + total->label = kAppStoreBillingLabelPlaceHolder; + total->amount = payments::mojom::blink::PaymentCurrencyAmount::New(); + total->amount->currency = kUnknownCurrency; + total->amount->value = "0"; + + return total; +} + void ValidateAndConvertPaymentDetailsInit(const PaymentDetailsInit* input, const PaymentOptions* options, PaymentDetailsPtr& output, String& shipping_option_output, + bool ignore_total, ExecutionContext& execution_context, ExceptionState& exception_state) { - DCHECK(input->hasTotal()); - ValidateAndConvertTotal(input->total(), "total", output->total, - execution_context, exception_state); - if (exception_state.HadException()) - return; + if (ignore_total) { + output->total = CreateTotalPlaceHolderForAppStoreBilling(execution_context); + if (input->hasTotal()) { + execution_context.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kJavaScript, + mojom::blink::ConsoleMessageLevel::kWarning, + "Specified total is ignored for in-app purchases with app stores. " + "User will be shown the total derived from the product identifier.")); + } + } else { + // Whether details (i.e., input) being omitted, null, defined or {} is + // indistinguishable, so we check all of its attributes to decide whether it + // has been provided. + if (!input->hasTotal() && !input->hasId()) { + exception_state.ThrowTypeError("required member details is undefined."); + return; + } + if (!input->hasTotal()) { + exception_state.ThrowTypeError("required member total is undefined."); + return; + } + ValidateAndConvertTotal(input->total(), "total", output->total, + execution_context, exception_state); + if (exception_state.HadException()) + return; + } ValidateAndConvertPaymentDetailsBase(input, options, output, shipping_option_output, @@ -525,6 +579,7 @@ void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate* input, const PaymentOptions* options, PaymentDetailsPtr& output, String& shipping_option_output, + bool ignore_total, ExecutionContext& execution_context, ExceptionState& exception_state) { ValidateAndConvertPaymentDetailsBase(input, options, output, @@ -532,12 +587,17 @@ void ValidateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate* input, execution_context, exception_state); if (exception_state.HadException()) return; - if (input->hasTotal()) { - ValidateAndConvertTotal(input->total(), "total", output->total, - execution_context, exception_state); - if (exception_state.HadException()) - return; + DCHECK(!RuntimeEnabledFeatures::DigitalGoodsEnabled() || !ignore_total); + if (ignore_total) { + output->total = + CreateTotalPlaceHolderForAppStoreBilling(execution_context); + } else { + ValidateAndConvertTotal(input->total(), "total", output->total, + execution_context, exception_state); + if (exception_state.HadException()) + return; + } } if (input->hasError()) { @@ -603,6 +663,13 @@ void ValidateAndConvertPaymentMethodData( "Invalid payment method identifier format"); return; } + + if (method_names.Contains(payment_method_data->supportedMethod())) { + exception_state.ThrowRangeError( + "Cannot have duplicate payment method identifiers"); + return; + } + method_names.insert(payment_method_data->supportedMethod()); output.push_back(payments::mojom::blink::PaymentMethodData::New()); @@ -665,9 +732,9 @@ PaymentRequest* PaymentRequest::Create( const HeapVector<Member<PaymentMethodData>>& method_data, const PaymentDetailsInit* details, ExceptionState& exception_state) { - return MakeGarbageCollected<PaymentRequest>(execution_context, method_data, - details, PaymentOptions::Create(), - exception_state); + return MakeGarbageCollected<PaymentRequest>( + execution_context, method_data, details, PaymentOptions::Create(), + mojo::NullRemote(), exception_state); } PaymentRequest* PaymentRequest::Create( @@ -677,7 +744,8 @@ PaymentRequest* PaymentRequest::Create( const PaymentOptions* options, ExceptionState& exception_state) { return MakeGarbageCollected<PaymentRequest>( - execution_context, method_data, details, options, exception_state); + execution_context, method_data, details, options, mojo::NullRemote(), + exception_state); } PaymentRequest::~PaymentRequest() = default; @@ -982,7 +1050,7 @@ void PaymentRequest::OnUpdatePaymentDetails( PaymentDetailsPtr validated_details = payments::mojom::blink::PaymentDetails::New(); ValidateAndConvertPaymentDetailsUpdate( - details, options_, validated_details, shipping_option_, + details, options_, validated_details, shipping_option_, ignore_total_, *GetExecutionContext(), exception_state); if (exception_state.HadException()) { resolver->Reject(exception_state.GetException()); @@ -1030,7 +1098,7 @@ bool PaymentRequest::IsInteractive() const { return !!GetPendingAcceptPromiseResolver(); } -void PaymentRequest::Trace(Visitor* visitor) { +void PaymentRequest::Trace(Visitor* visitor) const { visitor->Trace(options_); visitor->Trace(shipping_address_); visitor->Trace(payment_response_); @@ -1067,6 +1135,8 @@ PaymentRequest::PaymentRequest( const HeapVector<Member<PaymentMethodData>>& method_data, const PaymentDetailsInit* details, const PaymentOptions* options, + mojo::PendingRemote<payments::mojom::blink::PaymentRequest> + mock_payment_provider, ExceptionState& exception_state) : ExecutionContextLifecycleObserver(execution_context), options_(options), @@ -1081,8 +1151,8 @@ PaymentRequest::PaymentRequest( this, &PaymentRequest::OnUpdatePaymentDetailsTimeout), is_waiting_for_show_promise_to_resolve_(false) { + DCHECK(details); DCHECK(GetExecutionContext()->IsSecureContext()); - if (!AllowedToUsePaymentRequest(execution_context)) { exception_state.ThrowSecurityError( "Must be in a top-level browsing context or an iframe needs to specify " @@ -1114,12 +1184,28 @@ PaymentRequest::PaymentRequest( if (exception_state.HadException()) return; + ignore_total_ = RuntimeEnabledFeatures::DigitalGoodsEnabled() && + RequestingOnlyAppStoreBillingMethods(validated_method_data); ValidateAndConvertPaymentDetailsInit(details, options_, validated_details, - shipping_option_, *GetExecutionContext(), - exception_state); + shipping_option_, ignore_total_, + *GetExecutionContext(), exception_state); if (exception_state.HadException()) return; + const WTF::HashSet<String> billing_methods = GetAppStoreBillingMethods(); + for (const PaymentMethodDataPtr& data : validated_method_data) { + if (billing_methods.Contains(data->supported_method) && + (options_->requestShipping() || options_->requestPayerName() || + options_->requestPayerEmail() || options_->requestPayerPhone())) { + execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kJavaScript, + mojom::blink::ConsoleMessageLevel::kError, + "Payment method \"" + data->supported_method + + "\" cannot be used with \"requestShipping\", \"requestPayerName\", " + "\"requestPayerEmail\", or \"requestPayerPhone\".")); + } + } + if (options_->requestShipping()) { shipping_type_ = options_->shippingType(); @@ -1143,8 +1229,14 @@ PaymentRequest::PaymentRequest( scoped_refptr<base::SingleThreadTaskRunner> task_runner = execution_context->GetTaskRunner(TaskType::kUserInteraction); - GetFrame()->GetBrowserInterfaceBroker().GetInterface( - payment_provider_.BindNewPipeAndPassReceiver(task_runner)); + if (mock_payment_provider) { + payment_provider_.Bind( + std::move(mock_payment_provider), + execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI)); + } else { + GetFrame()->GetBrowserInterfaceBroker().GetInterface( + payment_provider_.BindNewPipeAndPassReceiver(task_runner)); + } payment_provider_.set_disconnect_handler( WTF::Bind(&PaymentRequest::OnConnectionError, WrapWeakPersistent(this))); 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 2381feb6fb1..e946b2097cf 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.h @@ -65,6 +65,8 @@ class MODULES_EXPORT PaymentRequest final const HeapVector<Member<PaymentMethodData>>&, const PaymentDetailsInit*, const PaymentOptions*, + mojo::PendingRemote<payments::mojom::blink::PaymentRequest> + mock_payment_provider, ExceptionState&); ~PaymentRequest() override; @@ -106,7 +108,7 @@ class MODULES_EXPORT PaymentRequest final void OnUpdatePaymentDetailsFailure(const String& error) override; bool IsInteractive() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void OnCompleteTimeoutForTesting(); void OnUpdatePaymentDetailsTimeoutForTesting(); @@ -179,6 +181,7 @@ class MODULES_EXPORT PaymentRequest final TaskRunnerTimer<PaymentRequest> complete_timer_; TaskRunnerTimer<PaymentRequest> update_payment_details_timer_; bool is_waiting_for_show_promise_to_resolve_; + bool ignore_total_; DISALLOW_COPY_AND_ASSIGN(PaymentRequest); }; diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request.idl b/chromium/third_party/blink/renderer/modules/payments/payment_request.idl index 9ef367ee752..890952b0197 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request.idl +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request.idl @@ -11,7 +11,7 @@ Exposed=Window, ActiveScriptWrappable ] interface PaymentRequest : EventTarget { - [CallWith=ExecutionContext, RaisesException] constructor(sequence<PaymentMethodData> methodData, PaymentDetailsInit details, optional PaymentOptions options = {}); + [CallWith=ExecutionContext, RaisesException] constructor(sequence<PaymentMethodData> methodData, optional PaymentDetailsInit details = {}, optional PaymentOptions options = {}); [CallWith=ScriptState, RaisesException, NewObject] Promise<PaymentResponse> show(optional Promise<PaymentDetailsUpdate> detailsPromise); [CallWith=ScriptState, RaisesException, NewObject] Promise<void> abort(); [CallWith=ScriptState, RaisesException, HighEntropy, Measure, NewObject] Promise<boolean> canMakePayment(); 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 6285f00d36a..cbae9d8436b 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 @@ -44,6 +44,7 @@ PaymentRequestEvent* PaymentRequestEvent::Create( wait_until_observer, execution_context); } +// TODO(crbug.com/1070871): Use fooOr() in members' initializers. PaymentRequestEvent::PaymentRequestEvent( const AtomicString& type, const PaymentRequestEventInit* initializer, @@ -52,9 +53,14 @@ PaymentRequestEvent::PaymentRequestEvent( WaitUntilObserver* wait_until_observer, ExecutionContext* execution_context) : ExtendableEvent(type, initializer, wait_until_observer), - top_origin_(initializer->topOrigin()), - payment_request_origin_(initializer->paymentRequestOrigin()), - payment_request_id_(initializer->paymentRequestId()), + top_origin_(initializer->hasTopOrigin() ? initializer->topOrigin() + : String()), + payment_request_origin_(initializer->hasPaymentRequestOrigin() + ? initializer->paymentRequestOrigin() + : String()), + payment_request_id_(initializer->hasPaymentRequestId() + ? initializer->paymentRequestId() + : String()), method_data_(initializer->hasMethodData() ? initializer->methodData() : HeapVector<Member<PaymentMethodData>>()), @@ -63,7 +69,9 @@ PaymentRequestEvent::PaymentRequestEvent( modifiers_(initializer->hasModifiers() ? initializer->modifiers() : HeapVector<Member<PaymentDetailsModifier>>()), - instrument_key_(initializer->instrumentKey()), + instrument_key_(initializer->hasInstrumentKey() + ? initializer->instrumentKey() + : String()), payment_options_(initializer->hasPaymentOptions() ? initializer->paymentOptions() : PaymentOptions::Create()), @@ -180,14 +188,6 @@ ScriptPromise PaymentRequestEvent::openWindow(ScriptState* script_state, ScriptPromise PaymentRequestEvent::changePaymentMethod( ScriptState* script_state, const String& method_name, - ExceptionState& exception_state) { - return changePaymentMethod(script_state, method_name, ScriptValue(), - exception_state); -} - -ScriptPromise PaymentRequestEvent::changePaymentMethod( - ScriptState* script_state, - const String& method_name, const ScriptValue& method_details, ExceptionState& exception_state) { if (change_payment_request_details_resolver_) { @@ -205,7 +205,8 @@ ScriptPromise PaymentRequestEvent::changePaymentMethod( } auto method_data = payments::mojom::blink::PaymentHandlerMethodData::New(); - if (!method_details.IsEmpty()) { + if (!method_details.IsNull()) { + DCHECK(!method_details.IsEmpty()); PaymentsValidators::ValidateAndStringifyObject( script_state->GetIsolate(), "Method details", method_details, method_data->stringified_data, exception_state); @@ -321,7 +322,7 @@ void PaymentRequestEvent::respondWith(ScriptState* script_state, } } -void PaymentRequestEvent::Trace(Visitor* visitor) { +void PaymentRequestEvent::Trace(Visitor* visitor) const { visitor->Trace(method_data_); visitor->Trace(total_); visitor->Trace(modifiers_); 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 615b51e7570..3c4756e6a16 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 @@ -80,7 +80,7 @@ class MODULES_EXPORT PaymentRequestEvent final : public ExtendableEvent { ExceptionState&); void respondWith(ScriptState*, ScriptPromise, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void OnChangePaymentRequestDetailsResponse( diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_optional_total_test.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_optional_total_test.cc new file mode 100644 index 00000000000..ab7a9588db9 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_optional_total_test.cc @@ -0,0 +1,236 @@ +// Copyright 2020 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/payment_request.h" + +#include "build/build_config.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/mojom/payments/payment_request.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/event_type_names.h" +#include "third_party/blink/renderer/modules/payments/payment_test_helper.h" +#include "third_party/blink/renderer/platform/bindings/exception_code.h" +#include "third_party/blink/renderer/platform/heap/heap_allocator.h" +#include "third_party/blink/renderer/platform/testing/testing_platform_support.h" + +namespace blink { +namespace { + +class MockPaymentProvider : public payments::mojom::blink::PaymentRequest { + public: + // mojom::PaymentRequest +#if defined(OS_ANDROID) + void Init( + mojo::PendingRemote<payments::mojom::blink::PaymentRequestClient> client, + WTF::Vector<payments::mojom::blink::PaymentMethodDataPtr> method_data, + payments::mojom::blink::PaymentDetailsPtr details, + payments::mojom::blink::PaymentOptionsPtr options, + bool google_pay_bridge_eligible) override { + details_ = std::move(details); + } +#else + void Init( + mojo::PendingRemote<payments::mojom::blink::PaymentRequestClient> client, + WTF::Vector<payments::mojom::blink::PaymentMethodDataPtr> method_data, + payments::mojom::blink::PaymentDetailsPtr details, + payments::mojom::blink::PaymentOptionsPtr options) override { + details_ = std::move(details); + } +#endif + + void Show(bool is_user_gesture, bool wait_for_updated_details) override { + NOTREACHED(); + } + void Retry( + payments::mojom::blink::PaymentValidationErrorsPtr errors) override { + NOTREACHED(); + } + void UpdateWith( + payments::mojom::blink::PaymentDetailsPtr update_with_details) override { + NOTREACHED(); + } + void OnPaymentDetailsNotUpdated() override { NOTREACHED(); } + void Abort() override { NOTREACHED(); } + void Complete(payments::mojom::PaymentComplete result) override { + NOTREACHED(); + } + void CanMakePayment() override { NOTREACHED(); } + void HasEnrolledInstrument(bool per_method_quota) override { NOTREACHED(); } + + mojo::PendingRemote<payments::mojom::blink::PaymentRequest> + CreatePendingRemoteAndBind() { + mojo::PendingRemote<payments::mojom::blink::PaymentRequest> remote; + receiver_.Bind(remote.InitWithNewPipeAndPassReceiver()); + return remote; + } + + payments::mojom::blink::PaymentDetailsPtr& GetDetails() { return details_; } + + private: + mojo::Receiver<payments::mojom::blink::PaymentRequest> receiver_{this}; + payments::mojom::blink::PaymentDetailsPtr details_; +}; + +// This test suite is about the optional total parameter of the PaymentRequest +// constructor. +class PaymentRequestOptionalTotalTest : public testing::Test { + public: + void SetUp() override { + payment_provider_ = std::make_unique<MockPaymentProvider>(); + } + + std::unique_ptr<MockPaymentProvider> payment_provider_; + ScopedTestingPlatformSupport<TestingPlatformSupport> platform_; +}; + +// This test requests a mix of app-store billing methods and normal payment +// methods. Total is required in this scenario. +TEST_F(PaymentRequestOptionalTotalTest, + AppStoreBillingFlagEnabledTotalIsRequiredWhenMixMethods) { + RuntimeEnabledFeatures::SetDigitalGoodsEnabled(true); + + PaymentRequestV8TestingScope scope; + // Intentionally leaves the total of details unset. + PaymentDetailsInit* details = PaymentDetailsInit::Create(); + + HeapVector<Member<PaymentMethodData>> method_data(2); + method_data[0] = PaymentMethodData::Create(); + method_data[0]->setSupportedMethod("foo"); + method_data[1] = PaymentMethodData::Create(); + method_data[1]->setSupportedMethod("https://play.google.com/billing"); + + PaymentRequest::Create(scope.GetExecutionContext(), method_data, details, + scope.GetExceptionState()); + + EXPECT_TRUE(scope.GetExceptionState().HadException()); + EXPECT_EQ("required member details is undefined.", + scope.GetExceptionState().Message()); + EXPECT_FALSE(payment_provider_->GetDetails()); +} + +// When the DigitalGoods flag is disabled: although this test requests a +// app-store billing methods, total is required. +TEST_F(PaymentRequestOptionalTotalTest, + AppStoreBillingFlagDisabledTotalIsRequiredWhenMixMethods) { + RuntimeEnabledFeatures::SetDigitalGoodsEnabled(false); + + PaymentRequestV8TestingScope scope; + // Intentionally leaves the total of details unset. + PaymentDetailsInit* details = PaymentDetailsInit::Create(); + + HeapVector<Member<PaymentMethodData>> method_data(1); + method_data[0] = PaymentMethodData::Create(); + method_data[0]->setSupportedMethod("https://play.google.com/billing"); + + PaymentRequest::Create(scope.GetExecutionContext(), method_data, details, + scope.GetExceptionState()); + + EXPECT_TRUE(scope.GetExceptionState().HadException()); + EXPECT_EQ("required member details is undefined.", + scope.GetExceptionState().Message()); + EXPECT_FALSE(payment_provider_->GetDetails()); +} + +// When the DigitalGoods flag is enabled: undefined total gets a place holder +// when only requesting app-store billing methods. +TEST_F(PaymentRequestOptionalTotalTest, + AppStoreBillingFlagEnabledTotalGetPlaceHolder) { + RuntimeEnabledFeatures::SetDigitalGoodsEnabled(true); + + PaymentRequestV8TestingScope scope; + // Intentionally leaves the total of details unset. + PaymentDetailsInit* details = PaymentDetailsInit::Create(); + + HeapVector<Member<PaymentMethodData>> method_data( + 1, PaymentMethodData::Create()); + method_data[0]->setSupportedMethod("https://play.google.com/billing"); + + MakeGarbageCollected<PaymentRequest>( + scope.GetExecutionContext(), method_data, details, + PaymentOptions::Create(), payment_provider_->CreatePendingRemoteAndBind(), + ASSERT_NO_EXCEPTION); + platform_->RunUntilIdle(); + EXPECT_FALSE(scope.GetExceptionState().HadException()); + EXPECT_EQ("0", payment_provider_->GetDetails()->total->amount->value); + EXPECT_EQ("ZZZ", payment_provider_->GetDetails()->total->amount->currency); +} + +// When the DigitalGoods flag is disabled: undefined total is rejected. +TEST_F(PaymentRequestOptionalTotalTest, + AppStoreBillingFlagDisabledTotalGetRejected) { + RuntimeEnabledFeatures::SetDigitalGoodsEnabled(false); + + PaymentRequestV8TestingScope scope; + // Intentionally leaves the total of details unset. + PaymentDetailsInit* details = PaymentDetailsInit::Create(); + + HeapVector<Member<PaymentMethodData>> method_data( + 1, PaymentMethodData::Create()); + method_data[0]->setSupportedMethod("https://play.google.com/billing"); + + MakeGarbageCollected<PaymentRequest>( + scope.GetExecutionContext(), method_data, details, + PaymentOptions::Create(), payment_provider_->CreatePendingRemoteAndBind(), + scope.GetExceptionState()); + platform_->RunUntilIdle(); + // Verify that total is required. + EXPECT_TRUE(scope.GetExceptionState().HadException()); + EXPECT_EQ("required member details is undefined.", + scope.GetExceptionState().Message()); + EXPECT_FALSE(payment_provider_->GetDetails()); +} + +// When the DigitalGoods flag is enabled: total get overridden when only +// requesting app-store billing methods. +TEST_F(PaymentRequestOptionalTotalTest, + AppStoreBillingFlagEnabledTotalGetOverridden) { + RuntimeEnabledFeatures::SetDigitalGoodsEnabled(true); + + PaymentRequestV8TestingScope scope; + PaymentDetailsInit* details = PaymentDetailsInit::Create(); + // Set a non-empty total. + details->setTotal((BuildPaymentItemForTest())); + + HeapVector<Member<PaymentMethodData>> method_data( + 1, PaymentMethodData::Create()); + method_data[0]->setSupportedMethod("https://play.google.com/billing"); + + MakeGarbageCollected<PaymentRequest>( + scope.GetExecutionContext(), method_data, details, + PaymentOptions::Create(), payment_provider_->CreatePendingRemoteAndBind(), + ASSERT_NO_EXCEPTION); + platform_->RunUntilIdle(); + EXPECT_FALSE(scope.GetExceptionState().HadException()); + // Verify that the total get overridden. + EXPECT_EQ("0", payment_provider_->GetDetails()->total->amount->value); + EXPECT_EQ("ZZZ", payment_provider_->GetDetails()->total->amount->currency); +} + +// When the DigitalGoods flag is disabled: total does not get overridden when +// only requesting app-store billing methods. +TEST_F(PaymentRequestOptionalTotalTest, + AppStoreBillingFlagDisabledTotalNotGetOverridden) { + RuntimeEnabledFeatures::SetDigitalGoodsEnabled(false); + + PaymentRequestV8TestingScope scope; + PaymentDetailsInit* details = PaymentDetailsInit::Create(); + // Set a non-empty total. + details->setTotal(BuildPaymentItemForTest()); + + HeapVector<Member<PaymentMethodData>> method_data( + 1, PaymentMethodData::Create()); + method_data[0]->setSupportedMethod("https://play.google.com/billing"); + + MakeGarbageCollected<PaymentRequest>( + scope.GetExecutionContext(), method_data, details, + PaymentOptions::Create(), payment_provider_->CreatePendingRemoteAndBind(), + ASSERT_NO_EXCEPTION); + platform_->RunUntilIdle(); + // Verify that the total is set. + EXPECT_FALSE(scope.GetExceptionState().HadException()); + EXPECT_TRUE(payment_provider_->GetDetails()->total); +} +} // namespace +} // namespace blink 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 2d6a3b72b58..83a8c9b0241 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 @@ -172,7 +172,7 @@ PaymentRequestRespondWithObserver::PaymentRequestRespondWithObserver( WaitUntilObserver* observer) : RespondWithObserver(context, event_id, observer) {} -void PaymentRequestRespondWithObserver::Trace(Visitor* visitor) { +void PaymentRequestRespondWithObserver::Trace(Visitor* visitor) const { RespondWithObserver::Trace(visitor); } 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 2f06819f32b..4b66f94d677 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 @@ -39,7 +39,7 @@ class MODULES_EXPORT PaymentRequestRespondWithObserver final const char* property_name) override; void OnNoResponse() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void set_should_have_payer_name(bool should_have_payer_name) { should_have_payer_name_ = should_have_payer_name; diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.cc b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.cc index fe6de07bba3..c8711c265b8 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.cc @@ -70,7 +70,7 @@ void PaymentRequestUpdateEvent::updateWith(ScriptState* script_state, UpdatePaymentDetailsFunction::ResolveType::kReject)); } -void PaymentRequestUpdateEvent::Trace(Visitor* visitor) { +void PaymentRequestUpdateEvent::Trace(Visitor* visitor) const { visitor->Trace(request_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h index 96d0b510421..e0c80b0acf0 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_request_update_event.h @@ -44,7 +44,7 @@ class MODULES_EXPORT PaymentRequestUpdateEvent : public Event, void start_waiting_for_update(bool value) { wait_for_update_ = value; } bool is_waiting_for_update() const { return wait_for_update_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // True after event.updateWith() was called. 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 f2af6da908e..3d89c4a1261 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 @@ -34,7 +34,7 @@ class MockPaymentRequest : public GarbageCollected<MockPaymentRequest>, MOCK_METHOD1(OnUpdatePaymentDetailsFailure, void(const String& error)); bool IsInteractive() const override { return true; } - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} private: DISALLOW_COPY_AND_ASSIGN(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 22418c87097..11361b6ab9a 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_response.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.cc @@ -142,7 +142,7 @@ ExecutionContext* PaymentResponse::GetExecutionContext() const { return ExecutionContextClient::GetExecutionContext(); } -void PaymentResponse::Trace(Visitor* visitor) { +void PaymentResponse::Trace(Visitor* visitor) const { visitor->Trace(details_); visitor->Trace(shipping_address_); visitor->Trace(payment_state_resolver_); 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 4a48f2e9d34..b5832670e7a 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payment_response.h +++ b/chromium/third_party/blink/renderer/modules/payments/payment_response.h @@ -71,7 +71,7 @@ class MODULES_EXPORT PaymentResponse final const AtomicString& InterfaceName() const override; ExecutionContext* GetExecutionContext() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: String request_id_; 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 86e2b2af20b..ffd4a188dbe 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 @@ -46,7 +46,9 @@ class MockPaymentStateResolver final const PaymentValidationErrors* errorFields, ExceptionState&)); - void Trace(Visitor* visitor) override { visitor->Trace(dummy_promise_); } + void Trace(Visitor* visitor) const override { + visitor->Trace(dummy_promise_); + } private: ScriptPromise dummy_promise_; diff --git a/chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc b/chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc index e13cf4a7fdc..7164cab41a8 100644 --- a/chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc +++ b/chromium/third_party/blink/renderer/modules/payments/payments_validators_test.cc @@ -359,14 +359,14 @@ TEST(PaymentMethodValidatorTest, IsValidPaymentMethod) { } } -TEST(PaymentMethodValidatorTest, IsValidPaymentMethodWhitelisted) { +TEST(PaymentMethodValidatorTest, IsValidPaymentMethodSafelisted) { EXPECT_FALSE(PaymentsValidators::IsValidMethodFormat("http://alicepay.com")) << "http://alicepay.com is not a valid method format by default"; SecurityPolicy::AddOriginToTrustworthySafelist("http://alicepay.com"); EXPECT_TRUE(PaymentsValidators::IsValidMethodFormat("http://alicepay.com")) - << "http://alicepay.com should be valid if whitelisted"; + << "http://alicepay.com should be valid if safelisted"; } } // namespace diff --git a/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.cc b/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.cc index b019e50b7e5..2abfe84dc35 100644 --- a/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.cc +++ b/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.cc @@ -30,7 +30,7 @@ UpdatePaymentDetailsFunction::UpdatePaymentDetailsFunction( DCHECK(delegate_); } -void UpdatePaymentDetailsFunction::Trace(Visitor* visitor) { +void UpdatePaymentDetailsFunction::Trace(Visitor* visitor) const { visitor->Trace(delegate_); ScriptFunction::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.h b/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.h index 3b7a6426972..e91e4f8cc22 100644 --- a/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.h +++ b/chromium/third_party/blink/renderer/modules/payments/update_payment_details_function.h @@ -28,7 +28,7 @@ class UpdatePaymentDetailsFunction : public ScriptFunction { UpdatePaymentDetailsFunction(ScriptState*, PaymentRequestDelegate*, ResolveType); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; ScriptValue Call(ScriptValue) override; private: diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn index 27fe410a731..4151ab573a7 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/peerconnection/BUILD.gn @@ -155,6 +155,10 @@ 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", + "thermal_resource.cc", + "thermal_resource.h", + "thermal_uma_listener.cc", + "thermal_uma_listener.h", "transceiver_state_surfacer.cc", "transceiver_state_surfacer.h", "web_rtc_stats_report_callback_resolver.cc", @@ -168,7 +172,7 @@ blink_modules_sources("peerconnection") { ] public_deps = [ "//third_party/webrtc_overrides:webrtc_component" ] - deps = [ "//third_party/abseil-cpp/absl/types:optional" ] + deps = [ "//third_party/abseil-cpp:absl" ] } jumbo_source_set("test_support") { @@ -199,4 +203,6 @@ jumbo_source_set("test_support") { "//third_party/blink/renderer/platform", "//third_party/webrtc_overrides:webrtc_component", ] + + configs += [ "//third_party/blink/renderer:inside_blink" ] } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/DEPS b/chromium/third_party/blink/renderer/modules/peerconnection/DEPS index 22a107fd92e..5194e720e1d 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/DEPS +++ b/chromium/third_party/blink/renderer/modules/peerconnection/DEPS @@ -13,6 +13,7 @@ include_rules = [ "+base/lazy_instance.h", # TODO(crbug.com/787254): Remove the use of base::MessageLoopCurrent. "+base/message_loop/message_loop_current.h", + "+base/power_monitor/power_observer.h", # TODO(crbug.com/787254): Replace base::SequenceChecker by base::ThreadChecker. "+base/sequence_checker.h", # TODO(crbug.com/787254): Replace StringPrintf uses here. diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h index 5ba98d2bf75..09da798acdf 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/dtls_transport_proxy.h @@ -35,7 +35,7 @@ class DtlsTransportProxy : public webrtc::DtlsTransportObserverInterface { virtual void OnStartCompleted(webrtc::DtlsTransportInformation info) = 0; // Called when a state change is signalled from transport. virtual void OnStateChange(webrtc::DtlsTransportInformation info) = 0; - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} }; // Constructs a DtlsTransportProxy. // The caller is responsible for keeping |dtls_transport| and |delegate| diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc index 4dd8f7d60ba..32148834ee9 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_adapter_impl.cc @@ -6,6 +6,7 @@ #include <utility> +#include "base/notreached.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/quic_packet_transport_adapter.h" #include "third_party/webrtc/api/ice_transport_factory.h" diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc index b235aaa2fb3..d70c54fb869 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.h" +#include "base/feature_list.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_host.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h" @@ -24,8 +26,13 @@ IceTransportProxy::IceTransportProxy( delegate_(delegate), feature_handle_for_scheduler_(frame.GetFrameScheduler()->RegisterFeature( SchedulingPolicy::Feature::kWebRTC, - {SchedulingPolicy::DisableAggressiveThrottling(), - SchedulingPolicy::RecordMetricsForBackForwardCache()})) { + base::FeatureList::IsEnabled(features::kOptOutWebRTCFromAllThrottling) + ? SchedulingPolicy{SchedulingPolicy::DisableAllThrottling(), + SchedulingPolicy:: + RecordMetricsForBackForwardCache()} + : SchedulingPolicy{ + SchedulingPolicy::DisableAggressiveThrottling(), + SchedulingPolicy::RecordMetricsForBackForwardCache()})) { DCHECK(host_thread_); DCHECK(delegate_); DCHECK(adapter_factory); 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 d8325ae725b..538dc9379d2 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 @@ -90,7 +90,7 @@ TEST_F(P2PQuicStreamTest, StreamSendsFinAndCanNoLongerWrite) { .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 0u, 0u, quic::StreamSendingState::FIN, - quic::NOT_RETRANSMISSION, QuicheNullOpt); + quic::NOT_RETRANSMISSION, QUICHE_NULLOPT); })); stream_->WriteData({}, /*fin=*/true); @@ -129,7 +129,7 @@ TEST_F(P2PQuicStreamTest, StreamClosedAfterSendingThenReceivingFin) { .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 0u, 0u, quic::StreamSendingState::FIN, - quic::NOT_RETRANSMISSION, QuicheNullOpt); + quic::NOT_RETRANSMISSION, QUICHE_NULLOPT); })); stream_->WriteData({}, /*fin=*/true); @@ -157,7 +157,7 @@ TEST_F(P2PQuicStreamTest, StreamClosedAfterReceivingThenSendingFin) { .WillOnce(InvokeWithoutArgs([this]() { return session_->ConsumeData(stream_->id(), 0u, 0u, quic::StreamSendingState::FIN, - quic::NOT_RETRANSMISSION, QuicheNullOpt); + quic::NOT_RETRANSMISSION, QUICHE_NULLOPT); })); stream_->WriteData({}, /*fin=*/true); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h index 2380ed7ac3f..a93498df53f 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_P2P_QUIC_TRANSPORT_H_ -#include "base/logging.h" +#include "base/check_op.h" #include "third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_stats.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/vector.h" diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc index ddb46cf81be..5cf896dc0ae 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_impl.cc @@ -116,11 +116,11 @@ class P2PQuicPacketWriter : public quic::QuicPacketWriter, return false; } - char* GetNextWriteLocation( + quic::QuicPacketBuffer GetNextWriteLocation( const quic::QuicIpAddress& self_address, const quic::QuicSocketAddress& peer_address) override { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - return nullptr; + return {nullptr, nullptr}; } quic::WriteResult Flush() override { @@ -403,8 +403,7 @@ void P2PQuicTransportImpl::SendDatagram(Vector<uint8_t> datagram) { bool P2PQuicTransportImpl::CanSendDatagram() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return IsEncryptionEstablished() && - (connection()->transport_version() > quic::QUIC_VERSION_43) && - !IsClosed(); + (connection()->version().SupportsMessageFrames()) && !IsClosed(); } P2PQuicStreamImpl* P2PQuicTransportImpl::CreateOutgoingBidirectionalStream() { @@ -610,7 +609,7 @@ void P2PQuicTransportImpl::OnConnectionClosed( } bool P2PQuicTransportImpl::ShouldKeepConnectionAlive() const { - return GetNumOpenDynamicStreams() > 0; + return GetNumActiveStreams() > 0; } bool P2PQuicTransportImpl::IsClosed() { diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc index 2d97b02d98f..fb09e9c142a 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/p2p_quic_transport_test.cc @@ -485,8 +485,7 @@ class ConnectedCryptoClientStream final : public quic::QuicCryptoClientStream { session()->config()->ProcessPeerHello(message, quic::CLIENT, &error_details); session()->OnConfigNegotiated(); - if (session()->connection()->version().handshake_protocol == - quic::PROTOCOL_TLS1_3) { + if (session()->version().UsesTls()) { session()->OnOneRttKeysAvailable(); } else { session()->SetDefaultEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h index da39b23cecf..b999131ed61 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/sctp_transport_proxy.h @@ -40,7 +40,7 @@ class SctpTransportProxy : public webrtc::SctpTransportObserverInterface { virtual void OnStartCompleted(webrtc::SctpTransportInformation info) = 0; // Called when a state change is signalled from transport. virtual void OnStateChange(webrtc::SctpTransportInformation info) = 0; - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} }; // Constructs a SctpTransportProxy. The caller is responsible for keeping diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h index 0d6c40f0b42..ad74f6ad17b 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h @@ -34,6 +34,7 @@ class MediaStreamInterface; class RtpReceiverInterface; class SctpTransportInformation; class VideoTrackInterface; +struct DataBuffer; } namespace blink { @@ -171,6 +172,12 @@ struct CrossThreadCopier<rtc::scoped_refptr<webrtc::VideoTrackInterface>> STATIC_ONLY(CrossThreadCopier); }; +template <> +struct CrossThreadCopier<webrtc::DataBuffer> + : public CrossThreadCopierPassThrough<webrtc::DataBuffer> { + STATIC_ONLY(CrossThreadCopier); +}; + } // namespace WTF #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_ADAPTERS_WEB_RTC_CROSS_THREAD_COPIER_H_ 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 index d158076281e..5ce40463693 100644 --- 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 @@ -9,7 +9,7 @@ namespace blink { -blink::WebMediaStreamTrack CreateWebMediaStreamTrack( +MediaStreamComponent* CreateWebMediaStreamTrack( const std::string& id, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { blink::WebMediaStreamSource web_source; @@ -23,10 +23,10 @@ blink::WebMediaStreamTrack CreateWebMediaStreamTrack( // 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; + MediaStreamComponent* component = + MakeGarbageCollected<MediaStreamComponent>(web_source.Id(), web_source); + audio_source->ConnectToTrack(component); + return component; } FakeRTCRtpSenderImpl::FakeRTCRtpSenderImpl( @@ -69,9 +69,9 @@ FakeRTCRtpSenderImpl::DtlsTransportInformation() { return dummy; } -blink::WebMediaStreamTrack FakeRTCRtpSenderImpl::Track() const { +MediaStreamComponent* FakeRTCRtpSenderImpl::Track() const { return track_id_ ? CreateWebMediaStreamTrack(*track_id_, task_runner_) - : blink::WebMediaStreamTrack(); // null + : nullptr; } Vector<String> FakeRTCRtpSenderImpl::StreamIds() const { @@ -83,8 +83,8 @@ Vector<String> FakeRTCRtpSenderImpl::StreamIds() const { return wtf_stream_ids; } -void FakeRTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track, - blink::RTCVoidRequest* request) { +void FakeRTCRtpSenderImpl::ReplaceTrack(MediaStreamComponent* with_track, + RTCVoidRequest* request) { NOTIMPLEMENTED(); } @@ -120,7 +120,7 @@ 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)), + : component_(CreateWebMediaStreamTrack(track_id, task_runner)), stream_ids_(std::move(stream_ids)) {} FakeRTCRtpReceiverImpl::FakeRTCRtpReceiverImpl(const FakeRTCRtpReceiverImpl&) = @@ -155,8 +155,8 @@ FakeRTCRtpReceiverImpl::DtlsTransportInformation() { return dummy; } -const blink::WebMediaStreamTrack& FakeRTCRtpReceiverImpl::Track() const { - return track_; +MediaStreamComponent* FakeRTCRtpReceiverImpl::Track() const { + return component_; } Vector<String> FakeRTCRtpReceiverImpl::StreamIds() const { diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h index e8bac93497a..da098ec3850 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/fake_rtc_rtp_transceiver_impl.h @@ -13,6 +13,7 @@ #include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/renderer/platform/mediastream/media_constraints.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_receiver_platform.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h" @@ -23,7 +24,7 @@ namespace blink { // TODO(https://crbug.com/868868): Similar methods to this exist in many blink // unittests. Move to a separate file and reuse it in all of them. -blink::WebMediaStreamTrack CreateWebMediaStreamTrack( +MediaStreamComponent* CreateWebMediaStreamTrack( const std::string& id, scoped_refptr<base::SingleThreadTaskRunner> task_runner); @@ -40,9 +41,9 @@ class FakeRTCRtpSenderImpl : public blink::RTCRtpSenderPlatform { uintptr_t Id() const override; rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override; webrtc::DtlsTransportInformation DtlsTransportInformation() override; - blink::WebMediaStreamTrack Track() const override; + MediaStreamComponent* Track() const override; Vector<String> StreamIds() const override; - void ReplaceTrack(blink::WebMediaStreamTrack with_track, + void ReplaceTrack(MediaStreamComponent* with_track, blink::RTCVoidRequest* request) override; std::unique_ptr<blink::RtcDtmfSenderHandler> GetDtmfSender() const override; std::unique_ptr<webrtc::RtpParameters> GetParameters() const override; @@ -73,7 +74,7 @@ class FakeRTCRtpReceiverImpl : public RTCRtpReceiverPlatform { uintptr_t Id() const override; rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override; webrtc::DtlsTransportInformation DtlsTransportInformation() override; - const blink::WebMediaStreamTrack& Track() const override; + MediaStreamComponent* Track() const override; Vector<String> StreamIds() const override; Vector<std::unique_ptr<RTCRtpSource>> GetSources() override; void GetStats(RTCStatsReportCallback, @@ -83,7 +84,7 @@ class FakeRTCRtpReceiverImpl : public RTCRtpReceiverPlatform { base::Optional<double> delay_seconds) override; private: - blink::WebMediaStreamTrack track_; + Persistent<MediaStreamComponent> component_; std::vector<std::string> stream_ids_; }; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc index f0e12d83d5a..d83906e4896 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_remote_video_source.cc @@ -275,9 +275,8 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame( // Rotation may be explicitly set sometimes. if (incoming_frame.rotation() != webrtc::kVideoRotation_0) { - video_frame->metadata()->SetRotation( - media::VideoFrameMetadata::ROTATION, - WebRtcToMediaVideoRotation(incoming_frame.rotation())); + video_frame->metadata()->rotation = + WebRtcToMediaVideoRotation(incoming_frame.rotation()); } if (incoming_frame.color_space()) { @@ -288,24 +287,21 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame( // Run render smoothness algorithm only when we don't have to render // immediately. - if (!render_immediately) { - video_frame->metadata()->SetTimeTicks( - media::VideoFrameMetadata::REFERENCE_TIME, render_time); - } - video_frame->metadata()->SetTimeTicks( - media::VideoFrameMetadata::DECODE_END_TIME, current_time); + if (!render_immediately) + video_frame->metadata()->reference_time = render_time; + + video_frame->metadata()->decode_end_time = current_time; // RTP_TIMESTAMP, PROCESSING_TIME, and CAPTURE_BEGIN_TIME are all exposed - // through the JavaScript callback mechanism video.requestAnimationFrame(). - video_frame->metadata()->SetDouble( - media::VideoFrameMetadata::RTP_TIMESTAMP, - static_cast<double>(incoming_frame.timestamp())); + // through the JavaScript callback mechanism + // video.requestVideoFrameCallback(). + video_frame->metadata()->rtp_timestamp = + static_cast<double>(incoming_frame.timestamp()); if (incoming_frame.processing_time()) { - video_frame->metadata()->SetTimeDelta( - media::VideoFrameMetadata::PROCESSING_TIME, + video_frame->metadata()->processing_time = base::TimeDelta::FromMicroseconds( - incoming_frame.processing_time()->Elapsed().us())); + incoming_frame.processing_time()->Elapsed().us()); } // Set capture time to the NTP time, which is the estimated capture time @@ -316,8 +312,7 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame( base::TimeDelta::FromMilliseconds(incoming_frame.ntp_time_ms() + ntp_offset_) + time_diff_; - video_frame->metadata()->SetTimeTicks( - media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, capture_time); + video_frame->metadata()->capture_begin_time = capture_time; } // Set receive time to arrival of last packet. @@ -333,8 +328,7 @@ void MediaStreamRemoteVideoSource::RemoteVideoSourceDelegate::OnFrame( const base::TimeTicks receive_time = base::TimeTicks() + base::TimeDelta::FromMilliseconds(last_packet_arrival_ms) + time_diff_; - video_frame->metadata()->SetTimeTicks( - media::VideoFrameMetadata::RECEIVE_TIME, receive_time); + video_frame->metadata()->receive_time = receive_time; } // Use our computed render time as estimated capture time. If timestamp_us() 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 index f69debc185e..46e6389cae6 100644 --- 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 @@ -367,27 +367,20 @@ TEST_F(MediaStreamRemoteVideoSourceTest, scoped_refptr<media::VideoFrame> output_frame = sink.last_frame(); EXPECT_TRUE(output_frame); - base::TimeDelta elapsed; - EXPECT_TRUE(output_frame->metadata()->GetTimeDelta( - media::VideoFrameMetadata::PROCESSING_TIME, &elapsed)); - EXPECT_FLOAT_EQ(elapsed.InSecondsF(), kProcessingTime); - - base::TimeTicks capture_time; - EXPECT_TRUE(output_frame->metadata()->GetTimeTicks( - media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, &capture_time)); - EXPECT_NEAR((capture_time - kExpectedCaptureTime).InMillisecondsF(), 0.0f, - kChromiumWebRtcMaxTimeDiffMs); - - base::TimeTicks receive_time; - EXPECT_TRUE(output_frame->metadata()->GetTimeTicks( - media::VideoFrameMetadata::RECEIVE_TIME, &receive_time)); - EXPECT_NEAR((receive_time - kExpectedReceiveTime).InMillisecondsF(), 0.0f, - kChromiumWebRtcMaxTimeDiffMs); - - double rtp_timestamp; - EXPECT_TRUE(output_frame->metadata()->GetDouble( - media::VideoFrameMetadata::RTP_TIMESTAMP, &rtp_timestamp)); - EXPECT_EQ(static_cast<uint32_t>(rtp_timestamp), kRtpTimestamp); + EXPECT_FLOAT_EQ(output_frame->metadata()->processing_time->InSecondsF(), + kProcessingTime); + + EXPECT_NEAR( + (*output_frame->metadata()->capture_begin_time - kExpectedCaptureTime) + .InMillisecondsF(), + 0.0f, kChromiumWebRtcMaxTimeDiffMs); + + EXPECT_NEAR((*output_frame->metadata()->receive_time - kExpectedReceiveTime) + .InMillisecondsF(), + 0.0f, kChromiumWebRtcMaxTimeDiffMs); + + EXPECT_EQ(static_cast<uint32_t>(*output_frame->metadata()->rtp_timestamp), + kRtpTimestamp); track->RemoveSink(&sink); } @@ -416,10 +409,7 @@ TEST_F(MediaStreamRemoteVideoSourceTest, MAYBE_ReferenceTimeEqualsTimestampUs) { scoped_refptr<media::VideoFrame> output_frame = sink.last_frame(); EXPECT_TRUE(output_frame); - base::TimeTicks reference_time; - EXPECT_TRUE(output_frame->metadata()->GetTimeTicks( - media::VideoFrameMetadata::REFERENCE_TIME, &reference_time)); - EXPECT_NEAR((reference_time - + EXPECT_NEAR((*output_frame->metadata()->reference_time - (base::TimeTicks() + base::TimeDelta::FromMicroseconds(kTimestampUs) + time_diff())) .InMillisecondsF(), @@ -449,9 +439,7 @@ TEST_F(MediaStreamRemoteVideoSourceTest, NoTimestampUsMeansNoReferenceTime) { scoped_refptr<media::VideoFrame> output_frame = sink.last_frame(); EXPECT_TRUE(output_frame); - base::TimeTicks reference_time; - EXPECT_FALSE(output_frame->metadata()->GetTimeTicks( - media::VideoFrameMetadata::REFERENCE_TIME, &reference_time)); + EXPECT_FALSE(output_frame->metadata()->reference_time.has_value()); track->RemoveSink(&sink); } 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 index 6ba143f9911..385841f6b97 100644 --- 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 @@ -17,6 +17,7 @@ #include "third_party/blink/public/web/modules/mediastream/web_media_stream_utils.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints_util.h" #include "third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.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" @@ -208,11 +209,11 @@ void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter:: } MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink( - const WebMediaStreamTrack& track, + MediaStreamComponent* component, PeerConnectionDependencyFactory* factory, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { MediaStreamVideoTrack* video_track = - MediaStreamVideoTrack::GetVideoTrack(track); + MediaStreamVideoTrack::GetVideoTrack(WebMediaStreamTrack(component)); DCHECK(video_track); absl::optional<bool> needs_denoising = @@ -261,15 +262,15 @@ MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink( // PeerConnectionFactory::CreateVideoTrack doesn't do reference counting. video_source_proxy_ = factory->CreateVideoTrackSourceProxy(video_source_.get()); - video_track_ = - factory->CreateLocalVideoTrack(track.Id(), video_source_proxy_.get()); + video_track_ = factory->CreateLocalVideoTrack(component->Id(), + video_source_proxy_.get()); video_track_->set_content_hint( - ContentHintTypeToWebRtcContentHint(track.ContentHint())); - video_track_->set_enabled(track.IsEnabled()); + ContentHintTypeToWebRtcContentHint(component->ContentHint())); + video_track_->set_enabled(component->Enabled()); source_adapter_ = base::MakeRefCounted<WebRtcVideoSourceAdapter>( - factory->GetWebRtcWorkerTaskRunner(), video_source_.get(), + factory->GetWebRtcNetworkTaskRunner(), video_source_.get(), refresh_interval, ConvertToBaseRepeatingCallback(CrossThreadBindRepeating( &MediaStreamVideoWebRtcSink::RequestRefreshFrame, @@ -277,7 +278,7 @@ MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink( std::move(task_runner)); MediaStreamVideoSink::ConnectToTrack( - track, + WebMediaStreamTrack(component), ConvertToBaseRepeatingCallback(CrossThreadBindRepeating( &WebRtcVideoSourceAdapter::OnVideoFrameOnIO, source_adapter_)), false); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.h b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.h index 52e2cbe8a45..dd1ccf29770 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.h @@ -34,7 +34,7 @@ class WebRtcVideoTrackSource; class MODULES_EXPORT MediaStreamVideoWebRtcSink : public MediaStreamVideoSink { public: MediaStreamVideoWebRtcSink( - const WebMediaStreamTrack& track, + MediaStreamComponent* component, PeerConnectionDependencyFactory* factory, scoped_refptr<base::SingleThreadTaskRunner> task_runner); ~MediaStreamVideoWebRtcSink() override; 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 index a9f054ed15d..49f8a6d0567 100644 --- 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 @@ -9,6 +9,7 @@ #include "third_party/blink/renderer/modules/mediastream/mock_media_stream_registry.h" #include "third_party/blink/renderer/modules/mediastream/video_track_adapter_settings.h" #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" namespace blink { @@ -18,10 +19,9 @@ class MediaStreamVideoWebRtcSinkTest : public ::testing::Test { 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 + auto video_components = registry_.test_stream()->VideoComponents(); + component_ = video_components[0]; + // TODO(hta): Verify that component_ is valid. When constraints produce // no valid format, using the track will cause a crash. } @@ -30,15 +30,14 @@ class MediaStreamVideoWebRtcSinkTest : public ::testing::Test { 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 + auto video_components = registry_.test_stream()->VideoComponents(); + component_ = video_components[0]; + // TODO(hta): Verify that component_ is valid. When constraints produce // no valid format, using the track will cause a crash. } protected: - blink::WebMediaStreamTrack track_; + Persistent<MediaStreamComponent> component_; blink::MockPeerConnectionDependencyFactory dependency_factory_; private: @@ -50,7 +49,7 @@ class MediaStreamVideoWebRtcSinkTest : public ::testing::Test { TEST_F(MediaStreamVideoWebRtcSinkTest, NoiseReductionDefaultsToNotSet) { SetVideoTrack(); blink::MediaStreamVideoWebRtcSink my_sink( - track_, &dependency_factory_, + component_, &dependency_factory_, blink::scheduler::GetSingleThreadTaskRunnerForTesting()); EXPECT_TRUE(my_sink.webrtc_video_track()); EXPECT_FALSE(my_sink.SourceNeedsDenoisingForTesting()); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h index 48b2b0691b5..24bdf5aae3c 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h @@ -8,10 +8,11 @@ #include <memory> #include <string> -#include "base/logging.h" #include "base/macros.h" +#include "base/notreached.h" #include "base/optional.h" #include "testing/gmock/include/gmock/gmock.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/webrtc/api/dtls_transport_interface.h" #include "third_party/webrtc/api/peer_connection_interface.h" #include "third_party/webrtc/api/sctp_transport_interface.h" @@ -359,6 +360,15 @@ class MockPeerConnectionImpl : public webrtc::DummyPeerConnection { static const char kDummyOffer[]; static const char kDummyAnswer[]; + void AddAdaptationResource( + rtc::scoped_refptr<webrtc::Resource> resource) override { + adaptation_resources_.push_back(resource); + } + + Vector<rtc::scoped_refptr<webrtc::Resource>> adaptation_resources() const { + return adaptation_resources_; + } + protected: ~MockPeerConnectionImpl() override; @@ -385,6 +395,7 @@ class MockPeerConnectionImpl : public webrtc::DummyPeerConnection { webrtc::RTCErrorType setconfiguration_error_type_ = webrtc::RTCErrorType::NONE; rtc::scoped_refptr<webrtc::RTCStatsReport> stats_report_; + Vector<rtc::scoped_refptr<webrtc::Resource>> adaptation_resources_; DISALLOW_COPY_AND_ASSIGN(MockPeerConnectionImpl); }; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc index 5372b035aaf..65ea352cf20 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc @@ -11,6 +11,8 @@ #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_vector.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_rtp_sender_platform.h" @@ -33,25 +35,24 @@ class DummyRtpSenderInternal static uintptr_t last_id_; public: - explicit DummyRtpSenderInternal(WebMediaStreamTrack track) - : id_(++last_id_), track_(std::move(track)) {} + explicit DummyRtpSenderInternal(MediaStreamComponent* component) + : id_(++last_id_), component_(component) {} uintptr_t id() const { return id_; } - WebMediaStreamTrack track() const { return track_; } - void set_track(WebMediaStreamTrack track) { track_ = std::move(track); } + MediaStreamComponent* track() const { return component_; } + void set_track(MediaStreamComponent* component) { component_ = component; } private: const uintptr_t id_; - WebMediaStreamTrack track_; + Persistent<MediaStreamComponent> component_; }; uintptr_t DummyRtpSenderInternal::last_id_ = 0; class DummyRTCRtpSenderPlatform : public RTCRtpSenderPlatform { public: - explicit DummyRTCRtpSenderPlatform(WebMediaStreamTrack track) - : internal_( - base::MakeRefCounted<DummyRtpSenderInternal>(std::move(track))) {} + explicit DummyRTCRtpSenderPlatform(MediaStreamComponent* component) + : internal_(base::MakeRefCounted<DummyRtpSenderInternal>(component)) {} DummyRTCRtpSenderPlatform(const DummyRTCRtpSenderPlatform& other) : internal_(other.internal_) {} ~DummyRTCRtpSenderPlatform() override {} @@ -70,11 +71,11 @@ class DummyRTCRtpSenderPlatform : public RTCRtpSenderPlatform { webrtc::DtlsTransportState::kNew); return dummy; } - WebMediaStreamTrack Track() const override { return internal_->track(); } + MediaStreamComponent* Track() const override { return internal_->track(); } Vector<String> StreamIds() const override { return Vector<String>({String::FromUTF8("DummyStringId")}); } - void ReplaceTrack(WebMediaStreamTrack, RTCVoidRequest*) override {} + void ReplaceTrack(MediaStreamComponent*, RTCVoidRequest*) override {} std::unique_ptr<RtcDtmfSenderHandler> GetDtmfSender() const override { return nullptr; } @@ -98,14 +99,15 @@ class DummyRTCRtpReceiverPlatform : public RTCRtpReceiverPlatform { public: explicit DummyRTCRtpReceiverPlatform(WebMediaStreamSource::Type type) - : id_(++last_id_), track_() { + : id_(++last_id_) { if (type == WebMediaStreamSource::Type::kTypeAudio) { WebMediaStreamSource web_source; web_source.Initialize(WebString::FromUTF8("remoteAudioId"), WebMediaStreamSource::Type::kTypeAudio, WebString::FromUTF8("remoteAudioName"), true /* remote */); - track_.Initialize(web_source.Id(), web_source); + component_ = MakeGarbageCollected<MediaStreamComponent>(web_source.Id(), + web_source); } else { DCHECK_EQ(type, WebMediaStreamSource::Type::kTypeVideo); WebMediaStreamSource web_source; @@ -113,12 +115,13 @@ class DummyRTCRtpReceiverPlatform : public RTCRtpReceiverPlatform { WebMediaStreamSource::Type::kTypeVideo, WebString::FromUTF8("remoteVideoName"), true /* remote */); - track_.Initialize(web_source.Id(), web_source); + component_ = MakeGarbageCollected<MediaStreamComponent>(web_source.Id(), + web_source); } } DummyRTCRtpReceiverPlatform(const DummyRTCRtpReceiverPlatform& other) - : id_(other.id_), track_(other.track_) {} - ~DummyRTCRtpReceiverPlatform() override {} + : id_(other.id_), component_(other.component_) {} + ~DummyRTCRtpReceiverPlatform() override = default; std::unique_ptr<RTCRtpReceiverPlatform> ShallowCopy() const override { return nullptr; @@ -132,7 +135,7 @@ class DummyRTCRtpReceiverPlatform : public RTCRtpReceiverPlatform { webrtc::DtlsTransportState::kNew); return dummy; } - const WebMediaStreamTrack& Track() const override { return track_; } + MediaStreamComponent* Track() const override { return component_; } Vector<String> StreamIds() const override { return Vector<String>(); } Vector<std::unique_ptr<RTCRtpSource>> GetSources() override { return Vector<std::unique_ptr<RTCRtpSource>>(); @@ -148,7 +151,7 @@ class DummyRTCRtpReceiverPlatform : public RTCRtpReceiverPlatform { private: const uintptr_t id_; - WebMediaStreamTrack track_; + Persistent<MediaStreamComponent> component_; }; uintptr_t DummyRTCRtpReceiverPlatform::last_id_ = 0; @@ -167,8 +170,9 @@ class DummyTransceiverInternal sender_(std::move(sender_track)), receiver_(type), direction_(webrtc::RtpTransceiverDirection::kSendRecv) { - DCHECK(sender_.Track().IsNull() || - sender_.Track().Source().GetType() == type); + DCHECK(!sender_.Track() || + sender_.Track()->Source()->GetType() == + static_cast<MediaStreamSource::StreamType>(type)); } uintptr_t id() const { return id_; } 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 index 3e7a15c8ad2..4e589e73f03 100644 --- 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 @@ -115,10 +115,8 @@ PeerConnectionDependencyFactory::PeerConnectionDependencyFactory( : network_manager_(nullptr), p2p_socket_dispatcher_( create_p2p_socket_dispatcher ? new P2PSocketDispatcher() : nullptr), - signaling_thread_(nullptr), - worker_thread_(nullptr), chrome_signaling_thread_("WebRTC_Signaling"), - chrome_worker_thread_("WebRTC_Worker") { + chrome_network_thread_("WebRTC_Network") { TryScheduleStunProbeTrial(); } @@ -166,11 +164,11 @@ void PeerConnectionDependencyFactory::WillDestroyCurrentMessageLoop() { void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() { DCHECK(!pc_factory_.get()); DCHECK(!signaling_thread_); - DCHECK(!worker_thread_); + DCHECK(!network_thread_); DCHECK(!network_manager_); DCHECK(!socket_factory_); DCHECK(!chrome_signaling_thread_.IsRunning()); - DCHECK(!chrome_worker_thread_.IsRunning()); + DCHECK(!chrome_network_thread_.IsRunning()); DVLOG(1) << "PeerConnectionDependencyFactory::CreatePeerConnectionFactory()"; @@ -192,18 +190,15 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() { EnsureWebRtcAudioDeviceImpl(); - CHECK(chrome_signaling_thread_.Start()); - CHECK(chrome_worker_thread_.Start()); + // Init SSL, which will be needed by PeerConnection. + if (!rtc::InitializeSSL()) { + LOG(ERROR) << "Failed on InitializeSSL."; + NOTREACHED(); + return; + } - base::WaitableEvent start_worker_event( - base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - PostCrossThreadTask( - *chrome_worker_thread_.task_runner().get(), FROM_HERE, - CrossThreadBindOnce( - &PeerConnectionDependencyFactory::InitializeWorkerThread, - CrossThreadUnretained(this), CrossThreadUnretained(&worker_thread_), - CrossThreadUnretained(&start_worker_event))); + CHECK(chrome_signaling_thread_.Start()); + CHECK(chrome_network_thread_.Start()); base::WaitableEvent create_network_manager_event( base::WaitableEvent::ResetPolicy::MANUAL, @@ -218,24 +213,16 @@ void PeerConnectionDependencyFactory::CreatePeerConnectionFactory() { } #endif // BUILDFLAG(ENABLE_MDNS) PostCrossThreadTask( - *chrome_worker_thread_.task_runner().get(), FROM_HERE, + *chrome_network_thread_.task_runner().get(), FROM_HERE, CrossThreadBindOnce(&PeerConnectionDependencyFactory:: - CreateIpcNetworkManagerOnWorkerThread, + CreateIpcNetworkManagerOnNetworkThread, CrossThreadUnretained(this), CrossThreadUnretained(&create_network_manager_event), - std::move(mdns_responder))); + std::move(mdns_responder), + CrossThreadUnretained(&network_thread_))); - 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; - } + CHECK(network_thread_); base::WaitableEvent start_signaling_event( base::WaitableEvent::ResetPolicy::MANUAL, @@ -256,7 +243,7 @@ void PeerConnectionDependencyFactory::InitializeSignalingThread( media::GpuVideoAcceleratorFactories* gpu_factories, base::WaitableEvent* event) { DCHECK(chrome_signaling_thread_.task_runner()->BelongsToCurrentThread()); - DCHECK(worker_thread_); + DCHECK(network_thread_); DCHECK(p2p_socket_dispatcher_.get()); jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); @@ -323,9 +310,9 @@ void PeerConnectionDependencyFactory::InitializeSignalingThread( } webrtc::PeerConnectionFactoryDependencies pcf_deps; - pcf_deps.worker_thread = worker_thread_; - pcf_deps.network_thread = worker_thread_; + pcf_deps.worker_thread = signaling_thread_; pcf_deps.signaling_thread = signaling_thread_; + pcf_deps.network_thread = network_thread_; pcf_deps.task_queue_factory = CreateWebRtcTaskQueueFactory(); pcf_deps.call_factory = webrtc::CreateCallFactory(); pcf_deps.event_log_factory = std::make_unique<webrtc::RtcEventLogFactory>( @@ -494,12 +481,12 @@ scoped_refptr<webrtc::VideoTrackSourceInterface> PeerConnectionDependencyFactory::CreateVideoTrackSourceProxy( webrtc::VideoTrackSourceInterface* source) { // PeerConnectionFactory needs to be instantiated to make sure that - // signaling_thread_ and worker_thread_ exist. + // signaling_thread_ and network_thread_ exist. if (!PeerConnectionFactoryCreated()) CreatePeerConnectionFactory(); return webrtc::VideoTrackSourceProxy::Create(signaling_thread_, - worker_thread_, source) + network_thread_, source) .get(); } @@ -533,15 +520,6 @@ PeerConnectionDependencyFactory::GetWebRtcAudioDevice() { 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<WebString> params = Platform::Current()->WebRtcStunProbeTrialParameter(); @@ -551,34 +529,41 @@ void PeerConnectionDependencyFactory::TryScheduleStunProbeTrial() { GetPcFactory(); PostDelayedCrossThreadTask( - *chrome_worker_thread_.task_runner().get(), FROM_HERE, + *chrome_network_thread_.task_runner().get(), FROM_HERE, CrossThreadBindOnce( - &PeerConnectionDependencyFactory::StartStunProbeTrialOnWorkerThread, + &PeerConnectionDependencyFactory::StartStunProbeTrialOnNetworkThread, CrossThreadUnretained(this), String(*params)), base::TimeDelta::FromMilliseconds(blink::kExperimentStartDelayMs)); } -void PeerConnectionDependencyFactory::StartStunProbeTrialOnWorkerThread( +void PeerConnectionDependencyFactory::StartStunProbeTrialOnNetworkThread( const String& params) { DCHECK(network_manager_); - DCHECK(chrome_worker_thread_.task_runner()->BelongsToCurrentThread()); + DCHECK(chrome_network_thread_.task_runner()->BelongsToCurrentThread()); // TODO(crbug.com/787254): Remove the UTF8 conversion when StunProberTrial // operates over WTF::String. stun_trial_.reset(new StunProberTrial(network_manager_.get(), params.Utf8(), socket_factory_.get())); } -void PeerConnectionDependencyFactory::CreateIpcNetworkManagerOnWorkerThread( +void PeerConnectionDependencyFactory::CreateIpcNetworkManagerOnNetworkThread( base::WaitableEvent* event, - std::unique_ptr<MdnsResponderAdapter> mdns_responder) { - DCHECK(chrome_worker_thread_.task_runner()->BelongsToCurrentThread()); + std::unique_ptr<MdnsResponderAdapter> mdns_responder, + rtc::Thread** thread) { + DCHECK(chrome_network_thread_.task_runner()->BelongsToCurrentThread()); + + jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); + jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); + *thread = jingle_glue::JingleThreadWrapper::current(); + 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()); + DCHECK(chrome_network_thread_.task_runner()->BelongsToCurrentThread()); network_manager_.reset(); } @@ -588,16 +573,17 @@ void PeerConnectionDependencyFactory::CleanupPeerConnectionFactory() { 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()) { + if (chrome_network_thread_.IsRunning()) { PostCrossThreadTask( - *chrome_worker_thread_.task_runner().get(), FROM_HERE, + *chrome_network_thread_.task_runner().get(), FROM_HERE, CrossThreadBindOnce( &PeerConnectionDependencyFactory::DeleteIpcNetworkManager, CrossThreadUnretained(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(); + chrome_network_thread_.Stop(); + DCHECK(!network_manager_); } else { NOTREACHED() << "Worker thread not running."; } @@ -610,10 +596,11 @@ void PeerConnectionDependencyFactory::EnsureInitialized() { } scoped_refptr<base::SingleThreadTaskRunner> -PeerConnectionDependencyFactory::GetWebRtcWorkerTaskRunner() { +PeerConnectionDependencyFactory::GetWebRtcNetworkTaskRunner() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - return chrome_worker_thread_.IsRunning() ? chrome_worker_thread_.task_runner() - : nullptr; + return chrome_network_thread_.IsRunning() + ? chrome_network_thread_.task_runner() + : nullptr; } scoped_refptr<base::SingleThreadTaskRunner> diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h index 9984fa118ca..3029b4a2bc6 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h @@ -115,7 +115,7 @@ class MODULES_EXPORT PeerConnectionDependencyFactory // Returns the SingleThreadTaskRunner suitable for running WebRTC networking. // An rtc::Thread will have already been created. - scoped_refptr<base::SingleThreadTaskRunner> GetWebRtcWorkerTaskRunner(); + scoped_refptr<base::SingleThreadTaskRunner> GetWebRtcNetworkTaskRunner(); virtual scoped_refptr<base::SingleThreadTaskRunner> GetWebRtcSignalingTaskRunner(); @@ -139,7 +139,7 @@ class MODULES_EXPORT PeerConnectionDependencyFactory // Functions related to Stun probing trial to determine how fast we could send // Stun request without being dropped by NAT. void TryScheduleStunProbeTrial(); - void StartStunProbeTrialOnWorkerThread(const String& params); + void StartStunProbeTrialOnNetworkThread(const String& params); // Creates |pc_factory_|, which in turn is used for // creating PeerConnection objects. @@ -149,11 +149,10 @@ class MODULES_EXPORT PeerConnectionDependencyFactory media::GpuVideoAcceleratorFactories* gpu_factories, base::WaitableEvent* event); - void InitializeWorkerThread(rtc::Thread** thread, base::WaitableEvent* event); - - void CreateIpcNetworkManagerOnWorkerThread( + void CreateIpcNetworkManagerOnNetworkThread( base::WaitableEvent* event, - std::unique_ptr<MdnsResponderAdapter> mdns_responder); + std::unique_ptr<MdnsResponderAdapter> mdns_responder, + rtc::Thread** thread); void DeleteIpcNetworkManager(); void CleanupPeerConnectionFactory(); @@ -173,10 +172,10 @@ class MODULES_EXPORT PeerConnectionDependencyFactory // PeerConnection threads. signaling_thread_ is created from the // "current" chrome thread. - rtc::Thread* signaling_thread_; - rtc::Thread* worker_thread_; + rtc::Thread* signaling_thread_ = nullptr; + rtc::Thread* network_thread_ = nullptr; base::Thread chrome_signaling_thread_; - base::Thread chrome_worker_thread_; + base::Thread chrome_network_thread_; THREAD_CHECKER(thread_checker_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc index da8d1e0c9d8..9ac93f4ac71 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.cc @@ -12,7 +12,9 @@ #include <utility> #include <vector> +#include "base/power_monitor/power_observer.h" #include "base/values.h" +#include "third_party/blink/public/common/peerconnection/peer_connection_tracker_mojom_traits.h" #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_media_stream.h" @@ -24,6 +26,7 @@ #include "third_party/blink/renderer/modules/mediastream/user_media_request.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h" #include "third_party/blink/renderer/platform/mediastream/media_constraints.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h" @@ -162,11 +165,11 @@ String SerializeSender(const String& indent, // track:'id', result.Append(indent); result.Append(" track:"); - if (sender.Track().IsNull()) { + if (!sender.Track()) { result.Append("null"); } else { result.Append("'"); - result.Append(String(sender.Track().Source().Id())); + result.Append(sender.Track()->Source()->Id()); result.Append("'"); } result.Append(",\n"); @@ -185,10 +188,10 @@ String SerializeReceiver(const String& indent, StringBuilder result; result.Append("{\n"); // track:'id', - DCHECK(!receiver.Track().IsNull()); + DCHECK(receiver.Track()); result.Append(indent); result.Append(" track:'"); - result.Append(String(receiver.Track().Source().Id())); + result.Append(receiver.Track()->Source()->Id()); result.Append("',\n"); // streams:['id,'id'], result.Append(indent); @@ -705,6 +708,17 @@ void PeerConnectionTracker::OnSuspend() { } } +void PeerConnectionTracker::OnThermalStateChange( + mojom::blink::DeviceThermalState thermal_state) { + DCHECK_CALLED_ON_VALID_THREAD(main_thread_); + mojo::EnumTraits<mojom::blink::DeviceThermalState, + base::PowerObserver::DeviceThermalState>:: + FromMojom(thermal_state, ¤t_thermal_state_); + for (auto& entry : peer_connection_local_id_map_) { + entry.key->OnThermalStateChange(current_thermal_state_); + } +} + void PeerConnectionTracker::StartEventLog(int peer_connection_local_id, int output_period_ms) { DCHECK_CALLED_ON_VALID_THREAD(main_thread_); @@ -778,6 +792,11 @@ void PeerConnectionTracker::RegisterPeerConnection( peer_connection_tracker_host_->AddPeerConnection(std::move(info)); peer_connection_local_id_map_.insert(pc_handler, lid); + + if (current_thermal_state_ != + base::PowerObserver::DeviceThermalState::kUnknown) { + pc_handler->OnThermalStateChange(current_thermal_state_); + } } void PeerConnectionTracker::UnregisterPeerConnection( diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h index 069e01c1e41..7000bc48ea4 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h @@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/power_monitor/power_observer.h" #include "base/threading/thread_checker.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -225,6 +226,9 @@ class MODULES_EXPORT PeerConnectionTracker FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, CreatingObject); FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnSuspend); + FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, OnThermalStateChange); + FRIEND_TEST_ALL_PREFIXES(PeerConnectionTrackerTest, + ReportInitialThermalState); explicit PeerConnectionTracker( scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner); @@ -249,6 +253,8 @@ class MODULES_EXPORT PeerConnectionTracker // PeerConnectionTracker implementation. void OnSuspend() override; + void OnThermalStateChange( + mojom::blink::DeviceThermalState thermal_state) override; void StartEventLog(int peer_connection_local_id, int output_period_ms) override; void StopEventLog(int peer_connection_local_id) override; @@ -276,6 +282,8 @@ class MODULES_EXPORT PeerConnectionTracker // This map stores the local ID assigned to each RTCPeerConnectionHandler. typedef WTF::HashMap<RTCPeerConnectionHandler*, int> PeerConnectionLocalIdMap; PeerConnectionLocalIdMap peer_connection_local_id_map_; + base::PowerObserver::DeviceThermalState current_thermal_state_ = + base::PowerObserver::DeviceThermalState::kUnknown; // This keeps track of the next available local ID. int next_local_id_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc index af78a085136..6991518346c 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/peer_connection_tracker_test.cc @@ -127,6 +127,8 @@ class MockPeerConnectionHandler : public RTCPeerConnectionHandler { /*force_encoded_audio_insertable_streams=*/false, /*force_encoded_video_insertable_streams=*/false) {} MOCK_METHOD0(CloseClientPeerConnection, void()); + MOCK_METHOD1(OnThermalStateChange, + void(base::PowerObserver::DeviceThermalState)); private: blink::MockPeerConnectionDependencyFactory dependency_factory_; @@ -189,6 +191,89 @@ TEST_F(PeerConnectionTrackerTest, OnSuspend) { tracker_->OnSuspend(); } +TEST_F(PeerConnectionTrackerTest, OnThermalStateChange) { + CreateTrackerWithMocks(); + CreateAndRegisterPeerConnectionHandler(); + + EXPECT_CALL( + *mock_handler_, + OnThermalStateChange(base::PowerObserver::DeviceThermalState::kUnknown)) + .Times(1); + tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kUnknown); + + EXPECT_CALL( + *mock_handler_, + OnThermalStateChange(base::PowerObserver::DeviceThermalState::kNominal)) + .Times(1); + tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kNominal); + + EXPECT_CALL( + *mock_handler_, + OnThermalStateChange(base::PowerObserver::DeviceThermalState::kFair)) + .Times(1); + tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kFair); + + EXPECT_CALL( + *mock_handler_, + OnThermalStateChange(base::PowerObserver::DeviceThermalState::kSerious)) + .Times(1); + tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kSerious); + + EXPECT_CALL( + *mock_handler_, + OnThermalStateChange(base::PowerObserver::DeviceThermalState::kCritical)) + .Times(1); + tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kCritical); +} + +TEST_F(PeerConnectionTrackerTest, ReportInitialThermalState) { + MockPeerConnectionHandler handler0; + MockPeerConnectionHandler handler1; + MockPeerConnectionHandler handler2; + CreateTrackerWithMocks(); + + // Nothing is reported by default. + EXPECT_CALL(handler0, OnThermalStateChange(_)).Times(0); + EXPECT_CALL(*mock_host_, AddPeerConnection(_)).Times(1); + tracker_->RegisterPeerConnection( + &handler0, webrtc::PeerConnectionInterface::RTCConfiguration(), + MediaConstraints(), nullptr); + base::RunLoop().RunUntilIdle(); + + // Report a known thermal state. + EXPECT_CALL(handler0, OnThermalStateChange( + base::PowerObserver::DeviceThermalState::kNominal)) + .Times(1); + tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kNominal); + + // Handlers registered late will get the event upon registering. + EXPECT_CALL(handler1, OnThermalStateChange( + base::PowerObserver::DeviceThermalState::kNominal)) + .Times(1); + EXPECT_CALL(*mock_host_, AddPeerConnection(_)).Times(1); + tracker_->RegisterPeerConnection( + &handler1, webrtc::PeerConnectionInterface::RTCConfiguration(), + MediaConstraints(), nullptr); + base::RunLoop().RunUntilIdle(); + + // Report the unknown thermal state. + EXPECT_CALL(handler0, OnThermalStateChange( + base::PowerObserver::DeviceThermalState::kUnknown)) + .Times(1); + EXPECT_CALL(handler1, OnThermalStateChange( + base::PowerObserver::DeviceThermalState::kUnknown)) + .Times(1); + tracker_->OnThermalStateChange(blink::mojom::DeviceThermalState::kUnknown); + + // Handlers registered late get no event. + EXPECT_CALL(handler2, OnThermalStateChange(_)).Times(0); + EXPECT_CALL(*mock_host_, AddPeerConnection(_)).Times(1); + tracker_->RegisterPeerConnection( + &handler2, webrtc::PeerConnectionInterface::RTCConfiguration(), + MediaConstraints(), nullptr); + base::RunLoop().RunUntilIdle(); +} + TEST_F(PeerConnectionTrackerTest, AddTransceiverWithOptionalValuesPresent) { CreateTrackerWithMocks(); CreateAndRegisterPeerConnectionHandler(); 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 index 60a6ff42529..77c2a8c053b 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc @@ -94,7 +94,7 @@ void GenerateCertificateWithOptionalExpiration( scoped_refptr<RTCCertificateGeneratorRequest> request = base::MakeRefCounted<RTCCertificateGeneratorRequest>( - task_runner, pc_dependency_factory->GetWebRtcWorkerTaskRunner()); + task_runner, pc_dependency_factory->GetWebRtcNetworkTaskRunner()); request->GenerateCertificateAsync(key_params, expires_ms, std::move(completion_callback)); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc index 83dae0b5ebb..b74fa162ae0 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc @@ -36,6 +36,7 @@ #include "third_party/blink/renderer/core/fileapi/blob.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h" +#include "third_party/blink/renderer/modules/peerconnection/adapters/web_rtc_cross_thread_copier.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_error_event.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h" @@ -45,6 +46,17 @@ #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" +namespace WTF { + +template <> +struct CrossThreadCopier<scoped_refptr<webrtc::DataChannelInterface>> + : public CrossThreadCopierPassThrough< + scoped_refptr<webrtc::DataChannelInterface>> { + STATIC_ONLY(CrossThreadCopier); +}; + +} // namespace WTF + namespace blink { namespace { @@ -110,6 +122,12 @@ void RecordMessageSent(const webrtc::DataChannelInterface& channel, } } +void SendOnSignalingThread( + const scoped_refptr<webrtc::DataChannelInterface> channel, + const webrtc::DataBuffer data_buffer) { + channel->Send(data_buffer); +} + } // namespace static void ThrowNotOpenException(ExceptionState* exception_state) { @@ -223,10 +241,12 @@ RTCDataChannel::RTCDataChannel( buffered_amount_(0U), stopped_(false), closed_from_owner_(false), + is_rtp_data_channel_(peer_connection_handler->enable_rtp_data_channel()), observer_(base::MakeRefCounted<Observer>( context->GetTaskRunner(TaskType::kNetworking), this, - channel)) { + channel)), + signaling_thread_(peer_connection_handler->signaling_thread()) { DCHECK(peer_connection_handler); // Register observer and get state update to make up for state change updates @@ -364,9 +384,7 @@ void RTCDataChannel::send(const String& data, ExceptionState& exception_state) { } buffered_amount_ += data_buffer.size(); RecordMessageSent(*channel().get(), data_buffer.size()); - if (!channel()->Send(data_buffer)) { - // TODO(https://crbug.com/937848): Don't throw an exception if data is - // queued. + if (!SendDataBuffer(std::move(data_buffer))) { ThrowCouldNotSendDataException(&exception_state); } } @@ -482,7 +500,7 @@ bool RTCDataChannel::HasPendingActivity() const { bufferedAmount() > 0; } -void RTCDataChannel::Trace(Visitor* visitor) { +void RTCDataChannel::Trace(Visitor* visitor) const { visitor->Trace(scheduled_events_); EventTargetWithInlineData::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); @@ -613,7 +631,20 @@ bool RTCDataChannel::SendRawData(const char* data, size_t length) { rtc::CopyOnWriteBuffer buffer(data, length); webrtc::DataBuffer data_buffer(buffer, true); RecordMessageSent(*channel().get(), data_buffer.size()); - return channel()->Send(data_buffer); + return SendDataBuffer(std::move(data_buffer)); +} + +bool RTCDataChannel::SendDataBuffer(webrtc::DataBuffer data_buffer) { + // RTP data channels return false on failure to send. SCTP data channels + // queue the packet on failure and always return true, so Send can be + // called asynchronously for them. + if (is_rtp_data_channel_) { + return channel()->Send(data_buffer); + } + PostCrossThreadTask(*signaling_thread_.get(), FROM_HERE, + CrossThreadBindOnce(&SendOnSignalingThread, channel(), + std::move(data_buffer))); + return true; } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h index 288d87c3d5d..7288c6f20de 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h @@ -110,7 +110,7 @@ class MODULES_EXPORT RTCDataChannel final // ScriptWrappable bool HasPendingActivity() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class Observer; @@ -165,6 +165,7 @@ class MODULES_EXPORT RTCDataChannel final const scoped_refptr<webrtc::DataChannelInterface>& channel() const; bool SendRawData(const char* data, size_t length); + bool SendDataBuffer(webrtc::DataBuffer data_buffer); webrtc::DataChannelInterface::DataState state_; @@ -182,7 +183,9 @@ class MODULES_EXPORT RTCDataChannel final unsigned buffered_amount_; bool stopped_; bool closed_from_owner_; + bool is_rtp_data_channel_; scoped_refptr<Observer> observer_; + scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_; THREAD_CHECKER(thread_checker_); }; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc index 54df93f03ed..02774485435 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.cc @@ -56,7 +56,7 @@ const AtomicString& RTCDataChannelEvent::InterfaceName() const { return event_interface_names::kRTCDataChannelEvent; } -void RTCDataChannelEvent::Trace(Visitor* visitor) { +void RTCDataChannelEvent::Trace(Visitor* visitor) const { visitor->Trace(channel_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h index 78e649a63f0..6ef1fcb5028 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h @@ -50,7 +50,7 @@ class RTCDataChannelEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<RTCDataChannel> channel_; 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 a701b2aef55..62fea13d595 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 @@ -51,6 +51,11 @@ class MockPeerConnectionHandler : public MockRTCPeerConnectionHandlerPlatform { scoped_refptr<base::TestSimpleTaskRunner> signaling_thread) : signaling_thread_(signaling_thread) {} + scoped_refptr<base::SingleThreadTaskRunner> signaling_thread() + const override { + return signaling_thread_; + } + void RunSynchronousOnceClosureOnSignalingThread( CrossThreadOnceClosure closure, const char* trace_event_name) override { @@ -253,6 +258,9 @@ TEST_F(RTCDataChannelTest, BufferedAmount) { String message(std::string(100, 'A').c_str()); channel->send(message, IGNORE_EXCEPTION_FOR_TESTING); EXPECT_EQ(100U, channel->bufferedAmount()); + // The actual send operation is posted to the signaling thread; wait for it + // to run to avoid a memory leak. + signaling_thread()->RunUntilIdle(); } TEST_F(RTCDataChannelTest, BufferedAmountLow) { @@ -272,6 +280,9 @@ TEST_F(RTCDataChannelTest, BufferedAmountLow) { ASSERT_EQ(1U, channel->scheduled_events_.size()); EXPECT_EQ("bufferedamountlow", channel->scheduled_events_.back()->type().Utf8()); + // The actual send operation is posted to the signaling thread; wait for it + // to run to avoid a memory leak. + signaling_thread()->RunUntilIdle(); } TEST_F(RTCDataChannelTest, Open) { diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc index db9377f349e..2764b87bb6a 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.cc @@ -53,7 +53,7 @@ std::unique_ptr<DtlsTransportProxy> CreateProxy( frame->GetTaskRunner(TaskType::kNetworking); scoped_refptr<base::SingleThreadTaskRunner> host_thread = PeerConnectionDependencyFactory::GetInstance() - ->GetWebRtcWorkerTaskRunner(); + ->GetWebRtcNetworkTaskRunner(); return DtlsTransportProxy::Create(*frame, proxy_thread, host_thread, native_transport, delegate); @@ -177,7 +177,7 @@ ExecutionContext* RTCDtlsTransport::GetExecutionContext() const { return ExecutionContextClient::GetExecutionContext(); } -void RTCDtlsTransport::Trace(Visitor* visitor) { +void RTCDtlsTransport::Trace(Visitor* visitor) const { visitor->Trace(remote_certificates_); visitor->Trace(ice_transport_); DtlsTransportProxy::Delegate::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h index 36a5ff14885..ac20996ca47 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h @@ -60,7 +60,7 @@ class MODULES_EXPORT RTCDtlsTransport final const AtomicString& InterfaceName() const override; ExecutionContext* GetExecutionContext() const override; // For garbage collection. - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // Others void ChangeState(webrtc::DtlsTransportInformation info); webrtc::DtlsTransportInterface* native_transport(); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc index fd3da661668..00b19b20ba3 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.cc @@ -182,7 +182,7 @@ void RTCDTMFSender::ContextDestroyed() { handler_->SetClient(nullptr); } -void RTCDTMFSender::Trace(Visitor* visitor) { +void RTCDTMFSender::Trace(Visitor* visitor) const { EventTargetWithInlineData::Trace(visitor); RtcDtmfSenderHandler::Client::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h index c100eb4c154..2212bc7dce7 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h @@ -70,7 +70,7 @@ class RTCDTMFSender final : public EventTargetWithInlineData, // ExecutionContextLifecycleObserver void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void Dispose(); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc index e0ef02556e9..0edbe837e9c 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.cc @@ -60,7 +60,7 @@ const AtomicString& RTCDTMFToneChangeEvent::InterfaceName() const { return event_interface_names::kRTCDTMFToneChangeEvent; } -void RTCDTMFToneChangeEvent::Trace(Visitor* visitor) { +void RTCDTMFToneChangeEvent::Trace(Visitor* visitor) const { Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h index 88dcddac178..c57e8c8f859 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.h @@ -49,7 +49,7 @@ class RTCDTMFToneChangeEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: String tone_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc index 287b4f08951..698a8155b2a 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.cc @@ -101,7 +101,7 @@ RTCEncodedAudioFrame::PassWebRtcFrame() { return delegate_->PassWebRtcFrame(); } -void RTCEncodedAudioFrame::Trace(Visitor* visitor) { +void RTCEncodedAudioFrame::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); visitor->Trace(frame_data_); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h index fc7e6799b80..45ee51111c3 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.h @@ -52,7 +52,7 @@ class MODULES_EXPORT RTCEncodedAudioFrame final : public ScriptWrappable { // backed by that internal WebRTC frame. std::unique_ptr<webrtc::TransformableFrameInterface> PassWebRtcFrame(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: scoped_refptr<RTCEncodedAudioFrameDelegate> delegate_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc index 81441387008..1e5feaf5a26 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.cc @@ -81,7 +81,7 @@ ScriptPromise RTCEncodedAudioUnderlyingSink::abort( return close(script_state, exception_state); } -void RTCEncodedAudioUnderlyingSink::Trace(Visitor* visitor) { +void RTCEncodedAudioUnderlyingSink::Trace(Visitor* visitor) const { UnderlyingSinkBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h index 152606c43f3..7f7cae2d87c 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_sink.h @@ -33,7 +33,7 @@ class MODULES_EXPORT RTCEncodedAudioUnderlyingSink final ScriptValue reason, ExceptionState&) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: TransformerCallback transformer_callback_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc index 91addd31f78..c6f30c34756 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.cc @@ -45,7 +45,7 @@ ScriptPromise RTCEncodedAudioUnderlyingSource::Cancel(ScriptState* script_state, return ScriptPromise::CastUndefined(script_state); } -void RTCEncodedAudioUnderlyingSource::Trace(Visitor* visitor) { +void RTCEncodedAudioUnderlyingSource::Trace(Visitor* visitor) const { visitor->Trace(script_state_); UnderlyingSourceBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.h index 7ee6684a9eb..586002e9efb 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_underlying_source.h @@ -30,7 +30,7 @@ class MODULES_EXPORT RTCEncodedAudioUnderlyingSource void OnFrameFromSource(std::unique_ptr<webrtc::TransformableFrameInterface>); void Close(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: FRIEND_TEST_ALL_PREFIXES(RTCEncodedAudioUnderlyingSourceTest, diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc index 770b0be26fc..67f8130ad73 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.cc @@ -41,13 +41,27 @@ RTCEncodedVideoFrameMetadata* RTCEncodedVideoFrame::getMetadata() const { RTCEncodedVideoFrameMetadata* metadata = RTCEncodedVideoFrameMetadata::Create(); metadata->setSynchronizationSource(delegate_->Ssrc()); + const auto* webrtc_metadata = delegate_->GetMetadata(); + if (!webrtc_metadata) + return metadata; + + if (webrtc_metadata->GetFrameId()) + metadata->setFrameId(*webrtc_metadata->GetFrameId()); + + Vector<int64_t> dependencies; + for (const auto& dependency : webrtc_metadata->GetFrameDependencies()) + dependencies.push_back(dependency); + metadata->setDependencies(dependencies); + metadata->setWidth(webrtc_metadata->GetWidth()); + metadata->setHeight(webrtc_metadata->GetHeight()); + metadata->setSpatialIndex(webrtc_metadata->GetSpatialIndex()); + metadata->setTemporalIndex(webrtc_metadata->GetTemporalIndex()); return metadata; } DOMArrayBuffer* RTCEncodedVideoFrame::additionalData() const { if (!additional_data_) additional_data_ = delegate_->CreateAdditionalDataBuffer(); - return additional_data_; } @@ -90,7 +104,7 @@ RTCEncodedVideoFrame::PassWebRtcFrame() { return delegate_->PassWebRtcFrame(); } -void RTCEncodedVideoFrame::Trace(Visitor* visitor) { +void RTCEncodedVideoFrame::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); visitor->Trace(frame_data_); visitor->Trace(additional_data_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h index 08925a46adf..c1d35847d0b 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.h @@ -51,7 +51,7 @@ class MODULES_EXPORT RTCEncodedVideoFrame final : public ScriptWrappable { // backed by that internal WebRTC frame. std::unique_ptr<webrtc::TransformableVideoFrameInterface> PassWebRtcFrame(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: const scoped_refptr<RTCEncodedVideoFrameDelegate> delegate_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc index 6d2de5b2b77..db839f8d3e1 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.cc @@ -80,6 +80,12 @@ uint32_t RTCEncodedVideoFrameDelegate::Ssrc() const { return webrtc_frame_ ? webrtc_frame_->GetSsrc() : 0; } +const webrtc::VideoFrameMetadata* RTCEncodedVideoFrameDelegate::GetMetadata() + const { + MutexLocker lock(mutex_); + return webrtc_frame_ ? &webrtc_frame_->GetMetadata() : nullptr; +} + std::unique_ptr<webrtc::TransformableVideoFrameInterface> RTCEncodedVideoFrameDelegate::PassWebRtcFrame() { MutexLocker lock(mutex_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h index 5bc300b6e82..cd7cc64b28f 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_delegate.h @@ -15,6 +15,7 @@ #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" #include "third_party/blink/renderer/platform/wtf/threading_primitives.h" #include "third_party/webrtc/api/frame_transformer_interface.h" +#include "third_party/webrtc/api/video/video_frame_metadata.h" namespace blink { @@ -35,6 +36,7 @@ class RTCEncodedVideoFrameDelegate void SetData(const DOMArrayBuffer* data); DOMArrayBuffer* CreateAdditionalDataBuffer() const; uint32_t Ssrc() const; + const webrtc::VideoFrameMetadata* GetMetadata() const; std::unique_ptr<webrtc::TransformableVideoFrameInterface> PassWebRtcFrame(); private: diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl index 14cb60c0f33..e6618993021 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl @@ -7,12 +7,12 @@ [Serializable] dictionary RTCEncodedVideoFrameMetadata { - long long frame_id; + long long frameId; sequence<long long> dependencies; unsigned short width; unsigned short height; - long spatial_index; - long temporal_index; + long spatialIndex; + long temporalIndex; unsigned long synchronizationSource; sequence<unsigned long> contributingSources; }; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc index b4b7bd85aaf..c390ab72418 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.cc @@ -81,7 +81,7 @@ ScriptPromise RTCEncodedVideoUnderlyingSink::abort( return close(script_state, exception_state); } -void RTCEncodedVideoUnderlyingSink::Trace(Visitor* visitor) { +void RTCEncodedVideoUnderlyingSink::Trace(Visitor* visitor) const { UnderlyingSinkBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h index 74719373e4e..dd1cad227eb 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink.h @@ -33,7 +33,7 @@ class MODULES_EXPORT RTCEncodedVideoUnderlyingSink final ScriptValue reason, ExceptionState&) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: TransformerCallback transformer_callback_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc index 3a606d1e894..614d16e9a43 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_sink_test.cc @@ -20,9 +20,12 @@ #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" #include "third_party/webrtc/api/frame_transformer_interface.h" #include "third_party/webrtc/api/scoped_refptr.h" +#include "third_party/webrtc/api/test/mock_transformable_video_frame.h" #include "third_party/webrtc/rtc_base/ref_counted_object.h" using testing::_; +using testing::NiceMock; +using testing::Return; namespace blink { @@ -37,26 +40,6 @@ class MockWebRtcTransformedFrameCallback void(std::unique_ptr<webrtc::TransformableFrameInterface>)); }; -class FakeVideoFrame : public webrtc::TransformableVideoFrameInterface { - public: - explicit FakeVideoFrame(uint32_t ssrc) : ssrc_(ssrc) {} - - rtc::ArrayView<const uint8_t> GetData() const override { - return rtc::ArrayView<const uint8_t>(); - } - - void SetData(rtc::ArrayView<const uint8_t> data) override {} - uint32_t GetTimestamp() const override { return 0; } - uint32_t GetSsrc() const override { return ssrc_; } - bool IsKeyFrame() const override { return true; } - std::vector<uint8_t> GetAdditionalData() const override { - return std::vector<uint8_t>(); - } - - private: - uint32_t ssrc_; -}; - bool IsDOMException(ScriptState* script_state, ScriptValue value, DOMExceptionCode code) { @@ -109,8 +92,11 @@ class RTCEncodedVideoUnderlyingSinkTest : public testing::Test { RTCEncodedVideoStreamTransformer* GetTransformer() { return &transformer_; } ScriptValue CreateEncodedVideoFrameChunk(ScriptState* script_state) { - RTCEncodedVideoFrame* frame = MakeGarbageCollected<RTCEncodedVideoFrame>( - std::make_unique<FakeVideoFrame>(kSSRC)); + auto mock_frame = + std::make_unique<NiceMock<webrtc::MockTransformableVideoFrame>>(); + ON_CALL(*mock_frame.get(), GetSsrc).WillByDefault(Return(kSSRC)); + RTCEncodedVideoFrame* frame = + MakeGarbageCollected<RTCEncodedVideoFrame>(std::move(mock_frame)); return ScriptValue(script_state->GetIsolate(), ToV8(frame, script_state->GetContext()->Global(), script_state->GetIsolate())); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc index a459e4112b2..63f012e9acd 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.cc @@ -42,7 +42,7 @@ ScriptPromise RTCEncodedVideoUnderlyingSource::Cancel(ScriptState* script_state, return ScriptPromise::CastUndefined(script_state); } -void RTCEncodedVideoUnderlyingSource::Trace(Visitor* visitor) { +void RTCEncodedVideoUnderlyingSource::Trace(Visitor* visitor) const { visitor->Trace(script_state_); UnderlyingSourceBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.h index 8ceb0b8b492..d80efb7b518 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source.h @@ -30,7 +30,7 @@ class MODULES_EXPORT RTCEncodedVideoUnderlyingSource std::unique_ptr<webrtc::TransformableVideoFrameInterface>); void Close(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: FRIEND_TEST_ALL_PREFIXES(RTCEncodedVideoUnderlyingSourceTest, QueuedFramesAreDroppedWhenOverflow); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source_test.cc index 225207b3f52..664e7d42e9e 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_underlying_source_test.cc @@ -14,28 +14,10 @@ #include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/webrtc/api/frame_transformer_interface.h" +#include "third_party/webrtc/api/test/mock_transformable_video_frame.h" namespace blink { -namespace { -class FakeTransformableFrame : public webrtc::TransformableVideoFrameInterface { - public: - FakeTransformableFrame() = default; - ~FakeTransformableFrame() override = default; - - rtc::ArrayView<const uint8_t> GetData() const override { return nullptr; } - - void SetData(rtc::ArrayView<const uint8_t> data) override {} - - uint32_t GetTimestamp() const override { return 0; } - uint32_t GetSsrc() const override { return 0; } - bool IsKeyFrame() const override { return false; } - std::vector<uint8_t> GetAdditionalData() const override { - return std::vector<uint8_t>(); - } -}; -} // namespace - class RTCEncodedVideoUnderlyingSourceTest : public testing::Test { public: RTCEncodedVideoUnderlyingSource* CreateSource(ScriptState* script_state) { @@ -61,7 +43,8 @@ TEST_F(RTCEncodedVideoUnderlyingSourceTest, ScriptPromiseTester read_tester(script_state, reader->read(script_state, exception_state)); EXPECT_FALSE(read_tester.IsFulfilled()); - source->OnFrameFromSource(std::make_unique<FakeTransformableFrame>()); + source->OnFrameFromSource( + std::make_unique<webrtc::MockTransformableVideoFrame>()); read_tester.WaitUntilSettled(); EXPECT_TRUE(read_tester.IsFulfilled()); @@ -90,12 +73,14 @@ TEST_F(RTCEncodedVideoUnderlyingSourceTest, QueuedFramesAreDroppedWhenOverflow) for (int i = 0; i > RTCEncodedVideoUnderlyingSource::kMinQueueDesiredSize; --i) { EXPECT_EQ(source->Controller()->DesiredSize(), i); - source->OnFrameFromSource(std::make_unique<FakeTransformableFrame>()); + source->OnFrameFromSource( + std::make_unique<webrtc::MockTransformableVideoFrame>()); } EXPECT_EQ(source->Controller()->DesiredSize(), RTCEncodedVideoUnderlyingSource::kMinQueueDesiredSize); - source->OnFrameFromSource(std::make_unique<FakeTransformableFrame>()); + source->OnFrameFromSource( + std::make_unique<webrtc::MockTransformableVideoFrame>()); EXPECT_EQ(source->Controller()->DesiredSize(), RTCEncodedVideoUnderlyingSource::kMinQueueDesiredSize); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.cc index cf9127aabc6..e4b67447679 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error.cc @@ -8,6 +8,36 @@ namespace blink { +namespace { + +String RTCErrorDetailToString(webrtc::RTCErrorDetailType detail) { + switch (detail) { + case webrtc::RTCErrorDetailType::NONE: + // This should not happen, it indicates an error in webrtc + LOG(ERROR) << "RTCError: RTCErrorDetail is NONE"; + return ""; + case webrtc::RTCErrorDetailType::DATA_CHANNEL_FAILURE: + return "data-channel-failure"; + case webrtc::RTCErrorDetailType::DTLS_FAILURE: + return "dtls-failure"; + case webrtc::RTCErrorDetailType::FINGERPRINT_FAILURE: + return "fingerprint-failure"; + case webrtc::RTCErrorDetailType::SCTP_FAILURE: + return "sctp-failure"; + case webrtc::RTCErrorDetailType::SDP_SYNTAX_ERROR: + return "sdp-syntax-error"; + case webrtc::RTCErrorDetailType::HARDWARE_ENCODER_NOT_AVAILABLE: + return "hardware-encoder-not-available"; + case webrtc::RTCErrorDetailType::HARDWARE_ENCODER_ERROR: + return "hardware-encoder-error"; + default: + // Included to ease introduction of new errors at the webrtc layer. + NOTREACHED(); + return ""; + } +} +} // namespace + // static RTCError* RTCError::Create(const RTCErrorInit* init, String message) { return MakeGarbageCollected<RTCError>(init, std::move(message)); @@ -35,7 +65,7 @@ RTCError::RTCError(const RTCErrorInit* init, String message) RTCError::RTCError(webrtc::RTCError err) : DOMException(DOMExceptionCode::kOperationError, err.message()), - error_detail_(webrtc::ToString(err.error_detail())), + error_detail_(RTCErrorDetailToString(err.error_detail())), sctp_cause_code_(err.sctp_cause_code() ? base::Optional<int32_t>(*err.sctp_cause_code()) : base::nullopt) {} diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.cc index b9df9f5a853..5bb0eac2788 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.cc @@ -28,7 +28,7 @@ RTCError* RTCErrorEvent::error() const { return error_; } -void RTCErrorEvent::Trace(Visitor* visitor) { +void RTCErrorEvent::Trace(Visitor* visitor) const { visitor->Trace(error_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.h index 9c25d404fc8..70ba53021e5 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_error_event.h @@ -30,7 +30,7 @@ class RTCErrorEvent final : public Event { RTCError* error() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<RTCError> error_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc index 64c42691733..48c9a2f0fdd 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.cc @@ -49,7 +49,7 @@ RTCIceCandidate* RTCIceCandidate::Create( const RTCIceCandidateInit* candidate_init, ExceptionState& exception_state) { if (candidate_init->sdpMid().IsNull() && - !candidate_init->hasSdpMLineIndex()) { + !candidate_init->hasSdpMLineIndexNonNull()) { exception_state.ThrowTypeError("sdpMid and sdpMLineIndex are both null."); return nullptr; } @@ -57,8 +57,8 @@ RTCIceCandidate* RTCIceCandidate::Create( String sdp_mid = candidate_init->sdpMid(); base::Optional<uint16_t> sdp_m_line_index; - if (candidate_init->hasSdpMLineIndex()) { - sdp_m_line_index = candidate_init->sdpMLineIndex(); + if (candidate_init->hasSdpMLineIndexNonNull()) { + sdp_m_line_index = candidate_init->sdpMLineIndexNonNull(); } else { UseCounter::Count(context, WebFeature::kRTCIceCandidateDefaultSdpMLineIndex); @@ -94,7 +94,7 @@ RTCIceCandidatePlatform* RTCIceCandidate::PlatformCandidate() const { return platform_candidate_; } -void RTCIceCandidate::Trace(Visitor* visitor) { +void RTCIceCandidate::Trace(Visitor* visitor) const { visitor->Trace(platform_candidate_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h index ac5ce3fb344..c4e60a52b9c 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.h @@ -74,7 +74,7 @@ class MODULES_EXPORT RTCIceCandidate final : public ScriptWrappable { RTCIceCandidatePlatform* PlatformCandidate() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<RTCIceCandidatePlatform> platform_candidate_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.idl index e14ccf1f307..62cfdc2bc5a 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.idl +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.idl @@ -8,5 +8,5 @@ dictionary RTCIceCandidateInit { DOMString candidate = ""; DOMString? sdpMid = null; unsigned short? sdpMLineIndex = null; - DOMString usernameFragment; + DOMString? usernameFragment = null; }; 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 486ae5a9099..984e4d1e6b3 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 @@ -116,7 +116,7 @@ RTCIceTransport* RTCIceTransport::Create(ExecutionContext* context) { PeerConnectionDependencyFactory::GetInstance()->EnsureInitialized(); scoped_refptr<base::SingleThreadTaskRunner> host_thread = PeerConnectionDependencyFactory::GetInstance() - ->GetWebRtcWorkerTaskRunner(); + ->GetWebRtcNetworkTaskRunner(); return MakeGarbageCollected<RTCIceTransport>( context, std::move(proxy_thread), std::move(host_thread), std::make_unique<DefaultIceTransportAdapterCrossThreadFactory>()); @@ -132,7 +132,7 @@ RTCIceTransport* RTCIceTransport::Create( PeerConnectionDependencyFactory::GetInstance()->EnsureInitialized(); scoped_refptr<base::SingleThreadTaskRunner> host_thread = PeerConnectionDependencyFactory::GetInstance() - ->GetWebRtcWorkerTaskRunner(); + ->GetWebRtcNetworkTaskRunner(); return MakeGarbageCollected<RTCIceTransport>( context, std::move(proxy_thread), std::move(host_thread), std::make_unique<DtlsIceTransportAdapterCrossThreadFactory>( @@ -303,8 +303,12 @@ static webrtc::PeerConnectionInterface::IceServer ConvertIceServer( for (const String& url_string : url_strings) { converted_ice_server.urls.push_back(url_string.Utf8()); } - converted_ice_server.username = ice_server->username().Utf8(); - converted_ice_server.password = ice_server->credential().Utf8(); + if (ice_server->hasUsername()) { + converted_ice_server.username = ice_server->username().Utf8(); + } + if (ice_server->hasCredential()) { + converted_ice_server.password = ice_server->credential().Utf8(); + } return converted_ice_server; } @@ -580,7 +584,7 @@ bool RTCIceTransport::HasPendingActivity() const { return !!proxy_; } -void RTCIceTransport::Trace(Visitor* visitor) { +void RTCIceTransport::Trace(Visitor* visitor) const { visitor->Trace(local_candidates_); visitor->Trace(remote_candidates_); visitor->Trace(local_parameters_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h index ebd077282b8..6e011468425 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h @@ -152,7 +152,7 @@ class MODULES_EXPORT RTCIceTransport final bool HasPendingActivity() const final; // For garbage collection. - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: // IceTransportProxy::Delegate overrides. 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 2ec6259205e..1503444ac29 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 @@ -184,7 +184,7 @@ bool IsIceCandidateMissingSdp( const RTCIceCandidateInit* ice_candidate_init = candidate.GetAsRTCIceCandidateInit(); return ice_candidate_init->sdpMid().IsNull() && - !ice_candidate_init->hasSdpMLineIndex(); + !ice_candidate_init->hasSdpMLineIndexNonNull(); } DCHECK(candidate.IsRTCIceCandidate()); @@ -221,8 +221,8 @@ RTCIceCandidatePlatform* ConvertToRTCIceCandidatePlatform( candidate.GetAsRTCIceCandidateInit(); // TODO(guidou): Change default value to -1. crbug.com/614958. uint16_t sdp_m_line_index = 0; - if (ice_candidate_init->hasSdpMLineIndex()) { - sdp_m_line_index = ice_candidate_init->sdpMLineIndex(); + if (ice_candidate_init->hasSdpMLineIndexNonNull()) { + sdp_m_line_index = ice_candidate_init->sdpMLineIndexNonNull(); } else { UseCounter::Count(context, WebFeature::kRTCIceCandidateDefaultSdpMLineIndex); @@ -370,9 +370,6 @@ webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration( return {}; } - String username = ice_server->username(); - String credential = ice_server->credential(); - for (const String& url_string : url_strings) { KURL url(NullURL(), url_string); if (!url.IsValid()) { @@ -391,7 +388,7 @@ webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration( return {}; } if ((url.ProtocolIs("turn") || url.ProtocolIs("turns")) && - (username.IsNull() || credential.IsNull())) { + (!ice_server->hasUsername() || !ice_server->hasCredential())) { exception_state->ThrowDOMException( DOMExceptionCode::kInvalidAccessError, "Both username and credential are " @@ -402,8 +399,12 @@ webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration( auto converted_ice_server = webrtc::PeerConnectionInterface::IceServer(); converted_ice_server.urls.push_back(String(url).Utf8()); - converted_ice_server.username = username.Utf8(); - converted_ice_server.password = credential.Utf8(); + if (ice_server->hasUsername()) { + converted_ice_server.username = ice_server->username().Utf8(); + } + if (ice_server->hasCredential()) { + converted_ice_server.password = ice_server->credential().Utf8(); + } ice_servers.emplace_back(std::move(converted_ice_server)); } @@ -632,7 +633,7 @@ bool RTCPeerConnection::EventWrapper::Setup() { return true; } -void RTCPeerConnection::EventWrapper::Trace(Visitor* visitor) { +void RTCPeerConnection::EventWrapper::Trace(Visitor* visitor) const { visitor->Trace(event_); } @@ -749,8 +750,9 @@ RTCPeerConnection::RTCPeerConnection( peer_connection_state_( webrtc::PeerConnectionInterface::PeerConnectionState::kNew), negotiation_needed_(false), - stopped_(false), - closed_(false), + peer_handler_unregistered_(true), + closed_(true), + suppress_events_(true), has_data_channels_(false), sdp_semantics_(configuration.sdp_semantics), sdp_semantics_specified_(sdp_semantics_specified), @@ -769,8 +771,6 @@ RTCPeerConnection::RTCPeerConnection( // assert in the destructor. if (InstanceCounters::CounterValue( InstanceCounters::kRTCPeerConnectionCounter) > kMaxPeerConnections) { - closed_ = true; - stopped_ = true; exception_state.ThrowDOMException(DOMExceptionCode::kUnknownError, "Cannot create so many PeerConnections"); return; @@ -790,8 +790,6 @@ RTCPeerConnection::RTCPeerConnection( } if (!peer_handler_) { - closed_ = true; - stopped_ = true; exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, "No PeerConnection handler can be " "created, perhaps WebRTC is disabled?"); @@ -801,26 +799,33 @@ RTCPeerConnection::RTCPeerConnection( auto* web_frame = static_cast<WebLocalFrame*>(WebFrame::FromFrame(window->GetFrame())); if (!peer_handler_->Initialize(configuration, constraints, web_frame)) { - closed_ = true; - stopped_ = true; exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError, "Failed to initialize native PeerConnection."); return; } + // The RTCPeerConnection was successfully constructed. + closed_ = false; + peer_handler_unregistered_ = false; + suppress_events_ = false; feature_handle_for_scheduler_ = window->GetFrame()->GetFrameScheduler()->RegisterFeature( SchedulingPolicy::Feature::kWebRTC, - {SchedulingPolicy::DisableAggressiveThrottling(), - SchedulingPolicy::RecordMetricsForBackForwardCache()}); + base::FeatureList::IsEnabled(features::kOptOutWebRTCFromAllThrottling) + ? SchedulingPolicy{SchedulingPolicy::DisableAllThrottling(), + SchedulingPolicy:: + RecordMetricsForBackForwardCache()} + : SchedulingPolicy{ + SchedulingPolicy::DisableAggressiveThrottling(), + SchedulingPolicy::RecordMetricsForBackForwardCache()}); } RTCPeerConnection::~RTCPeerConnection() { // This checks that close() or stop() is called before the destructor. // We are assuming that a wrapper is always created when RTCPeerConnection is // created. - DCHECK(closed_ || stopped_); + DCHECK(closed_ || peer_handler_unregistered_); InstanceCounters::DecrementCounter( InstanceCounters::kRTCPeerConnectionCounter); DCHECK_GE(InstanceCounters::CounterValue( @@ -2302,7 +2307,7 @@ RTCRtpTransceiver* RTCPeerConnection::addTransceiver( } if (ThrowExceptionIfSignalingStateClosed(signaling_state_, &exception_state)) return nullptr; - auto webrtc_init = ToRtpTransceiverInit(init); + auto webrtc_init = ToRtpTransceiverInit(GetExecutionContext(), init); // Validate sendEncodings. for (auto& encoding : webrtc_init.send_encodings) { if (encoding.rid.length() > 16) { @@ -2672,10 +2677,11 @@ RTCRtpReceiver* RTCPeerConnection::CreateOrUpdateReceiver( RTCRtpTransceiver* RTCPeerConnection::CreateOrUpdateTransceiver( std::unique_ptr<RTCRtpTransceiverPlatform> platform_transceiver) { - String kind = (platform_transceiver->Receiver()->Track().Source().GetType() == - WebMediaStreamSource::kTypeAudio) - ? "audio" - : "video"; + String kind = + (platform_transceiver->Receiver()->Track()->Source()->GetType() == + MediaStreamSource::kTypeAudio) + ? "audio" + : "video"; RTCRtpSender* sender = CreateOrUpdateSender(platform_transceiver->Sender(), kind); RTCRtpReceiver* receiver = @@ -2770,6 +2776,7 @@ RTCDTMFSender* RTCPeerConnection::createDTMFSender( } void RTCPeerConnection::close() { + suppress_events_ = true; if (signaling_state_ == webrtc::PeerConnectionInterface::SignalingState::kClosed) { return; @@ -2836,7 +2843,7 @@ void RTCPeerConnection::MaybeFireNegotiationNeeded() { if (!negotiation_needed_ || closed_) return; negotiation_needed_ = false; - DispatchEvent(*Event::Create(event_type_names::kNegotiationneeded)); + MaybeDispatchEvent(Event::Create(event_type_names::kNegotiationneeded)); } void RTCPeerConnection::DidGenerateICECandidate( @@ -3123,7 +3130,7 @@ void RTCPeerConnection::DidModifyTransceivers( auto* track_event = MakeGarbageCollected<RTCTrackEvent>( transceiver->receiver(), transceiver->receiver()->track(), transceiver->receiver()->streams(), transceiver); - DispatchEvent(*track_event); + MaybeDispatchEvent(track_event); } // Unmute "pc.ontrack" tracks. Fires "track.onunmute" synchronously. @@ -3201,7 +3208,7 @@ void RTCPeerConnection::DidAddRemoteDataChannel( GetExecutionContext(), std::move(channel), peer_handler_.get()); has_data_channels_ = true; blink_channel->SetStateToOpenWithoutEvent(); - DispatchEvent(*MakeGarbageCollected<RTCDataChannelEvent>( + MaybeDispatchEvent(MakeGarbageCollected<RTCDataChannelEvent>( event_type_names::kDatachannel, blink_channel)); // The event handler might have closed the channel. if (blink_channel->readyState() == "open") { @@ -3213,22 +3220,27 @@ void RTCPeerConnection::DidNoteInterestingUsage(int usage_pattern) { if (!GetExecutionContext()) return; LocalDOMWindow* window = To<LocalDOMWindow>(GetExecutionContext()); - ukm::SourceId source_id = window->document()->UkmSourceID(); + ukm::SourceId source_id = window->UkmSourceID(); ukm::builders::WebRTC_AddressHarvesting(source_id) .SetUsagePattern(usage_pattern) - .Record(window->document()->UkmRecorder()); + .Record(window->UkmRecorder()); } void RTCPeerConnection::UnregisterPeerConnectionHandler() { - if (stopped_) + if (peer_handler_unregistered_) { + DCHECK(scheduled_events_.IsEmpty()) + << "Undelivered events can cause memory leaks due to " + << "WrapPersistent(this) in setup function callbacks"; return; + } - stopped_ = true; + peer_handler_unregistered_ = true; ice_connection_state_ = webrtc::PeerConnectionInterface::kIceConnectionClosed; signaling_state_ = webrtc::PeerConnectionInterface::SignalingState::kClosed; peer_handler_->StopAndUnregister(); dispatch_scheduled_events_task_handle_.Cancel(); + scheduled_events_.clear(); feature_handle_for_scheduler_.reset(); } @@ -3247,6 +3259,7 @@ ExecutionContext* RTCPeerConnection::GetExecutionContext() const { } void RTCPeerConnection::ContextDestroyed() { + suppress_events_ = true; if (!closed_) { CloseInternal(); } @@ -3263,7 +3276,7 @@ void RTCPeerConnection::ChangeSignalingState( signaling_state_ = signaling_state; Event* event = Event::Create(event_type_names::kSignalingstatechange); if (dispatch_event_immediately) - DispatchEvent(*event); + MaybeDispatchEvent(event); else ScheduleDispatchEvent(event); } @@ -3306,7 +3319,8 @@ void RTCPeerConnection::ChangeIceConnectionState( return; } ice_connection_state_ = ice_connection_state; - DispatchEvent(*Event::Create(event_type_names::kIceconnectionstatechange)); + MaybeDispatchEvent( + Event::Create(event_type_names::kIceconnectionstatechange)); } webrtc::PeerConnectionInterface::IceConnectionState @@ -3431,12 +3445,30 @@ void RTCPeerConnection::CloseInternal() { feature_handle_for_scheduler_.reset(); } +void RTCPeerConnection::MaybeDispatchEvent(Event* event) { + if (suppress_events_) + return; + DispatchEvent(*event); +} + void RTCPeerConnection::ScheduleDispatchEvent(Event* event) { ScheduleDispatchEvent(event, BoolFunction()); } void RTCPeerConnection::ScheduleDispatchEvent(Event* event, BoolFunction setup_function) { + if (peer_handler_unregistered_) { + DCHECK(scheduled_events_.IsEmpty()) + << "Undelivered events can cause memory leaks due to " + << "WrapPersistent(this) in setup function callbacks"; + return; + } + if (suppress_events_) { + // If suppressed due to closing we also want to ignore the event, but we + // don't need to crash. + return; + } + scheduled_events_.push_back( MakeGarbageCollected<EventWrapper>(event, std::move(setup_function))); @@ -3444,6 +3476,13 @@ void RTCPeerConnection::ScheduleDispatchEvent(Event* event, return; if (auto* context = GetExecutionContext()) { + if (dispatch_events_task_created_callback_for_testing_) { + context->GetTaskRunner(TaskType::kNetworking) + ->PostTask( + FROM_HERE, + std::move(dispatch_events_task_created_callback_for_testing_)); + } + // WebRTC spec specifies kNetworking as task source. // https://www.w3.org/TR/webrtc/#operation dispatch_scheduled_events_task_handle_ = PostCancellableTask( @@ -3454,8 +3493,17 @@ void RTCPeerConnection::ScheduleDispatchEvent(Event* event, } void RTCPeerConnection::DispatchScheduledEvents() { - if (stopped_) + if (peer_handler_unregistered_) { + DCHECK(scheduled_events_.IsEmpty()) + << "Undelivered events can cause memory leaks due to " + << "WrapPersistent(this) in setup function callbacks"; + return; + } + if (suppress_events_) { + // If suppressed due to closing we also want to ignore the event, but we + // don't need to crash. return; + } HeapVector<Member<EventWrapper>> events; events.swap(scheduled_events_); @@ -3470,7 +3518,7 @@ void RTCPeerConnection::DispatchScheduledEvents() { events.clear(); } -void RTCPeerConnection::Trace(Visitor* visitor) { +void RTCPeerConnection::Trace(Visitor* visitor) const { visitor->Trace(tracks_); visitor->Trace(rtp_senders_); visitor->Trace(rtp_receivers_); 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 d0143080d7c..88326302a64 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 @@ -295,8 +295,10 @@ class MODULES_EXPORT RTCPeerConnection final void RegisterTrack(MediaStreamTrack*); // We allow getStats after close, but not other calls or callbacks. - bool ShouldFireDefaultCallbacks() { return !closed_ && !stopped_; } - bool ShouldFireGetStatsCallback() { return !stopped_; } + bool ShouldFireDefaultCallbacks() { + return !closed_ && !peer_handler_unregistered_; + } + bool ShouldFireGetStatsCallback() { return !peer_handler_unregistered_; } DEFINE_ATTRIBUTE_EVENT_LISTENER(negotiationneeded, kNegotiationneeded) DEFINE_ATTRIBUTE_EVENT_LISTENER(icecandidate, kIcecandidate) @@ -365,7 +367,9 @@ class MODULES_EXPORT RTCPeerConnection final // ScriptWrappable // We keep the this object alive until either stopped or closed. - bool HasPendingActivity() const final { return !closed_ && !stopped_; } + bool HasPendingActivity() const final { + return !closed_ && !peer_handler_unregistered_; + } // For testing; exported to testing/InternalWebRTCPeerConnection static int PeerConnectionCount(); @@ -411,7 +415,7 @@ class MODULES_EXPORT RTCPeerConnection final return force_encoded_video_insertable_streams_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; base::TimeTicks WebRtcTimestampToBlinkTimestamp( base::TimeTicks webrtc_monotonic_time) const; @@ -422,6 +426,7 @@ class MODULES_EXPORT RTCPeerConnection final RtcPeerConnectionHandlerFactoryCallback); private: + friend class InternalsRTCPeerConnection; FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetAudioTrack); FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetVideoTrack); FRIEND_TEST_ALL_PREFIXES(RTCPeerConnectionTest, GetAudioAndVideoTrack); @@ -439,7 +444,7 @@ class MODULES_EXPORT RTCPeerConnection final // |m_event| will only be fired if setup() returns true; bool Setup(); - void Trace(Visitor*); + void Trace(Visitor*) const; Member<Event> event_; @@ -448,6 +453,7 @@ class MODULES_EXPORT RTCPeerConnection final }; void Dispose(); + void MaybeDispatchEvent(Event*); void ScheduleDispatchEvent(Event*); void ScheduleDispatchEvent(Event*, BoolFunction); void DispatchScheduledEvents(); @@ -604,6 +610,7 @@ class MODULES_EXPORT RTCPeerConnection final // TODO(crbug.com/787254): Use RTCPeerConnectionHandler. std::unique_ptr<RTCPeerConnectionHandler> peer_handler_; + base::OnceClosure dispatch_events_task_created_callback_for_testing_; TaskHandle dispatch_scheduled_events_task_handle_; HeapVector<Member<EventWrapper>> scheduled_events_; @@ -613,8 +620,31 @@ class MODULES_EXPORT RTCPeerConnection final feature_handle_for_scheduler_; bool negotiation_needed_; - bool stopped_; + // When the |peer_handler_| is unregistered, the native peer connection is + // closed and disappears from the chrome://webrtc-internals page. This happens + // when page context is destroyed. + // + // Note that the peer connection can be |closed_| without being unregistered + // (in which case it is still visible in chrome://webrtc-internals). If + // context is destroyed before the peer connection is closed, the native peer + // connection will be closed and stop surfacing states to blink but the blink + // peer connection will be unaware of the native layer being closed. + bool peer_handler_unregistered_; + // Reflects the RTCPeerConnection's [[IsClosed]] internal slot. + // https://w3c.github.io/webrtc-pc/#dfn-isclosed + // TODO(https://crbug.com/1083204): According to spec, the peer connection can + // only be closed through the close() API. However, our implementation can + // also be closed asynchronously by the |peer_handler_|, such as in response + // to laptop lid close on some system (depending on OS and settings). bool closed_; + // When true, events on the RTCPeerConnection will not be dispatched to + // JavaScript. This happens when close() is called but not if the peer + // connection was closed asynchronously. This also happens if the context is + // destroyed. + // TODO(https://crbug.com/1083204): When we are spec compliant and don't close + // the peer connection asynchronously, this can be removed in favor of + // |closed_|. + bool suppress_events_; // Internal state [[LastOffer]] and [[LastAnswer]] String last_offer_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.cc index c5e426df9b0..9f292d6c753 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.cc @@ -41,7 +41,7 @@ void RTCPeerConnectionController::MaybeReportComplexSdp( .Record(GetSupplementable()->UkmRecorder()); } -void RTCPeerConnectionController::Trace(Visitor* visitor) { +void RTCPeerConnectionController::Trace(Visitor* visitor) const { Supplement<Document>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.h index 597fc11ab71..0d04166502b 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_controller.h @@ -40,7 +40,7 @@ class RTCPeerConnectionController explicit RTCPeerConnectionController(Document&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: bool has_reported_ukm_ = false; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc index 287adeaa254..5a4f7a6405b 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc @@ -37,6 +37,7 @@ #include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/mediastream/media_constraints.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_event_log_output_sink.h" @@ -897,7 +898,7 @@ class RTCPeerConnectionHandler::Observer } } - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} protected: // TODO(hbos): Remove once no longer mandatory to implement. @@ -1888,6 +1889,7 @@ RTCPeerConnectionHandler::AddTrack(const WebMediaStreamTrack& track, native_peer_connection_, track_adapter_map_, std::move(sender_state), force_encoded_audio_insertable_streams_, force_encoded_video_insertable_streams_)); + MaybeCreateThermalUmaListner(); platform_transceiver = std::make_unique<blink::RTCRtpSenderOnlyTransceiver>( std::make_unique<blink::RTCRtpSenderImpl>(*rtp_senders_.back().get())); } else { @@ -1966,16 +1968,16 @@ RTCPeerConnectionHandler::RemoveTrack(blink::RTCRtpSenderPlatform* web_sender) { bool RTCPeerConnectionHandler::RemoveTrackPlanB( blink::RTCRtpSenderPlatform* web_sender) { DCHECK_EQ(configuration_.sdp_semantics, webrtc::SdpSemantics::kPlanB); - auto web_track = web_sender->Track(); + auto* track = web_sender->Track(); auto it = FindSender(web_sender->Id()); if (it == rtp_senders_.end()) return false; if (!(*it)->RemoveFromPeerConnection(native_peer_connection_.get())) return false; - if (web_track) { + if (track) { track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kSend, - MediaStreamTrackMetricsKind(web_track), - web_track.Id().Utf8()); + MediaStreamTrackMetricsKind(track), + track->Id().Utf8()); } if (peer_connection_tracker_) { auto sender_only_transceiver = @@ -2084,6 +2086,44 @@ void RTCPeerConnectionHandler::CloseClientPeerConnection() { client_->ClosePeerConnection(); } +void RTCPeerConnectionHandler::MaybeCreateThermalUmaListner() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + if (!thermal_uma_listener_) { + // Instantiate the thermal uma listener only if we are sending video. + for (const auto& sender : rtp_senders_) { + if (sender->Track() && sender->Track()->Source()->GetType() == + MediaStreamSource::kTypeVideo) { + thermal_uma_listener_ = ThermalUmaListener::Create(task_runner_); + thermal_uma_listener_->OnThermalMeasurement(last_thermal_state_); + return; + } + } + } +} + +ThermalUmaListener* RTCPeerConnectionHandler::thermal_uma_listener() const { + return thermal_uma_listener_.get(); +} + +void RTCPeerConnectionHandler::OnThermalStateChange( + base::PowerObserver::DeviceThermalState thermal_state) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + if (is_closed_) + return; + last_thermal_state_ = thermal_state; + if (thermal_uma_listener_) { + thermal_uma_listener_->OnThermalMeasurement(thermal_state); + } + if (!base::FeatureList::IsEnabled(kWebRtcThermalResource)) + return; + if (!thermal_resource_) { + thermal_resource_ = ThermalResource::Create(task_runner_); + native_peer_connection_->AddAdaptationResource( + rtc::scoped_refptr<ThermalResource>(thermal_resource_.get())); + } + thermal_resource_->OnThermalMeasurement(thermal_state); +} + void RTCPeerConnectionHandler::StartEventLog(int output_period_ms) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); // TODO(eladalon): StartRtcEventLog() return value is not useful; remove it @@ -2313,11 +2353,11 @@ void RTCPeerConnectionHandler::OnAddReceiverPlanB( DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(receiver_state.is_initialized()); TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnAddReceiverPlanB"); - auto web_track = receiver_state.track_ref()->web_track(); + auto* track = receiver_state.track_ref()->track(); // Update metrics. track_metrics_.AddTrack(MediaStreamTrackMetrics::Direction::kReceive, - MediaStreamTrackMetricsKind(web_track), - web_track.Id().Utf8()); + MediaStreamTrackMetricsKind(track), + track->Id().Utf8()); for (const auto& stream_id : receiver_state.stream_ids()) { // New remote stream? if (!IsRemoteStream(rtp_receivers_, stream_id)) { @@ -2358,7 +2398,7 @@ void RTCPeerConnectionHandler::OnRemoveReceiverPlanB(uintptr_t receiver_id) { // Update metrics. track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive, MediaStreamTrackMetricsKind(receiver->Track()), - receiver->Track().Id().Utf8()); + receiver->Track()->Id().Utf8()); if (peer_connection_tracker_) { auto receiver_only_transceiver = std::make_unique<blink::RTCRtpReceiverOnlyTransceiver>( @@ -2650,6 +2690,7 @@ RTCPeerConnectionHandler::CreateOrUpdateTransceiver( rtp_senders_.end()); rtp_senders_.push_back(std::make_unique<blink::RTCRtpSenderImpl>( *transceiver->content_sender())); + MaybeCreateThermalUmaListner(); DCHECK(FindReceiver(blink::RTCRtpReceiverImpl::getId( webrtc_receiver.get())) == rtp_receivers_.end()); rtp_receivers_.push_back(std::make_unique<blink::RTCRtpReceiverImpl>( diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h index ba58b48c37f..77d3058edad 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h @@ -15,12 +15,15 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" +#include "base/power_monitor/power_observer.h" #include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/web_media_stream_source.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/peerconnection/media_stream_track_metrics.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h" +#include "third_party/blink/renderer/modules/peerconnection/thermal_resource.h" +#include "third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h" #include "third_party/blink/renderer/modules/peerconnection/transceiver_state_surfacer.h" #include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h" #include "third_party/blink/renderer/platform/heap/member.h" @@ -210,6 +213,10 @@ class MODULES_EXPORT RTCPeerConnectionHandler { // Tells the |client_| to close RTCPeerConnection. // Make it virtual for testing purpose. virtual void CloseClientPeerConnection(); + // Invoked when a new thermal state is received from the OS. + // Virtual for testing purposes. + virtual void OnThermalStateChange( + base::PowerObserver::DeviceThermalState thermal_state); // Start recording an event log. void StartEventLog(int output_period_ms); @@ -219,6 +226,9 @@ class MODULES_EXPORT RTCPeerConnectionHandler { // WebRTC event log fragments sent back from PeerConnection land here. void OnWebRtcEventLogWrite(const WTF::Vector<uint8_t>& output); + // Virtual for testing purposes. + virtual scoped_refptr<base::SingleThreadTaskRunner> signaling_thread() const; + bool force_encoded_audio_insertable_streams() { return force_encoded_audio_insertable_streams_; } @@ -227,6 +237,10 @@ class MODULES_EXPORT RTCPeerConnectionHandler { return force_encoded_video_insertable_streams_; } + bool enable_rtp_data_channel() const { + return configuration_.enable_rtp_data_channel; + } + protected: // Constructor to be used for constructing mocks only. explicit RTCPeerConnectionHandler( @@ -274,6 +288,9 @@ class MODULES_EXPORT RTCPeerConnectionHandler { const String& error_text); void OnInterestingUsage(int usage_pattern); + // Protected for testing. + ThermalUmaListener* thermal_uma_listener() const; + private: // Record info about the first SessionDescription from the local and // remote side to record UMA stats once both are set. @@ -366,8 +383,7 @@ class MODULES_EXPORT RTCPeerConnectionHandler { std::unique_ptr<blink::RTCRtpTransceiverImpl> CreateOrUpdateTransceiver( blink::RtpTransceiverState transceiver_state, blink::TransceiverStateUpdateMode update_mode); - - scoped_refptr<base::SingleThreadTaskRunner> signaling_thread() const; + void MaybeCreateThermalUmaListner(); // Initialize() is never expected to be called more than once, even if the // first call fails. @@ -444,6 +460,15 @@ class MODULES_EXPORT RTCPeerConnectionHandler { bool force_encoded_audio_insertable_streams_ = false; bool force_encoded_video_insertable_streams_ = false; + // Resources for Adaptation. + // The Thermal Resource is lazily instantiated on platforms where thermal + // signals are supported. + scoped_refptr<ThermalResource> thermal_resource_ = nullptr; + // ThermalUmaListener is only tracked on peer connection that add a track. + std::unique_ptr<ThermalUmaListener> thermal_uma_listener_ = nullptr; + base::PowerObserver::DeviceThermalState last_thermal_state_ = + base::PowerObserver::DeviceThermalState::kUnknown; + // Record info about the first SessionDescription from the local and // remote side to record UMA stats once both are set. We only check // for the first offer or answer. "pranswer"s and "unknown"s (from diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc index d2e420256eb..c59296e1f4c 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc @@ -21,6 +21,8 @@ #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/values.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -41,10 +43,12 @@ #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h" #include "third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_client.h" #include "third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h" +#include "third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h" #include "third_party/blink/renderer/modules/webrtc/webrtc_audio_device_impl.h" #include "third_party/blink/renderer/platform/mediastream/media_constraints.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_peer_connection_handler_client.h" @@ -225,7 +229,9 @@ class DummyRTCVoidRequest final : public RTCVoidRequest { void RequestSucceeded() override { was_called_ = true; } void RequestFailed(const webrtc::RTCError&) override { was_called_ = true; } - void Trace(Visitor* visitor) override { RTCVoidRequest::Trace(visitor); } + void Trace(Visitor* visitor) const override { + RTCVoidRequest::Trace(visitor); + } private: bool was_called_ = false; @@ -274,6 +280,8 @@ class RTCPeerConnectionHandlerUnderTest : public RTCPeerConnectionHandler { webrtc::PeerConnectionObserver* observer() { return native_peer_connection()->observer(); } + + bool HasThermalUmaListner() const { return thermal_uma_listener(); } }; class RTCPeerConnectionHandlerTest : public ::testing::Test { @@ -432,7 +440,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test { std::vector<std::unique_ptr<blink::RTCRtpSenderImpl>>::iterator FindSenderForTrack(const blink::WebMediaStreamTrack& web_track) { for (auto it = senders_.begin(); it != senders_.end(); ++it) { - if ((*it)->Track().UniqueId() == web_track.UniqueId()) + if ((*it)->Track()->UniqueId() == web_track.UniqueId()) return it; } return senders_.end(); @@ -542,7 +550,7 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test { const webrtc::MediaStreamTrackInterface& track, const std::vector<std::unique_ptr<RTCRtpReceiverPlatform>>& receivers) { for (const auto& receiver : receivers) { - if (receiver->Track().Id().Utf8() == track.id()) + if (receiver->Track()->Id().Utf8() == track.id()) return true; } return false; @@ -914,7 +922,7 @@ TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithBadSelector) { } TEST_F(RTCPeerConnectionHandlerTest, GetRTCStats) { - blink::WhitelistStatsForTesting(webrtc::RTCTestStats::kType); + blink::AllowStatsForTesting(webrtc::RTCTestStats::kType); rtc::scoped_refptr<webrtc::RTCStatsReport> report = webrtc::RTCStatsReport::Create(); @@ -1294,4 +1302,49 @@ TEST_F(RTCPeerConnectionHandlerTest, CheckInsertableStreamsConfig) { } } +TEST_F(RTCPeerConnectionHandlerTest, ThermalResourceIsDisabledByDefault) { + EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty()); + pc_handler_->OnThermalStateChange( + base::PowerObserver::DeviceThermalState::kCritical); + // A ThermalResource is not created despite the thermal signal. + EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty()); +} + +TEST_F(RTCPeerConnectionHandlerTest, + ThermalStateChangeTriggersThermalResourceIfEnabled) { + // Overwrite base::Feature kWebRtcThermalResource's default to ENABLED. + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature(kWebRtcThermalResource); + + EXPECT_TRUE(mock_peer_connection_->adaptation_resources().IsEmpty()); + // ThermalResource is created and injected on the fly. + pc_handler_->OnThermalStateChange( + base::PowerObserver::DeviceThermalState::kCritical); + auto resources = mock_peer_connection_->adaptation_resources(); + ASSERT_EQ(1u, resources.size()); + auto thermal_resource = resources[0]; + EXPECT_EQ("ThermalResource", thermal_resource->Name()); + // The initial kOveruse is observed. + FakeResourceListener resource_listener; + thermal_resource->SetResourceListener(&resource_listener); + EXPECT_EQ(1u, resource_listener.measurement_count()); + EXPECT_EQ(webrtc::ResourceUsageState::kOveruse, + resource_listener.latest_measurement()); + // ThermalResource responds to new measurements. + pc_handler_->OnThermalStateChange( + base::PowerObserver::DeviceThermalState::kNominal); + EXPECT_EQ(2u, resource_listener.measurement_count()); + EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse, + resource_listener.latest_measurement()); +} + +TEST_F(RTCPeerConnectionHandlerTest, + ThermalStateUmaListenerCreatedWhenVideoStreamAdded) { + base::HistogramTester histogram; + EXPECT_FALSE(pc_handler_->HasThermalUmaListner()); + blink::WebMediaStream local_stream(CreateLocalMediaStream("local_stream")); + EXPECT_TRUE(AddStream(local_stream)); + EXPECT_TRUE(pc_handler_->HasThermalUmaListner()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc index eab9b0c8f39..4f44d82f0a0 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.cc @@ -48,13 +48,18 @@ RTCPeerConnectionIceErrorEvent::RTCPeerConnectionIceErrorEvent( RTCPeerConnectionIceErrorEvent::RTCPeerConnectionIceErrorEvent( const AtomicString& type, const RTCPeerConnectionIceErrorEventInit* initializer) - : Event(type, initializer), - address_(initializer->address()), - port_(initializer->port()), - host_candidate_(initializer->hostCandidate()), - url_(initializer->url()), - error_code_(initializer->errorCode()), - error_text_(initializer->statusText()) {} + : Event(type, initializer), error_code_(initializer->errorCode()) { + if (initializer->hasAddress()) + address_ = initializer->address(); + if (initializer->hasPort()) + port_ = initializer->port(); + if (initializer->hasHostCandidate()) + host_candidate_ = initializer->hostCandidate(); + if (initializer->hasUrl()) + url_ = initializer->url(); + if (initializer->hasStatusText()) + error_text_ = initializer->statusText(); +} RTCPeerConnectionIceErrorEvent::~RTCPeerConnectionIceErrorEvent() = default; @@ -86,7 +91,7 @@ const AtomicString& RTCPeerConnectionIceErrorEvent::InterfaceName() const { return event_interface_names::kRTCPeerConnectionIceErrorEvent; } -void RTCPeerConnectionIceErrorEvent::Trace(Visitor* visitor) { +void RTCPeerConnectionIceErrorEvent::Trace(Visitor* visitor) const { Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h index 4ea1db2bbb6..e5baeff59c2 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h @@ -46,7 +46,7 @@ class MODULES_EXPORT RTCPeerConnectionIceErrorEvent final : public Event { String errorText() const; const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: String address_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc index 2d59646ae15..bd9a9cdc4d7 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.cc @@ -45,10 +45,13 @@ RTCPeerConnectionIceEvent::RTCPeerConnectionIceEvent(RTCIceCandidate* candidate) : Event(event_type_names::kIcecandidate, Bubbles::kNo, Cancelable::kNo), candidate_(candidate) {} +// TODO(crbug.com/1070871): Use candidateOr(nullptr). RTCPeerConnectionIceEvent::RTCPeerConnectionIceEvent( const AtomicString& type, const RTCPeerConnectionIceEventInit* initializer) - : Event(type, initializer), candidate_(initializer->candidate()) {} + : Event(type, initializer), + candidate_(initializer->hasCandidate() ? initializer->candidate() + : nullptr) {} RTCPeerConnectionIceEvent::~RTCPeerConnectionIceEvent() = default; @@ -60,7 +63,7 @@ const AtomicString& RTCPeerConnectionIceEvent::InterfaceName() const { return event_interface_names::kRTCPeerConnectionIceEvent; } -void RTCPeerConnectionIceEvent::Trace(Visitor* visitor) { +void RTCPeerConnectionIceEvent::Trace(Visitor* visitor) const { visitor->Trace(candidate_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h index 803f67c546f..9aca54df4d8 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h @@ -51,7 +51,7 @@ class MODULES_EXPORT RTCPeerConnectionIceEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<RTCIceCandidate> candidate_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc index e3931626a5e..a229bbb157e 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_test.cc @@ -380,11 +380,12 @@ class RTCPeerConnectionTest : public testing::Test { public: RTCPeerConnection* CreatePC( V8TestingScope& scope, - const String& sdp_semantics = String(), + const base::Optional<String>& sdp_semantics = base::nullopt, bool force_encoded_audio_insertable_streams = false, bool force_encoded_video_insertable_streams = false) { RTCConfiguration* config = RTCConfiguration::Create(); - config->setSdpSemantics(sdp_semantics); + if (sdp_semantics) + config->setSdpSemantics(sdp_semantics.value()); config->setForceEncodedAudioInsertableStreams( force_encoded_audio_insertable_streams); config->setForceEncodedVideoInsertableStreams( @@ -654,7 +655,7 @@ TEST_F(RTCPeerConnectionTest, CheckInsertableStreamsConfig) { for (bool force_encoded_video_insertable_streams : {true, false}) { V8TestingScope scope; Persistent<RTCPeerConnection> pc = - CreatePC(scope, String(), force_encoded_audio_insertable_streams, + CreatePC(scope, base::nullopt, force_encoded_audio_insertable_streams, force_encoded_video_insertable_streams); EXPECT_EQ(pc->force_encoded_audio_insertable_streams(), force_encoded_audio_insertable_streams); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc index cbdcc36d046..fda672d9d81 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.cc @@ -26,7 +26,7 @@ class RTCQuicStream::PendingReadBufferedAmountPromise ScriptPromiseResolver* promise_resolver() const { return promise_resolver_; } uint32_t readable_amount() const { return readable_amount_; } - void Trace(Visitor* visitor) { visitor->Trace(promise_resolver_); } + void Trace(Visitor* visitor) const { visitor->Trace(promise_resolver_); } private: Member<ScriptPromiseResolver> promise_resolver_; @@ -43,7 +43,7 @@ class RTCQuicStream::PendingWriteBufferedAmountPromise ScriptPromiseResolver* promise_resolver() const { return promise_resolver_; } uint32_t threshold() const { return threshold_; } - void Trace(Visitor* visitor) { visitor->Trace(promise_resolver_); } + void Trace(Visitor* visitor) const { visitor->Trace(promise_resolver_); } private: Member<ScriptPromiseResolver> promise_resolver_; @@ -402,7 +402,7 @@ ExecutionContext* RTCQuicStream::GetExecutionContext() const { return ExecutionContextClient::GetExecutionContext(); } -void RTCQuicStream::Trace(Visitor* visitor) { +void RTCQuicStream::Trace(Visitor* visitor) const { visitor->Trace(transport_); visitor->Trace(pending_read_buffered_amount_promises_); visitor->Trace(pending_write_buffered_amount_promises_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h index 069934a6288..0bea5a240cb 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream.h @@ -83,7 +83,7 @@ class MODULES_EXPORT RTCQuicStream final : public EventTargetWithInlineData, ExecutionContext* GetExecutionContext() const override; // For garbage collection. - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: class PendingReadBufferedAmountPromise; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc index 13298ae9a4c..7f61f1915bf 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.cc @@ -37,7 +37,7 @@ const AtomicString& RTCQuicStreamEvent::InterfaceName() const { return event_interface_names::kRTCQuicStreamEvent; } -void RTCQuicStreamEvent::Trace(Visitor* visitor) { +void RTCQuicStreamEvent::Trace(Visitor* visitor) const { visitor->Trace(stream_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h index 39888dbe79d..faeb397bd66 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.h @@ -32,7 +32,7 @@ class MODULES_EXPORT RTCQuicStreamEvent final : public Event { const AtomicString& InterfaceName() const override; // For garbage collection. - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<RTCQuicStream> stream_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc index 801e5baeef4..ac76dd1476a 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.cc @@ -92,7 +92,7 @@ RTCQuicTransport* RTCQuicTransport::Create( return Create(context, transport, certificates, exception_state, std::make_unique<DefaultP2PQuicTransportFactory>( PeerConnectionDependencyFactory::GetInstance() - ->GetWebRtcWorkerTaskRunner())); + ->GetWebRtcNetworkTaskRunner())); } RTCQuicTransport* RTCQuicTransport::Create( @@ -694,7 +694,7 @@ ExecutionContext* RTCQuicTransport::GetExecutionContext() const { return ExecutionContextClient::GetExecutionContext(); } -void RTCQuicTransport::Trace(Visitor* visitor) { +void RTCQuicTransport::Trace(Visitor* visitor) const { visitor->Trace(transport_); visitor->Trace(certificates_); visitor->Trace(remote_certificates_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h index 160625bba92..921b889cb5c 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_quic_transport.h @@ -187,7 +187,7 @@ class MODULES_EXPORT RTCQuicTransport final ExecutionContext* GetExecutionContext() const override; // For garbage collection. - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: enum class StartReason { diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl index a3a012cbecd..951f4d95b67 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl @@ -22,4 +22,6 @@ dictionary RTCRtpEncodingParameters : RTCRtpCodingParameters { double maxFramerate; // https://w3c.github.io/webrtc-svc/#dom-rtcrtpencodingparameters-scalabilitymode [RuntimeEnabled=RTCSvcScalabilityMode] DOMString scalabilityMode; + // https://w3c.github.io/webrtc-extensions/#dom-rtcrtpencodingparameters-adaptiveptime + [RuntimeEnabled=RTCAdaptivePtime] boolean adaptivePtime = false; }; 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 0590022d393..e7044c35a6c 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 @@ -261,7 +261,7 @@ void RTCRtpReceiver::SetContributingSourcesNeedsUpdating() { web_sources_needs_updating_ = true; } -void RTCRtpReceiver::Trace(Visitor* visitor) { +void RTCRtpReceiver::Trace(Visitor* visitor) const { visitor->Trace(pc_); visitor->Trace(track_); visitor->Trace(transport_); 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 587e410906c..be0545acafa 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 @@ -74,7 +74,7 @@ class RTCRtpReceiver final : public ScriptWrappable { void set_transport(RTCDtlsTransport*); void UpdateSourcesIfNeeded(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void SetContributingSourcesNeedsUpdating(); 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 index 8c059a3ee3b..aab131e7030 100644 --- 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 @@ -317,8 +317,8 @@ RTCRtpReceiverImpl::DtlsTransportInformation() { return internal_->state().webrtc_dtls_transport_information(); } -const blink::WebMediaStreamTrack& RTCRtpReceiverImpl::Track() const { - return internal_->state().track_ref()->web_track(); +MediaStreamComponent* RTCRtpReceiverImpl::Track() const { + return internal_->state().track_ref()->track(); } Vector<String> RTCRtpReceiverImpl::StreamIds() const { diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h index 81c2d44cace..0c0c980e0b8 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl.h @@ -132,7 +132,7 @@ class MODULES_EXPORT RTCRtpReceiverImpl : public RTCRtpReceiverPlatform { rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override; webrtc::DtlsTransportInformation DtlsTransportInformation() override; - const blink::WebMediaStreamTrack& Track() const override; + MediaStreamComponent* Track() const override; Vector<String> StreamIds() const override; Vector<std::unique_ptr<RTCRtpSource>> GetSources() override; void GetStats(RTCStatsReportCallback, 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 index 9036b5d7990..a29e20e7d44 100644 --- 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 @@ -20,6 +20,7 @@ #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h" #include "third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h" #include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_stats.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" @@ -118,8 +119,8 @@ 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_FALSE(!receiver_->Track()); + EXPECT_EQ(receiver_->Track()->Id().Utf8(), webrtc_track->id()); EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track); EXPECT_FALSE(receiver_->GetEncodedAudioStreamTransformer()); EXPECT_FALSE(receiver_->GetEncodedVideoStreamTransformer()); @@ -132,16 +133,16 @@ TEST_F(RTCRtpReceiverImplTest, ShallowCopy) { 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(); + 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); + 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); + EXPECT_EQ(copy->Track()->UniqueId(), web_track_unique_id); } TEST_F(RTCRtpReceiverImplTest, GetStats) { 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 4cdeff5846d..9f9d61987a3 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 @@ -17,6 +17,8 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_header_extension_capability.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_header_extension_parameters.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/web_feature.h" #include "third_party/blink/renderer/core/streams/readable_stream.h" #include "third_party/blink/renderer/core/streams/writable_stream.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_track.h" @@ -35,6 +37,7 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #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/peerconnection/rtc_dtmf_sender_handler.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_audio_stream_transformer.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_encoded_video_stream_transformer.h" @@ -70,7 +73,7 @@ class ReplaceTrackRequest : public RTCVoidRequest { resolver_->Reject(exception_state); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(sender_); visitor->Trace(with_track_); visitor->Trace(resolver_); @@ -101,7 +104,7 @@ class SetParametersRequest : public RTCVoidRequestScriptPromiseResolverImpl { RTCVoidRequestScriptPromiseResolverImpl::RequestFailed(error); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(sender_); RTCVoidRequestScriptPromiseResolverImpl::Trace(visitor); } @@ -286,13 +289,14 @@ webrtc::Priority PriorityToEnum(const WTF::String& priority) { std::tuple<Vector<webrtc::RtpEncodingParameters>, absl::optional<webrtc::DegradationPreference>> -ToRtpParameters(const RTCRtpSendParameters* parameters) { +ToRtpParameters(ExecutionContext* context, + const RTCRtpSendParameters* parameters) { Vector<webrtc::RtpEncodingParameters> encodings; if (parameters->hasEncodings()) { encodings.ReserveCapacity(parameters->encodings().size()); for (const auto& encoding : parameters->encodings()) { - encodings.push_back(ToRtpEncodingParameters(encoding)); + encodings.push_back(ToRtpEncodingParameters(context, encoding)); } } @@ -318,6 +322,7 @@ ToRtpParameters(const RTCRtpSendParameters* parameters) { } // namespace webrtc::RtpEncodingParameters ToRtpEncodingParameters( + ExecutionContext* context, const RTCRtpEncodingParameters* encoding) { webrtc::RtpEncodingParameters webrtc_encoding; if (encoding->hasRid()) { @@ -345,6 +350,10 @@ webrtc::RtpEncodingParameters ToRtpEncodingParameters( webrtc_encoding.num_temporal_layers = 3; } } + if (encoding->adaptivePtime()) { + UseCounter::Count(context, WebFeature::kRTCAdaptivePtime); + } + webrtc_encoding.adaptive_ptime = encoding->adaptivePtime(); return webrtc_encoding; } @@ -502,6 +511,7 @@ RTCRtpSendParameters* RTCRtpSender::getParameters() { << *webrtc_encoding.num_temporal_layers; } } + encoding->setAdaptivePtime(webrtc_encoding.adaptive_ptime); encodings.push_back(encoding); } parameters->setEncodings(encodings); @@ -557,7 +567,8 @@ ScriptPromise RTCRtpSender::setParameters( // parameters. Vector<webrtc::RtpEncodingParameters> encodings; absl::optional<webrtc::DegradationPreference> degradation_preference; - std::tie(encodings, degradation_preference) = ToRtpParameters(parameters); + std::tie(encodings, degradation_preference) = + ToRtpParameters(pc_->GetExecutionContext(), parameters); auto* request = MakeGarbageCollected<SetParametersRequest>(resolver, this); sender_->SetParameters(std::move(encodings), degradation_preference, request); @@ -690,7 +701,7 @@ RTCInsertableStreams* RTCRtpSender::createEncodedVideoStreams( return encoded_video_streams_; } -void RTCRtpSender::Trace(Visitor* visitor) { +void RTCRtpSender::Trace(Visitor* visitor) const { visitor->Trace(pc_); visitor->Trace(track_); visitor->Trace(transport_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h index 4c1b10e01fd..28167a0f9e2 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h @@ -10,6 +10,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_encoding_parameters.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_send_parameters.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/mediastream/media_stream.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -36,6 +37,7 @@ class RTCRtpTransceiver; class RTCInsertableStreams; webrtc::RtpEncodingParameters ToRtpEncodingParameters( + ExecutionContext* context, const RTCRtpEncodingParameters*); RTCRtpHeaderExtensionParameters* ToRtpHeaderExtensionParameters( const webrtc::RtpExtension& headers); @@ -85,7 +87,7 @@ class RTCRtpSender final : public ScriptWrappable { void set_transceiver(RTCRtpTransceiver*); void set_transport(RTCDtlsTransport*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void RegisterEncodedAudioStreamCallback(); 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 index 03cd1f7b596..fae544b2169 100644 --- 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 @@ -228,13 +228,13 @@ class RTCRtpSenderImpl::RTCRtpSenderInternal state_ = std::move(state); } - void ReplaceTrack(blink::WebMediaStreamTrack with_track, + void ReplaceTrack(MediaStreamComponent* 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()) { + if (with_track) { track_ref = track_map_->GetOrCreateLocalTrackAdapter(with_track); webrtc_track = track_ref->webrtc_track(); } @@ -287,6 +287,7 @@ class RTCRtpSenderImpl::RTCRtpSenderInternal new_parameters.encodings[i].rid = encoding.rid; new_parameters.encodings[i].scale_resolution_down_by = encoding.scale_resolution_down_by; + new_parameters.encodings[i].adaptive_ptime = encoding.adaptive_ptime; } PostCrossThreadTask( @@ -498,9 +499,9 @@ webrtc::DtlsTransportInformation RTCRtpSenderImpl::DtlsTransportInformation() { return internal_->state().webrtc_dtls_transport_information(); } -blink::WebMediaStreamTrack RTCRtpSenderImpl::Track() const { +MediaStreamComponent* RTCRtpSenderImpl::Track() const { const auto& track_ref = internal_->state().track_ref(); - return track_ref ? track_ref->web_track() : blink::WebMediaStreamTrack(); + return track_ref ? track_ref->track() : nullptr; } Vector<String> RTCRtpSenderImpl::StreamIds() const { @@ -512,11 +513,10 @@ Vector<String> RTCRtpSenderImpl::StreamIds() const { return wtf_stream_ids; } -void RTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track, - blink::RTCVoidRequest* request) { +void RTCRtpSenderImpl::ReplaceTrack(MediaStreamComponent* with_track, + RTCVoidRequest* request) { internal_->ReplaceTrack( - std::move(with_track), - WTF::Bind(&OnReplaceTrackCompleted, WrapPersistent(request))); + with_track, WTF::Bind(&OnReplaceTrackCompleted, WrapPersistent(request))); } std::unique_ptr<blink::RtcDtmfSenderHandler> RTCRtpSenderImpl::GetDtmfSender() @@ -547,9 +547,9 @@ void RTCRtpSenderImpl::SetStreams(const Vector<String>& stream_ids) { internal_->SetStreams(stream_ids); } -void RTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track, +void RTCRtpSenderImpl::ReplaceTrack(MediaStreamComponent* with_track, base::OnceCallback<void(bool)> callback) { - internal_->ReplaceTrack(std::move(with_track), std::move(callback)); + internal_->ReplaceTrack(with_track, std::move(callback)); } bool RTCRtpSenderImpl::RemoveFromPeerConnection( diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h index 7ea211799b2..ffd0897ceda 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.h @@ -138,10 +138,10 @@ class MODULES_EXPORT RTCRtpSenderImpl : public blink::RTCRtpSenderPlatform { uintptr_t Id() const override; rtc::scoped_refptr<webrtc::DtlsTransportInterface> DtlsTransport() override; webrtc::DtlsTransportInformation DtlsTransportInformation() override; - blink::WebMediaStreamTrack Track() const override; + MediaStreamComponent* Track() const override; Vector<String> StreamIds() const override; - void ReplaceTrack(blink::WebMediaStreamTrack with_track, - blink::RTCVoidRequest* request) override; + void ReplaceTrack(MediaStreamComponent* with_track, + RTCVoidRequest* request) override; std::unique_ptr<blink::RtcDtmfSenderHandler> GetDtmfSender() const override; std::unique_ptr<webrtc::RtpParameters> GetParameters() const override; void SetParameters(Vector<webrtc::RtpEncodingParameters>, @@ -159,7 +159,7 @@ class MODULES_EXPORT RTCRtpSenderImpl : public blink::RTCRtpSenderPlatform { // top of this, which returns the result in a callback instead. Allows doing // ReplaceTrack() without having a blink::RTCVoidRequest, which can only be // constructed inside of blink. - void ReplaceTrack(blink::WebMediaStreamTrack with_track, + void ReplaceTrack(MediaStreamComponent* with_track, base::OnceCallback<void(bool)> callback); bool RemoveFromPeerConnection(webrtc::PeerConnectionInterface* pc); 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 index 3c60c478ba5..819b347f68b 100644 --- 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 @@ -23,6 +23,7 @@ #include "third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h" #include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h" #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" @@ -157,14 +158,14 @@ class RTCRtpSenderImplTest : public ::testing::Test { 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()); + EXPECT_TRUE(sender_->Track()); + 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()); + EXPECT_FALSE(sender_->Track()); } TEST_F(RTCRtpSenderImplTest, ReplaceTrackSetsTrack) { @@ -175,8 +176,8 @@ TEST_F(RTCRtpSenderImplTest, ReplaceTrackSetsTrack) { 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()); + ASSERT_TRUE(sender_->Track()); + EXPECT_EQ(web_track2.UniqueId(), sender_->Track()->UniqueId()); } TEST_F(RTCRtpSenderImplTest, ReplaceTrackWithNullTrack) { @@ -187,22 +188,22 @@ TEST_F(RTCRtpSenderImplTest, ReplaceTrackWithNullTrack) { 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()); + EXPECT_FALSE(sender_->Track()); } 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()); + ASSERT_TRUE(sender_->Track()); + 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()); + ASSERT_TRUE(sender_->Track()); + EXPECT_EQ(web_track.UniqueId(), sender_->Track()->UniqueId()); } TEST_F(RTCRtpSenderImplTest, ReplaceTrackIsNotSetSynchronously) { @@ -213,8 +214,8 @@ TEST_F(RTCRtpSenderImplTest, ReplaceTrackIsNotSetSynchronously) { 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()); + ASSERT_TRUE(sender_->Track()); + EXPECT_NE(web_track2.UniqueId(), sender_->Track()->UniqueId()); // Wait for operation to run to ensure EXPECT_CALL is satisfied. std::move(replaceTrackRunLoopAndGetResult).Run(); } @@ -258,8 +259,8 @@ TEST_F(RTCRtpSenderImplTest, CopiedSenderSharesInternalStates) { EXPECT_TRUE(std::move(replaceTrackRunLoopAndGetResult).Run()); // Both original and copy shows a modified state. - EXPECT_TRUE(sender_->Track().IsNull()); - EXPECT_TRUE(copy->Track().IsNull()); + EXPECT_FALSE(sender_->Track()); + EXPECT_FALSE(copy->Track()); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc index 0dae6df2457..50bde044284 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.cc @@ -69,6 +69,7 @@ bool TransceiverDirectionFromString( } // namespace webrtc::RtpTransceiverInit ToRtpTransceiverInit( + ExecutionContext* context, const RTCRtpTransceiverInit* init) { webrtc::RtpTransceiverInit webrtc_init; base::Optional<webrtc::RtpTransceiverDirection> direction; @@ -83,7 +84,8 @@ webrtc::RtpTransceiverInit ToRtpTransceiverInit( } DCHECK(init->hasSendEncodings()); for (const auto& encoding : init->sendEncodings()) { - webrtc_init.send_encodings.push_back(ToRtpEncodingParameters(encoding)); + webrtc_init.send_encodings.push_back( + ToRtpEncodingParameters(context, encoding)); } return webrtc_init; } @@ -248,7 +250,7 @@ void RTCRtpTransceiver::setCodecPreferences( } } -void RTCRtpTransceiver::Trace(Visitor* visitor) { +void RTCRtpTransceiver::Trace(Visitor* visitor) const { visitor->Trace(pc_); visitor->Trace(sender_); visitor->Trace(receiver_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h index a5ca5da2c5f..d2d82ca8958 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h @@ -8,6 +8,7 @@ #include "base/optional.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_codec_capability.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_transceiver_init.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -24,7 +25,8 @@ class RTCPeerConnection; class RTCRtpReceiver; class RTCRtpSender; -webrtc::RtpTransceiverInit ToRtpTransceiverInit(const RTCRtpTransceiverInit*); +webrtc::RtpTransceiverInit ToRtpTransceiverInit(ExecutionContext* context, + const RTCRtpTransceiverInit*); class RTCRtpTransceiver final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); @@ -65,7 +67,7 @@ class RTCRtpTransceiver final : public ScriptWrappable { bool DirectionHasRecv() const; bool FiredDirectionHasRecv() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<RTCPeerConnection> pc_; 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 index 66982d8c84f..2e151f21546 100644 --- 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 @@ -425,7 +425,7 @@ TEST_F(RTCRtpTransceiverImplTest, TransceiverStateUpdateModeSetDescription) { 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()); + EXPECT_TRUE(transceiver.Sender()->Track()); // The direction still "sendrecv", even though the modified state has // "inactive". EXPECT_EQ(transceiver.Direction(), diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc index ea73ae10199..2fedeb937be 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.cc @@ -65,7 +65,7 @@ RTCSctpTransport::RTCSctpTransport( native_transport, context->GetTaskRunner(TaskType::kNetworking), PeerConnectionDependencyFactory::GetInstance() - ->GetWebRtcWorkerTaskRunner()) {} + ->GetWebRtcNetworkTaskRunner()) {} RTCSctpTransport::RTCSctpTransport( ExecutionContext* context, @@ -157,7 +157,7 @@ ExecutionContext* RTCSctpTransport::GetExecutionContext() const { return ExecutionContextClient::GetExecutionContext(); } -void RTCSctpTransport::Trace(Visitor* visitor) { +void RTCSctpTransport::Trace(Visitor* visitor) const { visitor->Trace(dtls_transport_); EventTargetWithInlineData::Trace(visitor); ExecutionContextClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h index 64ed98b5ee0..1dcd905f48d 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h @@ -63,7 +63,7 @@ class MODULES_EXPORT RTCSctpTransport final // Called from owning RtcPeerConnection when it is closed. void Close(); // For garbage collection. - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: webrtc::SctpTransportInformation current_state_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc index d745c55d479..508fd140af8 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.cc @@ -95,7 +95,7 @@ RTCSessionDescriptionPlatform* RTCSessionDescription::WebSessionDescription() { return platform_session_description_; } -void RTCSessionDescription::Trace(Visitor* visitor) { +void RTCSessionDescription::Trace(Visitor* visitor) const { visitor->Trace(platform_session_description_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h index f0171ec1fb1..8a9b06c0903 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description.h @@ -62,7 +62,7 @@ class RTCSessionDescription final : public ScriptWrappable { RTCSessionDescriptionPlatform* WebSessionDescription(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<RTCSessionDescriptionPlatform> platform_session_description_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc index 13ff0641076..5c238ba7aac 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc @@ -100,7 +100,7 @@ void RTCSessionDescriptionRequestImpl::Clear() { requester_.Clear(); } -void RTCSessionDescriptionRequestImpl::Trace(Visitor* visitor) { +void RTCSessionDescriptionRequestImpl::Trace(Visitor* visitor) const { visitor->Trace(success_callback_); visitor->Trace(error_callback_); visitor->Trace(requester_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h index de4b1f9dc12..3e07223cc86 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h @@ -73,7 +73,7 @@ class RTCSessionDescriptionRequestImpl final // ExecutionContextLifecycleObserver void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void Clear(); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc index 638ad1029c8..ec7ce3573da 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc @@ -83,7 +83,7 @@ void RTCSessionDescriptionRequestPromiseImpl::Clear() { requester_.Clear(); } -void RTCSessionDescriptionRequestPromiseImpl::Trace(Visitor* visitor) { +void RTCSessionDescriptionRequestPromiseImpl::Trace(Visitor* visitor) const { visitor->Trace(resolver_); visitor->Trace(requester_); RTCSessionDescriptionRequest::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h index 3413844cf87..e01411c5023 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h @@ -39,7 +39,7 @@ class RTCSessionDescriptionRequestPromiseImpl final void RequestSucceeded(RTCSessionDescriptionPlatform*) override; void RequestFailed(const webrtc::RTCError& error) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void Clear(); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc index 785932a3d1e..2230120df96 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.cc @@ -73,7 +73,7 @@ void RTCStatsRequestImpl::Clear() { requester_.Clear(); } -void RTCStatsRequestImpl::Trace(Visitor* visitor) { +void RTCStatsRequestImpl::Trace(Visitor* visitor) const { visitor->Trace(success_callback_); visitor->Trace(component_); visitor->Trace(requester_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h index 031c5444dc6..70254e0ba6d 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_request_impl.h @@ -58,7 +58,7 @@ class RTCStatsRequestImpl final : public RTCStatsRequest, // ExecutionContextLifecycleObserver void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void Clear(); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc index 1945e076953..53d191a2e13 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.cc @@ -46,7 +46,7 @@ void RTCStatsResponse::AddStats(const RTCLegacyStats& stats) { } } -void RTCStatsResponse::Trace(Visitor* visitor) { +void RTCStatsResponse::Trace(Visitor* visitor) const { visitor->Trace(result_); RTCStatsResponseBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h index 39a8eebfc6c..c701da7e8d5 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_stats_response.h @@ -48,7 +48,7 @@ class RTCStatsResponse final : public RTCStatsResponseBase { void AddStats(const RTCLegacyStats&) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: HeapVector<Member<RTCLegacyStatsReport>> result_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc index e3268c654f4..aedef9be201 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.cc @@ -57,7 +57,7 @@ RTCRtpTransceiver* RTCTrackEvent::transceiver() const { return transceiver_; } -void RTCTrackEvent::Trace(Visitor* visitor) { +void RTCTrackEvent::Trace(Visitor* visitor) const { visitor->Trace(receiver_); visitor->Trace(track_); visitor->Trace(streams_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h index cdcd99aa374..595755d92eb 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_track_event.h @@ -37,7 +37,7 @@ class RTCTrackEvent final : public Event { const HeapVector<Member<MediaStream>>& streams() const; RTCRtpTransceiver* transceiver() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<RTCRtpReceiver> receiver_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc index eb55fd9d5d8..4c75ae57772 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.cc @@ -87,7 +87,7 @@ void RTCVoidRequestImpl::Clear() { requester_.Clear(); } -void RTCVoidRequestImpl::Trace(Visitor* visitor) { +void RTCVoidRequestImpl::Trace(Visitor* visitor) const { visitor->Trace(success_callback_); visitor->Trace(error_callback_); visitor->Trace(requester_); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h index 7455d4cfcca..f872fead744 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h @@ -65,7 +65,7 @@ class RTCVoidRequestImpl final : public RTCVoidRequest, // ExecutionContextLifecycleObserver void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void Clear(); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc index 1443e2e415c..43b7951c6bc 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.cc @@ -64,7 +64,7 @@ void RTCVoidRequestPromiseImpl::Clear() { requester_.Clear(); } -void RTCVoidRequestPromiseImpl::Trace(Visitor* visitor) { +void RTCVoidRequestPromiseImpl::Trace(Visitor* visitor) const { visitor->Trace(resolver_); visitor->Trace(requester_); RTCVoidRequest::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h index 2a2b1af02f6..b4c1b4e67a8 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h @@ -31,7 +31,7 @@ class RTCVoidRequestPromiseImpl final : public RTCVoidRequest { void RequestSucceeded() override; void RequestFailed(const webrtc::RTCError&) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void Clear(); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc index e8f22ed0f28..27e13f3239a 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.cc @@ -37,7 +37,7 @@ void RTCVoidRequestScriptPromiseResolverImpl::RequestFailed( resolver_->Reject(exception_state); } -void RTCVoidRequestScriptPromiseResolverImpl::Trace(Visitor* visitor) { +void RTCVoidRequestScriptPromiseResolverImpl::Trace(Visitor* visitor) const { visitor->Trace(resolver_); RTCVoidRequest::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h index 3d02337262c..49caf12a335 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_void_request_script_promise_resolver_impl.h @@ -23,7 +23,7 @@ class RTCVoidRequestScriptPromiseResolverImpl : public RTCVoidRequest { void RequestSucceeded() override; void RequestFailed(const webrtc::RTCError&) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: Member<ScriptPromiseResolver> resolver_; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.cc b/chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.cc new file mode 100644 index 00000000000..002e98a665d --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.cc @@ -0,0 +1,27 @@ +// Copyright (c) 2020 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/testing/fake_resource_listener.h" + +#include "base/check.h" + +namespace blink { + +size_t FakeResourceListener::measurement_count() const { + return measurement_count_; +} + +webrtc::ResourceUsageState FakeResourceListener::latest_measurement() const { + DCHECK(measurement_count_); + return latest_measurement_; +} + +void FakeResourceListener::OnResourceUsageStateMeasured( + rtc::scoped_refptr<webrtc::Resource> resource, + webrtc::ResourceUsageState usage_state) { + latest_measurement_ = usage_state; + ++measurement_count_; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h b/chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h new file mode 100644 index 00000000000..f8ad199283d --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h @@ -0,0 +1,33 @@ +// Copyright (c) 2020 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_TESTING_FAKE_RESOURCE_LISTENER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_FAKE_RESOURCE_LISTENER_H_ + +#include "base/memory/scoped_refptr.h" +#include "third_party/webrtc/api/adaptation/resource.h" + +namespace blink { + +class FakeResourceListener : public webrtc::ResourceListener { + public: + ~FakeResourceListener() override = default; + + size_t measurement_count() const; + webrtc::ResourceUsageState latest_measurement() const; + + // webrtc::ResourceListener implementation. + void OnResourceUsageStateMeasured( + rtc::scoped_refptr<webrtc::Resource> resource, + webrtc::ResourceUsageState usage_state) override; + + private: + size_t measurement_count_ = 0u; + webrtc::ResourceUsageState latest_measurement_ = + webrtc::ResourceUsageState::kUnderuse; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_FAKE_RESOURCE_LISTENER_H_ diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.cc b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.cc index d8ab1dda91c..01fdd6afe06 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.cc +++ b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" + namespace blink { int InternalsRTCPeerConnection::peerConnectionCount(Internals& internals) { @@ -14,4 +16,18 @@ int InternalsRTCPeerConnection::peerConnectionCountLimit(Internals& internals) { return RTCPeerConnection::PeerConnectionCountLimit(); } +ScriptPromise +InternalsRTCPeerConnection::waitForPeerConnectionDispatchEventsTaskCreated( + ScriptState* script_state, + Internals& internals, + RTCPeerConnection* connection) { + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + CHECK(!connection->dispatch_events_task_created_callback_for_testing_); + connection->dispatch_events_task_created_callback_for_testing_ = + WTF::Bind([](ScriptPromiseResolver* resolver) { resolver->Resolve(); }, + WrapPersistent(resolver)); + return promise; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.h b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.h index 8f1119a2aa9..7ff12ca6b03 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_INTERNALS_RTC_PEER_CONNECTION_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_TESTING_INTERNALS_RTC_PEER_CONNECTION_H_ +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -18,6 +19,11 @@ class InternalsRTCPeerConnection { public: static int peerConnectionCount(Internals&); static int peerConnectionCountLimit(Internals&); + + static ScriptPromise waitForPeerConnectionDispatchEventsTaskCreated( + ScriptState*, + Internals&, + RTCPeerConnection*); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.idl b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.idl index 5c572c409c5..5e7afe4badf 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.idl +++ b/chromium/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.idl @@ -7,4 +7,6 @@ ] partial interface Internals { long peerConnectionCount(); readonly attribute long peerConnectionCountLimit; + + [CallWith=ScriptState] Promise<any> waitForPeerConnectionDispatchEventsTaskCreated(RTCPeerConnection connection); }; diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc new file mode 100644 index 00000000000..d819e86c769 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.cc @@ -0,0 +1,86 @@ +// Copyright (c) 2020 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/thermal_resource.h" + +#include "third_party/webrtc/rtc_base/ref_counted_object.h" + +namespace blink { + +namespace { + +const int kReportIntervalSeconds = 10; + +} // namespace + +const base::Feature kWebRtcThermalResource{"WebRtcThermalResource", + base::FEATURE_DISABLED_BY_DEFAULT}; + +// static +scoped_refptr<ThermalResource> ThermalResource::Create( + scoped_refptr<base::SequencedTaskRunner> task_runner) { + return new rtc::RefCountedObject<ThermalResource>(std::move(task_runner)); +} + +ThermalResource::ThermalResource( + scoped_refptr<base::SequencedTaskRunner> task_runner) + : task_runner_(std::move(task_runner)) {} + +void ThermalResource::OnThermalMeasurement( + base::PowerObserver::DeviceThermalState measurement) { + base::AutoLock auto_lock(lock_); + measurement_ = measurement; + ++measurement_id_; + ReportMeasurementWhileHoldingLock(measurement_id_); +} + +std::string ThermalResource::Name() const { + return "ThermalResource"; +} + +void ThermalResource::SetResourceListener(webrtc::ResourceListener* listener) { + base::AutoLock auto_lock(lock_); + listener_ = listener; + if (listener_ && + measurement_ != base::PowerObserver::DeviceThermalState::kUnknown) { + ReportMeasurementWhileHoldingLock(measurement_id_); + } +} + +void ThermalResource::ReportMeasurement(size_t measurement_id) { + base::AutoLock auto_lock(lock_); + ReportMeasurementWhileHoldingLock(measurement_id); +} + +// EXCLUSIVE_LOCKS_REQUIRED(&lock_) +void ThermalResource::ReportMeasurementWhileHoldingLock(size_t measurement_id) { + // Stop repeating measurements if the measurement was invalidated or we don't + // have a listtener. + if (measurement_id != measurement_id_ || !listener_) + return; + switch (measurement_) { + case base::PowerObserver::DeviceThermalState::kUnknown: + // Stop repeating measurements. + return; + case base::PowerObserver::DeviceThermalState::kNominal: + case base::PowerObserver::DeviceThermalState::kFair: + listener_->OnResourceUsageStateMeasured( + this, webrtc::ResourceUsageState::kUnderuse); + break; + case base::PowerObserver::DeviceThermalState::kSerious: + case base::PowerObserver::DeviceThermalState::kCritical: + listener_->OnResourceUsageStateMeasured( + this, webrtc::ResourceUsageState::kOveruse); + break; + } + // Repeat the reporting every 10 seconds until a new measurement is made or + // the listener is unregistered. + task_runner_->PostDelayedTask( + FROM_HERE, + base::BindOnce(&ThermalResource::ReportMeasurement, + scoped_refptr<ThermalResource>(this), measurement_id), + base::TimeDelta::FromSeconds(kReportIntervalSeconds)); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.h b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.h new file mode 100644 index 00000000000..281caaf0a3b --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource.h @@ -0,0 +1,71 @@ +// Copyright (c) 2020 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_THERMAL_RESOURCE_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_THERMAL_RESOURCE_H_ + +#include "base/feature_list.h" +#include "base/memory/scoped_refptr.h" +#include "base/power_monitor/power_observer.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/lock.h" +#include "base/thread_annotations.h" +#include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/webrtc/api/adaptation/resource.h" + +namespace blink { + +MODULES_EXPORT extern const base::Feature kWebRtcThermalResource; + +// The ThermalResource reports kOveruse or kUnderuse every 10 seconds(*) while +// it has a registered listener and the DeviceThermalMeasurement is known. +// Because OnThermalMeasurement() only happens when the thermal state changes, +// repeated kOveruse is needed to adapt multiple steps. +// +// Based on [1] and manual observations, we do not want to adapt if thermals are +// kNominal or kFair so we map these to kUnderuse. But if thermals are kSerious +// or kCritical this is a strong signal from the OS that "corrective action" or +// "immediate corrective action" is needed. +// +// (*) It can easily take a minute before the thermal state changes after load +// distribution has changed, so the effects of ThermalResource is likely to +// result in either maximally adapted or not adapted at all. The repeated +// interval of 10 seconds was somewhat arbitrarily chosen but was chosen as a +// tradeoff between giving the OS time to measure the new load and not making +// the resource too spammy. +// +// [1] +// https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/RespondToThermalStateChanges.html +class MODULES_EXPORT ThermalResource : public webrtc::Resource { + public: + static scoped_refptr<ThermalResource> Create( + scoped_refptr<base::SequencedTaskRunner> task_runner); + + explicit ThermalResource( + scoped_refptr<base::SequencedTaskRunner> task_runner); + ~ThermalResource() override = default; + + void OnThermalMeasurement( + base::PowerObserver::DeviceThermalState measurement); + + // webrtc::Resource implementation. + std::string Name() const override; + void SetResourceListener(webrtc::ResourceListener* listener) override; + + private: + void ReportMeasurement(size_t measurement_id); + void ReportMeasurementWhileHoldingLock(size_t measurement_id) + EXCLUSIVE_LOCKS_REQUIRED(&lock_); + + const scoped_refptr<base::SequencedTaskRunner> task_runner_; + base::Lock lock_; + webrtc::ResourceListener* listener_ GUARDED_BY(&lock_) = nullptr; + base::PowerObserver::DeviceThermalState measurement_ GUARDED_BY(&lock_) = + base::PowerObserver::DeviceThermalState::kUnknown; + size_t measurement_id_ GUARDED_BY(&lock_) = 0u; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_THERMAL_RESOURCE_H_ diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc new file mode 100644 index 00000000000..628a170c583 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_resource_test.cc @@ -0,0 +1,220 @@ +// Copyright (c) 2020 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/thermal_resource.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/modules/peerconnection/testing/fake_resource_listener.h" +#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h" +#include "third_party/webrtc/api/adaptation/resource.h" + +namespace blink { + +namespace { + +const int64_t kReportIntervalMs = 10000; + +class ThermalResourceTest : public ::testing::Test { + public: + ThermalResourceTest() + : task_runner_(platform_->test_task_runner()), + resource_(ThermalResource::Create(task_runner_)) {} + + void TearDown() override { + // Give in-flight tasks a chance to run before shutdown. + resource_->SetResourceListener(nullptr); + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs)); + } + + protected: + ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> + platform_; + // Tasks run on the test thread with fake time, use FastForwardBy() to + // advance time and execute delayed tasks. + scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; + scoped_refptr<ThermalResource> resource_; + FakeResourceListener listener_; +}; + +} // namespace + +TEST_F(ThermalResourceTest, NoMeasurementsByDefault) { + resource_->SetResourceListener(&listener_); + EXPECT_EQ(0u, listener_.measurement_count()); + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs)); + EXPECT_EQ(0u, listener_.measurement_count()); +} + +TEST_F(ThermalResourceTest, NominalTriggersUnderuse) { + resource_->SetResourceListener(&listener_); + resource_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kNominal); + EXPECT_EQ(1u, listener_.measurement_count()); + EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse, + listener_.latest_measurement()); +} + +TEST_F(ThermalResourceTest, FairTriggersUnderuse) { + resource_->SetResourceListener(&listener_); + resource_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kFair); + EXPECT_EQ(1u, listener_.measurement_count()); + EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse, + listener_.latest_measurement()); +} + +TEST_F(ThermalResourceTest, SeriousTriggersOveruse) { + resource_->SetResourceListener(&listener_); + resource_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kSerious); + EXPECT_EQ(1u, listener_.measurement_count()); + EXPECT_EQ(webrtc::ResourceUsageState::kOveruse, + listener_.latest_measurement()); +} + +TEST_F(ThermalResourceTest, CriticalTriggersOveruse) { + resource_->SetResourceListener(&listener_); + resource_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kCritical); + EXPECT_EQ(1u, listener_.measurement_count()); + EXPECT_EQ(webrtc::ResourceUsageState::kOveruse, + listener_.latest_measurement()); +} + +TEST_F(ThermalResourceTest, UnknownDoesNotTriggerUsage) { + resource_->SetResourceListener(&listener_); + resource_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kUnknown); + EXPECT_EQ(0u, listener_.measurement_count()); +} + +TEST_F(ThermalResourceTest, MeasurementsRepeatEvery10Seconds) { + resource_->SetResourceListener(&listener_); + resource_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kSerious); + size_t expected_count = listener_.measurement_count(); + + // First Interval. + // No new measurement if we advance less than the interval. + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs - 1)); + EXPECT_EQ(expected_count, listener_.measurement_count()); + // When the interval is reached, expect a new measurement. + task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1)); + ++expected_count; + EXPECT_EQ(expected_count, listener_.measurement_count()); + + // Second Interval. + // No new measurement if we advance less than the interval. + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs - 1)); + EXPECT_EQ(expected_count, listener_.measurement_count()); + // When the interval is reached, expect a new measurement. + task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1)); + ++expected_count; + EXPECT_EQ(expected_count, listener_.measurement_count()); + + // Third Interval. + // No new measurement if we advance less than the interval. + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs - 1)); + EXPECT_EQ(expected_count, listener_.measurement_count()); + // When the interval is reached, expect a new measurement. + task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1)); + ++expected_count; + EXPECT_EQ(expected_count, listener_.measurement_count()); +} + +TEST_F(ThermalResourceTest, NewMeasurementInvalidatesInFlightRepetition) { + resource_->SetResourceListener(&listener_); + resource_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kSerious); + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs)); + + // We are repeatedly kOveruse. + EXPECT_EQ(2u, listener_.measurement_count()); + EXPECT_EQ(webrtc::ResourceUsageState::kOveruse, + listener_.latest_measurement()); + // Fast-forward half an interval. The repeated measurement is still in-flight. + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs / 2)); + EXPECT_EQ(2u, listener_.measurement_count()); + EXPECT_EQ(webrtc::ResourceUsageState::kOveruse, + listener_.latest_measurement()); + // Trigger kUnderuse. + resource_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kNominal); + EXPECT_EQ(3u, listener_.measurement_count()); + EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse, + listener_.latest_measurement()); + // Fast-forward another half an interval, giving the previous in-flight task + // a chance to run. No new measurement is expected. + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs / 2)); + EXPECT_EQ(3u, listener_.measurement_count()); + EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse, + listener_.latest_measurement()); + // Once more, and the repetition of kUnderuse should be observed (one interval + // has passed since the OnThermalMeasurement). + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs / 2)); + EXPECT_EQ(4u, listener_.measurement_count()); + EXPECT_EQ(webrtc::ResourceUsageState::kUnderuse, + listener_.latest_measurement()); +} + +TEST_F(ThermalResourceTest, UnknownStopsRepeatedMeasurements) { + resource_->SetResourceListener(&listener_); + resource_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kSerious); + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs)); + // The measurement is repeating. + EXPECT_EQ(2u, listener_.measurement_count()); + + resource_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kUnknown); + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs)); + // No more measurements. + EXPECT_EQ(2u, listener_.measurement_count()); +} + +TEST_F(ThermalResourceTest, UnregisteringStopsRepeatedMeasurements) { + resource_->SetResourceListener(&listener_); + resource_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kSerious); + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs)); + // The measurement is repeating. + EXPECT_EQ(2u, listener_.measurement_count()); + + resource_->SetResourceListener(nullptr); + // If repeating tasks were not stopped, this line would block forever. + task_runner_->FastForwardUntilNoTasksRemain(); + // No more measurements. + EXPECT_EQ(2u, listener_.measurement_count()); +} + +TEST_F(ThermalResourceTest, RegisteringLateTriggersRepeatedMeasurements) { + resource_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kSerious); + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs)); + EXPECT_EQ(0u, listener_.measurement_count()); + // Registering triggers kOveruse. + resource_->SetResourceListener(&listener_); + EXPECT_EQ(1u, listener_.measurement_count()); + EXPECT_EQ(webrtc::ResourceUsageState::kOveruse, + listener_.latest_measurement()); + // The measurement is repeating. + task_runner_->FastForwardBy( + base::TimeDelta::FromMilliseconds(kReportIntervalMs)); + EXPECT_EQ(2u, listener_.measurement_count()); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc new file mode 100644 index 00000000000..d1e63fac5a5 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.cc @@ -0,0 +1,91 @@ +// Copyright (c) 2020 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/thermal_uma_listener.h" + +#include <memory> +#include <utility> + +#include "base/memory/scoped_refptr.h" +#include "base/metrics/histogram_macros.h" +#include "base/notreached.h" +#include "base/power_monitor/power_observer.h" +#include "base/sequenced_task_runner.h" + +namespace blink { + +namespace { + +const base::TimeDelta kStatsReportingPeriod = base::TimeDelta::FromMinutes(1); + +enum class ThermalStateUMA { + kNominal = 0, + kFair = 1, + kSerious = 2, + kCritical = 3, + kMaxValue = kCritical, +}; + +ThermalStateUMA ToThermalStateUMA( + base::PowerObserver::DeviceThermalState state) { + switch (state) { + case base::PowerObserver::DeviceThermalState::kNominal: + return ThermalStateUMA::kNominal; + case base::PowerObserver::DeviceThermalState::kFair: + return ThermalStateUMA::kFair; + case base::PowerObserver::DeviceThermalState::kSerious: + return ThermalStateUMA::kSerious; + case base::PowerObserver::DeviceThermalState::kCritical: + return ThermalStateUMA::kCritical; + default: + NOTREACHED(); + return ThermalStateUMA::kNominal; + } +} + +} // namespace + +// static +std::unique_ptr<ThermalUmaListener> ThermalUmaListener::Create( + scoped_refptr<base::SequencedTaskRunner> task_runner) { + std::unique_ptr<ThermalUmaListener> listener = + std::make_unique<ThermalUmaListener>(std::move(task_runner)); + listener->ScheduleReport(); + return listener; +} + +ThermalUmaListener::ThermalUmaListener( + scoped_refptr<base::SequencedTaskRunner> task_runner) + : task_runner_(std::move(task_runner)), + current_thermal_state_(base::PowerObserver::DeviceThermalState::kUnknown), + weak_ptr_factor_(this) { + DCHECK(task_runner_); +} + +void ThermalUmaListener::OnThermalMeasurement( + base::PowerObserver::DeviceThermalState measurement) { + base::AutoLock crit(lock_); + current_thermal_state_ = measurement; +} + +void ThermalUmaListener::ScheduleReport() { + task_runner_->PostDelayedTask(FROM_HERE, + base::BindOnce(&ThermalUmaListener::ReportStats, + weak_ptr_factor_.GetWeakPtr()), + kStatsReportingPeriod); +} + +void ThermalUmaListener::ReportStats() { + { + base::AutoLock crit(lock_); + if (current_thermal_state_ != + base::PowerObserver::DeviceThermalState::kUnknown) { + UMA_HISTOGRAM_ENUMERATION("WebRTC.PeerConnection.ThermalState", + ToThermalStateUMA(current_thermal_state_)); + } + } + ScheduleReport(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h new file mode 100644 index 00000000000..a4006a304ca --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h @@ -0,0 +1,48 @@ +// Copyright (c) 2020 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_THERMAL_UMA_LISTENER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_THERMAL_UMA_LISTENER_H_ + +#include <memory> + +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "base/optional.h" +#include "base/power_monitor/power_observer.h" +#include "base/synchronization/lock.h" +#include "base/thread_annotations.h" +#include "base/time/time.h" +#include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/wtf/hash_map.h" + +namespace blink { + +// Tracks the thermal stats and logs to a UMA histogram. +class MODULES_EXPORT ThermalUmaListener { + public: + static std::unique_ptr<ThermalUmaListener> Create( + scoped_refptr<base::SequencedTaskRunner> task_runner); + + explicit ThermalUmaListener( + scoped_refptr<base::SequencedTaskRunner> task_runner); + ~ThermalUmaListener() = default; + + void OnThermalMeasurement( + base::PowerObserver::DeviceThermalState measurement); + + private: + void ReportStats(); + void ScheduleReport(); + + base::Lock lock_; + scoped_refptr<base::SequencedTaskRunner> task_runner_; + base::PowerObserver::DeviceThermalState current_thermal_state_ + GUARDED_BY(&lock_); + base::WeakPtrFactory<ThermalUmaListener> weak_ptr_factor_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_THERMAL_UMA_LISTENER_H_ diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc new file mode 100644 index 00000000000..4e3bc30cfb2 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/peerconnection/thermal_uma_listener_test.cc @@ -0,0 +1,102 @@ +// Copyright (c) 2020 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 <memory> + +#include "base/power_monitor/power_observer.h" +#include "base/test/metrics/histogram_tester.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/modules/peerconnection/thermal_uma_listener.h" +#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h" + +namespace blink { + +namespace { + +const base::TimeDelta kStatsReportingPeriod = base::TimeDelta::FromMinutes(1); + +class ThermalUmaListenerTest : public ::testing::Test { + public: + void SetUp() override { + task_runner_ = platform_->test_task_runner(); + thermal_uma_listener_ = ThermalUmaListener::Create(task_runner_); + } + + protected: + ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> + platform_; + // Tasks run on the test thread with fake time, use FastForwardBy() to + // advance time and execute delayed tasks. + scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; + base::HistogramTester histogram_; + std::unique_ptr<ThermalUmaListener> thermal_uma_listener_; +}; + +} // namespace + +using base::Bucket; + +TEST_F(ThermalUmaListenerTest, NoMeasurementsHasNoHistograms) { + EXPECT_THAT(histogram_.GetTotalCountsForPrefix("WebRTC.PeerConnectio"), + testing::IsEmpty()); + task_runner_->FastForwardBy(kStatsReportingPeriod); + EXPECT_THAT(histogram_.GetTotalCountsForPrefix("WebRTC.PeerConnection"), + testing::IsEmpty()); +} + +TEST_F(ThermalUmaListenerTest, HistogramAfterSignal) { + thermal_uma_listener_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kFair); + task_runner_->FastForwardBy(kStatsReportingPeriod); + + EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"), + testing::ElementsAre(Bucket(1, 1))); +} + +TEST_F(ThermalUmaListenerTest, DeletionCancelsListener) { + thermal_uma_listener_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kFair); + task_runner_->FastForwardBy(2 * kStatsReportingPeriod); + EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"), + testing::ElementsAre(Bucket(1, 2))); + + thermal_uma_listener_ = nullptr; + task_runner_->FastForwardBy(kStatsReportingPeriod); + EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"), + testing::ElementsAre(Bucket(1, 2))); +} + +TEST_F(ThermalUmaListenerTest, RecordsMostRecentState) { + thermal_uma_listener_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kFair); + task_runner_->FastForwardBy(kStatsReportingPeriod / 2); + thermal_uma_listener_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kSerious); + task_runner_->FastForwardBy(kStatsReportingPeriod / 2); + + EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"), + testing::ElementsAre(Bucket(2, 1))); +} + +TEST_F(ThermalUmaListenerTest, HistogramBucketsIncludesPreviousPeriod) { + thermal_uma_listener_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kNominal); + task_runner_->FastForwardBy(kStatsReportingPeriod); + thermal_uma_listener_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kFair); + task_runner_->FastForwardBy(kStatsReportingPeriod); + thermal_uma_listener_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kSerious); + task_runner_->FastForwardBy(kStatsReportingPeriod); + thermal_uma_listener_->OnThermalMeasurement( + base::PowerObserver::DeviceThermalState::kCritical); + task_runner_->FastForwardBy(kStatsReportingPeriod); + + EXPECT_THAT(histogram_.GetAllSamples("WebRTC.PeerConnection.ThermalState"), + testing::ElementsAre(Bucket(0, 1), Bucket(1, 1), Bucket(2, 1), + Bucket(3, 1))); +} + +} // 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 index d70aefb00fa..83f583894b6 100644 --- 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 @@ -15,13 +15,12 @@ #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_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/web_heap.h" #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h" #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h" #include "third_party/blink/renderer/platform/peerconnection/webrtc_util.h" using testing::AnyNumber; @@ -73,7 +72,7 @@ class TransceiverStateSurfacerTest : public ::testing::Test { std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> CreateLocalTrackAndAdapter(const std::string& id) { return track_adapter_map_->GetOrCreateLocalTrackAdapter( - CreateBlinkLocalTrack(id)); + CreateLocalTrack(id)); } rtc::scoped_refptr<blink::FakeRtpTransceiver> CreateWebRtcTransceiver( @@ -223,21 +222,20 @@ class TransceiverStateSurfacerTest : public ::testing::Test { } 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)); + MediaStreamComponent* CreateLocalTrack(const std::string& id) { + auto* source = MakeGarbageCollected<MediaStreamSource>( + String::FromUTF8(id), MediaStreamSource::kTypeAudio, + String::FromUTF8("local_audio_track"), false); + auto audio_source = std::make_unique<MediaStreamAudioSource>( + scheduler::GetSingleThreadTaskRunnerForTesting(), true); + auto* audio_source_ptr = audio_source.get(); + audio_source->SetOwner(source); + source->SetPlatformSource(std::move(audio_source)); - blink::WebMediaStreamTrack web_track; - web_track.Initialize(web_source.Id(), web_source); - audio_source->ConnectToTrack(web_track); - return web_track; + auto* component = + MakeGarbageCollected<MediaStreamComponent>(source->Id(), source); + audio_source_ptr->ConnectToTrack(component); + return component; } void AsyncInitializeSurfacerWithWaitableEventOnSignalingThread( 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 index 6ec834173ca..6bfc9284050 100644 --- 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 @@ -28,18 +28,17 @@ scoped_refptr<WebRtcMediaStreamTrackAdapter> WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter( blink::PeerConnectionDependencyFactory* factory, const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, - const blink::WebMediaStreamTrack& web_track) { + MediaStreamComponent* component) { DCHECK(factory); DCHECK(main_thread->BelongsToCurrentThread()); - DCHECK(!web_track.IsNull()); + DCHECK(component); scoped_refptr<WebRtcMediaStreamTrackAdapter> local_track_adapter( base::AdoptRef(new WebRtcMediaStreamTrackAdapter(factory, main_thread))); - if (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio) { - local_track_adapter->InitializeLocalAudioTrack(web_track); + if (component->Source()->GetType() == MediaStreamSource::kTypeAudio) { + local_track_adapter->InitializeLocalAudioTrack(component); } else { - DCHECK_EQ(web_track.Source().GetType(), - blink::WebMediaStreamSource::kTypeVideo); - local_track_adapter->InitializeLocalVideoTrack(web_track); + DCHECK_EQ(component->Source()->GetType(), MediaStreamSource::kTypeVideo); + local_track_adapter->InitializeLocalVideoTrack(component); } return local_track_adapter; } @@ -108,15 +107,13 @@ void WebRtcMediaStreamTrackAdapter::Dispose() { return; remote_track_can_complete_initialization_.Reset(); is_disposed_ = true; - if (web_track_.Source().GetType() == - blink::WebMediaStreamSource::kTypeAudio) { + if (component_->Source()->GetType() == MediaStreamSource::kTypeAudio) { if (local_track_audio_sink_) DisposeLocalAudioTrack(); else DisposeRemoteAudioTrack(); } else { - DCHECK_EQ(web_track_.Source().GetType(), - blink::WebMediaStreamSource::kTypeVideo); + DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeVideo); if (local_track_video_sink_) DisposeLocalVideoTrack(); else @@ -137,11 +134,11 @@ void WebRtcMediaStreamTrackAdapter::InitializeOnMainThread() { EnsureTrackIsInitialized(); } -const blink::WebMediaStreamTrack& WebRtcMediaStreamTrackAdapter::web_track() { +MediaStreamComponent* WebRtcMediaStreamTrackAdapter::track() { DCHECK(main_thread_->BelongsToCurrentThread()); EnsureTrackIsInitialized(); - DCHECK(!web_track_.IsNull()); - return web_track_; + DCHECK(component_); + return component_.Get(); } webrtc::MediaStreamTrackInterface* @@ -152,37 +149,34 @@ WebRtcMediaStreamTrackAdapter::webrtc_track() { return webrtc_track_.get(); } -bool WebRtcMediaStreamTrackAdapter::IsEqual( - const blink::WebMediaStreamTrack& web_track) { +bool WebRtcMediaStreamTrackAdapter::IsEqual(MediaStreamComponent* component) { DCHECK(main_thread_->BelongsToCurrentThread()); EnsureTrackIsInitialized(); - return web_track_.GetPlatformTrack() == web_track.GetPlatformTrack(); + return component_->GetPlatformTrack() == component->GetPlatformTrack(); } void WebRtcMediaStreamTrackAdapter::InitializeLocalAudioTrack( - const blink::WebMediaStreamTrack& web_track) { + MediaStreamComponent* component) { DCHECK(main_thread_->BelongsToCurrentThread()); DCHECK(!is_initialized_); - DCHECK(!web_track.IsNull()); - DCHECK_EQ(web_track.Source().GetType(), - blink::WebMediaStreamSource::kTypeAudio); + DCHECK(component); + DCHECK_EQ(component->Source()->GetType(), MediaStreamSource::kTypeAudio); SendLogMessage(base::StringPrintf("InitializeLocalAudioTrack({id=%s})", - web_track.Id().Utf8().c_str())); - web_track_ = web_track; - blink::MediaStreamAudioTrack* native_track = - blink::MediaStreamAudioTrack::From(web_track_); + component->Id().Utf8().c_str())); + component_ = component; + auto* native_track = MediaStreamAudioTrack::From(component_); 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_)); + local_track_audio_sink_ = std::make_unique<blink::WebRtcAudioSink>( + component_->Id().Utf8(), source_interface, + factory_->GetWebRtcSignalingTaskRunner(), main_thread_); if (auto* media_stream_source = blink::ProcessedLocalAudioSource::From( - blink::MediaStreamAudioSource::From(web_track_.Source()))) { + blink::MediaStreamAudioSource::From(component_->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 @@ -199,15 +193,14 @@ void WebRtcMediaStreamTrackAdapter::InitializeLocalAudioTrack( } void WebRtcMediaStreamTrackAdapter::InitializeLocalVideoTrack( - const blink::WebMediaStreamTrack& web_track) { + MediaStreamComponent* component) { 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_)); + DCHECK(component); + DCHECK_EQ(component->Source()->GetType(), MediaStreamSource::kTypeVideo); + component_ = component; + local_track_video_sink_ = std::make_unique<blink::MediaStreamVideoWebRtcSink>( + component_, factory_, main_thread_); webrtc_track_ = local_track_video_sink_->webrtc_video_track(); DCHECK(webrtc_track_); is_initialized_ = true; @@ -267,10 +260,10 @@ void WebRtcMediaStreamTrackAdapter:: if (remote_audio_track_adapter_) { remote_audio_track_adapter_->Initialize(); - web_track_ = *remote_audio_track_adapter_->web_track(); + component_ = remote_audio_track_adapter_->track(); } else { remote_video_track_adapter_->Initialize(); - web_track_ = *remote_video_track_adapter_->web_track(); + component_ = remote_video_track_adapter_->track(); } is_initialized_ = true; } @@ -289,32 +282,28 @@ void WebRtcMediaStreamTrackAdapter::EnsureTrackIsInitialized() { 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_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeAudio); + auto* audio_track = MediaStreamAudioTrack::From(component_); DCHECK(audio_track); audio_track->RemoveSink(local_track_audio_sink_.get()); local_track_audio_sink_.reset(); webrtc_track_ = nullptr; - web_track_.Reset(); + component_ = nullptr; } void WebRtcMediaStreamTrackAdapter::DisposeLocalVideoTrack() { DCHECK(main_thread_->BelongsToCurrentThread()); DCHECK(local_track_video_sink_); - DCHECK_EQ(web_track_.Source().GetType(), - blink::WebMediaStreamSource::kTypeVideo); + DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeVideo); local_track_video_sink_.reset(); webrtc_track_ = nullptr; - web_track_.Reset(); + component_ = nullptr; } void WebRtcMediaStreamTrackAdapter::DisposeRemoteAudioTrack() { DCHECK(main_thread_->BelongsToCurrentThread()); DCHECK(remote_audio_track_adapter_); - DCHECK_EQ(web_track_.Source().GetType(), - blink::WebMediaStreamSource::kTypeAudio); + DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeAudio); PostCrossThreadTask( *factory_->GetWebRtcSignalingTaskRunner().get(), FROM_HERE, CrossThreadBindOnce( @@ -326,8 +315,7 @@ void WebRtcMediaStreamTrackAdapter::DisposeRemoteAudioTrack() { void WebRtcMediaStreamTrackAdapter::DisposeRemoteVideoTrack() { DCHECK(main_thread_->BelongsToCurrentThread()); DCHECK(remote_video_track_adapter_); - DCHECK_EQ(web_track_.Source().GetType(), - blink::WebMediaStreamSource::kTypeVideo); + DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeVideo); FinalizeRemoteTrackDisposingOnMainThread(); } @@ -349,7 +337,7 @@ void WebRtcMediaStreamTrackAdapter::FinalizeRemoteTrackDisposingOnMainThread() { remote_audio_track_adapter_ = nullptr; remote_video_track_adapter_ = nullptr; webrtc_track_ = nullptr; - web_track_.Reset(); + component_ = nullptr; } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.h b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.h index 5f00b4d2884..1f9d41c0246 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.h @@ -9,10 +9,10 @@ #include "base/synchronization/waitable_event.h" #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/renderer/modules/mediastream/remote_media_stream_track_adapter.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.h" #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" #include "third_party/webrtc/api/media_stream_interface.h" @@ -35,9 +35,9 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapter // Invoke on the main thread. The returned adapter is fully initialized, see // |is_initialized|. The adapter will keep a reference to the |main_thread|. static scoped_refptr<WebRtcMediaStreamTrackAdapter> CreateLocalTrackAdapter( - blink::PeerConnectionDependencyFactory* factory, + PeerConnectionDependencyFactory* factory, const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, - const blink::WebMediaStreamTrack& web_track); + MediaStreamComponent* component); // Invoke on the webrtc signaling thread. Initialization finishes on the main // thread in a post, meaning returned adapters are ensured to be initialized // in posts to the main thread, see |is_initialized|. The adapter will keep @@ -58,9 +58,9 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapter // These methods must be called on the main thread. // TODO(hbos): Allow these methods to be called on any thread and make them // const. https://crbug.com/756436 - const blink::WebMediaStreamTrack& web_track(); + MediaStreamComponent* track(); webrtc::MediaStreamTrackInterface* webrtc_track(); - bool IsEqual(const blink::WebMediaStreamTrack& web_track); + bool IsEqual(MediaStreamComponent* component); // For testing. blink::WebRtcAudioSink* GetLocalTrackAudioSinkForTesting() { @@ -88,8 +88,8 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapter private: // Initialization of local tracks occurs on the main thread. - void InitializeLocalAudioTrack(const blink::WebMediaStreamTrack& web_track); - void InitializeLocalVideoTrack(const blink::WebMediaStreamTrack& web_track); + void InitializeLocalAudioTrack(MediaStreamComponent* component); + void InitializeLocalVideoTrack(MediaStreamComponent* component); // Initialization of remote tracks starts on the webrtc signaling thread and // finishes on the main thread. void InitializeRemoteAudioTrack( @@ -121,7 +121,7 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapter base::WaitableEvent remote_track_can_complete_initialization_; bool is_initialized_; bool is_disposed_; - blink::WebMediaStreamTrack web_track_; + CrossThreadPersistent<MediaStreamComponent> component_; scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_; // If the track is local, a sink is added to the local webrtc track that is // owned by us. 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 index 36cab7da739..60c220d21fa 100644 --- 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 @@ -42,7 +42,7 @@ WebRtcMediaStreamTrackAdapterMap::AdapterRef::~AdapterRef() { DCHECK(adapter->is_initialized()); if (type_ == Type::kLocal) { map_->local_track_adapters_.EraseByPrimary( - adapter->web_track().UniqueId()); + adapter->track()->UniqueId()); } else { map_->remote_track_adapters_.EraseByPrimary(adapter->webrtc_track()); } @@ -66,9 +66,9 @@ 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())) { + if (!map_->remote_track_adapters_.FindBySecondary(track()->UniqueId())) { map_->remote_track_adapters_.SetSecondaryKey(webrtc_track(), - web_track().UniqueId()); + track()->UniqueId()); } } } @@ -88,10 +88,10 @@ WebRtcMediaStreamTrackAdapterMap::~WebRtcMediaStreamTrackAdapterMap() { std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> WebRtcMediaStreamTrackAdapterMap::GetLocalTrackAdapter( - const blink::WebMediaStreamTrack& web_track) { + MediaStreamComponent* component) { base::AutoLock scoped_lock(lock_); scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr = - local_track_adapters_.FindByPrimary(web_track.UniqueId()); + local_track_adapters_.FindByPrimary(component->UniqueId()); if (!adapter_ptr) return nullptr; return base::WrapUnique( @@ -112,12 +112,12 @@ WebRtcMediaStreamTrackAdapterMap::GetLocalTrackAdapter( std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> WebRtcMediaStreamTrackAdapterMap::GetOrCreateLocalTrackAdapter( - const blink::WebMediaStreamTrack& web_track) { - DCHECK(!web_track.IsNull()); + MediaStreamComponent* component) { + DCHECK(component); DCHECK(main_thread_->BelongsToCurrentThread()); base::AutoLock scoped_lock(lock_); scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr = - local_track_adapters_.FindByPrimary(web_track.UniqueId()); + local_track_adapters_.FindByPrimary(component->UniqueId()); if (adapter_ptr) { return base::WrapUnique( new AdapterRef(this, AdapterRef::Type::kLocal, *adapter_ptr)); @@ -129,11 +129,11 @@ WebRtcMediaStreamTrackAdapterMap::GetOrCreateLocalTrackAdapter( // 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); + factory_, main_thread_, component); } DCHECK(new_adapter->is_initialized()); - local_track_adapters_.Insert(web_track.UniqueId(), new_adapter); - local_track_adapters_.SetSecondaryKey(web_track.UniqueId(), + local_track_adapters_.Insert(component->UniqueId(), new_adapter); + local_track_adapters_.SetSecondaryKey(component->UniqueId(), new_adapter->webrtc_track()); return base::WrapUnique( new AdapterRef(this, AdapterRef::Type::kLocal, new_adapter)); @@ -146,10 +146,10 @@ size_t WebRtcMediaStreamTrackAdapterMap::GetLocalTrackCount() const { std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> WebRtcMediaStreamTrackAdapterMap::GetRemoteTrackAdapter( - const blink::WebMediaStreamTrack& web_track) { + MediaStreamComponent* component) { base::AutoLock scoped_lock(lock_); scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr = - remote_track_adapters_.FindBySecondary(web_track.UniqueId()); + remote_track_adapters_.FindBySecondary(component->UniqueId()); if (!adapter_ptr) return nullptr; DCHECK((*adapter_ptr)->is_initialized()); diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h index 9491038cb3b..eb3a77b3871 100644 --- a/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h +++ b/chromium/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h @@ -5,9 +5,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_ -#include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/peerconnection/two_keys_adapter_map.h" #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" #include "third_party/webrtc/api/media_stream_interface.h" @@ -38,9 +38,7 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapterMap std::unique_ptr<AdapterRef> Copy() const; bool is_initialized() const { return adapter_->is_initialized(); } void InitializeOnMainThread(); - const blink::WebMediaStreamTrack& web_track() const { - return adapter_->web_track(); - } + MediaStreamComponent* track() const { return adapter_->track(); } webrtc::MediaStreamTrackInterface* webrtc_track() const { return adapter_->webrtc_track(); } @@ -81,7 +79,7 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapterMap // The adapter is a associated with a blink and webrtc track, lookup works by // either track. std::unique_ptr<AdapterRef> GetLocalTrackAdapter( - const blink::WebMediaStreamTrack& web_track); + MediaStreamComponent* component); std::unique_ptr<AdapterRef> GetLocalTrackAdapter( webrtc::MediaStreamTrackInterface* webrtc_track); // Invoke on the main thread. Gets a new reference to the local track adapter @@ -89,7 +87,7 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapterMap // initialized. When all references are destroyed the adapter is disposed and // removed from the map. References must be destroyed on the main thread. std::unique_ptr<AdapterRef> GetOrCreateLocalTrackAdapter( - const blink::WebMediaStreamTrack& web_track); + MediaStreamComponent* component); size_t GetLocalTrackCount() const; // Gets a new reference to the remote track adapter. When all references are @@ -100,7 +98,7 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapterMap // First variety: If an adapter exists it will already be initialized, if one // does not exist null is returned. std::unique_ptr<AdapterRef> GetRemoteTrackAdapter( - const blink::WebMediaStreamTrack& web_track); + MediaStreamComponent* component); // Second variety: If an adapter exists it may or may not be initialized, see // |AdapterRef::is_initialized|. If an adapter does not exist null is // returned. @@ -118,20 +116,20 @@ class MODULES_EXPORT WebRtcMediaStreamTrackAdapterMap private: friend class WTF::ThreadSafeRefCounted<WebRtcMediaStreamTrackAdapterMap>; - // "(blink::WebMediaStreamTrack, webrtc::MediaStreamTrackInterface) -> + // "(MediaStreamComponent, webrtc::MediaStreamTrackInterface) -> // WebRtcMediaStreamTrackAdapter" maps. The primary key is based on the object // used to create the adapter. Local tracks are created from - // |blink::WebMediaStreamTrack|s, remote tracks are created from + // |MediaStreamComponent|s, remote tracks are created from // |webrtc::MediaStreamTrackInterface|s. // The adapter keeps the |webrtc::MediaStreamTrackInterface| alive with ref // counting making it safe to use a raw pointer for key. using LocalTrackAdapterMap = blink::TwoKeysAdapterMap< - int, // blink::WebMediaStreamTrack::UniqueId() + int, // MediaStreamComponent::UniqueId() webrtc::MediaStreamTrackInterface*, scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>>; using RemoteTrackAdapterMap = blink::TwoKeysAdapterMap< webrtc::MediaStreamTrackInterface*, - int, // blink::WebMediaStreamTrack::UniqueId() + int, // MediaStreamComponent::UniqueId() scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>>; // Invoke on the main thread. 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 index b1f4af0d59f..f5186af398a 100644 --- 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 @@ -15,12 +15,10 @@ #include "base/test/test_timeouts.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_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/web_heap.h" #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_dependency_factory.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h" +#include "third_party/blink/renderer/platform/mediastream/media_stream_component.h" #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" namespace blink { @@ -40,21 +38,20 @@ class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test { 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); + MediaStreamComponent* CreateLocalTrack(const std::string& id) { + auto* source = MakeGarbageCollected<MediaStreamSource>( + String::FromUTF8(id), MediaStreamSource::kTypeAudio, + String::FromUTF8("local_audio_track"), false); + MediaStreamAudioSource* audio_source = new MediaStreamAudioSource( + scheduler::GetSingleThreadTaskRunnerForTesting(), true); // Takes ownership of |audio_source|. - web_source.SetPlatformSource(base::WrapUnique(audio_source)); + audio_source->SetOwner(source); + 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; + auto* component = + MakeGarbageCollected<MediaStreamComponent>(source->Id(), source); + audio_source->ConnectToTrack(component); + return component; } std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> @@ -120,17 +117,17 @@ class WebRtcMediaStreamTrackAdapterMapTest : public ::testing::Test { }; TEST_F(WebRtcMediaStreamTrackAdapterMapTest, AddAndRemoveLocalTrackAdapter) { - blink::WebMediaStreamTrack web_track = CreateLocalTrack("local_track"); + MediaStreamComponent* track = CreateLocalTrack("local_track"); std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> - adapter_ref = map_->GetOrCreateLocalTrackAdapter(web_track); + adapter_ref = map_->GetOrCreateLocalTrackAdapter(track); EXPECT_TRUE(adapter_ref->is_initialized()); EXPECT_EQ(adapter_ref->GetAdapterForTesting(), - map_->GetLocalTrackAdapter(web_track)->GetAdapterForTesting()); + map_->GetLocalTrackAdapter(track)->GetAdapterForTesting()); EXPECT_EQ(1u, map_->GetLocalTrackCount()); // "GetOrCreate" for already existing track. std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> - adapter_ref2 = map_->GetOrCreateLocalTrackAdapter(web_track); + adapter_ref2 = map_->GetOrCreateLocalTrackAdapter(track); EXPECT_EQ(adapter_ref->GetAdapterForTesting(), adapter_ref2->GetAdapterForTesting()); EXPECT_EQ(1u, map_->GetLocalTrackCount()); @@ -143,7 +140,7 @@ TEST_F(WebRtcMediaStreamTrackAdapterMapTest, AddAndRemoveLocalTrackAdapter) { // dispose it. adapter_ref.reset(); EXPECT_EQ(0u, map_->GetLocalTrackCount()); - EXPECT_EQ(nullptr, map_->GetLocalTrackAdapter(web_track)); + EXPECT_EQ(nullptr, map_->GetLocalTrackAdapter(track)); // Allow the disposing of track to occur. RunMessageLoopsUntilIdle(); } @@ -207,13 +204,12 @@ TEST_F(WebRtcMediaStreamTrackAdapterMapTest, // 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); + MediaStreamComponent* local_track = CreateLocalTrack(id); std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef> - local_adapter = map_->GetOrCreateLocalTrackAdapter(local_web_track); + local_adapter = map_->GetOrCreateLocalTrackAdapter(local_track); EXPECT_TRUE(local_adapter->is_initialized()); - EXPECT_EQ( - local_adapter->GetAdapterForTesting(), - map_->GetLocalTrackAdapter(local_web_track)->GetAdapterForTesting()); + EXPECT_EQ(local_adapter->GetAdapterForTesting(), + map_->GetLocalTrackAdapter(local_track)->GetAdapterForTesting()); EXPECT_EQ(1u, map_->GetLocalTrackCount()); scoped_refptr<blink::MockWebRtcAudioTrack> remote_webrtc_track = @@ -233,15 +229,15 @@ TEST_F(WebRtcMediaStreamTrackAdapterMapTest, 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_->GetLocalTrackAdapter(local_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)); + MediaStreamComponent* local_track = CreateLocalTrack("missing"); + EXPECT_EQ(nullptr, map_->GetLocalTrackAdapter(local_track)); } TEST_F(WebRtcMediaStreamTrackAdapterMapTest, GetMissingRemoteTrackAdapter) { 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 index 18ea868fdcf..3f63d8a7aa5 100644 --- 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 @@ -127,14 +127,14 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, LocalAudioTrack) { 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_->track()); + EXPECT_EQ(track_adapter_->track()->Source()->GetType(), + MediaStreamSource::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()); + track_adapter_->track()->Id()); EXPECT_TRUE(track_adapter_->GetLocalTrackAudioSinkForTesting()); EXPECT_EQ( track_adapter_->GetLocalTrackAudioSinkForTesting()->webrtc_audio_track(), @@ -147,14 +147,14 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, DISABLED_LocalVideoTrack) { 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_->track()); + EXPECT_EQ(track_adapter_->track()->Source()->GetType(), + MediaStreamSource::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()); + track_adapter_->track()->Id()); EXPECT_TRUE(track_adapter_->GetLocalTrackVideoSinkForTesting()); EXPECT_EQ( track_adapter_->GetLocalTrackVideoSinkForTesting()->webrtc_video_track(), @@ -173,14 +173,14 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteAudioTrack) { 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_->track()); + EXPECT_EQ(track_adapter_->track()->Source()->GetType(), + MediaStreamSource::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()); + track_adapter_->track()->Id()); EXPECT_TRUE(track_adapter_->GetRemoteAudioTrackAdapterForTesting()); EXPECT_TRUE( track_adapter_->GetRemoteAudioTrackAdapterForTesting()->initialized()); @@ -198,14 +198,14 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteVideoTrack) { 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_->track()); + EXPECT_EQ(track_adapter_->track()->Source()->GetType(), + MediaStreamSource::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()); + track_adapter_->track()->Id()); EXPECT_TRUE(track_adapter_->GetRemoteVideoTrackAdapterForTesting()); EXPECT_TRUE( track_adapter_->GetRemoteVideoTrackAdapterForTesting()->initialized()); @@ -227,14 +227,14 @@ TEST_F(WebRtcMediaStreamTrackAdapterTest, RemoteTrackExplicitlyInitialized) { // 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_->track()); + EXPECT_EQ(track_adapter_->track()->Source()->GetType(), + MediaStreamSource::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()); + track_adapter_->track()->Id()); EXPECT_TRUE(track_adapter_->GetRemoteAudioTrackAdapterForTesting()); EXPECT_TRUE( track_adapter_->GetRemoteAudioTrackAdapterForTesting()->initialized()); diff --git a/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.cc b/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.cc index 566c3cf60bf..7a400ad9db5 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.cc +++ b/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/permissions/navigator_permissions.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/navigator.h" #include "third_party/blink/renderer/modules/permissions/permissions.h" @@ -28,12 +29,14 @@ NavigatorPermissions& NavigatorPermissions::From(Navigator& navigator) { // static Permissions* NavigatorPermissions::permissions(Navigator& navigator) { NavigatorPermissions& self = NavigatorPermissions::From(navigator); - if (!self.permissions_) - self.permissions_ = MakeGarbageCollected<Permissions>(); + if (!self.permissions_) { + self.permissions_ = + MakeGarbageCollected<Permissions>(navigator.DomWindow()); + } return self.permissions_.Get(); } -void NavigatorPermissions::Trace(Visitor* visitor) { +void NavigatorPermissions::Trace(Visitor* visitor) const { visitor->Trace(permissions_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.h b/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.h index 434c43a0a52..167314193d5 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.h +++ b/chromium/third_party/blink/renderer/modules/permissions/navigator_permissions.h @@ -27,7 +27,7 @@ class NavigatorPermissions final NavigatorPermissions(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<Permissions> permissions_; diff --git a/chromium/third_party/blink/renderer/modules/permissions/permission_status.cc b/chromium/third_party/blink/renderer/modules/permissions/permission_status.cc index 2360bae4429..c2c4df55029 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/permission_status.cc +++ b/chromium/third_party/blink/renderer/modules/permissions/permission_status.cc @@ -44,10 +44,6 @@ PermissionStatus::PermissionStatus(ExecutionContext* execution_context, PermissionStatus::~PermissionStatus() = default; -void PermissionStatus::Dispose() { - StopListening(); -} - const AtomicString& PermissionStatus::InterfaceName() const { return event_target_names::kPermissionStatus; } @@ -98,7 +94,7 @@ void PermissionStatus::OnPermissionStatusChange(MojoPermissionStatus status) { DispatchEvent(*Event::Create(event_type_names::kChange)); } -void PermissionStatus::Trace(Visitor* visitor) { +void PermissionStatus::Trace(Visitor* visitor) const { visitor->Trace(receiver_); EventTargetWithInlineData::Trace(visitor); ExecutionContextLifecycleStateObserver::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/permissions/permission_status.h b/chromium/third_party/blink/renderer/modules/permissions/permission_status.h index d97de3c856b..746c2b3548b 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/permission_status.h +++ b/chromium/third_party/blink/renderer/modules/permissions/permission_status.h @@ -27,7 +27,6 @@ class PermissionStatus final : public EventTargetWithInlineData, public mojom::blink::PermissionObserver { USING_GARBAGE_COLLECTED_MIXIN(PermissionStatus); DEFINE_WRAPPERTYPEINFO(); - USING_PRE_FINALIZER(PermissionStatus, Dispose); using MojoPermissionDescriptor = mojom::blink::PermissionDescriptorPtr; using MojoPermissionStatus = mojom::blink::PermissionStatus; @@ -45,7 +44,6 @@ class PermissionStatus final : public EventTargetWithInlineData, MojoPermissionStatus, MojoPermissionDescriptor); ~PermissionStatus() override; - void Dispose(); // EventTarget implementation. const AtomicString& InterfaceName() const override; @@ -62,7 +60,7 @@ class PermissionStatus final : public EventTargetWithInlineData, DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange) - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void StartListening(); 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 27fe6e51ded..b0bf8e68969 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc +++ b/chromium/third_party/blink/renderer/modules/permissions/permission_utils.cc @@ -108,7 +108,6 @@ PermissionDescriptorPtr ParsePermissionDescriptor( if (name == "geolocation") return CreatePermissionDescriptor(PermissionName::GEOLOCATION); if (name == "camera") { -#if !defined(OS_ANDROID) CameraDevicePermissionDescriptor* camera_device_permission = NativeValueTraits<CameraDevicePermissionDescriptor>::NativeValue( script_state->GetIsolate(), raw_descriptor.V8Value(), @@ -120,7 +119,7 @@ PermissionDescriptorPtr ParsePermissionDescriptor( return CreateVideoCapturePermissionDescriptor( camera_device_permission->panTiltZoom()); } -#endif + return CreateVideoCapturePermissionDescriptor(false /* pan_tilt_zoom */); } if (name == "microphone") diff --git a/chromium/third_party/blink/renderer/modules/permissions/permission_utils.h b/chromium/third_party/blink/renderer/modules/permissions/permission_utils.h index 72736da329a..07f8e74153a 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/permission_utils.h +++ b/chromium/third_party/blink/renderer/modules/permissions/permission_utils.h @@ -34,6 +34,9 @@ mojom::blink::PermissionDescriptorPtr CreateClipboardPermissionDescriptor( bool allow_without_gesture, bool allow_without_sanitization); +mojom::blink::PermissionDescriptorPtr CreateVideoCapturePermissionDescriptor( + bool pan_tilt_zoom); + // Parses the raw permission dictionary and returns the Mojo // PermissionDescriptor if parsing was successful. If an exception occurs, it // will be stored in |exceptionState| and nullptr will be returned. diff --git a/chromium/third_party/blink/renderer/modules/permissions/permissions.cc b/chromium/third_party/blink/renderer/modules/permissions/permissions.cc index ffc6d7d4651..3b190d73000 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/permissions.cc +++ b/chromium/third_party/blink/renderer/modules/permissions/permissions.cc @@ -31,6 +31,9 @@ using mojom::blink::PermissionDescriptorPtr; using mojom::blink::PermissionName; using mojom::blink::PermissionService; +Permissions::Permissions(ExecutionContext* execution_context) + : service_(execution_context) {} + ScriptPromise Permissions::query(ScriptState* script_state, const ScriptValue& raw_permission, ExceptionState& exception_state) { @@ -153,7 +156,7 @@ ScriptPromise Permissions::requestAll( return promise; } -void Permissions::Trace(Visitor* visitor) { +void Permissions::Trace(Visitor* visitor) const { visitor->Trace(service_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/permissions/permissions.h b/chromium/third_party/blink/renderer/modules/permissions/permissions.h index c58cd0f4b8f..8f501d972b3 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/permissions.h +++ b/chromium/third_party/blink/renderer/modules/permissions/permissions.h @@ -7,6 +7,7 @@ #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/execution_context/execution_context.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/heap_mojo_remote.h" @@ -23,7 +24,7 @@ class Permissions final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - Permissions() : service_(nullptr) {} + explicit Permissions(ExecutionContext* execution_context); ScriptPromise query(ScriptState*, const ScriptValue&, ExceptionState&); ScriptPromise request(ScriptState*, const ScriptValue&, ExceptionState&); ScriptPromise revoke(ScriptState*, const ScriptValue&, ExceptionState&); @@ -31,7 +32,7 @@ class Permissions final : public ScriptWrappable { const HeapVector<ScriptValue>&, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: mojom::blink::PermissionService* GetService(ExecutionContext*); diff --git a/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc b/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc index 1016492501c..bfcfb2f6617 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc +++ b/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/permissions/worker_navigator_permissions.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/workers/worker_navigator.h" #include "third_party/blink/renderer/modules/permissions/permissions.h" @@ -33,12 +34,14 @@ Permissions* WorkerNavigatorPermissions::permissions( WorkerNavigator& worker_navigator) { WorkerNavigatorPermissions& self = WorkerNavigatorPermissions::From(worker_navigator); - if (!self.permissions_) - self.permissions_ = MakeGarbageCollected<Permissions>(); + if (!self.permissions_) { + self.permissions_ = + MakeGarbageCollected<Permissions>(worker_navigator.DomWindow()); + } return self.permissions_; } -void WorkerNavigatorPermissions::Trace(Visitor* visitor) { +void WorkerNavigatorPermissions::Trace(Visitor* visitor) const { visitor->Trace(permissions_); Supplement<WorkerNavigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.h b/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.h index 2139f5e8b4c..ddcba35a95a 100644 --- a/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.h +++ b/chromium/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.h @@ -27,7 +27,7 @@ class WorkerNavigatorPermissions final WorkerNavigatorPermissions(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<Permissions> permissions_; diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn b/chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn index be418f1b026..1841d2d6d02 100644 --- a/chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/BUILD.gn @@ -8,14 +8,14 @@ blink_modules_sources("picture_in_picture") { sources = [ "document_picture_in_picture.cc", "document_picture_in_picture.h", - "enter_picture_in_picture_event.cc", - "enter_picture_in_picture_event.h", "html_element_picture_in_picture.cc", "html_element_picture_in_picture.h", "html_video_element_picture_in_picture.cc", "html_video_element_picture_in_picture.h", "picture_in_picture_controller_impl.cc", "picture_in_picture_controller_impl.h", + "picture_in_picture_event.cc", + "picture_in_picture_event.h", "picture_in_picture_window.cc", "picture_in_picture_window.h", "shadow_root_picture_in_picture.cc", diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h b/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h deleted file mode 100644 index cc3b34fffe3..00000000000 --- a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.h +++ /dev/null @@ -1,41 +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_PICTURE_IN_PICTURE_ENTER_PICTURE_IN_PICTURE_EVENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_ENTER_PICTURE_IN_PICTURE_EVENT_H_ - -#include "third_party/blink/renderer/bindings/modules/v8/v8_enter_picture_in_picture_event_init.h" -#include "third_party/blink/renderer/modules/event_modules.h" -#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" - -namespace blink { - -// An EnterPictureInPictureEvent is a subclass of Event with an additional -// attribute that points to the Picture-in-Picture window. -class MODULES_EXPORT EnterPictureInPictureEvent final : public Event { - DEFINE_WRAPPERTYPEINFO(); - - public: - static EnterPictureInPictureEvent* Create(const AtomicString&, - PictureInPictureWindow*); - static EnterPictureInPictureEvent* Create( - const AtomicString&, - const EnterPictureInPictureEventInit*); - - EnterPictureInPictureEvent(AtomicString const&, PictureInPictureWindow*); - EnterPictureInPictureEvent(AtomicString const&, - const EnterPictureInPictureEventInit*); - - PictureInPictureWindow* pictureInPictureWindow() const; - - void Trace(Visitor*) override; - - private: - Member<PictureInPictureWindow> picture_in_picture_window_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_ENTER_PICTURE_IN_PICTURE_EVENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl deleted file mode 100644 index 2c8aad04e79..00000000000 --- a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl +++ /dev/null @@ -1,13 +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. - -// https://wicg.github.io/picture-in-picture/#enterpictureinpictureevent -[ - RuntimeEnabled=PictureInPictureAPI, - Exposed=Window -] interface EnterPictureInPictureEvent : Event { - constructor(DOMString type, EnterPictureInPictureEventInit eventInitDict); - [SameObject] readonly attribute PictureInPictureWindow pictureInPictureWindow; -}; - diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl deleted file mode 100644 index a2117b3e527..00000000000 --- a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl +++ /dev/null @@ -1,8 +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. - -// https://wicg.github.io/picture-in-picture/#dictdef-enterpictureinpictureeventinit -dictionary EnterPictureInPictureEventInit : EventInit { - required PictureInPictureWindow pictureInPictureWindow; -}; diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/idls.gni b/chromium/third_party/blink/renderer/modules/picture_in_picture/idls.gni index 10b5024d081..e678f0079c1 100644 --- a/chromium/third_party/blink/renderer/modules/picture_in_picture/idls.gni +++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/idls.gni @@ -3,12 +3,12 @@ # found in the LICENSE file. modules_idl_files = [ - "enter_picture_in_picture_event.idl", + "picture_in_picture_event.idl", "picture_in_picture_window.idl", ] modules_dictionary_idl_files = [ - "enter_picture_in_picture_event_init.idl", + "picture_in_picture_event_init.idl", "picture_in_picture_options.idl", ] 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 9a80e367203..1c12e557242 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 @@ -20,7 +20,7 @@ #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/modules/picture_in_picture/enter_picture_in_picture_event.h" +#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.h" #include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" @@ -74,7 +74,7 @@ PictureInPictureControllerImpl::IsDocumentAllowed(bool report_failure) const { // If document is not allowed to use the policy-controlled feature named // "picture-in-picture", return kDisabledByFeaturePolicy status. if (RuntimeEnabledFeatures::PictureInPictureAPIEnabled() && - !GetSupplementable()->IsFeatureEnabled( + !GetSupplementable()->GetExecutionContext()->IsFeatureEnabled( blink::mojom::blink::FeaturePolicyFeature::kPictureInPicture, report_failure ? ReportOptions::kReportOnFailure : ReportOptions::kDoNotReport)) { @@ -227,10 +227,9 @@ void PictureInPictureControllerImpl::OnEnteredPictureInPicture( picture_in_picture_window_ = MakeGarbageCollected<PictureInPictureWindow>( GetExecutionContext(), picture_in_picture_window_size); - picture_in_picture_element_->DispatchEvent( - *EnterPictureInPictureEvent::Create( - event_type_names::kEnterpictureinpicture, - WrapPersistent(picture_in_picture_window_.Get()))); + picture_in_picture_element_->DispatchEvent(*PictureInPictureEvent::Create( + event_type_names::kEnterpictureinpicture, + WrapPersistent(picture_in_picture_window_.Get()))); if (resolver) resolver->Resolve(picture_in_picture_window_); @@ -256,16 +255,19 @@ void PictureInPictureControllerImpl::OnExitedPictureInPicture( if (!GetSupplementable()->IsActive()) return; - if (picture_in_picture_window_) + // The Picture-in-Picture window and the Picture-in-Picture element + // should be either both set or both null. + DCHECK(!picture_in_picture_element_ == !picture_in_picture_window_); + if (picture_in_picture_element_) { picture_in_picture_window_->OnClose(); - if (picture_in_picture_element_) { HTMLVideoElement* element = picture_in_picture_element_; picture_in_picture_element_ = nullptr; element->OnExitedPictureInPicture(); - element->DispatchEvent( - *Event::CreateBubble(event_type_names::kLeavepictureinpicture)); + element->DispatchEvent(*PictureInPictureEvent::Create( + event_type_names::kLeavepictureinpicture, + WrapPersistent(picture_in_picture_window_.Get()))); } if (resolver) @@ -400,7 +402,7 @@ void PictureInPictureControllerImpl::OnStopped() { OnExitedPictureInPicture(nullptr); } -void PictureInPictureControllerImpl::Trace(Visitor* visitor) { +void PictureInPictureControllerImpl::Trace(Visitor* visitor) const { visitor->Trace(picture_in_picture_element_); visitor->Trace(auto_picture_in_picture_elements_); visitor->Trace(picture_in_picture_window_); @@ -431,7 +433,7 @@ bool PictureInPictureControllerImpl::EnsureService() { scoped_refptr<base::SingleThreadTaskRunner> task_runner = GetSupplementable()->GetFrame()->GetTaskRunner( TaskType::kMediaElementEvent); - GetSupplementable()->GetBrowserInterfaceBroker().GetInterface( + GetSupplementable()->GetFrame()->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_impl.h b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h index 5876e82218a..5cc2f9ef48c 100644 --- a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h +++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_controller_impl.h @@ -90,7 +90,7 @@ class MODULES_EXPORT PictureInPictureControllerImpl // Implementation of PageVisibilityObserver. void PageVisibilityChanged() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool IsSessionObserverReceiverBoundForTesting() { return session_observer_receiver_.is_bound(); 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 c43a2bf9c7e..d7ac0aafade 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 @@ -11,8 +11,6 @@ #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" #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" @@ -21,6 +19,8 @@ #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/core/testing/wait_for_event.h" #include "third_party/blink/renderer/platform/heap/heap.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/testing/empty_web_media_player.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" @@ -151,7 +151,7 @@ class PictureInPictureControllerTest : public PageTestBase { nullptr, PictureInPictureControllerFrameClient::Create( std::make_unique<PictureInPictureControllerPlayer>())); - GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting( + GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting( mojom::blink::PictureInPictureService::Name_, WTF::BindRepeating(&MockPictureInPictureService::Bind, WTF::Unretained(&mock_service_))); @@ -164,10 +164,10 @@ class PictureInPictureControllerTest : public PageTestBase { std::string test_name = testing::UnitTest::GetInstance()->current_test_info()->name(); if (test_name.find("MediaSource") != std::string::npos) { - blink::WebMediaStream web_media_stream; - blink::WebVector<blink::WebMediaStreamTrack> dummy_tracks; - web_media_stream.Initialize(dummy_tracks, dummy_tracks); - Video()->SetSrcObject(web_media_stream); + MediaStreamComponentVector dummy_tracks; + auto* descriptor = MakeGarbageCollected<MediaStreamDescriptor>( + dummy_tracks, dummy_tracks); + Video()->SetSrcObject(descriptor); } else { video_->SetSrc("http://example.com/foo.mp4"); } @@ -176,7 +176,7 @@ class PictureInPictureControllerTest : public PageTestBase { } void TearDown() override { - GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting( + GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting( mojom::blink::PictureInPictureService::Name_, {}); } diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.cc index f20e0b7d878..f60579ebf40 100644 --- a/chromium/third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.cc +++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.cc @@ -1,42 +1,41 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2020 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/picture_in_picture/enter_picture_in_picture_event.h" +#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.h" namespace blink { -EnterPictureInPictureEvent* EnterPictureInPictureEvent::Create( +PictureInPictureEvent* PictureInPictureEvent::Create( const AtomicString& type, PictureInPictureWindow* picture_in_picture_window) { - return MakeGarbageCollected<EnterPictureInPictureEvent>( - type, picture_in_picture_window); + return MakeGarbageCollected<PictureInPictureEvent>(type, + picture_in_picture_window); } -EnterPictureInPictureEvent* EnterPictureInPictureEvent::Create( +PictureInPictureEvent* PictureInPictureEvent::Create( const AtomicString& type, - const EnterPictureInPictureEventInit* initializer) { - return MakeGarbageCollected<EnterPictureInPictureEvent>(type, initializer); + const PictureInPictureEventInit* initializer) { + return MakeGarbageCollected<PictureInPictureEvent>(type, initializer); } -PictureInPictureWindow* EnterPictureInPictureEvent::pictureInPictureWindow() - const { +PictureInPictureWindow* PictureInPictureEvent::pictureInPictureWindow() const { return picture_in_picture_window_.Get(); } -EnterPictureInPictureEvent::EnterPictureInPictureEvent( +PictureInPictureEvent::PictureInPictureEvent( AtomicString const& type, PictureInPictureWindow* picture_in_picture_window) : Event(type, Bubbles::kYes, Cancelable::kNo), picture_in_picture_window_(picture_in_picture_window) {} -EnterPictureInPictureEvent::EnterPictureInPictureEvent( +PictureInPictureEvent::PictureInPictureEvent( AtomicString const& type, - const EnterPictureInPictureEventInit* initializer) + const PictureInPictureEventInit* initializer) : Event(type, initializer), picture_in_picture_window_(initializer->pictureInPictureWindow()) {} -void EnterPictureInPictureEvent::Trace(Visitor* visitor) { +void PictureInPictureEvent::Trace(Visitor* visitor) const { visitor->Trace(picture_in_picture_window_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.h b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.h new file mode 100644 index 00000000000..c8463dafeaa --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.h @@ -0,0 +1,39 @@ +// Copyright 2020 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_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_EVENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_EVENT_H_ + +#include "third_party/blink/renderer/bindings/modules/v8/v8_picture_in_picture_event_init.h" +#include "third_party/blink/renderer/modules/event_modules.h" +#include "third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h" +#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" + +namespace blink { + +// An PictureInPictureEvent is a subclass of Event with an additional +// attribute that points to the Picture-in-Picture window. +class MODULES_EXPORT PictureInPictureEvent final : public Event { + DEFINE_WRAPPERTYPEINFO(); + + public: + static PictureInPictureEvent* Create(const AtomicString&, + PictureInPictureWindow*); + static PictureInPictureEvent* Create(const AtomicString&, + const PictureInPictureEventInit*); + + PictureInPictureEvent(AtomicString const&, PictureInPictureWindow*); + PictureInPictureEvent(AtomicString const&, const PictureInPictureEventInit*); + + PictureInPictureWindow* pictureInPictureWindow() const; + + void Trace(Visitor*) const override; + + private: + Member<PictureInPictureWindow> picture_in_picture_window_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_PICTURE_IN_PICTURE_PICTURE_IN_PICTURE_EVENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.idl new file mode 100644 index 00000000000..6b525f640ce --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.idl @@ -0,0 +1,13 @@ +// Copyright 2020 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/picture-in-picture/#pictureinpictureevent +[ + RuntimeEnabled=PictureInPictureAPI, + Exposed=Window +] interface PictureInPictureEvent : Event { + constructor(DOMString type, PictureInPictureEventInit eventInitDict); + [SameObject] readonly attribute PictureInPictureWindow pictureInPictureWindow; +}; + diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event_init.idl b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event_init.idl new file mode 100644 index 00000000000..71c4ef50657 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event_init.idl @@ -0,0 +1,8 @@ +// Copyright 2020 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/picture-in-picture/#dictdef-pictureinpictureeventinit +dictionary PictureInPictureEventInit : EventInit { + required PictureInPictureWindow pictureInPictureWindow; +}; diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.cc b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.cc index 2403ed2412f..9f91a6010f9 100644 --- a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.cc +++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.cc @@ -48,7 +48,7 @@ bool PictureInPictureWindow::HasPendingActivity() const { return GetExecutionContext() && HasEventListeners(); } -void PictureInPictureWindow::Trace(Visitor* visitor) { +void PictureInPictureWindow::Trace(Visitor* visitor) const { EventTargetWithInlineData::Trace(visitor); ExecutionContextClient::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h index 8035b88a5bf..d05977550ab 100644 --- a/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h +++ b/chromium/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.h @@ -48,7 +48,7 @@ class PictureInPictureWindow // ActiveScriptWrappable overrides. bool HasPendingActivity() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: // EventTarget overrides. diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.cc b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.cc index d39c2dc248d..48f1901ac9e 100644 --- a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.cc +++ b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.cc @@ -35,7 +35,7 @@ DOMMimeType::DOMMimeType(LocalFrame* frame, const MimeClassInfo& mime_class_info) : ExecutionContextClient(frame), mime_class_info_(&mime_class_info) {} -void DOMMimeType::Trace(Visitor* visitor) { +void DOMMimeType::Trace(Visitor* visitor) const { visitor->Trace(mime_class_info_); ScriptWrappable::Trace(visitor); ExecutionContextClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.h b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.h index 23ee306115f..a11113987d1 100644 --- a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.h +++ b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type.h @@ -45,7 +45,7 @@ class DOMMimeType final : public ScriptWrappable, const String& description() const; DOMPlugin* enabledPlugin() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<const MimeClassInfo> mime_class_info_; diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc index a4ad5cc9371..431aacf087f 100644 --- a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc +++ b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.cc @@ -35,7 +35,7 @@ DOMMimeTypeArray::DOMMimeTypeArray(LocalFrame* frame) UpdatePluginData(); } -void DOMMimeTypeArray::Trace(Visitor* visitor) { +void DOMMimeTypeArray::Trace(Visitor* visitor) const { visitor->Trace(dom_mime_types_); ScriptWrappable::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.h b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.h index af3afc3aaa2..21f464df364 100644 --- a/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.h +++ b/chromium/third_party/blink/renderer/modules/plugins/dom_mime_type_array.h @@ -54,7 +54,7 @@ class DOMMimeTypeArray final : public ScriptWrappable, // PluginsChangedObserver implementation. void PluginsChanged() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: PluginData* GetPluginData() const; diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.cc b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.cc index 09bf7a21e1b..14ad0e6ced0 100644 --- a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.cc +++ b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.cc @@ -28,7 +28,7 @@ namespace blink { DOMPlugin::DOMPlugin(LocalFrame* frame, const PluginInfo& plugin_info) : ExecutionContextClient(frame), plugin_info_(&plugin_info) {} -void DOMPlugin::Trace(Visitor* visitor) { +void DOMPlugin::Trace(Visitor* visitor) const { visitor->Trace(plugin_info_); ScriptWrappable::Trace(visitor); ExecutionContextClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.h b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.h index 9b738d96015..4be40503fe6 100644 --- a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.h +++ b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin.h @@ -49,7 +49,7 @@ class DOMPlugin final : public ScriptWrappable, public ExecutionContextClient { void NamedPropertyEnumerator(Vector<String>&, ExceptionState&) const; bool NamedPropertyQuery(const AtomicString&, ExceptionState&) const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<const PluginInfo> plugin_info_; diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc index f5256d4a98d..c7e41cbb470 100644 --- a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc +++ b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.cc @@ -39,7 +39,7 @@ DOMPluginArray::DOMPluginArray(LocalFrame* frame) UpdatePluginData(); } -void DOMPluginArray::Trace(Visitor* visitor) { +void DOMPluginArray::Trace(Visitor* visitor) const { visitor->Trace(dom_plugins_); ScriptWrappable::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.h b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.h index 031fe219515..df8cd8ae169 100644 --- a/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.h +++ b/chromium/third_party/blink/renderer/modules/plugins/dom_plugin_array.h @@ -56,7 +56,7 @@ class DOMPluginArray final : public ScriptWrappable, // PluginsChangedObserver implementation. void PluginsChanged() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: PluginData* GetPluginData() const; diff --git a/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.cc b/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.cc index 921dbd87b04..58a61076866 100644 --- a/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.cc +++ b/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/plugins/navigator_plugins.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h" +#include "third_party/blink/public/common/privacy_budget/identifiable_token_builder.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/core/frame/settings.h" @@ -51,7 +53,38 @@ bool NavigatorPlugins::javaEnabled(Navigator& navigator) { DOMPluginArray* NavigatorPlugins::plugins(LocalFrame* frame) const { if (!plugins_) plugins_ = MakeGarbageCollected<DOMPluginArray>(frame); - return plugins_.Get(); + + DOMPluginArray* result = plugins_.Get(); + if (!frame) + return result; + Document* document = frame->GetDocument(); + if (!document) + return result; + + // Build digest... + IdentifiableTokenBuilder builder; + for (unsigned i = 0; i < result->length(); i++) { + DOMPlugin* plugin = result->item(i); + builder.AddAtomic(StringToBytesSafe(plugin->name())) + .AddAtomic(StringToBytesSafe(plugin->description())) + .AddAtomic(StringToBytesSafe(plugin->filename())); + for (unsigned j = 0; j < plugin->length(); j++) { + DOMMimeType* mimeType = plugin->item(j); + builder.AddAtomic(StringToBytesSafe(mimeType->type())) + .AddAtomic(StringToBytesSafe(mimeType->description())) + .AddAtomic(StringToBytesSafe(mimeType->suffixes())); + } + } + // ...and report to UKM. + IdentifiabilityMetricBuilder(document->UkmSourceID()) + .SetWebfeature(WebFeature::kNavigatorPlugins, builder.GetToken()) + .Record(document->UkmRecorder()); + + return result; +} + +base::span<const uint8_t> NavigatorPlugins::StringToBytesSafe(String str) const { + return str.Is8Bit() ? str.Span8() : as_bytes(str.Span16()); } DOMMimeTypeArray* NavigatorPlugins::mimeTypes(LocalFrame* frame) const { @@ -60,7 +93,7 @@ DOMMimeTypeArray* NavigatorPlugins::mimeTypes(LocalFrame* frame) const { return mime_types_.Get(); } -void NavigatorPlugins::Trace(Visitor* visitor) { +void NavigatorPlugins::Trace(Visitor* visitor) const { visitor->Trace(plugins_); visitor->Trace(mime_types_); Supplement<Navigator>::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.h b/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.h index 4fcc984c013..01613eaaa9f 100644 --- a/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.h +++ b/chromium/third_party/blink/renderer/modules/plugins/navigator_plugins.h @@ -31,7 +31,7 @@ class NavigatorPlugins final : public GarbageCollected<NavigatorPlugins>, explicit NavigatorPlugins(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: DOMPluginArray* plugins(LocalFrame*) const; @@ -39,6 +39,8 @@ class NavigatorPlugins final : public GarbageCollected<NavigatorPlugins>, mutable Member<DOMPluginArray> plugins_; mutable Member<DOMMimeTypeArray> mime_types_; + + base::span<const uint8_t> StringToBytesSafe(String str) const; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.cc b/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.cc index a03eb7d3141..fe567416654 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.cc @@ -36,7 +36,7 @@ Presentation* NavigatorPresentation::presentation(Navigator& navigator) { return self.presentation_; } -void NavigatorPresentation::Trace(Visitor* visitor) { +void NavigatorPresentation::Trace(Visitor* visitor) const { visitor->Trace(presentation_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.h b/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.h index 86ecc636cab..a9e9c032357 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.h +++ b/chromium/third_party/blink/renderer/modules/presentation/navigator_presentation.h @@ -27,7 +27,7 @@ class NavigatorPresentation final NavigatorPresentation(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Presentation* presentation(); diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation.cc index 7136af30a28..92d07dbe677 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation.cc @@ -29,7 +29,7 @@ Presentation* Presentation::Create(LocalDOMWindow* window) { return presentation; } -void Presentation::Trace(Visitor* visitor) { +void Presentation::Trace(Visitor* visitor) const { visitor->Trace(default_request_); visitor->Trace(receiver_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation.h b/chromium/third_party/blink/renderer/modules/presentation/presentation.h index 4b736148f35..cc093c00f58 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation.h @@ -30,7 +30,7 @@ class Presentation final : public ScriptWrappable, explicit Presentation(LocalDOMWindow*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; PresentationRequest* defaultRequest() const; void setDefaultRequest(PresentationRequest*); diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc index 65e01cfa3eb..3694c6a2a1e 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.cc @@ -122,7 +122,7 @@ bool PresentationAvailability::value() const { return value_; } -void PresentationAvailability::Trace(Visitor* visitor) { +void PresentationAvailability::Trace(Visitor* visitor) const { EventTargetWithInlineData::Trace(visitor); PageVisibilityObserver::Trace(visitor); ExecutionContextLifecycleStateObserver::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.h index e46c910beb3..baaa1a84ec9 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability.h @@ -64,7 +64,7 @@ class MODULES_EXPORT PresentationAvailability final DEFINE_ATTRIBUTE_EVENT_LISTENER(change, kChange) - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: // EventTarget implementation. diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.cc index bb4593da903..6bdd735c44f 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.cc @@ -49,7 +49,7 @@ void PresentationAvailabilityCallbacks::RejectAvailabilityNotSupported() { resolver_->Reject(CreateAvailabilityNotSupportedError()); } -void PresentationAvailabilityCallbacks::Trace(Visitor* visitor) { +void PresentationAvailabilityCallbacks::Trace(Visitor* visitor) const { visitor->Trace(resolver_); } 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 0622ae6ac1e..0c121916b1b 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 @@ -29,7 +29,7 @@ class MODULES_EXPORT PresentationAvailabilityCallbacks virtual void Resolve(bool value); virtual void RejectAvailabilityNotSupported(); - void Trace(Visitor*); + void Trace(Visitor*) const; private: Member<PresentationAvailabilityProperty> resolver_; diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc index b9990104a97..add54fad846 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_availability_state.cc @@ -136,7 +136,7 @@ void PresentationAvailabilityState::UpdateAvailability( } } -void PresentationAvailabilityState::Trace(Visitor* visitor) { +void PresentationAvailabilityState::Trace(Visitor* visitor) const { visitor->Trace(availability_listeners_); } @@ -261,7 +261,7 @@ PresentationAvailabilityState::AvailabilityListener::~AvailabilityListener() = default; void PresentationAvailabilityState::AvailabilityListener::Trace( - blink::Visitor* visitor) { + blink::Visitor* visitor) const { visitor->Trace(availability_callbacks); visitor->Trace(availability_observers); } 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 45ce76eefee..d93fe9c8ef4 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 @@ -48,7 +48,7 @@ class MODULES_EXPORT PresentationAvailabilityState final // callbacks and observers. void UpdateAvailability(const KURL&, mojom::blink::ScreenAvailability); - void Trace(Visitor*); + void Trace(Visitor*) const; private: enum class ListeningState { @@ -71,7 +71,7 @@ class MODULES_EXPORT PresentationAvailabilityState final availability_callbacks; HeapVector<Member<PresentationAvailabilityObserver>> availability_observers; - void Trace(Visitor*); + void Trace(Visitor*) const; private: DISALLOW_COPY_AND_ASSIGN(AvailabilityListener); 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 15cd203b35d..ffa2632700f 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.cc @@ -111,7 +111,7 @@ class PresentationConnection::Message final Message(scoped_refptr<BlobDataHandle> blob_data_handle) : type(kMessageTypeBlob), blob_data_handle(std::move(blob_data_handle)) {} - void Trace(Visitor* visitor) { visitor->Trace(array_buffer); } + void Trace(Visitor* visitor) const { visitor->Trace(array_buffer); } MessageType type; String text; @@ -148,7 +148,9 @@ class PresentationConnection::BlobLoader final void Cancel() { loader_->Cancel(); } - void Trace(Visitor* visitor) { visitor->Trace(presentation_connection_); } + void Trace(Visitor* visitor) const { + visitor->Trace(presentation_connection_); + } private: Member<PresentationConnection> presentation_connection_; @@ -263,7 +265,7 @@ ControllerPresentationConnection::ControllerPresentationConnection( ControllerPresentationConnection::~ControllerPresentationConnection() {} -void ControllerPresentationConnection::Trace(Visitor* visitor) { +void ControllerPresentationConnection::Trace(Visitor* visitor) const { visitor->Trace(controller_); PresentationConnection::Trace(visitor); } @@ -377,7 +379,7 @@ void ReceiverPresentationConnection::TerminateInternal() { target_connection_->DidChangeState(state_); } -void ReceiverPresentationConnection::Trace(Visitor* visitor) { +void ReceiverPresentationConnection::Trace(Visitor* visitor) const { visitor->Trace(receiver_); PresentationConnection::Trace(visitor); } @@ -429,7 +431,7 @@ void PresentationConnection::CloseConnection() { connection_receiver_.reset(); } -void PresentationConnection::Trace(Visitor* visitor) { +void PresentationConnection::Trace(Visitor* visitor) const { visitor->Trace(connection_receiver_); visitor->Trace(target_connection_); visitor->Trace(blob_loader_); diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h index 5d8db41bfe3..054d5d4f452 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection.h @@ -46,7 +46,7 @@ class PresentationConnection : public EventTargetWithInlineData, const AtomicString& InterfaceName() const override; ExecutionContext* GetExecutionContext() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const String& id() const { return id_; } const String& url() const { return url_; } @@ -186,7 +186,7 @@ class ControllerPresentationConnection final : public PresentationConnection { const KURL&); ~ControllerPresentationConnection() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Initializes Mojo message pipes and registers with the PresentationService. void Init(mojo::PendingRemote<mojom::blink::PresentationConnection> @@ -222,7 +222,7 @@ class ReceiverPresentationConnection final : public PresentationConnection { const KURL&); ~ReceiverPresentationConnection() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void Init(mojo::PendingRemote<mojom::blink::PresentationConnection> controller_connection_remote, diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.cc index a6dd3e2c47b..6e73dc5e4d9 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.cc @@ -27,7 +27,7 @@ const AtomicString& PresentationConnectionAvailableEvent::InterfaceName() return event_interface_names::kPresentationConnectionAvailableEvent; } -void PresentationConnectionAvailableEvent::Trace(Visitor* visitor) { +void PresentationConnectionAvailableEvent::Trace(Visitor* visitor) const { visitor->Trace(connection_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h index b5a5a6b7967..1b1393d32d6 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.h @@ -44,7 +44,7 @@ class PresentationConnectionAvailableEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<PresentationConnection> connection_; diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc index aed6db7826f..b19f398e3a5 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_callbacks.cc @@ -64,9 +64,10 @@ void PresentationConnectionCallbacks::OnSuccess( resolver_.Get(), presentation_info, request_); } - resolver_->Resolve(connection_); connection_->Init(std::move(connection_remote), std::move(connection_receiver)); + + resolver_->Resolve(connection_); } void PresentationConnectionCallbacks::OnError( diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.cc index 7b77fbedf63..c1355d0fd2a 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.cc @@ -27,7 +27,7 @@ const AtomicString& PresentationConnectionCloseEvent::InterfaceName() const { return event_interface_names::kPresentationConnectionCloseEvent; } -void PresentationConnectionCloseEvent::Trace(Visitor* visitor) { +void PresentationConnectionCloseEvent::Trace(Visitor* visitor) const { Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h index e13f871a531..a2ccd7d1b45 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.h @@ -47,7 +47,7 @@ class PresentationConnectionCloseEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: String reason_; diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc index ba1210de20b..d8fc612d48d 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.cc @@ -63,7 +63,7 @@ bool PresentationConnectionList::IsEmpty() { return connections_.IsEmpty(); } -void PresentationConnectionList::Trace(Visitor* visitor) { +void PresentationConnectionList::Trace(Visitor* visitor) const { visitor->Trace(connections_); EventTargetWithInlineData::Trace(visitor); ExecutionContextClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.h index 5405a6c8c8f..4a0515cb41f 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_connection_list.h @@ -43,7 +43,7 @@ class MODULES_EXPORT PresentationConnectionList final void DispatchConnectionAvailableEvent(PresentationConnection*); bool IsEmpty(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: // EventTarget implementation. 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 21c143d8467..a6c9dbfba66 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.cc @@ -47,7 +47,7 @@ PresentationController* PresentationController::FromContext( return From(*To<LocalDOMWindow>(execution_context)); } -void PresentationController::Trace(Visitor* visitor) { +void PresentationController::Trace(Visitor* visitor) const { visitor->Trace(presentation_controller_receiver_); visitor->Trace(presentation_); visitor->Trace(connections_); 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 479f806f26e..4aee3a0d5e7 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_controller.h @@ -43,7 +43,7 @@ class MODULES_EXPORT PresentationController static PresentationController* FromContext(ExecutionContext*); // Implementation of Supplement. - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Called by the Presentation object to advertize itself to the controller. // The Presentation object is kept as a WeakMember in order to avoid keeping 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 75824f90bed..21b3c3c7cce 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.cc @@ -109,7 +109,7 @@ void PresentationReceiver::RegisterConnection( connection_list_->AddConnection(connection); } -void PresentationReceiver::Trace(Visitor* visitor) { +void PresentationReceiver::Trace(Visitor* visitor) const { visitor->Trace(connection_list_); visitor->Trace(connection_list_property_); visitor->Trace(presentation_receiver_receiver_); diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h index 956d5e239ff..ae116afd220 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_receiver.h @@ -58,7 +58,7 @@ class MODULES_EXPORT PresentationReceiver final LocalDOMWindow* GetWindow() const { return window_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class PresentationReceiverTest; diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc index 192bb3ac774..183be0a4bbe 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.cc @@ -216,7 +216,7 @@ const Vector<KURL>& PresentationRequest::Urls() const { return urls_; } -void PresentationRequest::Trace(Visitor* visitor) { +void PresentationRequest::Trace(Visitor* visitor) const { visitor->Trace(availability_property_); EventTargetWithInlineData::Trace(visitor); ExecutionContextClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.h b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.h index 9d6d944f0bb..85d35573235 100644 --- a/chromium/third_party/blink/renderer/modules/presentation/presentation_request.h +++ b/chromium/third_party/blink/renderer/modules/presentation/presentation_request.h @@ -55,7 +55,7 @@ class MODULES_EXPORT PresentationRequest final DEFINE_ATTRIBUTE_EVENT_LISTENER(connectionavailable, kConnectionavailable) - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: // EventTarget implementation. diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_event.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_event.cc index b2e685968b3..7e587b57477 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_event.cc +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_event.cc @@ -48,7 +48,7 @@ PushMessageData* PushEvent::data() { return data_.Get(); } -void PushEvent::Trace(Visitor* visitor) { +void PushEvent::Trace(Visitor* visitor) const { visitor->Trace(data_); ExtendableEvent::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_event.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_event.h index 82a2005933c..841289a58b8 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_event.h +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_event.h @@ -45,7 +45,7 @@ class MODULES_EXPORT PushEvent final : public ExtendableEvent { PushMessageData* data(); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<PushMessageData> data_; diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc index 432a846f5be..69e13f7cafe 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.cc @@ -138,7 +138,7 @@ ScriptPromise PushManager::permissionState( ->GetPermissionState(script_state, options); } -void PushManager::Trace(Visitor* visitor) { +void PushManager::Trace(Visitor* visitor) const { visitor->Trace(registration_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.h index c66927e8347..d68c824e310 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.h +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_manager.h @@ -35,7 +35,7 @@ class MODULES_EXPORT PushManager final : public ScriptWrappable { const PushSubscriptionOptionsInit* options, ExceptionState& exception_state); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<ServiceWorkerRegistration> registration_; diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc index 3b8c2e1b697..5cd5058ee55 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.cc @@ -42,7 +42,7 @@ PushMessagingBridge* PushMessagingBridge::From( PushMessagingBridge::PushMessagingBridge( ServiceWorkerRegistration& registration) : Supplement<ServiceWorkerRegistration>(registration), - permission_service_(nullptr) {} + permission_service_(registration.GetExecutionContext()) {} PushMessagingBridge::~PushMessagingBridge() = default; @@ -80,7 +80,7 @@ ScriptPromise PushMessagingBridge::GetPermissionState( return promise; } -void PushMessagingBridge::Trace(Visitor* visitor) { +void PushMessagingBridge::Trace(Visitor* visitor) const { visitor->Trace(permission_service_); Supplement<ServiceWorkerRegistration>::Trace(visitor); } 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 388b885a53c..4bab7fd8e6e 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 @@ -41,7 +41,7 @@ class PushMessagingBridge final : public GarbageCollected<PushMessagingBridge>, ScriptPromise GetPermissionState(ScriptState* script_state, const PushSubscriptionOptionsInit* options); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Method to be invoked when the permission status has been retrieved from the 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 bbceb135601..d5bda0a62da 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 @@ -81,7 +81,7 @@ void PushMessagingClient::Subscribe( } } -void PushMessagingClient::Trace(Visitor* visitor) { +void PushMessagingClient::Trace(Visitor* visitor) const { Supplement<LocalDOMWindow>::Trace(visitor); visitor->Trace(push_messaging_manager_); } 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 333127b5bab..a6c3a22bae1 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 @@ -43,7 +43,7 @@ class PushMessagingClient final : public GarbageCollected<PushMessagingClient>, PushSubscriptionOptions* options, bool user_gesture, std::unique_ptr<PushSubscriptionCallbacks> callbacks); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Returns an initialized PushMessaging service. A connection will be diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.cc index 06d82392539..39f09abc248 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.cc +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_provider.cc @@ -24,7 +24,7 @@ const char PushProvider::kSupplementName[] = "PushProvider"; PushProvider::PushProvider(ServiceWorkerRegistration& registration) : Supplement<ServiceWorkerRegistration>(registration), - push_messaging_manager_(nullptr) {} + push_messaging_manager_(registration.GetExecutionContext()) {} // static PushProvider* PushProvider::From(ServiceWorkerRegistration* registration) { @@ -126,7 +126,7 @@ void PushProvider::GetSubscription( WTF::Passed(std::move(callbacks)))); } -void PushProvider::Trace(Visitor* visitor) { +void PushProvider::Trace(Visitor* visitor) const { visitor->Trace(push_messaging_manager_); Supplement::Trace(visitor); } 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 7f528d1976f..81bba45d577 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 @@ -47,7 +47,7 @@ class PushProvider final : public GarbageCollected<PushProvider>, void Unsubscribe(std::unique_ptr<PushUnsubscribeCallbacks> callbacks); void GetSubscription(std::unique_ptr<PushSubscriptionCallbacks> callbacks); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Returns an initialized PushMessaging service. A connection will be diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.cc index 0cbd9388c74..ea49f2d73d4 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.cc +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription.cc @@ -124,7 +124,7 @@ ScriptValue PushSubscription::toJSONForBinding(ScriptState* script_state) { return result.GetScriptValue(); } -void PushSubscription::Trace(Visitor* visitor) { +void PushSubscription::Trace(Visitor* visitor) const { visitor->Trace(options_); visitor->Trace(p256dh_); visitor->Trace(auth_); 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 ab44cd75652..116bf52a5a4 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 @@ -52,7 +52,7 @@ class MODULES_EXPORT PushSubscription final : public ScriptWrappable { ScriptValue toJSONForBinding(ScriptState* script_state); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: FRIEND_TEST_ALL_PREFIXES(PushSubscriptionTest, diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.cc index a152970b08c..657879a0ad5 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.cc +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.cc @@ -37,7 +37,7 @@ PushSubscription* PushSubscriptionChangeEvent::oldSubscription() const { return old_subscription_; } -void PushSubscriptionChangeEvent::Trace(Visitor* visitor) { +void PushSubscriptionChangeEvent::Trace(Visitor* visitor) const { visitor->Trace(new_subscription_); visitor->Trace(old_subscription_); ExtendableEvent::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.h index 0eb9214c71e..c8fe93c03d3 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.h +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.h @@ -45,7 +45,7 @@ class MODULES_EXPORT PushSubscriptionChangeEvent final PushSubscription* newSubscription() const; PushSubscription* oldSubscription() const; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<PushSubscription> new_subscription_; diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc index 02af187467e..b962d493b58 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.cc @@ -103,7 +103,7 @@ PushSubscriptionOptions::PushSubscriptionOptions( application_server_key.data(), SafeCast<unsigned>(application_server_key.size()))) {} -void PushSubscriptionOptions::Trace(Visitor* visitor) { +void PushSubscriptionOptions::Trace(Visitor* visitor) const { visitor->Trace(application_server_key_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h index 99d5467d204..1b1e2648b0b 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h +++ b/chromium/third_party/blink/renderer/modules/push_messaging/push_subscription_options.h @@ -37,7 +37,7 @@ class PushSubscriptionOptions final : public ScriptWrappable { return application_server_key_; } - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: bool user_visible_only_; diff --git a/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.cc b/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.cc index 2977148f2a3..be8eb6c4d55 100644 --- a/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.cc +++ b/chromium/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.cc @@ -43,7 +43,7 @@ PushManager* ServiceWorkerRegistrationPush::pushManager() { return push_manager_.Get(); } -void ServiceWorkerRegistrationPush::Trace(Visitor* visitor) { +void ServiceWorkerRegistrationPush::Trace(Visitor* visitor) const { visitor->Trace(registration_); visitor->Trace(push_manager_); Supplement<ServiceWorkerRegistration>::Trace(visitor); 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 aa8c1293c69..21f21059731 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 @@ -32,7 +32,7 @@ class ServiceWorkerRegistrationPush final static PushManager* pushManager(ServiceWorkerRegistration& registration); PushManager* pushManager(); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<ServiceWorkerRegistration> registration_; diff --git a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.cc b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.cc index 44235d9feca..223d7407231 100644 --- a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.cc +++ b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.cc @@ -53,7 +53,8 @@ void DeprecatedStorageInfo::queryUsageAndQuota( WebFeature::kQuotaRead); // Dispatching the request to DeprecatedStorageQuota, as this interface is // deprecated in favor of DeprecatedStorageQuota. - DeprecatedStorageQuota* storage_quota = GetStorageQuota(storage_type); + DeprecatedStorageQuota* storage_quota = + GetStorageQuota(storage_type, ExecutionContext::From(script_state)); if (!storage_quota) { // Unknown storage type is requested. DeprecatedStorageQuota::EnqueueStorageErrorCallback( @@ -76,7 +77,8 @@ void DeprecatedStorageInfo::requestQuota( WebFeature::kQuotaRead); // Dispatching the request to DeprecatedStorageQuota, as this interface is // deprecated in favor of DeprecatedStorageQuota. - DeprecatedStorageQuota* storage_quota = GetStorageQuota(storage_type); + DeprecatedStorageQuota* storage_quota = + GetStorageQuota(storage_type, ExecutionContext::From(script_state)); if (!storage_quota) { // Unknown storage type is requested. DeprecatedStorageQuota::EnqueueStorageErrorCallback( @@ -88,25 +90,26 @@ void DeprecatedStorageInfo::requestQuota( } DeprecatedStorageQuota* DeprecatedStorageInfo::GetStorageQuota( - int storage_type) { + int storage_type, + ExecutionContext* execution_context) { switch (storage_type) { case kTemporary: if (!temporary_storage_) { temporary_storage_ = MakeGarbageCollected<DeprecatedStorageQuota>( - DeprecatedStorageQuota::kTemporary); + DeprecatedStorageQuota::kTemporary, execution_context); } return temporary_storage_.Get(); case kPersistent: if (!persistent_storage_) { persistent_storage_ = MakeGarbageCollected<DeprecatedStorageQuota>( - DeprecatedStorageQuota::kPersistent); + DeprecatedStorageQuota::kPersistent, execution_context); } return persistent_storage_.Get(); } return nullptr; } -void DeprecatedStorageInfo::Trace(Visitor* visitor) { +void DeprecatedStorageInfo::Trace(Visitor* visitor) const { visitor->Trace(temporary_storage_); visitor->Trace(persistent_storage_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.h b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.h index b981528176c..fe83a64999c 100644 --- a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.h +++ b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_info.h @@ -65,10 +65,11 @@ class DeprecatedStorageInfo final : public ScriptWrappable { V8StorageQuotaCallback* = nullptr, V8StorageErrorCallback* = nullptr); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: - DeprecatedStorageQuota* GetStorageQuota(int storage_type); + DeprecatedStorageQuota* GetStorageQuota(int storage_type, + ExecutionContext* execution_context); mutable Member<DeprecatedStorageQuota> temporary_storage_; mutable Member<DeprecatedStorageQuota> persistent_storage_; diff --git a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc index 349d2d373cb..d98c703b529 100644 --- a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc +++ b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.cc @@ -122,8 +122,10 @@ void DeprecatedStorageQuota::EnqueueStorageErrorCallback( WrapPersistent(DOMError::Create(exception_code)))); } -DeprecatedStorageQuota::DeprecatedStorageQuota(Type type) - : type_(type), quota_host_(nullptr) {} +DeprecatedStorageQuota::DeprecatedStorageQuota( + Type type, + ExecutionContext* execution_context) + : type_(type), quota_host_(execution_context) {} void DeprecatedStorageQuota::queryUsageAndQuota( ScriptState* script_state, @@ -201,7 +203,7 @@ void DeprecatedStorageQuota::requestQuota( 0, 0)); } -void DeprecatedStorageQuota::Trace(Visitor* visitor) { +void DeprecatedStorageQuota::Trace(Visitor* visitor) const { visitor->Trace(quota_host_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.h b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.h index 77a3c970e67..c4e57cc9397 100644 --- a/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.h +++ b/chromium/third_party/blink/renderer/modules/quota/deprecated_storage_quota.h @@ -32,6 +32,7 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_QUOTA_DEPRECATED_STORAGE_QUOTA_H_ #include "third_party/blink/public/mojom/quota/quota_manager_host.mojom-blink.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/platform/bindings/exception_code.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -59,7 +60,7 @@ class DeprecatedStorageQuota final : public ScriptWrappable { V8StorageErrorCallback*, DOMExceptionCode); - explicit DeprecatedStorageQuota(Type); + DeprecatedStorageQuota(Type, ExecutionContext*); void queryUsageAndQuota(ScriptState*, V8StorageUsageCallback*, @@ -70,7 +71,7 @@ class DeprecatedStorageQuota final : public ScriptWrappable { V8StorageQuotaCallback* = nullptr, V8StorageErrorCallback* = nullptr); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Binds the interface (if not already bound) with the given interface diff --git a/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.cc b/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.cc index 5ccf5e8b497..74ccc5380cf 100644 --- a/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.cc +++ b/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.cc @@ -65,7 +65,7 @@ DeprecatedStorageInfo* DOMWindowQuota::webkitStorageInfo() const { return storage_info_.Get(); } -void DOMWindowQuota::Trace(Visitor* visitor) { +void DOMWindowQuota::Trace(Visitor* visitor) const { visitor->Trace(storage_info_); Supplement<LocalDOMWindow>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.h b/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.h index 997056fa2bd..96c9d1773c2 100644 --- a/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.h +++ b/chromium/third_party/blink/renderer/modules/quota/dom_window_quota.h @@ -52,7 +52,7 @@ class DOMWindowQuota final : public GarbageCollected<DOMWindowQuota>, static DeprecatedStorageInfo* webkitStorageInfo(LocalDOMWindow&); DeprecatedStorageInfo* webkitStorageInfo() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: mutable Member<DeprecatedStorageInfo> storage_info_; diff --git a/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.cc b/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.cc index 98952985bc6..d0d70e45c21 100644 --- a/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.cc +++ b/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.cc @@ -69,7 +69,7 @@ StorageManager* NavigatorStorageQuota::storage(Navigator& navigator) { DeprecatedStorageQuota* NavigatorStorageQuota::webkitTemporaryStorage() const { if (!temporary_storage_) { temporary_storage_ = MakeGarbageCollected<DeprecatedStorageQuota>( - DeprecatedStorageQuota::kTemporary); + DeprecatedStorageQuota::kTemporary, GetSupplementable()->DomWindow()); } return temporary_storage_.Get(); } @@ -77,20 +77,20 @@ DeprecatedStorageQuota* NavigatorStorageQuota::webkitTemporaryStorage() const { DeprecatedStorageQuota* NavigatorStorageQuota::webkitPersistentStorage() const { if (!persistent_storage_) { persistent_storage_ = MakeGarbageCollected<DeprecatedStorageQuota>( - DeprecatedStorageQuota::kPersistent); + DeprecatedStorageQuota::kPersistent, GetSupplementable()->DomWindow()); } return persistent_storage_.Get(); } StorageManager* NavigatorStorageQuota::storage() const { if (!storage_manager_) { - storage_manager_ = MakeGarbageCollected<StorageManager>( - GetSupplementable() ? GetSupplementable()->DomWindow() : nullptr); + storage_manager_ = + MakeGarbageCollected<StorageManager>(GetSupplementable()->DomWindow()); } return storage_manager_.Get(); } -void NavigatorStorageQuota::Trace(Visitor* visitor) { +void NavigatorStorageQuota::Trace(Visitor* visitor) const { visitor->Trace(temporary_storage_); visitor->Trace(persistent_storage_); visitor->Trace(storage_manager_); diff --git a/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.h b/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.h index 8812881b0bf..536dc5e7827 100644 --- a/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.h +++ b/chromium/third_party/blink/renderer/modules/quota/navigator_storage_quota.h @@ -60,7 +60,7 @@ class NavigatorStorageQuota final explicit NavigatorStorageQuota(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: mutable Member<DeprecatedStorageQuota> temporary_storage_; diff --git a/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc b/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc index e9741f0e2a3..b839a14836c 100644 --- a/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc +++ b/chromium/third_party/blink/renderer/modules/quota/storage_manager.cc @@ -157,7 +157,7 @@ ScriptPromise StorageManager::estimate(ScriptState* script_state) { return promise; } -void StorageManager::Trace(Visitor* visitor) { +void StorageManager::Trace(Visitor* visitor) const { visitor->Trace(permission_service_); visitor->Trace(quota_host_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/quota/storage_manager.h b/chromium/third_party/blink/renderer/modules/quota/storage_manager.h index 7b9831145e4..7bd1b179a89 100644 --- a/chromium/third_party/blink/renderer/modules/quota/storage_manager.h +++ b/chromium/third_party/blink/renderer/modules/quota/storage_manager.h @@ -30,7 +30,7 @@ class StorageManager final : public ScriptWrappable { ScriptPromise estimate(ScriptState*); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: mojom::blink::PermissionService* GetPermissionService(ExecutionContext*); diff --git a/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.cc b/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.cc index 96c8c28059d..e76f9a5bcee 100644 --- a/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.cc +++ b/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.cc @@ -65,7 +65,7 @@ StorageManager* WorkerNavigatorStorageQuota::storage() const { return storage_manager_.Get(); } -void WorkerNavigatorStorageQuota::Trace(Visitor* visitor) { +void WorkerNavigatorStorageQuota::Trace(Visitor* visitor) const { visitor->Trace(storage_manager_); Supplement<WorkerNavigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.h b/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.h index b2bc26f52fa..9fbe4583d13 100644 --- a/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.h +++ b/chromium/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.h @@ -56,7 +56,7 @@ class WorkerNavigatorStorageQuota final explicit WorkerNavigatorStorageQuota(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: mutable Member<StorageManager> storage_manager_; diff --git a/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.cc b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.cc index 4167756a102..ea70e4f744c 100644 --- a/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.cc +++ b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.cc @@ -82,10 +82,6 @@ void RemoteObjectGatewayImpl::OnClearWindowObjectInMainWorld() { InjectNamed(pair.key, pair.value); } -void RemoteObjectGatewayImpl::Dispose() { - receiver_.reset(); -} - void RemoteObjectGatewayImpl::AddNamedObject(const WTF::String& name, int32_t id) { // Added objects only become available after page reload, so here they diff --git a/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h index 140826e52c7..9d68e7249c8 100644 --- a/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h +++ b/chromium/third_party/blink/renderer/modules/remote_objects/remote_object_gateway_impl.h @@ -25,7 +25,6 @@ class MODULES_EXPORT RemoteObjectGatewayImpl public Supplement<LocalFrame>, public mojom::blink::RemoteObjectGateway { USING_GARBAGE_COLLECTED_MIXIN(RemoteObjectGatewayImpl); - USING_PRE_FINALIZER(RemoteObjectGatewayImpl, Dispose); public: static const char kSupplementName[]; @@ -40,7 +39,6 @@ class MODULES_EXPORT RemoteObjectGatewayImpl RemoteObjectGatewayImpl(const RemoteObjectGatewayImpl&) = delete; RemoteObjectGatewayImpl& operator=(const RemoteObjectGatewayImpl&) = delete; ~RemoteObjectGatewayImpl() override = default; - void Dispose(); static void BindMojoReceiver( LocalFrame*, @@ -53,7 +51,7 @@ class MODULES_EXPORT RemoteObjectGatewayImpl void OnClearWindowObjectInMainWorld(); - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(receiver_); visitor->Trace(object_host_); Supplement<LocalFrame>::Trace(visitor); @@ -75,10 +73,10 @@ class MODULES_EXPORT RemoteObjectGatewayImpl HeapMojoReceiver<mojom::blink::RemoteObjectGateway, RemoteObjectGatewayImpl, - HeapMojoWrapperMode::kWithoutContextObserver> + HeapMojoWrapperMode::kForceWithoutContextObserver> receiver_; HeapMojoRemote<mojom::blink::RemoteObjectHost, - HeapMojoWrapperMode::kWithoutContextObserver> + HeapMojoWrapperMode::kForceWithoutContextObserver> object_host_; }; diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.cc b/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.cc index 526b56716c6..39de85ca4b3 100644 --- a/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.cc +++ b/chromium/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.cc @@ -28,7 +28,7 @@ void AvailabilityCallbackWrapper::Run(RemotePlayback* remote_playback, bindings_cb_->InvokeAndReportException(remote_playback, new_availability); } -void AvailabilityCallbackWrapper::Trace(Visitor* visitor) { +void AvailabilityCallbackWrapper::Trace(Visitor* visitor) const { visitor->Trace(bindings_cb_); } 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 79abd6c89db..2cdf5b3dfc8 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 @@ -29,7 +29,7 @@ class AvailabilityCallbackWrapper final void Run(RemotePlayback*, bool new_availability); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "AvailabilityCallbackWrapper"; } 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 1929581aac1..821d168e68e 100644 --- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc +++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.cc @@ -610,7 +610,7 @@ void RemotePlayback::MaybeStartListeningForAvailability() { is_listening_ = true; } -void RemotePlayback::Trace(Visitor* visitor) { +void RemotePlayback::Trace(Visitor* visitor) const { visitor->Trace(availability_callbacks_); visitor->Trace(prompt_promise_resolver_); visitor->Trace(media_element_); diff --git a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h index 02fbe2399ad..65e1a76dca6 100644 --- a/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h +++ b/chromium/third_party/blink/renderer/modules/remoteplayback/remote_playback.h @@ -136,7 +136,7 @@ class MODULES_EXPORT RemotePlayback final DEFINE_ATTRIBUTE_EVENT_LISTENER(connect, kConnect) DEFINE_ATTRIBUTE_EVENT_LISTENER(disconnect, kDisconnect) - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class V8RemotePlayback; diff --git a/chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn b/chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn index a3dfacaba95..f69ccbd3433 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/scheduler/BUILD.gn @@ -14,7 +14,5 @@ blink_modules_sources("scheduler") { "dom_task_controller.h", "dom_task_signal.cc", "dom_task_signal.h", - "window_scheduler.cc", - "window_scheduler.h", ] } diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc index faa8475d811..745eca12ad0 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc +++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.cc @@ -32,7 +32,7 @@ static ScriptPromise RejectPromiseImmediately(ExceptionState& exception_state) { const char DOMScheduler::kSupplementName[] = "DOMScheduler"; -DOMScheduler* DOMScheduler::From(LocalDOMWindow& window) { +DOMScheduler* DOMScheduler::scheduler(LocalDOMWindow& window) { DOMScheduler* scheduler = Supplement<LocalDOMWindow>::From<DOMScheduler>(window); if (!scheduler) { @@ -56,7 +56,7 @@ void DOMScheduler::ContextDestroyed() { global_task_queues_.clear(); } -void DOMScheduler::Trace(Visitor* visitor) { +void DOMScheduler::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); Supplement<LocalDOMWindow>::Trace(visitor); @@ -74,7 +74,8 @@ ScriptPromise DOMScheduler::postTask(ScriptState* script_state, // Always honor the priority and the task signal if given. DOMTaskSignal* task_signal = nullptr; - if (!options->hasPriority() && IsA<DOMTaskSignal>(options->signal())) { + // TODO(crbug.com/1070871): Stop using APIs for non-null. + if (!options->hasPriorityNonNull() && IsA<DOMTaskSignal>(options->signal())) { // If only a signal is given, and it is a TaskSignal rather than an // basic AbortSignal, use it. task_signal = To<DOMTaskSignal>(options->signal()); @@ -87,8 +88,9 @@ ScriptPromise DOMScheduler::postTask(ScriptState* script_state, // own task queue. Instead, it will use the appropriate task queue from // |global_task_queues_|. WebSchedulingPriority priority = - options->hasPriority() - ? WebSchedulingPriorityFromString(AtomicString(options->priority())) + options->hasPriorityNonNull() + ? WebSchedulingPriorityFromString( + AtomicString(options->priorityNonNull())) : WebSchedulingPriority::kUserVisiblePriority; task_signal = MakeGarbageCollected<DOMTaskSignal>( GetSupplementable(), priority, DOMTaskSignal::Type::kImplicit); diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h index e557ca14b8d..886c7cf7027 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h +++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_scheduler.h @@ -34,7 +34,7 @@ class MODULES_EXPORT DOMScheduler : public ScriptWrappable, public: static const char kSupplementName[]; - static DOMScheduler* From(LocalDOMWindow&); + static DOMScheduler* scheduler(LocalDOMWindow&); explicit DOMScheduler(LocalDOMWindow*); @@ -67,7 +67,7 @@ class MODULES_EXPORT DOMScheduler : public ScriptWrappable, void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: static constexpr size_t kWebSchedulingPriorityCount = diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc index 75b847c53a3..03e6a5f0100 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc +++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.cc @@ -62,7 +62,7 @@ DOMTask::DOMTask(DOMScheduler* scheduler, &async_task_id_); } -void DOMTask::Trace(Visitor* visitor) { +void DOMTask::Trace(Visitor* visitor) const { visitor->Trace(scheduler_); visitor->Trace(callback_); visitor->Trace(arguments_); diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_task.h b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.h index d9c4f784d0c..7c490b2a427 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/dom_task.h +++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task.h @@ -30,7 +30,7 @@ class DOMTask final : public GarbageCollected<DOMTask> { DOMTaskSignal*, base::TimeDelta delay); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; private: // Entry point for running this DOMTask's |callback_|. diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.cc b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.cc index bd1aab5d820..b49fb90a7e9 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.cc +++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.cc @@ -59,10 +59,10 @@ base::SingleThreadTaskRunner* DOMTaskSignal::GetTaskRunner() { return nullptr; if (web_scheduling_task_queue_) return web_scheduling_task_queue_->GetTaskRunner().get(); - return DOMScheduler::From(*window)->GetTaskRunnerFor(priority_); + return DOMScheduler::scheduler(*window)->GetTaskRunnerFor(priority_); } -void DOMTaskSignal::Trace(Visitor* visitor) { +void DOMTaskSignal::Trace(Visitor* visitor) const { AbortSignal::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.h b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.h index 7ffbbf12e6e..88f885c7a78 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.h +++ b/chromium/third_party/blink/renderer/modules/scheduler/dom_task_signal.h @@ -51,7 +51,7 @@ class MODULES_EXPORT DOMTaskSignal final bool IsTaskSignal() const override { return true; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; PriorityChangeStatus GetPriorityChangeStatus() const { return priority_change_status_; diff --git a/chromium/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl b/chromium/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl index c3a301134ef..2e9704eb05b 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl +++ b/chromium/third_party/blink/renderer/modules/scheduler/scheduler_post_task_options.idl @@ -11,7 +11,7 @@ enum TaskPriority { }; dictionary SchedulerPostTaskOptions { - AbortSignal? signal; - TaskPriority? priority; + AbortSignal? signal = null; + TaskPriority? priority = null; long delay = 0; }; diff --git a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.cc b/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.cc deleted file mode 100644 index 7a6863a93f5..00000000000 --- a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.cc +++ /dev/null @@ -1,16 +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/window_scheduler.h" - -#include "third_party/blink/renderer/core/frame/local_dom_window.h" -#include "third_party/blink/renderer/modules/scheduler/dom_scheduler.h" - -namespace blink { - -DOMScheduler* WindowScheduler::scheduler(LocalDOMWindow& window) { - return DOMScheduler::From(window); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.h b/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.h deleted file mode 100644 index e8739bcfc70..00000000000 --- a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.h +++ /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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_WINDOW_SCHEDULER_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_WINDOW_SCHEDULER_H_ - -#include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -class DOMScheduler; -class LocalDOMWindow; - -class MODULES_EXPORT WindowScheduler { - STATIC_ONLY(WindowScheduler); - - public: - static DOMScheduler* scheduler(LocalDOMWindow&); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SCHEDULER_WINDOW_SCHEDULER_H_ diff --git a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.idl b/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.idl index 7abdda42690..439b421567a 100644 --- a/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.idl +++ b/chromium/third_party/blink/renderer/modules/scheduler/window_scheduler.idl @@ -5,7 +5,7 @@ // Experimental Scheduling API Proposal: // https://docs.google.com/document/d/1xU7HyNsEsbXhTgt0ZnXDbeSXm5-m5FzkLJAT6LTizEI/edit# [ - ImplementedAs=WindowScheduler + ImplementedAs=DOMScheduler ] partial interface Window { [RuntimeEnabled=WebScheduler, SameObject, Replaceable] readonly attribute Scheduler scheduler; }; diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc index a14dfdebf17..43aaa3a700b 100644 --- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc +++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.cc @@ -172,7 +172,7 @@ ScreenOrientationController* ScreenOrientation::Controller() { *To<LocalDOMWindow>(GetExecutionContext())); } -void ScreenOrientation::Trace(Visitor* visitor) { +void ScreenOrientation::Trace(Visitor* visitor) const { EventTargetWithInlineData::Trace(visitor); ExecutionContextClient::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h index ea4b89015b4..deb53f12621 100644 --- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h +++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation.h @@ -54,7 +54,7 @@ class MODULES_EXPORT ScreenOrientation final : public EventTargetWithInlineData, // Helper being used by this class and LockOrientationCallback. static const AtomicString& OrientationTypeToString(WebScreenOrientationType); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ScreenOrientationController* Controller(); diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.cc b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.cc index a670515778d..a0944f2fb9b 100644 --- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.cc +++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.cc @@ -226,7 +226,7 @@ void ScreenOrientationController::ContextDestroyed() { active_lock_ = false; } -void ScreenOrientationController::Trace(Visitor* visitor) { +void ScreenOrientationController::Trace(Visitor* visitor) const { visitor->Trace(orientation_); visitor->Trace(screen_orientation_service_); ExecutionContextLifecycleObserver::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h index aec4d259692..20604b26ff4 100644 --- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h +++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_orientation_controller.h @@ -49,7 +49,7 @@ class MODULES_EXPORT ScreenOrientationController final void SetScreenOrientationAssociatedRemoteForTests( HeapMojoAssociatedRemote<device::mojom::blink::ScreenOrientation>); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class MediaControlsOrientationLockAndRotateToFullscreenDelegateTest; diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc index 343697ca1ed..a862879dd10 100644 --- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc +++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.cc @@ -38,7 +38,7 @@ ScreenOrientation* ScreenScreenOrientation::orientation(Screen& screen) { const char ScreenScreenOrientation::kSupplementName[] = "ScreenScreenOrientation"; -void ScreenScreenOrientation::Trace(Visitor* visitor) { +void ScreenScreenOrientation::Trace(Visitor* visitor) const { visitor->Trace(orientation_); Supplement<Screen>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.h b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.h index c7d63845576..57a975ae4a1 100644 --- a/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.h +++ b/chromium/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.h @@ -26,7 +26,7 @@ class ScreenScreenOrientation final static ScreenOrientation* orientation(Screen&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<ScreenOrientation> orientation_; 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 8c67fe88f1a..0479c6e49ad 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 @@ -38,7 +38,7 @@ AbsoluteOrientationSensor::AbsoluteOrientationSensor( mojom::blink::FeaturePolicyFeature::kGyroscope, mojom::blink::FeaturePolicyFeature::kMagnetometer}) {} -void AbsoluteOrientationSensor::Trace(Visitor* visitor) { +void AbsoluteOrientationSensor::Trace(Visitor* visitor) const { OrientationSensor::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.h b/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.h index 588c5dc78c1..d0133130315 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.h +++ b/chromium/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.h @@ -23,7 +23,7 @@ class AbsoluteOrientationSensor final : public OrientationSensor { const SpatialSensorOptions*, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // 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 315fa9d2ef4..77e3861f7b4 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.cc @@ -57,7 +57,7 @@ base::Optional<double> Accelerometer::z() const { return base::nullopt; } -void Accelerometer::Trace(Visitor* visitor) { +void Accelerometer::Trace(Visitor* visitor) const { Sensor::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.h b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.h index e339c4ed4e5..a5d0d0ea8e0 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/accelerometer.h +++ b/chromium/third_party/blink/renderer/modules/sensor/accelerometer.h @@ -29,7 +29,7 @@ class Accelerometer : public Sensor { base::Optional<double> y() const; base::Optional<double> z() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // 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 e6463e49a9c..20c7e36df2c 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 @@ -57,6 +57,10 @@ AmbientLightSensor::AmbientLightSensor(ExecutionContext* execution_context, SensorType::AMBIENT_LIGHT, {mojom::blink::FeaturePolicyFeature::kAmbientLightSensor}) {} +bool AmbientLightSensor::hasReading() const { + return latest_reading_.has_value() && Sensor::hasReading(); +} + base::Optional<double> AmbientLightSensor::illuminance() const { if (hasReading()) { DCHECK(latest_reading_.has_value()); @@ -72,7 +76,7 @@ void AmbientLightSensor::OnSensorReadingChanged() { // The platform sensor may start sending readings before the sensor is fully // activated on the Blink side. In this case, bail out early, otherwise we // will set |latest_reading_| and not send a "reading" event. - if (!IsActivated()) + if (!activated()) return; const double new_reading = GetReading().als.value; 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 0db46bfba8f..df25023c1ea 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 @@ -23,6 +23,7 @@ class MODULES_EXPORT AmbientLightSensor final : public Sensor { AmbientLightSensor(ExecutionContext*, const SensorOptions*, ExceptionState&); + bool hasReading() const override; base::Optional<double> illuminance() const; void OnSensorReadingChanged() override; 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 index 305e19cb78f..ff501b72db2 100644 --- 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 @@ -187,14 +187,18 @@ TEST(AmbientLightSensorTest, PlatformSensorReadingsBeforeActivation) { // a fully activated state. mock_observer->WaitForSensorInitialization(); context.sensor_provider()->UpdateAmbientLightSensorData(42); - ASSERT_FALSE(sensor->IsActivated()); + ASSERT_FALSE(sensor->activated()); + EXPECT_FALSE(sensor->hasReading()); EXPECT_FALSE(sensor->illuminance().has_value()); + EXPECT_FALSE(sensor->timestamp(context.GetScriptState()).has_value()); SensorTestUtils::WaitForEvent(sensor, event_type_names::kReading); EXPECT_EQ(42, sensor->latest_reading_); + EXPECT_TRUE(sensor->hasReading()); ASSERT_TRUE(sensor->illuminance().has_value()); EXPECT_EQ(50, sensor->illuminance().value()); + EXPECT_TRUE(sensor->timestamp(context.GetScriptState()).has_value()); } } // 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 e4346adeebe..bc167a5e1c9 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.cc @@ -51,7 +51,7 @@ base::Optional<double> Gyroscope::z() const { return base::nullopt; } -void Gyroscope::Trace(Visitor* visitor) { +void Gyroscope::Trace(Visitor* visitor) const { Sensor::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.h b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.h index 7f26700a1e3..dba36886b53 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/gyroscope.h +++ b/chromium/third_party/blink/renderer/modules/sensor/gyroscope.h @@ -25,7 +25,7 @@ class Gyroscope final : public Sensor { base::Optional<double> y() const; base::Optional<double> z() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // 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 a1bcf3beccf..e455bf02972 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 @@ -36,7 +36,7 @@ LinearAccelerationSensor::LinearAccelerationSensor( SensorType::LINEAR_ACCELERATION, {mojom::blink::FeaturePolicyFeature::kAccelerometer}) {} -void LinearAccelerationSensor::Trace(Visitor* visitor) { +void LinearAccelerationSensor::Trace(Visitor* visitor) const { Accelerometer::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.h b/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.h index 96dc875e415..af9c6efb56e 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.h +++ b/chromium/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.h @@ -22,7 +22,7 @@ class LinearAccelerationSensor final : public Accelerometer { const SpatialSensorOptions*, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // 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 7a12f79c79c..a6e173c98bb 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.cc @@ -52,7 +52,7 @@ base::Optional<double> Magnetometer::z() const { return base::nullopt; } -void Magnetometer::Trace(Visitor* visitor) { +void Magnetometer::Trace(Visitor* visitor) const { Sensor::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.h b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.h index 47811383c6c..98d0d647038 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/magnetometer.h +++ b/chromium/third_party/blink/renderer/modules/sensor/magnetometer.h @@ -25,7 +25,7 @@ class Magnetometer final : public Sensor { base::Optional<double> y() const; base::Optional<double> z() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.cc b/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.cc index 2f92149900c..681e392b6e4 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.cc @@ -129,7 +129,7 @@ void OrientationSensor::OnSensorReadingChanged() { Sensor::OnSensorReadingChanged(); } -void OrientationSensor::Trace(Visitor* visitor) { +void OrientationSensor::Trace(Visitor* visitor) const { Sensor::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.h b/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.h index 471d85464e8..1f5b00efcf9 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.h +++ b/chromium/third_party/blink/renderer/modules/sensor/orientation_sensor.h @@ -21,7 +21,7 @@ class OrientationSensor : public Sensor { bool isReadingDirty() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: OrientationSensor(ExecutionContext*, 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 ed7884e079d..4f7c99323c8 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 @@ -37,7 +37,7 @@ RelativeOrientationSensor::RelativeOrientationSensor( {mojom::blink::FeaturePolicyFeature::kAccelerometer, mojom::blink::FeaturePolicyFeature::kGyroscope}) {} -void RelativeOrientationSensor::Trace(Visitor* visitor) { +void RelativeOrientationSensor::Trace(Visitor* visitor) const { OrientationSensor::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h b/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h index 37562d1b94b..9ff5cefdb0c 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h +++ b/chromium/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.h @@ -23,7 +23,7 @@ class RelativeOrientationSensor final : public OrientationSensor { const SpatialSensorOptions*, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // 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 6a895c5ea0a..3c05cf3a4c7 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor.cc @@ -109,7 +109,7 @@ bool Sensor::activated() const { } bool Sensor::hasReading() const { - if (!IsActivated()) + if (!activated()) return false; DCHECK(sensor_proxy_); return sensor_proxy_->GetReading().timestamp() != 0.0; @@ -140,7 +140,7 @@ base::Optional<DOMHighResTimeStamp> Sensor::timestamp( base::TimeDelta::FromSecondsD(sensor_proxy_->GetReading().timestamp())); } -void Sensor::Trace(Visitor* visitor) { +void Sensor::Trace(Visitor* visitor) const { visitor->Trace(sensor_proxy_); ActiveScriptWrappable::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); @@ -346,7 +346,12 @@ void Sensor::NotifyActivated() { DCHECK_EQ(state_, SensorState::kActivating); state_ = SensorState::kActivated; - if (hasReading()) { + // Explicitly call the Sensor implementation of hasReading(). Subclasses may + // override the method and introduce additional requirements, but in this case + // we are really only interested in whether there is data in the shared + // buffer, so that we can then process it possibly for the first time in + // OnSensorReadingChanged(). + if (Sensor::hasReading()) { // 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. diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor.h b/chromium/third_party/blink/renderer/modules/sensor/sensor.h index 0bc69269dac..28c3c8ae3d4 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor.h +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor.h @@ -53,7 +53,7 @@ class MODULES_EXPORT Sensor : public EventTargetWithInlineData, // Getters bool activated() const; - bool hasReading() const; + virtual bool hasReading() const; base::Optional<DOMHighResTimeStamp> timestamp(ScriptState*) const; DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError) @@ -63,7 +63,7 @@ class MODULES_EXPORT Sensor : public EventTargetWithInlineData, // ActiveScriptWrappable overrides. bool HasPendingActivity() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: Sensor(ExecutionContext*, @@ -86,7 +86,6 @@ class MODULES_EXPORT Sensor : public EventTargetWithInlineData, // parameters if needed. virtual SensorConfigurationPtr CreateSensorConfig(); - bool IsActivated() const { return state_ == SensorState::kActivated; } bool IsIdleOrErrored() const; const device::SensorReading& GetReading() const; diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.cc index ac770c50116..0639f170228 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.cc @@ -27,7 +27,7 @@ const AtomicString& SensorErrorEvent::InterfaceName() const { return event_interface_names::kSensorErrorEvent; } -void SensorErrorEvent::Trace(Visitor* visitor) { +void SensorErrorEvent::Trace(Visitor* visitor) const { visitor->Trace(error_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.h index 5246fb18223..501801faf3e 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.h +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_error_event.h @@ -31,7 +31,7 @@ class SensorErrorEvent : public Event { const SensorErrorEventInit* initializer); ~SensorErrorEvent() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const AtomicString& InterfaceName() const override; diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc b/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc index 6a0448a161c..db68b4a2b69 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.cc @@ -17,7 +17,7 @@ namespace blink { SensorInspectorAgent::SensorInspectorAgent(LocalDOMWindow* window) : provider_(SensorProviderProxy::From(window)) {} -void SensorInspectorAgent::Trace(Visitor* visitor) { +void SensorInspectorAgent::Trace(Visitor* visitor) const { visitor->Trace(provider_); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h index 67f418589b9..715a6bf7be8 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_inspector_agent.h @@ -16,7 +16,7 @@ class SensorProviderProxy; class SensorInspectorAgent : public GarbageCollected<SensorInspectorAgent> { public: explicit SensorInspectorAgent(LocalDOMWindow* window); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; void DidCommitLoadForLocalFrame(LocalFrame* frame); 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 72ca3470276..e8f1c915973 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 @@ -47,7 +47,7 @@ SensorProviderProxy* SensorProviderProxy::From(LocalDOMWindow* window) { SensorProviderProxy::~SensorProviderProxy() = default; -void SensorProviderProxy::Trace(Visitor* visitor) { +void SensorProviderProxy::Trace(Visitor* visitor) const { visitor->Trace(sensor_proxies_); visitor->Trace(sensor_provider_); Supplement<LocalDOMWindow>::Trace(visitor); 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 a10fd50c0fc..cf514188a1d 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 @@ -40,7 +40,7 @@ class MODULES_EXPORT SensorProviderProxy final void set_inspector_mode(bool flag) { inspector_mode_ = flag; } bool inspector_mode() const { return inspector_mode_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class SensorProxy; 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 eb4e3f10f55..24b47d645a1 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.cc @@ -32,7 +32,7 @@ SensorProxy::SensorProxy(device::mojom::blink::SensorType sensor_type, SensorProxy::~SensorProxy() {} -void SensorProxy::Trace(Visitor* visitor) { +void SensorProxy::Trace(Visitor* visitor) const { visitor->Trace(observers_); visitor->Trace(provider_); PageVisibilityObserver::Trace(visitor); 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 c6c2ea69016..fe583ef7630 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.h +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy.h @@ -71,7 +71,7 @@ class MODULES_EXPORT SensorProxy : public GarbageCollected<SensorProxy>, // Detach from the local frame's SensorProviderProxy. void Detach(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; static const char kDefaultErrorDescription[]; 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 4da34701c04..c4ae9a5ae99 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 @@ -31,7 +31,7 @@ SensorProxyImpl::SensorProxyImpl(device::mojom::blink::SensorType sensor_type, SensorProxyImpl::~SensorProxyImpl() {} -void SensorProxyImpl::Trace(Visitor* visitor) { +void SensorProxyImpl::Trace(Visitor* visitor) const { visitor->Trace(sensor_remote_); visitor->Trace(client_receiver_); SensorProxy::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h index 9b344b67cae..8e444f732ae 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_impl.h @@ -28,7 +28,7 @@ class SensorProxyImpl final : public SensorProxy, Page*); ~SensorProxyImpl() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // SensorProxy overrides. @@ -76,11 +76,11 @@ class SensorProxyImpl final : public SensorProxy, device::mojom::blink::ReportingMode mode_ = device::mojom::blink::ReportingMode::CONTINUOUS; HeapMojoRemote<device::mojom::blink::Sensor, - HeapMojoWrapperMode::kWithoutContextObserver> + HeapMojoWrapperMode::kForceWithoutContextObserver> sensor_remote_; HeapMojoReceiver<device::mojom::blink::SensorClient, SensorProxyImpl, - HeapMojoWrapperMode::kWithoutContextObserver> + HeapMojoWrapperMode::kForceWithoutContextObserver> client_receiver_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 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 d398eedebdd..97bd1d575ef 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 @@ -22,7 +22,7 @@ SensorProxyInspectorImpl::SensorProxyInspectorImpl( SensorProxyInspectorImpl::~SensorProxyInspectorImpl() {} -void SensorProxyInspectorImpl::Trace(Visitor* visitor) { +void SensorProxyInspectorImpl::Trace(Visitor* visitor) const { SensorProxy::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.h b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.h index c5531d98a38..be5cfde344e 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.h +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_proxy_inspector_impl.h @@ -18,7 +18,7 @@ class SensorProxyInspectorImpl final : public SensorProxy { Page* page); ~SensorProxyInspectorImpl() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // SensorProxy overrides. 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 index cc0c3c8c79c..fc23d826218 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.cc +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.cc @@ -13,6 +13,7 @@ #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/bindings/script_state.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -46,14 +47,14 @@ SensorTestContext::SensorTestContext() { // Necessary for SensorProxy::ShouldSuspendUpdates() to work correctly. testing_scope_.GetPage().GetFocusController().SetFocused(true); - testing_scope_.GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting( + testing_scope_.GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting( device::mojom::blink::SensorProvider::Name_, WTF::BindRepeating(&SensorTestContext::BindSensorProviderRequest, WTF::Unretained(this))); } SensorTestContext::~SensorTestContext() { - testing_scope_.GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting( + testing_scope_.GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting( device::mojom::blink::SensorProvider::Name_, {}); } @@ -61,6 +62,10 @@ ExecutionContext* SensorTestContext::GetExecutionContext() const { return testing_scope_.GetExecutionContext(); } +ScriptState* SensorTestContext::GetScriptState() const { + return testing_scope_.GetScriptState(); +} + void SensorTestContext::BindSensorProviderRequest( mojo::ScopedMessagePipeHandle handle) { sensor_provider_.Bind( 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 index 1f43d08a1b6..49308453916 100644 --- a/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.h +++ b/chromium/third_party/blink/renderer/modules/sensor/sensor_test_utils.h @@ -16,6 +16,7 @@ namespace blink { class EventTarget; class ExecutionContext; +class ScriptState; class SensorTestContext final { STACK_ALLOCATED(); @@ -26,6 +27,7 @@ class SensorTestContext final { ~SensorTestContext(); ExecutionContext* GetExecutionContext() const; + ScriptState* GetScriptState() const; device::FakeSensorProvider* sensor_provider() { return &sensor_provider_; } diff --git a/chromium/third_party/blink/renderer/modules/serial/idls.gni b/chromium/third_party/blink/renderer/modules/serial/idls.gni index ba4a9008d2b..ad28c9ed62b 100644 --- a/chromium/third_party/blink/renderer/modules/serial/idls.gni +++ b/chromium/third_party/blink/renderer/modules/serial/idls.gni @@ -14,6 +14,7 @@ modules_dictionary_idl_files = [ "serial_options.idl", "serial_output_signals.idl", "serial_port_filter.idl", + "serial_port_info.idl", "serial_port_request_options.idl", ] diff --git a/chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc index 01f671ebcfa..a290e90aaef 100644 --- a/chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc +++ b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.cc @@ -25,7 +25,7 @@ Serial* NavigatorSerial::serial(Navigator& navigator) { return NavigatorSerial::From(navigator).serial(); } -void NavigatorSerial::Trace(Visitor* visitor) { +void NavigatorSerial::Trace(Visitor* visitor) const { visitor->Trace(serial_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/serial/navigator_serial.h b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.h index 6ffce8e109c..d47beb7dc24 100644 --- a/chromium/third_party/blink/renderer/modules/serial/navigator_serial.h +++ b/chromium/third_party/blink/renderer/modules/serial/navigator_serial.h @@ -27,7 +27,7 @@ class NavigatorSerial final : public GarbageCollected<NavigatorSerial>, explicit NavigatorSerial(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<Serial> serial_; diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.cc b/chromium/third_party/blink/renderer/modules/serial/serial.cc index 00ab0eb29a5..e8c393ecb48 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial.cc +++ b/chromium/third_party/blink/renderer/modules/serial/serial.cc @@ -104,7 +104,7 @@ ScriptPromise Serial::requestPort(ScriptState* script_state, return ScriptPromise(); } - if (!frame->GetDocument()->IsFeatureEnabled( + if (!GetExecutionContext()->IsFeatureEnabled( mojom::blink::FeaturePolicyFeature::kSerial, ReportOptions::kReportOnFailure)) { exception_state.ThrowSecurityError(kFeaturePolicyBlocked); @@ -164,7 +164,7 @@ void Serial::GetPort( service_->GetPort(token, std::move(receiver)); } -void Serial::Trace(Visitor* visitor) { +void Serial::Trace(Visitor* visitor) const { visitor->Trace(service_); visitor->Trace(receiver_); visitor->Trace(get_ports_promises_); diff --git a/chromium/third_party/blink/renderer/modules/serial/serial.h b/chromium/third_party/blink/renderer/modules/serial/serial.h index 7ff8eea900a..08cc1b54cee 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial.h +++ b/chromium/third_party/blink/renderer/modules/serial/serial.h @@ -56,7 +56,7 @@ class Serial final : public EventTargetWithInlineData, void GetPort( const base::UnguessableToken& token, mojo::PendingReceiver<device::mojom::blink::SerialPort> receiver); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: // EventTarget diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.cc b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.cc index c1ffbdde4df..98fd77de0fb 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.cc +++ b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.cc @@ -29,7 +29,7 @@ SerialConnectionEvent::SerialConnectionEvent(const AtomicString& type, SerialPort* port) : Event(type, Bubbles::kNo, Cancelable::kNo), port_(port) {} -void SerialConnectionEvent::Trace(Visitor* visitor) { +void SerialConnectionEvent::Trace(Visitor* visitor) const { visitor->Trace(port_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.h b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.h index ac4cd5242ea..ad47f6ced9c 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.h +++ b/chromium/third_party/blink/renderer/modules/serial/serial_connection_event.h @@ -27,7 +27,7 @@ class SerialConnectionEvent final : public Event { SerialPort* port() const { return port_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<SerialPort> port_; 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 f132ce0fbd3..8166b0726af 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial_port.cc +++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.cc @@ -10,6 +10,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_serial_input_signals.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_serial_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_serial_output_signals.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_serial_port_info.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/streams/readable_stream.h" #include "third_party/blink/renderer/core/streams/writable_stream.h" @@ -29,6 +30,8 @@ const char kResourcesExhaustedReadBuffer[] = "Resources exhausted allocating read buffer."; const char kResourcesExhaustedWriteBuffer[] = "Resources exhausted allocation write buffer."; +const char kNoSignals[] = + "Signals dictionary must contain at least one member."; const char kPortClosed[] = "The port is closed."; const char kOpenError[] = "Failed to open serial port."; const char kDeviceLostError[] = "The device has been lost."; @@ -122,7 +125,7 @@ class ContinueCloseFunction : public ScriptFunction { return port_->ContinueClose(GetScriptState()).GetScriptValue(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(port_); ScriptFunction::Trace(visitor); } @@ -148,7 +151,7 @@ class AbortCloseFunction : public ScriptFunction { return ScriptValue(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(port_); ScriptFunction::Trace(visitor); } @@ -166,6 +169,15 @@ SerialPort::SerialPort(Serial* parent, mojom::blink::SerialPortInfoPtr info) SerialPort::~SerialPort() = default; +SerialPortInfo* SerialPort::getInfo() { + auto* info = MakeGarbageCollected<SerialPortInfo>(); + if (info_->has_usb_vendor_id) + info->setUsbVendorId(info_->usb_vendor_id); + if (info_->has_usb_product_id) + info->setUsbProductId(info_->usb_product_id); + return info; +} + ScriptPromise SerialPort::open(ScriptState* script_state, const SerialOptions* options, ExceptionState& exception_state) { @@ -246,24 +258,6 @@ ScriptPromise SerialPort::open(ScriptState* script_state, mojo_options->has_cts_flow_control = true; mojo_options->cts_flow_control = options->rtscts(); - // Pipe handle pair for the ReadableStream. - mojo::ScopedDataPipeConsumerHandle readable_pipe; - mojo::ScopedDataPipeProducerHandle readable_pipe_producer; - if (!CreateDataPipe(&readable_pipe_producer, &readable_pipe)) { - 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)) { - exception_state.ThrowDOMException(DOMExceptionCode::kQuotaExceededError, - kResourcesExhaustedWriteBuffer); - return ScriptPromise(); - } - mojo::PendingRemote<device::mojom::blink::SerialPortClient> client; parent_->GetPort( info_->token, @@ -274,12 +268,9 @@ 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), client.InitWithNewPipeAndPassReceiver()); - port_->Open(std::move(mojo_options), std::move(writable_pipe_consumer), - std::move(readable_pipe_producer), std::move(client), - std::move(callback)); + port_->Open(std::move(mojo_options), std::move(client), std::move(callback)); return open_resolver_->Promise(); } @@ -291,16 +282,25 @@ ReadableStream* SerialPort::readable(ScriptState* script_state, if (!port_.is_bound() || open_resolver_ || closing_ || read_fatal_) return nullptr; - mojo::ScopedDataPipeConsumerHandle readable_pipe; - mojo::ScopedDataPipeProducerHandle readable_pipe_producer; - if (!CreateDataPipe(&readable_pipe_producer, &readable_pipe)) { + mojo::ScopedDataPipeProducerHandle producer; + mojo::ScopedDataPipeConsumerHandle consumer; + if (!CreateDataPipe(&producer, &consumer)) { exception_state.ThrowDOMException(DOMExceptionCode::kQuotaExceededError, kResourcesExhaustedReadBuffer); return nullptr; } - port_->ClearReadError(std::move(readable_pipe_producer)); - InitializeReadableStream(script_state, std::move(readable_pipe)); + port_->StartReading(std::move(producer)); + + DCHECK(!underlying_source_); + underlying_source_ = MakeGarbageCollected<SerialPortUnderlyingSource>( + script_state, this, std::move(consumer)); + // 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_, /*high_water_mark=*/0); return readable_; } @@ -312,16 +312,26 @@ WritableStream* SerialPort::writable(ScriptState* script_state, if (!port_.is_bound() || open_resolver_ || closing_ || write_fatal_) return nullptr; - mojo::ScopedDataPipeProducerHandle writable_pipe; - mojo::ScopedDataPipeConsumerHandle writable_pipe_consumer; - if (!CreateDataPipe(&writable_pipe, &writable_pipe_consumer)) { + mojo::ScopedDataPipeProducerHandle producer; + mojo::ScopedDataPipeConsumerHandle consumer; + if (!CreateDataPipe(&producer, &consumer)) { exception_state.ThrowDOMException(DOMExceptionCode::kQuotaExceededError, kResourcesExhaustedWriteBuffer); return nullptr; } - port_->ClearSendError(std::move(writable_pipe_consumer)); - InitializeWritableStream(script_state, std::move(writable_pipe)); + port_->StartWriting(std::move(consumer)); + + DCHECK(!underlying_sink_); + underlying_sink_ = + MakeGarbageCollected<SerialPortUnderlyingSink>(this, std::move(producer)); + // 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_, /*high_water_mark=*/1); return writable_; } @@ -350,6 +360,11 @@ ScriptPromise SerialPort::setSignals(ScriptState* script_state, return ScriptPromise(); } + if (!signals->hasDtr() && !signals->hasRts() && !signals->hasBrk()) { + exception_state.ThrowTypeError(kNoSignals); + return ScriptPromise(); + } + auto mojo_signals = device::mojom::blink::SerialHostControlSignals::New(); if (signals->hasDtr()) { mojo_signals->has_dtr = true; @@ -449,7 +464,7 @@ void SerialPort::ContextDestroyed() { port_.reset(); } -void SerialPort::Trace(Visitor* visitor) { +void SerialPort::Trace(Visitor* visitor) const { visitor->Trace(parent_); visitor->Trace(port_); visitor->Trace(client_receiver_); @@ -546,8 +561,6 @@ void SerialPort::OnConnectionError() { } void SerialPort::OnOpen( - mojo::ScopedDataPipeConsumerHandle readable_pipe, - mojo::ScopedDataPipeProducerHandle writable_pipe, mojo::PendingReceiver<device::mojom::blink::SerialPortClient> client_receiver, bool success) { @@ -563,9 +576,6 @@ void SerialPort::OnOpen( return; } - 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_receiver), GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI)); @@ -573,37 +583,6 @@ void SerialPort::OnOpen( open_resolver_ = nullptr; } -void SerialPort::InitializeReadableStream( - ScriptState* script_state, - mojo::ScopedDataPipeConsumerHandle readable_pipe) { - DCHECK(!underlying_source_); - 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_, /*high_water_mark=*/0); -} - -void SerialPort::InitializeWritableStream( - ScriptState* script_state, - mojo::ScopedDataPipeProducerHandle writable_pipe) { - DCHECK(!underlying_sink_); - 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_, /*high_water_mark=*/1); -} - void SerialPort::OnGetSignals( ScriptPromiseResolver* resolver, device::mojom::blink::SerialPortControlSignalsPtr mojo_signals) { 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 ff91601a342..d56e4b514a0 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial_port.h +++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.h @@ -29,6 +29,7 @@ class ScriptState; class Serial; class SerialOptions; class SerialOutputSignals; +class SerialPortInfo; class SerialPortUnderlyingSink; class SerialPortUnderlyingSource; class WritableStream; @@ -44,6 +45,7 @@ class SerialPort final : public ScriptWrappable, ~SerialPort() override; // Web-exposed functions + SerialPortInfo* getInfo(); ScriptPromise open(ScriptState*, const SerialOptions* options, ExceptionState&); @@ -63,7 +65,7 @@ class SerialPort final : public ScriptWrappable, void AbortClose(); void ContextDestroyed(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // ActiveScriptWrappable ExecutionContext* GetExecutionContext() const; @@ -77,14 +79,8 @@ class SerialPort final : public ScriptWrappable, bool CreateDataPipe(mojo::ScopedDataPipeProducerHandle* producer, mojo::ScopedDataPipeConsumerHandle* consumer); void OnConnectionError(); - void OnOpen(mojo::ScopedDataPipeConsumerHandle, - mojo::ScopedDataPipeProducerHandle, - mojo::PendingReceiver<device::mojom::blink::SerialPortClient>, + void OnOpen(mojo::PendingReceiver<device::mojom::blink::SerialPortClient>, bool success); - void InitializeReadableStream(ScriptState*, - mojo::ScopedDataPipeConsumerHandle); - void InitializeWritableStream(ScriptState*, - mojo::ScopedDataPipeProducerHandle); void OnGetSignals(ScriptPromiseResolver*, device::mojom::blink::SerialPortControlSignalsPtr); void OnSetSignals(ScriptPromiseResolver*, bool success); 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 04978e4d67c..7181642e7f0 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial_port.idl +++ b/chromium/third_party/blink/renderer/modules/serial/serial_port.idl @@ -14,12 +14,13 @@ [CallWith=ScriptState, RaisesException] readonly attribute WritableStream writable; + [MeasureAs=SerialPortGetInfo] SerialPortInfo getInfo(); [CallWith=ScriptState, RaisesException, MeasureAs=SerialPortOpen] Promise<void> open(SerialOptions options); [CallWith=ScriptState, RaisesException] Promise<SerialInputSignals> getSignals(); [CallWith=ScriptState, RaisesException] - Promise<void> setSignals(SerialOutputSignals signals); + Promise<void> setSignals(optional SerialOutputSignals signals = {}); [RaisesException, CallWith=ScriptState, MeasureAs=SerialPortClose] Promise<void> close(); }; diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_info.idl b/chromium/third_party/blink/renderer/modules/serial/serial_port_info.idl new file mode 100644 index 00000000000..54c2d5be3e6 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_info.idl @@ -0,0 +1,10 @@ +// Copyright 2020 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/serial + +dictionary SerialPortInfo { + unsigned short usbVendorId; + unsigned short usbProductId; +}; 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 439c6c995be..4ac7043f45b 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 @@ -108,7 +108,7 @@ void SerialPortUnderlyingSink::SignalErrorOnClose(DOMException* exception) { } } -void SerialPortUnderlyingSink::Trace(Visitor* visitor) { +void SerialPortUnderlyingSink::Trace(Visitor* visitor) const { visitor->Trace(serial_port_); visitor->Trace(pending_exception_); visitor->Trace(buffer_source_); diff --git a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h index 4b1ef651c19..b5ec5a30eae 100644 --- a/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h +++ b/chromium/third_party/blink/renderer/modules/serial/serial_port_underlying_sink.h @@ -37,7 +37,7 @@ class SerialPortUnderlyingSink final : public UnderlyingSinkBase { // rejected with this DOMException. void SignalErrorOnClose(DOMException*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void OnHandleReady(MojoResult, const mojo::HandleSignalsState&); 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 6f794772368..c36181bd1b1 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 @@ -71,7 +71,7 @@ void SerialPortUnderlyingSource::SignalErrorOnClose(DOMException* exception) { serial_port_->UnderlyingSourceClosed(); } -void SerialPortUnderlyingSource::Trace(Visitor* visitor) { +void SerialPortUnderlyingSource::Trace(Visitor* visitor) const { visitor->Trace(pending_exception_); visitor->Trace(serial_port_); UnderlyingSourceBase::Trace(visitor); 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 f96014d16f6..4d7d8b968e5 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 @@ -28,7 +28,7 @@ class SerialPortUnderlyingSource : public UnderlyingSourceBase { void SignalErrorImmediately(DOMException*); void SignalErrorOnClose(DOMException*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Reads data from |data_pipe_|. Returns true if data was enqueued to diff --git a/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc index e151cec9283..0ececc63f1d 100644 --- a/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc +++ b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.cc @@ -38,7 +38,7 @@ Serial* WorkerNavigatorSerial::serial(ScriptState* script_state) { return serial_; } -void WorkerNavigatorSerial::Trace(Visitor* visitor) { +void WorkerNavigatorSerial::Trace(Visitor* visitor) const { visitor->Trace(serial_); Supplement<WorkerNavigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.h b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.h index 5305bfd6e63..0d7dc798699 100644 --- a/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.h +++ b/chromium/third_party/blink/renderer/modules/serial/worker_navigator_serial.h @@ -29,7 +29,7 @@ class WorkerNavigatorSerial final explicit WorkerNavigatorSerial(WorkerNavigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<Serial> serial_; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.cc b/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.cc index f9734fc64d5..189664960cd 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.cc @@ -76,7 +76,7 @@ const AtomicString& ExtendableEvent::InterfaceName() const { return event_interface_names::kExtendableEvent; } -void ExtendableEvent::Trace(Visitor* visitor) { +void ExtendableEvent::Trace(Visitor* visitor) const { visitor->Trace(observer_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.h b/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.h index 45ac529723e..ca4cead86a9 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/extendable_event.h @@ -59,7 +59,7 @@ class MODULES_EXPORT ExtendableEvent : public Event { void waitUntil(ScriptState*, ScriptPromise, ExceptionState&); const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: Member<WaitUntilObserver> observer_; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc b/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc index a2725f915a4..67aa88f2475 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.cc @@ -102,7 +102,7 @@ const AtomicString& ExtendableMessageEvent::InterfaceName() const { return event_interface_names::kExtendableMessageEvent; } -void ExtendableMessageEvent::Trace(Visitor* visitor) { +void ExtendableMessageEvent::Trace(Visitor* visitor) const { visitor->Trace(data_); visitor->Trace(source_as_client_); visitor->Trace(source_as_service_worker_); diff --git a/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.h b/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.h index af67cae6b93..8709481d15c 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/extendable_message_event.h @@ -71,7 +71,7 @@ class MODULES_EXPORT ExtendableMessageEvent final : public ExtendableEvent { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: scoped_refptr<SerializedScriptValue> serialized_data_; 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 b5a3a8bb2ed..f115536e3cd 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 @@ -225,7 +225,7 @@ void FetchEvent::addPerformanceEntry(PerformanceMeasure* performance_measure) { } } -void FetchEvent::Trace(Visitor* visitor) { +void FetchEvent::Trace(Visitor* visitor) const { visitor->Trace(observer_); visitor->Trace(request_); visitor->Trace(preload_response_property_); diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h index 835aca8097c..d7e65b2994f 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h @@ -91,7 +91,7 @@ class MODULES_EXPORT FetchEvent final // ScriptWrappable bool HasPendingActivity() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<FetchRespondWithObserver> observer_; 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 37366e0e00a..f1e28214a91 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 @@ -177,7 +177,7 @@ class FetchLoaderClient final : public GarbageCollected<FetchLoaderClient>, std::move(body_stream_), std::move(callback_receiver_)); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { FetchDataLoader::Client::Trace(visitor); } @@ -275,30 +275,16 @@ void FetchRespondWithObserver::OnResponseFulfilled( return; } - ExceptionState exception_state(script_state->GetIsolate(), context_type, - interface_name, property_name); - if (response->IsBodyLocked(exception_state) == Body::BodyLocked::kLocked) { - DCHECK(!exception_state.HadException()); + if (response->IsBodyLocked()) { OnResponseRejected(ServiceWorkerResponseError::kBodyLocked); return; } - if (exception_state.HadException()) { - OnResponseRejected(ServiceWorkerResponseError::kResponseBodyBroken); - return; - } - - if (response->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) { - DCHECK(!exception_state.HadException()); + if (response->IsBodyUsed()) { OnResponseRejected(ServiceWorkerResponseError::kBodyUsed); return; } - if (exception_state.HadException()) { - OnResponseRejected(ServiceWorkerResponseError::kResponseBodyBroken); - return; - } - mojom::blink::FetchAPIResponsePtr fetch_api_response = response->PopulateFetchAPIResponse(request_url_); ServiceWorkerGlobalScope* service_worker_global_scope = @@ -336,6 +322,9 @@ void FetchRespondWithObserver::OnResponseFulfilled( // drained or loading begins. fetch_api_response->side_data_blob = buffer->TakeSideDataBlob(); + ExceptionState exception_state(script_state->GetIsolate(), context_type, + interface_name, property_name); + scoped_refptr<BlobDataHandle> blob_data_handle = buffer->DrainAsBlobDataHandle( BytesConsumer::BlobSizePolicy::kAllowBlobWithInvalidSize, @@ -406,7 +395,7 @@ FetchRespondWithObserver::FetchRespondWithObserver( corp_checker_(std::move(corp_checker)), task_runner_(context->GetTaskRunner(TaskType::kNetworking)) {} -void FetchRespondWithObserver::Trace(Visitor* visitor) { +void FetchRespondWithObserver::Trace(Visitor* visitor) const { RespondWithObserver::Trace(visitor); } 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 7900ac446a1..808cfe0142b 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 @@ -46,7 +46,7 @@ class MODULES_EXPORT FetchRespondWithObserver : public RespondWithObserver { const char* property_name) override; void OnNoResponse() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: const KURL request_url_; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc b/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc index 06b7f854921..ea9ab99870b 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc @@ -58,7 +58,7 @@ ScriptPromise NavigationPreloadManager::SetEnabled(bool enable, return promise; } -void NavigationPreloadManager::Trace(Visitor* visitor) { +void NavigationPreloadManager::Trace(Visitor* visitor) const { visitor->Trace(registration_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.h b/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.h index 631913533b9..2c4d886d203 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.h @@ -27,7 +27,7 @@ class NavigationPreloadManager final : public ScriptWrappable { ExceptionState& exception_state); ScriptPromise getState(ScriptState*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ScriptPromise SetEnabled(bool enable, ScriptState*); 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 15e5ec1dfa0..8a04139b4d8 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 @@ -106,7 +106,7 @@ RespondWithObserver::RespondWithObserver(ExecutionContext* context, state_(kInitial), observer_(observer) {} -void RespondWithObserver::Trace(Visitor* visitor) { +void RespondWithObserver::Trace(Visitor* visitor) const { visitor->Trace(observer_); ExecutionContextClient::Trace(visitor); } 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 20134324337..5efed53fa7f 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 @@ -54,7 +54,7 @@ class MODULES_EXPORT RespondWithObserver // Called when the event handler finished without calling respondWith(). virtual void OnNoResponse() = 0; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: RespondWithObserver(ExecutionContext*, int event_id, WaitUntilObserver*); 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 7f265a93d97..d79ef9ce87d 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 @@ -203,7 +203,7 @@ ServiceWorker::ServiceWorker(ExecutionContext* execution_context, ServiceWorker::~ServiceWorker() = default; -void ServiceWorker::Trace(Visitor* visitor) { +void ServiceWorker::Trace(Visitor* visitor) const { visitor->Trace(host_); visitor->Trace(receiver_); AbstractWorker::Trace(visitor); 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 ddf4d77bc2d..8ca3193b122 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 @@ -73,7 +73,7 @@ class MODULES_EXPORT ServiceWorker final ServiceWorker(ExecutionContext*, WebServiceWorkerObjectInfo); ~ServiceWorker() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void postMessage(ScriptState*, const ScriptValue& message, diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc index ed1dead91f4..c4dd8a29d6f 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc @@ -201,7 +201,7 @@ void ServiceWorkerContainer::ContextDestroyed() { controller_ = nullptr; } -void ServiceWorkerContainer::Trace(Visitor* visitor) { +void ServiceWorkerContainer::Trace(Visitor* visitor) const { visitor->Trace(controller_); visitor->Trace(ready_); visitor->Trace(dom_content_loaded_observer_); @@ -280,10 +280,10 @@ ScriptPromise ServiceWorkerContainer::registerServiceWorker( } KURL scope_url; - if (options->scope().IsNull()) - scope_url = KURL(script_url, "./"); - else + if (options->hasScope()) scope_url = execution_context->CompleteURL(options->scope()); + else + scope_url = KURL(script_url, "./"); scope_url.RemoveFragmentIdentifier(); if (!SchemeRegistry::ShouldTreatURLSchemeAsAllowingServiceWorkers( @@ -329,10 +329,7 @@ ScriptPromise ServiceWorkerContainer::registerServiceWorker( ContentSecurityPolicy* csp = execution_context->GetContentSecurityPolicy(); if (csp) { - if (!csp->AllowRequestWithoutIntegrity( - mojom::RequestContextType::SERVICE_WORKER, - network::mojom::RequestDestination::kServiceWorker, script_url) || - !csp->AllowWorkerContextFromSource(script_url)) { + if (!csp->AllowWorkerContextFromSource(script_url)) { callbacks->OnError(WebServiceWorkerError( mojom::blink::ServiceWorkerErrorType::kSecurity, String( @@ -633,7 +630,8 @@ void ServiceWorkerContainer::DispatchMessageEvent( TransferableMessage message) { DCHECK(is_client_message_queue_enabled_); - auto msg = ToBlinkTransferableMessage(std::move(message)); + auto msg = + BlinkTransferableMessage::FromTransferableMessage(std::move(message)); MessagePortArray* ports = MessagePort::EntanglePorts(*GetExecutionContext(), std::move(msg.ports)); ServiceWorker* service_worker = 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 953244b9b6a..3460ffab869 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 @@ -79,7 +79,7 @@ class MODULES_EXPORT ServiceWorkerContainer final explicit ServiceWorkerContainer(LocalDOMWindow&); ~ServiceWorkerContainer() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; ServiceWorker* controller() { return controller_; } ScriptPromise ready(ScriptState*, ExceptionState&); 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 8a64439f335..3fedb24256b 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,7 +46,7 @@ struct StubScriptFunction { size_t CallCount() { return call_count_; } ScriptValue Arg() { return arg_; } - void Trace(Visitor* visitor) { visitor->Trace(arg_); } + void Trace(Visitor* visitor) const { visitor->Trace(arg_); } private: size_t call_count_; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.h index 2899557c9f2..5557cf78fe7 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_event_queue.h @@ -113,6 +113,7 @@ class MODULES_EXPORT ServiceWorkerEventQueue { // Sets the |idle_delay_| to the new value, and re-schedule the idle callback // based on the new delay if it's now pending. + // This method must be called after the event queue is started. void SetIdleDelay(base::TimeDelta idle_delay); // Returns true if the event queue thinks no events ran for a while, and has 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 a5387204ebb..e8430b87133 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 @@ -38,6 +38,7 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_functions.h" #include "base/numerics/safe_conversions.h" +#include "base/time/time.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "services/network/public/cpp/cross_origin_embedder_policy.h" #include "services/network/public/mojom/cross_origin_embedder_policy.mojom.h" @@ -629,7 +630,7 @@ void ServiceWorkerGlobalScope::BindControllerServiceWorker( // and "handle functional event task source" defined in the service worker // spec and use them when dispatching events. controller_receivers_.Add( - this, std::move(receiver), /*context=*/nullptr, + std::move(receiver), /*context=*/nullptr, GetThread()->GetTaskRunner(TaskType::kInternalDefault)); } @@ -781,12 +782,19 @@ void ServiceWorkerGlobalScope::DispatchExtendableEventWithRespondWith( wait_until_observer->DidDispatchEvent(false /* event_dispatch_failed */); } -void ServiceWorkerGlobalScope::Trace(Visitor* visitor) { +void ServiceWorkerGlobalScope::Trace(Visitor* visitor) const { visitor->Trace(clients_); visitor->Trace(registration_); visitor->Trace(service_worker_); visitor->Trace(service_worker_objects_); + visitor->Trace(service_worker_host_); + visitor->Trace(receiver_); + visitor->Trace(abort_payment_result_callbacks_); + visitor->Trace(can_make_payment_result_callbacks_); + visitor->Trace(payment_response_callbacks_); + visitor->Trace(fetch_response_callbacks_); visitor->Trace(pending_preload_fetch_events_); + visitor->Trace(controller_receivers_); WorkerGlobalScope::Trace(visitor); } @@ -971,8 +979,8 @@ void ServiceWorkerGlobalScope::RespondToFetchEventWithNoResponse( TRACE_ID_LOCAL(fetch_event_id)), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(fetch_response_callbacks_.Contains(fetch_event_id)); - mojo::Remote<mojom::blink::ServiceWorkerFetchResponseCallback> - response_callback = fetch_response_callbacks_.Take(fetch_event_id); + mojom::blink::ServiceWorkerFetchResponseCallback* response_callback = + fetch_response_callbacks_.Take(fetch_event_id)->Value().get(); auto timing = mojom::blink::ServiceWorkerFetchEventTiming::New(); timing->dispatch_event_time = event_dispatch_time; @@ -997,8 +1005,8 @@ void ServiceWorkerGlobalScope::RespondToFetchEvent( TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(fetch_response_callbacks_.Contains(fetch_event_id)); - mojo::Remote<mojom::blink::ServiceWorkerFetchResponseCallback> - response_callback = fetch_response_callbacks_.Take(fetch_event_id); + mojom::blink::ServiceWorkerFetchResponseCallback* response_callback = + fetch_response_callbacks_.Take(fetch_event_id)->Value().get(); auto timing = mojom::blink::ServiceWorkerFetchEventTiming::New(); timing->dispatch_event_time = event_dispatch_time; @@ -1024,8 +1032,8 @@ void ServiceWorkerGlobalScope::RespondToFetchEventWithResponseStream( TRACE_ID_LOCAL(fetch_event_id)), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(fetch_response_callbacks_.Contains(fetch_event_id)); - mojo::Remote<mojom::blink::ServiceWorkerFetchResponseCallback> - response_callback = fetch_response_callbacks_.Take(fetch_event_id); + mojom::blink::ServiceWorkerFetchResponseCallback* response_callback = + fetch_response_callbacks_.Take(fetch_event_id)->Value().get(); auto timing = mojom::blink::ServiceWorkerFetchEventTiming::New(); timing->dispatch_event_time = event_dispatch_time; @@ -1151,8 +1159,8 @@ void ServiceWorkerGlobalScope::RespondToAbortPaymentEvent( TRACE_ID_LOCAL(event_id)), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(abort_payment_result_callbacks_.Contains(event_id)); - mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback> - result_callback = abort_payment_result_callbacks_.Take(event_id); + payments::mojom::blink::PaymentHandlerResponseCallback* result_callback = + abort_payment_result_callbacks_.Take(event_id)->Value().get(); result_callback->OnResponseForAbortPayment(payment_aborted); } @@ -1181,8 +1189,8 @@ void ServiceWorkerGlobalScope::RespondToCanMakePaymentEvent( TRACE_ID_LOCAL(event_id)), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(can_make_payment_result_callbacks_.Contains(event_id)); - mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback> - result_callback = can_make_payment_result_callbacks_.Take(event_id); + payments::mojom::blink::PaymentHandlerResponseCallback* result_callback = + can_make_payment_result_callbacks_.Take(event_id)->Value().get(); result_callback->OnResponseForCanMakePayment(std::move(response)); } @@ -1211,8 +1219,8 @@ void ServiceWorkerGlobalScope::RespondToPaymentRequestEvent( TRACE_ID_LOCAL(payment_event_id)), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); DCHECK(payment_response_callbacks_.Contains(payment_event_id)); - mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback> - response_callback = payment_response_callbacks_.Take(payment_event_id); + payments::mojom::blink::PaymentHandlerResponseCallback* response_callback = + payment_response_callbacks_.Take(payment_event_id)->Value().get(); response_callback->OnResponseForPaymentRequest(std::move(response)); } @@ -1307,7 +1315,7 @@ ServiceWorkerGlobalScope::TakeCacheStorage() { mojom::blink::ServiceWorkerHost* ServiceWorkerGlobalScope::GetServiceWorkerHost() { - DCHECK(service_worker_host_); + DCHECK(service_worker_host_.is_bound()); return service_worker_host_.get(); } @@ -1441,12 +1449,20 @@ void ServiceWorkerGlobalScope::StartFetchEvent( mojo::PendingRemote<mojom::blink::ServiceWorkerFetchResponseCallback> response_callback, DispatchFetchEventInternalCallback callback, + base::Optional<base::TimeTicks> created_time, int event_id) { DCHECK(IsContextThread()); + if (created_time.has_value()) { + RecordQueuingTime(created_time.value()); + } + fetch_event_callbacks_.Set(event_id, std::move(callback)); - fetch_response_callbacks_.Set( - event_id, mojo::Remote<mojom::blink::ServiceWorkerFetchResponseCallback>( - std::move(response_callback))); + HeapMojoRemote<mojom::blink::ServiceWorkerFetchResponseCallback, + HeapMojoWrapperMode::kWithoutContextObserver> + remote(this); + remote.Bind(std::move(response_callback), + GetThread()->GetTaskRunner(TaskType::kNetworking)); + fetch_response_callbacks_.Set(event_id, WrapDisallowNew(std::move(remote))); // This TRACE_EVENT is used for perf benchmark to confirm if all of fetch // events have completed. (crbug.com/736697) @@ -1465,25 +1481,26 @@ void ServiceWorkerGlobalScope::StartFetchEvent( std::move(params->preload_handle)); } - mojom::blink::FetchAPIRequest& fetch_request = *params->request; ScriptState::Scope scope(ScriptController()->GetScriptState()); auto* wait_until_observer = MakeGarbageCollected<WaitUntilObserver>( this, WaitUntilObserver::kFetch, event_id); auto* respond_with_observer = MakeGarbageCollected<FetchRespondWithObserver>( - this, event_id, std::move(corp_checker), fetch_request, + this, event_id, std::move(corp_checker), *params->request, wait_until_observer); - Request* request = - Request::Create(ScriptController()->GetScriptState(), fetch_request, - Request::ForServiceWorkerFetchEvent::kTrue); - request->getHeaders()->SetGuard(Headers::kImmutableGuard); FetchEventInit* event_init = FetchEventInit::Create(); event_init->setCancelable(true); - event_init->setRequest(request); event_init->setClientId( - fetch_request.is_main_resource_load ? String() : params->client_id); + params->request->is_main_resource_load ? String() : params->client_id); event_init->setResultingClientId( - !fetch_request.is_main_resource_load ? String() : params->client_id); - event_init->setIsReload(fetch_request.is_reload); + !params->request->is_main_resource_load ? String() : params->client_id); + event_init->setIsReload(params->request->is_reload); + + Request* request = Request::Create( + ScriptController()->GetScriptState(), std::move(params->request), + Request::ForServiceWorkerFetchEvent::kTrue); + request->getHeaders()->SetGuard(Headers::kImmutableGuard); + event_init->setRequest(request); + ScriptState* script_state = ScriptController()->GetScriptState(); FetchEvent* fetch_event = MakeGarbageCollected<FetchEvent>( script_state, event_type_names::kFetch, event_init, respond_with_observer, @@ -1527,14 +1544,14 @@ void ServiceWorkerGlobalScope::DispatchFetchEventForSubresource( WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent, WrapWeakPersistent(this), std::move(params), std::move(corp_checker), std::move(response_callback), - std::move(callback)), + std::move(callback), base::TimeTicks::Now()), CreateAbortCallback(&fetch_event_callbacks_), base::nullopt); } else { event_queue_->EnqueueNormal( WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent, WrapWeakPersistent(this), std::move(params), std::move(corp_checker), std::move(response_callback), - std::move(callback)), + std::move(callback), base::TimeTicks::Now()), CreateAbortCallback(&fetch_event_callbacks_), base::nullopt); } } @@ -1550,7 +1567,7 @@ void ServiceWorkerGlobalScope::Clone( cross_origin_embedder_policy, std::move(coep_reporter)); controller_receivers_.Add( - this, std::move(receiver), std::move(checker), + std::move(receiver), std::move(checker), GetThread()->GetTaskRunner(TaskType::kInternalDefault)); } @@ -1567,7 +1584,7 @@ void ServiceWorkerGlobalScope::InitializeGlobalScope( DCHECK(!global_scope_initialized_); DCHECK(service_worker_host.is_valid()); - DCHECK(!service_worker_host_); + DCHECK(!service_worker_host_.is_bound()); service_worker_host_.Bind(std::move(service_worker_host), GetTaskRunner(TaskType::kInternalDefault)); @@ -1884,14 +1901,14 @@ void ServiceWorkerGlobalScope::DispatchFetchEventForMainResource( WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent, WrapWeakPersistent(this), std::move(params), /*corp_checker=*/nullptr, std::move(response_callback), - std::move(callback)), + std::move(callback), base::nullopt), CreateAbortCallback(&fetch_event_callbacks_), base::nullopt); } else { event_queue_->EnqueueNormal( WTF::Bind(&ServiceWorkerGlobalScope::StartFetchEvent, WrapWeakPersistent(this), std::move(params), /*corp_checker=*/nullptr, std::move(response_callback), - std::move(callback)), + std::move(callback), base::TimeTicks::Now()), CreateAbortCallback(&fetch_event_callbacks_), base::nullopt); } } @@ -2126,10 +2143,17 @@ void ServiceWorkerGlobalScope::StartAbortPaymentEvent( int event_id) { DCHECK(IsContextThread()); abort_payment_event_callbacks_.Set(event_id, std::move(callback)); - abort_payment_result_callbacks_.Set( - event_id, - mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>( - std::move(response_callback))); + HeapMojoRemote<payments::mojom::blink::PaymentHandlerResponseCallback, + HeapMojoWrapperMode::kWithoutContextObserver> + remote(this); + // Payment task need to be processed on the user interaction task + // runner (TaskType::kUserInteraction). + // See: + // https://www.w3.org/TR/payment-request/#user-aborts-the-payment-request-algorithm + remote.Bind(std::move(response_callback), + GetThread()->GetTaskRunner(TaskType::kUserInteraction)); + abort_payment_result_callbacks_.Set(event_id, + WrapDisallowNew(std::move(remote))); TRACE_EVENT_WITH_FLOW0( "ServiceWorker", "ServiceWorkerGlobalScope::DispatchAbortPaymentEvent", TRACE_ID_WITH_SCOPE(kServiceWorkerGlobalScopeTraceScope, @@ -2171,10 +2195,17 @@ void ServiceWorkerGlobalScope::StartCanMakePaymentEvent( int event_id) { DCHECK(IsContextThread()); can_make_payment_event_callbacks_.Set(event_id, std::move(callback)); - can_make_payment_result_callbacks_.Set( - event_id, - mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>( - std::move(response_callback))); + HeapMojoRemote<payments::mojom::blink::PaymentHandlerResponseCallback, + HeapMojoWrapperMode::kWithoutContextObserver> + remote(this); + // Payment task need to be processed on the user interaction task + // runner (TaskType::kUserInteraction). + // See: + // https://www.w3.org/TR/payment-request/#canmakepayment-method + remote.Bind(std::move(response_callback), + GetThread()->GetTaskRunner(TaskType::kUserInteraction)); + can_make_payment_result_callbacks_.Set(event_id, + WrapDisallowNew(std::move(remote))); TRACE_EVENT_WITH_FLOW0( "ServiceWorker", "ServiceWorkerGlobalScope::DispatchCanMakePaymentEvent", TRACE_ID_WITH_SCOPE(kServiceWorkerGlobalScopeTraceScope, @@ -2218,10 +2249,16 @@ void ServiceWorkerGlobalScope::StartPaymentRequestEvent( int event_id) { DCHECK(IsContextThread()); payment_request_event_callbacks_.Set(event_id, std::move(callback)); - payment_response_callbacks_.Set( - event_id, - mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>( - std::move(response_callback))); + HeapMojoRemote<payments::mojom::blink::PaymentHandlerResponseCallback, + HeapMojoWrapperMode::kWithoutContextObserver> + remote(this); + // Payment task need to be processed on the user interaction task + // runner (TaskType::kUserInteraction). + // See: + // https://www.w3.org/TR/payment-request/#user-accepts-the-payment-request-algorithm + remote.Bind(std::move(response_callback), + GetThread()->GetTaskRunner(TaskType::kUserInteraction)); + payment_response_callbacks_.Set(event_id, WrapDisallowNew(std::move(remote))); TRACE_EVENT_WITH_FLOW0( "ServiceWorker", "ServiceWorkerGlobalScope::DispatchPaymentRequestEvent", TRACE_ID_WITH_SCOPE(kServiceWorkerGlobalScopeTraceScope, @@ -2372,4 +2409,10 @@ void ServiceWorkerGlobalScope::NoteRespondedToFetchEvent( unresponded_fetch_event_counts_.erase(it); } +void ServiceWorkerGlobalScope::RecordQueuingTime(base::TimeTicks created_time) { + base::UmaHistogramMediumTimes( + "ServiceWorker.FetchEvent.QueuingTime", + base::TimeTicks::Now() - created_time); +} + } // 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 09ad67c26a9..c6db4dff2ac 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 @@ -32,13 +32,11 @@ #include <memory> +#include "base/time/time.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" -#include "mojo/public/cpp/bindings/receiver.h" -#include "mojo/public/cpp/bindings/receiver_set.h" -#include "mojo/public/cpp/bindings/remote.h" #include "services/network/public/mojom/network_context.mojom-blink-forward.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" @@ -46,16 +44,22 @@ #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/cross_origin_resource_policy_checker.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_event_queue.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h" +#include "third_party/blink/renderer/platform/heap/disallow_new_wrapper.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap_allocator.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.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 { -class CrossOriginResourcePolicyChecker; class ExceptionState; class FetchEvent; class PendingURLLoaderFactoryBundle; @@ -292,7 +296,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final DEFINE_ATTRIBUTE_EVENT_LISTENER(message, kMessage) DEFINE_ATTRIBUTE_EVENT_LISTENER(messageerror, kMessageerror) - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Returns true if a FetchEvent exists with the given request URL and // is still waiting for a Response. @@ -483,6 +487,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final mojo::PendingRemote<mojom::blink::ServiceWorkerFetchResponseCallback> response_callback, DispatchFetchEventInternalCallback callback, + base::Optional<base::TimeTicks> created_time, int event_id); void StartInstallEvent(DispatchInstallEventCallback callback, int event_id); void StartActivateEvent(DispatchActivateEventCallback callback, int event_id); @@ -565,6 +570,10 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final DispatchContentDeleteEventCallback callback, int event_id); + // Records the time that a fetch event was queued in the + // ServiceWorker.FetchEvent.QueuingTime histogram. + void RecordQueuingTime(base::TimeTicks created_time); + Member<ServiceWorkerClients> clients_; Member<ServiceWorkerRegistration> registration_; Member<::blink::ServiceWorker> service_worker_; @@ -596,9 +605,14 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final // Bound by the first Mojo call received on the service worker thread // mojom::blink::ServiceWorker::InitializeGlobalScope(). - mojo::AssociatedRemote<mojom::blink::ServiceWorkerHost> service_worker_host_; + HeapMojoAssociatedRemote<mojom::blink::ServiceWorkerHost, + HeapMojoWrapperMode::kWithoutContextObserver> + service_worker_host_{this}; - mojo::Receiver<mojom::blink::ServiceWorker> receiver_{this}; + HeapMojoReceiver<mojom::blink::ServiceWorker, + ServiceWorkerGlobalScope, + HeapMojoWrapperMode::kWithoutContextObserver> + receiver_{this, this}; // Maps for inflight event callbacks. // These are mapped from an event id issued from ServiceWorkerEventQueue to @@ -616,8 +630,10 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final HashMap<int, DispatchSyncEventCallback> sync_event_callbacks_; HashMap<int, DispatchPeriodicSyncEventCallback> periodic_sync_event_callbacks_; - HashMap<int, - mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>> + HeapHashMap<int, + Member<DisallowNewWrapper<HeapMojoRemote< + payments::mojom::blink::PaymentHandlerResponseCallback, + HeapMojoWrapperMode::kWithoutContextObserver>>>> abort_payment_result_callbacks_; HashMap<int, DispatchCanMakePaymentEventCallback> abort_payment_event_callbacks_; @@ -641,13 +657,20 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final // Maps for response callbacks. // These are mapped from an event id to the Mojo interface pointer which is // passed from the relevant DispatchSomeEvent() method. - HashMap<int, - mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>> + HeapHashMap<int, + Member<DisallowNewWrapper<HeapMojoRemote< + payments::mojom::blink::PaymentHandlerResponseCallback, + HeapMojoWrapperMode::kWithoutContextObserver>>>> can_make_payment_result_callbacks_; - HashMap<int, - mojo::Remote<payments::mojom::blink::PaymentHandlerResponseCallback>> + HeapHashMap<int, + Member<DisallowNewWrapper<HeapMojoRemote< + payments::mojom::blink::PaymentHandlerResponseCallback, + HeapMojoWrapperMode::kWithoutContextObserver>>>> payment_response_callbacks_; - HashMap<int, mojo::Remote<mojom::blink::ServiceWorkerFetchResponseCallback>> + HeapHashMap<int, + Member<DisallowNewWrapper<HeapMojoRemote< + mojom::blink::ServiceWorkerFetchResponseCallback, + HeapMojoWrapperMode::kWithoutContextObserver>>>> fetch_response_callbacks_; HeapHashMap<int, Member<FetchEvent>> pending_preload_fetch_events_; @@ -669,8 +692,8 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final // 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 + // Connected by the ServiceWorkerHost in the browser process and by the + // controllees. |controller_bindings_| should be destroyed before // |event_queue_| since the pipe needs to be disconnected before callbacks // passed by DispatchSomeEvent() get destructed, which may be stored in // |event_queue_|. @@ -678,9 +701,11 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final // mojo::ReceiverSet is the policy for the client which dispatches FetchEvents // to the ControllerServiceWorker. It should be referred to before sending the // response back to the client. - mojo::ReceiverSet<mojom::blink::ControllerServiceWorker, - std::unique_ptr<CrossOriginResourcePolicyChecker>> - controller_receivers_; + HeapMojoReceiverSet<mojom::blink::ControllerServiceWorker, + ServiceWorkerGlobalScope, + HeapMojoWrapperMode::kWithoutContextObserver, + std::unique_ptr<CrossOriginResourcePolicyChecker>> + controller_receivers_{this, this}; }; template <> 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 8cc3133de17..cc24d5b878d 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 @@ -67,19 +67,17 @@ ServiceWorkerGlobalScopeProxy::~ServiceWorkerGlobalScopeProxy() { } void ServiceWorkerGlobalScopeProxy::BindServiceWorker( - mojo::ScopedMessagePipeHandle receiver_pipe) { + CrossVariantMojoReceiver<mojom::blink::ServiceWorkerInterfaceBase> + receiver) { DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_); - WorkerGlobalScope()->BindServiceWorker( - mojo::PendingReceiver<mojom::blink::ServiceWorker>( - std::move(receiver_pipe))); + WorkerGlobalScope()->BindServiceWorker(std::move(receiver)); } void ServiceWorkerGlobalScopeProxy::BindControllerServiceWorker( - mojo::ScopedMessagePipeHandle receiver_pipe) { + CrossVariantMojoReceiver<mojom::blink::ControllerServiceWorkerInterfaceBase> + receiver) { DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_); - WorkerGlobalScope()->BindControllerServiceWorker( - mojo::PendingReceiver<mojom::blink::ControllerServiceWorker>( - std::move(receiver_pipe))); + WorkerGlobalScope()->BindControllerServiceWorker(std::move(receiver)); } void ServiceWorkerGlobalScopeProxy::OnNavigationPreloadResponse( 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 74ab5568ba9..940f9274575 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 @@ -35,7 +35,9 @@ #include "base/macros.h" #include "base/threading/thread_checker.h" +#include "third_party/blink/public/mojom/service_worker/controller_service_worker.mojom-blink.h" #include "third_party/blink/public/mojom/service_worker/dispatch_fetch_event_params.mojom-blink.h" +#include "third_party/blink/public/mojom/service_worker/service_worker.mojom-blink.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h" #include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h" @@ -75,9 +77,13 @@ class ServiceWorkerGlobalScopeProxy final : public WebServiceWorkerContextProxy, ~ServiceWorkerGlobalScopeProxy() override; // WebServiceWorkerContextProxy overrides: - void BindServiceWorker(mojo::ScopedMessagePipeHandle receiver_pipe) override; + void BindServiceWorker( + CrossVariantMojoReceiver<mojom::blink::ServiceWorkerInterfaceBase> + receiver) override; void BindControllerServiceWorker( - mojo::ScopedMessagePipeHandle receiver_pipe) override; + CrossVariantMojoReceiver< + mojom::blink::ControllerServiceWorkerInterfaceBase> receiver) + override; void OnNavigationPreloadResponse( int fetch_event_id, std::unique_ptr<WebURLResponse>, 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 e4c2615fb09..e6d85ea4c32 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 @@ -262,10 +262,7 @@ ServiceWorkerInstalledScriptsManager::ServiceWorkerInstalledScriptsManager( 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_)); + std::move(installed_scripts_manager_params->manager_host_remote)); // Don't touch |installed_urls_| after this point. We're on the initiator // thread now, but |installed_urls_| will be accessed on the 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 22629df9c4e..c7f153f2587 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 @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h" +#include <utility> + #include "base/run_loop.h" #include "base/synchronization/waitable_event.h" #include "mojo/public/cpp/bindings/receiver.h" @@ -144,8 +146,8 @@ class ServiceWorkerInstalledScriptsManagerTest : public testing::Test { 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()); + std::move(installed_scripts_info->manager_receiver), + std::move(installed_scripts_info->manager_host_remote)); installed_scripts_manager_ = std::make_unique<ServiceWorkerInstalledScriptsManager>( std::move(installed_scripts_manager_params), 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 fa1c33f498a..5165dfadd60 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 @@ -46,7 +46,7 @@ void ServiceWorkerModuleTreeClient::NotifyModuleTreeLoadFinished( *module_script, base::nullopt /* v8_inspector::V8StackTraceId */); } -void ServiceWorkerModuleTreeClient::Trace(Visitor* visitor) { +void ServiceWorkerModuleTreeClient::Trace(Visitor* visitor) const { 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 8831a54c16f..9b6c86f4c24 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 @@ -23,7 +23,7 @@ class ServiceWorkerModuleTreeClient final : public ModuleTreeClient { // Implements ModuleTreeClient. void NotifyModuleTreeLoadFinished(ModuleScript*) final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<ScriptState> script_state_; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc index 3ca33e7cc29..2abdd9ae1b6 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc @@ -312,7 +312,7 @@ void ServiceWorkerRegistration::Dispose() { receiver_.reset(); } -void ServiceWorkerRegistration::Trace(Visitor* visitor) { +void ServiceWorkerRegistration::Trace(Visitor* visitor) const { visitor->Trace(installing_); visitor->Trace(waiting_); visitor->Trace(active_); diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h index ab20fc03861..6576f8a3aca 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.h @@ -92,7 +92,7 @@ class ServiceWorkerRegistration final void Dispose(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // ExecutionContextLifecycleObserver overrides. diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc index e8f9856a111..130a853279a 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc @@ -30,7 +30,7 @@ ServiceWorkerScriptCachedMetadataHandler:: ServiceWorkerScriptCachedMetadataHandler:: ~ServiceWorkerScriptCachedMetadataHandler() = default; -void ServiceWorkerScriptCachedMetadataHandler::Trace(Visitor* visitor) { +void ServiceWorkerScriptCachedMetadataHandler::Trace(Visitor* visitor) const { visitor->Trace(global_scope_); CachedMetadataHandler::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h index 7b7e8d3de5d..4ccf6eb85d5 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h @@ -24,7 +24,7 @@ class ServiceWorkerScriptCachedMetadataHandler const KURL& script_url, std::unique_ptr<Vector<uint8_t>> meta_data); ~ServiceWorkerScriptCachedMetadataHandler() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void SetCachedMetadata(uint32_t data_type_id, const uint8_t*, size_t) override; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc index 8f79377705c..edc4f351f4a 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc @@ -132,7 +132,7 @@ ScriptPromise ServiceWorkerWindowClient::navigate(ScriptState* script_state, return promise; } -void ServiceWorkerWindowClient::Trace(Visitor* visitor) { +void ServiceWorkerWindowClient::Trace(Visitor* visitor) const { ServiceWorkerClient::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h index d08a7bfff9e..a33d85601f5 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h +++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.h @@ -38,7 +38,7 @@ class MODULES_EXPORT ServiceWorkerWindowClient final ScriptPromise focus(ScriptState*); ScriptPromise navigate(ScriptState*, const String& url); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: bool page_hidden_; diff --git a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc index abfa072f96f..f9df0d94b12 100644 --- a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc +++ b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc @@ -63,7 +63,7 @@ class WaitUntilObserver::ThenFunction final : public ScriptFunction { resolve_type_(type), callback_(std::move(callback)) {} - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(observer_); ScriptFunction::Trace(visitor); } @@ -334,7 +334,7 @@ void WaitUntilObserver::ConsumeWindowInteraction(TimerBase*) { context->ConsumeWindowInteraction(); } -void WaitUntilObserver::Trace(Visitor* visitor) { +void WaitUntilObserver::Trace(Visitor* visitor) const { ExecutionContextClient::Trace(visitor); } 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 816ce1084b9..5b85f410e61 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 @@ -91,7 +91,7 @@ class MODULES_EXPORT WaitUntilObserver final // TODO(falken): Can this just use Event::IsBeingDispatched? bool IsDispatchingEvent() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class InternalsServiceWorker; 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 dca026cdb64..a742f793946 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 @@ -111,7 +111,8 @@ class FakeWebServiceWorkerFetchContext final return &fake_web_url_loader_factory_; } std::unique_ptr<WebURLLoaderFactory> WrapURLLoaderFactory( - mojo::ScopedMessagePipeHandle url_loader_factory_handle) override { + CrossVariantMojoRemote<network::mojom::URLLoaderFactoryInterfaceBase> + url_loader_factory) override { return nullptr; } void WillSendRequest(WebURLRequest&) override {} @@ -126,8 +127,8 @@ class FakeWebServiceWorkerFetchContext final return base::Optional<WebSecurityOrigin>(); } WebString GetAcceptLanguages() const override { return WebString(); } - mojo::ScopedMessagePipeHandle TakePendingWorkerTimingReceiver( - int request_id) override { + CrossVariantMojoReceiver<mojom::blink::WorkerTimingContainerInterfaceBase> + TakePendingWorkerTimingReceiver(int request_id) override { return {}; } void SetIsOfflineMode(bool is_offline_mode) override {} @@ -145,9 +146,11 @@ class MockServiceWorkerContextClient final MockServiceWorkerContextClient() = default; ~MockServiceWorkerContextClient() override = default; - MOCK_METHOD2(WorkerReadyForInspectionOnInitiatorThread, - void(mojo::ScopedMessagePipeHandle, - mojo::ScopedMessagePipeHandle)); + MOCK_METHOD2( + WorkerReadyForInspectionOnInitiatorThread, + void(CrossVariantMojoRemote<mojom::DevToolsAgentInterfaceBase> + devtools_agent_remote, + CrossVariantMojoReceiver<mojom::DevToolsAgentHostInterfaceBase>)); void WorkerContextStarted(WebServiceWorkerContextProxy* proxy, scoped_refptr<base::SequencedTaskRunner>) override { @@ -172,8 +175,7 @@ class MockServiceWorkerContextClient final // Simulates calling blink.mojom.ServiceWorker.InitializeGlobalScope() to // unblock the service worker script evaluation. mojo::Remote<mojom::blink::ServiceWorker> service_worker; - proxy->BindServiceWorker( - service_worker.BindNewPipeAndPassReceiver().PassPipe()); + proxy->BindServiceWorker(service_worker.BindNewPipeAndPassReceiver()); service_worker->InitializeGlobalScope( std::move(host_remote), mojom::blink::ServiceWorkerRegistrationObjectInfo::New( @@ -275,13 +277,12 @@ class WebEmbeddedWorkerImplTest : public testing::Test { } // namespace TEST_F(WebEmbeddedWorkerImplTest, TerminateSoonAfterStart) { - worker_->StartWorkerContext( - CreateStartData(), - /*installed_scripts_manager_params=*/nullptr, - /*content_settings_proxy=*/mojo::ScopedMessagePipeHandle(), - /*cache_storage_remote=*/mojo::ScopedMessagePipeHandle(), - /*browser_interface_broker=*/mojo::ScopedMessagePipeHandle(), - Thread::Current()->GetTaskRunner()); + worker_->StartWorkerContext(CreateStartData(), + /*installed_scripts_manager_params=*/nullptr, + /*content_settings_proxy=*/mojo::NullRemote(), + /*cache_storage_remote=*/mojo::NullRemote(), + /*browser_interface_broker=*/mojo::NullRemote(), + Thread::Current()->GetTaskRunner()); testing::Mock::VerifyAndClearExpectations(mock_client_.get()); // Terminate the worker immediately after start. @@ -293,13 +294,12 @@ TEST_F(WebEmbeddedWorkerImplTest, TerminateWhileWaitingForDebugger) { std::unique_ptr<WebEmbeddedWorkerStartData> start_data = CreateStartData(); start_data->wait_for_debugger_mode = WebEmbeddedWorkerStartData::kWaitForDebugger; - worker_->StartWorkerContext( - std::move(start_data), - /*installed_scripts_manager_params=*/nullptr, - /*content_settings_proxy=*/mojo::ScopedMessagePipeHandle(), - /*cache_storage_remote=*/mojo::ScopedMessagePipeHandle(), - /*browser_interface_broker=*/mojo::ScopedMessagePipeHandle(), - Thread::Current()->GetTaskRunner()); + worker_->StartWorkerContext(std::move(start_data), + /*installed_scripts_manager_params=*/nullptr, + /*content_settings_proxy=*/mojo::NullRemote(), + /*cache_storage_remote=*/mojo::NullRemote(), + /*browser_interface_broker=*/mojo::NullRemote(), + Thread::Current()->GetTaskRunner()); testing::Mock::VerifyAndClearExpectations(mock_client_.get()); // Terminate the worker while waiting for the debugger. @@ -314,13 +314,12 @@ TEST_F(WebEmbeddedWorkerImplTest, ScriptNotFound) { start_data->script_url = script_url; // Start worker and load the script. - worker_->StartWorkerContext( - std::move(start_data), - /*installed_scripts_manager_params=*/nullptr, - /*content_settings_proxy=*/mojo::ScopedMessagePipeHandle(), - /*cache_storage_remote=*/mojo::ScopedMessagePipeHandle(), - /*browser_interface_broker=*/mojo::ScopedMessagePipeHandle(), - Thread::Current()->GetTaskRunner()); + worker_->StartWorkerContext(std::move(start_data), + /*installed_scripts_manager_params=*/nullptr, + /*content_settings_proxy=*/mojo::NullRemote(), + /*cache_storage_remote=*/mojo::NullRemote(), + /*browser_interface_broker=*/mojo::NullRemote(), + Thread::Current()->GetTaskRunner()); testing::Mock::VerifyAndClearExpectations(mock_client_.get()); mock_client_->WaitUntilFailedToLoadClassicScript(); 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 5ca5cdd9b94..b8e7b7e7351 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc +++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.cc @@ -193,7 +193,7 @@ void BarcodeDetector::OnConnectionError() { } } -void BarcodeDetector::Trace(Visitor* visitor) { +void BarcodeDetector::Trace(Visitor* visitor) const { ShapeDetector::Trace(visitor); visitor->Trace(service_); visitor->Trace(detect_requests_); 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 13ea0674a99..4217f8980c9 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h +++ b/chromium/third_party/blink/renderer/modules/shapedetection/barcode_detector.h @@ -37,7 +37,7 @@ class MODULES_EXPORT BarcodeDetector final : public ShapeDetector { const BarcodeDetectorOptions*, ExceptionState& exception_state); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ~BarcodeDetector() override = default; 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 adde5e0f59f..5620c3d0679 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 @@ -53,7 +53,7 @@ ScriptPromise BarcodeDetectorStatics::EnumerateSupportedFormats( return promise; } -void BarcodeDetectorStatics::Trace(Visitor* visitor) { +void BarcodeDetectorStatics::Trace(Visitor* visitor) const { Supplement<ExecutionContext>::Trace(visitor); visitor->Trace(service_); visitor->Trace(get_supported_format_requests_); 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 bf31118f9c2..5f62515e22d 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 @@ -39,7 +39,7 @@ class BarcodeDetectorStatics final shape_detection::mojom::blink::BarcodeDetectorOptionsPtr); ScriptPromise EnumerateSupportedFormats(ScriptState*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void EnsureServiceConnection(); 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 766f30a271d..989c525e6be 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc +++ b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.cc @@ -114,7 +114,7 @@ void FaceDetector::OnFaceServiceConnectionError() { face_service_.reset(); } -void FaceDetector::Trace(Visitor* visitor) { +void FaceDetector::Trace(Visitor* visitor) const { ShapeDetector::Trace(visitor); visitor->Trace(face_service_); visitor->Trace(face_service_requests_); 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 bdfc333c7dc..111471d807b 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h +++ b/chromium/third_party/blink/renderer/modules/shapedetection/face_detector.h @@ -27,7 +27,7 @@ class MODULES_EXPORT FaceDetector final : public ShapeDetector { FaceDetector(ExecutionContext*, const FaceDetectorOptions*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ~FaceDetector() override = default; diff --git a/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.cc b/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.cc index 2ed51da2d4b..22678e4beaa 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.cc +++ b/chromium/third_party/blink/renderer/modules/shapedetection/shape_detector.cc @@ -72,8 +72,8 @@ ScriptPromise ShapeDetector::detect( canvas_image_source->ElementSize(FloatSize(), kRespectImageOrientation)); SourceImageStatus source_image_status = kInvalidSourceImageStatus; - scoped_refptr<Image> image = canvas_image_source->GetSourceImageForCanvas( - &source_image_status, kPreferNoAcceleration, size); + scoped_refptr<Image> image = + canvas_image_source->GetSourceImageForCanvas(&source_image_status, size); if (!image || source_image_status != kNormalSourceImageStatus) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, "Invalid element or state.")); @@ -150,15 +150,15 @@ ScriptPromise ShapeDetector::DetectShapesOnImageElement( return promise; } - ImageResourceContent* const image_resource = img->CachedImage(); - if (!image_resource || image_resource->ErrorOccurred()) { + ImageResourceContent* const image_content = img->CachedImage(); + if (!image_content || image_content->ErrorOccurred()) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, "Failed to load or decode HTMLImageElement.")); return promise; } - Image* const blink_image = image_resource->GetImage(); + Image* const blink_image = image_content->GetImage(); if (!blink_image) { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kInvalidStateError, 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 4fc1e0f36a5..db5275a284f 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc +++ b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.cc @@ -88,7 +88,7 @@ void TextDetector::OnTextServiceConnectionError() { text_service_.reset(); } -void TextDetector::Trace(Visitor* visitor) { +void TextDetector::Trace(Visitor* visitor) const { ShapeDetector::Trace(visitor); visitor->Trace(text_service_); visitor->Trace(text_service_requests_); 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 ea8cb033a76..2bed20a0668 100644 --- a/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h +++ b/chromium/third_party/blink/renderer/modules/shapedetection/text_detector.h @@ -26,7 +26,7 @@ class MODULES_EXPORT TextDetector final : public ShapeDetector { explicit TextDetector(ExecutionContext*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ~TextDetector() override = default; diff --git a/chromium/third_party/blink/renderer/modules/speech/BUILD.gn b/chromium/third_party/blink/renderer/modules/speech/BUILD.gn index 6b664e140a3..b120640f469 100644 --- a/chromium/third_party/blink/renderer/modules/speech/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/speech/BUILD.gn @@ -7,8 +7,6 @@ import("//third_party/blink/renderer/modules/modules.gni") blink_modules_sources("speech") { sources = [ "dom_window_speech.h", - "dom_window_speech_synthesis.cc", - "dom_window_speech_synthesis.h", "speech_grammar.cc", "speech_grammar.h", "speech_grammar_list.cc", diff --git a/chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.cc b/chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.cc deleted file mode 100644 index 912fda21f85..00000000000 --- a/chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.cc +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2012 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/speech/dom_window_speech_synthesis.h" - -#include "base/memory/scoped_refptr.h" -#include "third_party/blink/renderer/core/execution_context/execution_context.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/platform/bindings/script_state.h" - -namespace blink { - -DOMWindowSpeechSynthesis::DOMWindowSpeechSynthesis(LocalDOMWindow& window) - : Supplement<LocalDOMWindow>(window) {} - -const char DOMWindowSpeechSynthesis::kSupplementName[] = - "DOMWindowSpeechSynthesis"; - -// static -DOMWindowSpeechSynthesis& DOMWindowSpeechSynthesis::From( - LocalDOMWindow& window) { - DOMWindowSpeechSynthesis* supplement = - Supplement<LocalDOMWindow>::From<DOMWindowSpeechSynthesis>(window); - if (!supplement) { - supplement = MakeGarbageCollected<DOMWindowSpeechSynthesis>(window); - ProvideTo(window, supplement); - } - return *supplement; -} - -// static -SpeechSynthesis* DOMWindowSpeechSynthesis::speechSynthesis( - ScriptState* script_state, - LocalDOMWindow& window) { - return DOMWindowSpeechSynthesis::From(window).speechSynthesis(script_state); -} - -void DOMWindowSpeechSynthesis::Trace(Visitor* visitor) { - visitor->Trace(speech_synthesis_); - Supplement<LocalDOMWindow>::Trace(visitor); -} - -void DOMWindowSpeechSynthesis::SetSpeechSynthesisForTesting( - SpeechSynthesis* synthesis) { - speech_synthesis_ = synthesis; -} - -SpeechSynthesis* DOMWindowSpeechSynthesis::speechSynthesis( - ScriptState* script_state) { - if (!speech_synthesis_) { - speech_synthesis_ = - SpeechSynthesis::Create(ExecutionContext::From(script_state)); - } - return speech_synthesis_; -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.h b/chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.h deleted file mode 100644 index d215de871db..00000000000 --- a/chromium/third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2013 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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_SPEECH_DOM_WINDOW_SPEECH_SYNTHESIS_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_DOM_WINDOW_SPEECH_SYNTHESIS_H_ - -#include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/modules/speech/speech_synthesis.h" -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/supplementable.h" - -namespace blink { - -class LocalDOMWindow; -class ScriptState; - -class MODULES_EXPORT DOMWindowSpeechSynthesis final - : public GarbageCollected<DOMWindowSpeechSynthesis>, - public Supplement<LocalDOMWindow> { - USING_GARBAGE_COLLECTED_MIXIN(DOMWindowSpeechSynthesis); - - public: - static const char kSupplementName[]; - - explicit DOMWindowSpeechSynthesis(LocalDOMWindow&); - static DOMWindowSpeechSynthesis& From(LocalDOMWindow&); - - static SpeechSynthesis* speechSynthesis(ScriptState*, LocalDOMWindow&); - - void Trace(Visitor*) override; - - void SetSpeechSynthesisForTesting(SpeechSynthesis*); - - private: - SpeechSynthesis* speechSynthesis(ScriptState*); - - Member<SpeechSynthesis> speech_synthesis_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_SPEECH_DOM_WINDOW_SPEECH_SYNTHESIS_H_ diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc b/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc index 0d5a4955fa1..69aadd6287b 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc +++ b/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.cc @@ -57,7 +57,7 @@ void SpeechGrammarList::addFromString(const String& string, double weight) { SpeechGrammarList::SpeechGrammarList() = default; -void SpeechGrammarList::Trace(Visitor* visitor) { +void SpeechGrammarList::Trace(Visitor* visitor) const { visitor->Trace(grammars_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.h b/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.h index 8592a9abc73..120e18ba9c4 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.h +++ b/chromium/third_party/blink/renderer/modules/speech/speech_grammar_list.h @@ -49,7 +49,7 @@ class MODULES_EXPORT SpeechGrammarList final : public ScriptWrappable { void addFromUri(ScriptState*, const String& src, double weight = 1.0); void addFromString(const String&, double weight = 1.0); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: HeapVector<Member<SpeechGrammar>> grammars_; 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 cb3d408cb2c..7975d851d42 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.cc @@ -225,7 +225,7 @@ SpeechRecognition::SpeechRecognition(LocalDOMWindow* window) SpeechRecognition::~SpeechRecognition() = default; -void SpeechRecognition::Trace(Visitor* visitor) { +void SpeechRecognition::Trace(Visitor* visitor) const { visitor->Trace(grammars_); visitor->Trace(controller_); visitor->Trace(final_results_); 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 10c739f0d6e..5bf4c37b5d4 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition.h @@ -122,7 +122,7 @@ class MODULES_EXPORT SpeechRecognition final DEFINE_ATTRIBUTE_EVENT_LISTENER(start, kStart) DEFINE_ATTRIBUTE_EVENT_LISTENER(end, kEnd) - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void OnConnectionError(); 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 2db00dfe566..b87670fdf54 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 @@ -84,7 +84,7 @@ void SpeechRecognitionController::Start( GetSpeechRecognizer()->Start(std::move(msg_params)); } -void SpeechRecognitionController::Trace(Visitor* visitor) { +void SpeechRecognitionController::Trace(Visitor* visitor) const { Supplement::Trace(visitor); visitor->Trace(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 ac2f86b27cb..3ee66415e4c 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 @@ -34,6 +34,7 @@ #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" +#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h" #include "third_party/blink/renderer/platform/supplementable.h" namespace blink { @@ -64,7 +65,7 @@ class SpeechRecognitionController final static SpeechRecognitionController* From(LocalDOMWindow&); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: mojom::blink::SpeechRecognizer* GetSpeechRecognizer(); 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 7bb2fba5917..e4f00e0982b 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 @@ -54,7 +54,7 @@ class MODULES_EXPORT SpeechRecognitionErrorEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor* visitor) override { Event::Trace(visitor); } + void Trace(Visitor* visitor) const override { Event::Trace(visitor); } private: String error_; diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc index 394b7a97672..06e431fba99 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.cc @@ -80,7 +80,7 @@ SpeechRecognitionEvent::SpeechRecognitionEvent( SpeechRecognitionEvent::~SpeechRecognitionEvent() = default; -void SpeechRecognitionEvent::Trace(Visitor* visitor) { +void SpeechRecognitionEvent::Trace(Visitor* visitor) const { visitor->Trace(results_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h index fc1863be3e2..66e4eb02140 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_event.h @@ -66,7 +66,7 @@ class SpeechRecognitionEvent final : public Event { // Event const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: uint32_t result_index_; diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.cc index 40e22e00348..e1f8bfad0fb 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.cc +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.cc @@ -45,7 +45,7 @@ SpeechRecognitionResult::SpeechRecognitionResult( bool final) : final_(final), alternatives_(alternatives) {} -void SpeechRecognitionResult::Trace(Visitor* visitor) { +void SpeechRecognitionResult::Trace(Visitor* visitor) const { visitor->Trace(alternatives_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.h index 89ffd66ac41..9cf099f024b 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.h +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result.h @@ -49,7 +49,7 @@ class MODULES_EXPORT SpeechRecognitionResult final : public ScriptWrappable { SpeechRecognitionAlternative* item(unsigned index); bool isFinal() { return final_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: bool final_; diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.cc b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.cc index da548bb5ff4..f126ea7890e 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.cc +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.cc @@ -43,7 +43,7 @@ SpeechRecognitionResultList::SpeechRecognitionResultList( const HeapVector<Member<SpeechRecognitionResult>>& results) : results_(results) {} -void SpeechRecognitionResultList::Trace(Visitor* visitor) { +void SpeechRecognitionResultList::Trace(Visitor* visitor) const { visitor->Trace(results_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.h b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.h index e90cd8af048..5a1f2432634 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.h +++ b/chromium/third_party/blink/renderer/modules/speech/speech_recognition_result_list.h @@ -45,7 +45,7 @@ class SpeechRecognitionResultList : public ScriptWrappable { unsigned length() { return results_.size(); } SpeechRecognitionResult* item(unsigned index); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: HeapVector<Member<SpeechRecognitionResult>> results_; diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc index d2a53e2f82a..1fcb5297c15 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc +++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.cc @@ -44,33 +44,39 @@ namespace blink { -SpeechSynthesis* SpeechSynthesis::Create(ExecutionContext* context) { - SpeechSynthesis* synthesis = MakeGarbageCollected<SpeechSynthesis>(context); +const char SpeechSynthesis::kSupplementName[] = "SpeechSynthesis"; + +SpeechSynthesis* SpeechSynthesis::speechSynthesis(LocalDOMWindow& window) { + SpeechSynthesis* synthesis = + Supplement<LocalDOMWindow>::From<SpeechSynthesis>(window); + if (!synthesis) { + synthesis = MakeGarbageCollected<SpeechSynthesis>(window); + ProvideTo(window, synthesis); #if defined(OS_ANDROID) - // On Android devices we lazily initialize |mojom_synthesis_| to avoid - // needlessly binding to the TTS service, see https://crbug.com/811929. - // TODO(crbug/811929): Consider moving this logic into the Android- - // specific backend implementation. + // On Android devices we lazily initialize |mojom_synthesis_| to avoid + // needlessly binding to the TTS service, see https://crbug.com/811929. + // TODO(crbug/811929): Consider moving this logic into the Android- + // specific backend implementation. #else - synthesis->InitializeMojomSynthesis(); + synthesis->InitializeMojomSynthesis(); #endif + } return synthesis; } -SpeechSynthesis* SpeechSynthesis::CreateForTesting( - ExecutionContext* context, +void SpeechSynthesis::CreateForTesting( + LocalDOMWindow& window, mojo::PendingRemote<mojom::blink::SpeechSynthesis> mojom_synthesis) { - SpeechSynthesis* synthesis = MakeGarbageCollected<SpeechSynthesis>(context); + DCHECK(!Supplement<LocalDOMWindow>::From<SpeechSynthesis>(window)); + SpeechSynthesis* synthesis = MakeGarbageCollected<SpeechSynthesis>(window); + ProvideTo(window, synthesis); synthesis->SetMojomSynthesisForTesting(std::move(mojom_synthesis)); - return synthesis; } -SpeechSynthesis::SpeechSynthesis(ExecutionContext* context) - : ExecutionContextClient(context), - receiver_(this, context), - mojom_synthesis_(context) { - DCHECK(!GetExecutionContext() || GetExecutionContext()->IsDocument()); -} +SpeechSynthesis::SpeechSynthesis(LocalDOMWindow& window) + : ExecutionContextClient(&window), + receiver_(this, &window), + mojom_synthesis_(&window) {} void SpeechSynthesis::OnSetVoiceList( Vector<mojom::blink::SpeechSynthesisVoicePtr> mojom_voices) { @@ -115,7 +121,7 @@ void SpeechSynthesis::speak(ScriptState* script_state, // are generally global, whereas these are scoped to a single page load. LocalDOMWindow* window = To<LocalDOMWindow>(GetExecutionContext()); UseCounter::Count(window, WebFeature::kTextToSpeech_Speak); - window->document()->CountUseOnlyInCrossOriginIframe( + window->CountUseOnlyInCrossOriginIframe( WebFeature::kTextToSpeech_SpeakCrossOrigin); if (!IsAllowedToStartByAutoplay()) { Deprecation::CountDeprecation( @@ -289,12 +295,13 @@ SpeechSynthesisUtterance* SpeechSynthesis::CurrentSpeechUtterance() const { return utterance_queue_.front(); } -void SpeechSynthesis::Trace(Visitor* visitor) { +void SpeechSynthesis::Trace(Visitor* visitor) const { visitor->Trace(receiver_); visitor->Trace(mojom_synthesis_); visitor->Trace(voice_list_); visitor->Trace(utterance_queue_); ExecutionContextClient::Trace(visitor); + Supplement<LocalDOMWindow>::Trace(visitor); EventTargetWithInlineData::Trace(visitor); } @@ -340,8 +347,13 @@ void SpeechSynthesis::InitializeMojomSynthesis() { // mojom_synthesis_ before each use. ExecutionContext* context = GetExecutionContext(); - if (!context) + if (!context) { + // Mimic the LocalDOMWindow::GetTaskRunner code that uses the current + // task runner when frames are detached. + ignore_result(mojom_synthesis_.BindNewPipeAndPassReceiver( + Thread::Current()->GetTaskRunner())); return; + } auto receiver = mojom_synthesis_.BindNewPipeAndPassReceiver( context->GetTaskRunner(TaskType::kMiscPlatformAPI)); 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 b8a29b4136b..83f91cfbc2a 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h +++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis.h @@ -36,23 +36,29 @@ #include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" +#include "third_party/blink/renderer/platform/supplementable.h" namespace blink { +class LocalDOMWindow; + class MODULES_EXPORT SpeechSynthesis final : public EventTargetWithInlineData, public ExecutionContextClient, + public Supplement<LocalDOMWindow>, public mojom::blink::SpeechSynthesisVoiceListObserver { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(SpeechSynthesis); public: - static SpeechSynthesis* Create(ExecutionContext*); - static SpeechSynthesis* CreateForTesting( - ExecutionContext*, + static const char kSupplementName[]; + + static SpeechSynthesis* speechSynthesis(LocalDOMWindow&); + static void CreateForTesting( + LocalDOMWindow&, mojo::PendingRemote<mojom::blink::SpeechSynthesis>); - explicit SpeechSynthesis(ExecutionContext*); + explicit SpeechSynthesis(LocalDOMWindow&); bool pending() const; bool speaking() const; @@ -72,7 +78,7 @@ class MODULES_EXPORT SpeechSynthesis final } // GarbageCollected - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // mojom::blink::SpeechSynthesisVoiceListObserver void OnSetVoiceList( @@ -125,10 +131,10 @@ class MODULES_EXPORT SpeechSynthesis final HeapMojoReceiver<mojom::blink::SpeechSynthesisVoiceListObserver, SpeechSynthesis, - HeapMojoWrapperMode::kWithoutContextObserver> + HeapMojoWrapperMode::kForceWithoutContextObserver> receiver_; HeapMojoRemote<mojom::blink::SpeechSynthesis, - HeapMojoWrapperMode::kWithoutContextObserver> + HeapMojoWrapperMode::kForceWithoutContextObserver> mojom_synthesis_; HeapVector<Member<SpeechSynthesisVoice>> voice_list_; HeapDeque<Member<SpeechSynthesisUtterance>> utterance_queue_; diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc index fa0f6c83794..4f9d2383783 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc +++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.cc @@ -48,7 +48,7 @@ SpeechSynthesisEvent::SpeechSynthesisEvent(const AtomicString& type, elapsed_time_(elapsed_time), name_(name) {} -void SpeechSynthesisEvent::Trace(Visitor* visitor) { +void SpeechSynthesisEvent::Trace(Visitor* visitor) const { visitor->Trace(utterance_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h index 464e583126b..148c05f02d8 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h +++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_event.h @@ -56,7 +56,7 @@ class SpeechSynthesisEvent : public Event { return event_interface_names::kSpeechSynthesisEvent; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<SpeechSynthesisUtterance> utterance_; diff --git a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.cc b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.cc index e5f70e63c72..46df86bd966 100644 --- a/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.cc +++ b/chromium/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.cc @@ -75,7 +75,7 @@ void SpeechSynthesisUtterance::setVoice(SpeechSynthesisVoice* voice) { mojom_utterance_->voice = voice_ ? voice_->name() : String(); } -void SpeechSynthesisUtterance::Trace(Visitor* visitor) { +void SpeechSynthesisUtterance::Trace(Visitor* visitor) const { visitor->Trace(receiver_); visitor->Trace(synthesis_); visitor->Trace(voice_); @@ -150,10 +150,6 @@ void SpeechSynthesisUtterance::Start(SpeechSynthesis* synthesis) { &SpeechSynthesisUtterance::OnDisconnected, WrapWeakPersistent(this))); } -void SpeechSynthesisUtterance::Dispose() { - receiver_.reset(); -} - void SpeechSynthesisUtterance::OnDisconnected() { // If the remote end disconnects, just simulate that we finished normally. if (!finished_) 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 eb4942e59f0..9374d3e5e61 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 @@ -43,7 +43,6 @@ class SpeechSynthesisUtterance final public ExecutionContextClient, public mojom::blink::SpeechSynthesisClient { DEFINE_WRAPPERTYPEINFO(); - USING_PRE_FINALIZER(SpeechSynthesisUtterance, Dispose); USING_GARBAGE_COLLECTED_MIXIN(SpeechSynthesisUtterance); public: @@ -92,7 +91,7 @@ class SpeechSynthesisUtterance final return ExecutionContextClient::GetExecutionContext(); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // mojom::blink::SpeechSynthesisClient void OnStartedSpeaking() override; @@ -108,10 +107,6 @@ class SpeechSynthesisUtterance final void Start(SpeechSynthesis* synthesis); private: - // USING_PRE_FINALIZER interface. - // Called before the object gets garbage collected. - void Dispose(); - void OnDisconnected(); // EventTarget diff --git a/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.cc b/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.cc index a86c8c2d1b0..367c279b808 100644 --- a/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.cc +++ b/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.cc @@ -30,19 +30,15 @@ #include "third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.h" -#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/testing/internals.h" -#include "third_party/blink/renderer/modules/speech/dom_window_speech_synthesis.h" #include "third_party/blink/renderer/modules/speech/speech_synthesis.h" #include "third_party/blink/renderer/modules/speech/testing/mojom_speech_synthesis_mock.h" namespace blink { -void InternalsSpeechSynthesis::enableMockSpeechSynthesizer( - ScriptState* script_state, - Internals&, - DOMWindow* window) { +void InternalsSpeechSynthesis::enableMockSpeechSynthesizer(Internals&, + DOMWindow* window) { // TODO(dcheng): Performing a local/remote check is an anti-pattern. However, // it is necessary here since |window| is an argument passed from Javascript, // and the Window interface is accessible cross origin. The long-term fix is @@ -51,11 +47,8 @@ void InternalsSpeechSynthesis::enableMockSpeechSynthesizer( auto* local_window = DynamicTo<LocalDOMWindow>(window); if (!local_window) return; - - ExecutionContext* context = ExecutionContext::From(script_state); - DOMWindowSpeechSynthesis::From(*local_window) - .SetSpeechSynthesisForTesting(SpeechSynthesis::CreateForTesting( - context, MojomSpeechSynthesisMock::Create(context))); + SpeechSynthesis::CreateForTesting( + *local_window, MojomSpeechSynthesisMock::Create(local_window)); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.h b/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.h index a046427b737..18b1d9b3fed 100644 --- a/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.h +++ b/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.h @@ -37,13 +37,12 @@ namespace blink { class DOMWindow; class Internals; -class ScriptState; class InternalsSpeechSynthesis { STATIC_ONLY(InternalsSpeechSynthesis); public: - static void enableMockSpeechSynthesizer(ScriptState*, Internals&, DOMWindow*); + static void enableMockSpeechSynthesizer(Internals&, DOMWindow*); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.idl b/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.idl index 3488084547e..07532c76a3d 100644 --- a/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.idl +++ b/chromium/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.idl @@ -31,5 +31,5 @@ [ ImplementedAs=InternalsSpeechSynthesis ] partial interface Internals { - [CallWith=ScriptState] void enableMockSpeechSynthesizer(Window window); + void enableMockSpeechSynthesizer(Window window); }; diff --git a/chromium/third_party/blink/renderer/modules/speech/window_speech_synthesis.idl b/chromium/third_party/blink/renderer/modules/speech/window_speech_synthesis.idl index c7a94d9e50a..694734b7a5b 100644 --- a/chromium/third_party/blink/renderer/modules/speech/window_speech_synthesis.idl +++ b/chromium/third_party/blink/renderer/modules/speech/window_speech_synthesis.idl @@ -24,8 +24,8 @@ */ [ - ImplementedAs=DOMWindowSpeechSynthesis, + ImplementedAs=SpeechSynthesis, RuntimeEnabled=ScriptedSpeechSynthesis ] partial interface Window { - [Measure, CallWith=ScriptState] readonly attribute SpeechSynthesis speechSynthesis; + [Measure] readonly attribute SpeechSynthesis speechSynthesis; }; diff --git a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc index 709572e9a2a..a77fb13242b 100644 --- a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc +++ b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.cc @@ -24,7 +24,7 @@ namespace blink { DOMWindowStorage::DOMWindowStorage(LocalDOMWindow& window) : Supplement<LocalDOMWindow>(window) {} -void DOMWindowStorage::Trace(Visitor* visitor) { +void DOMWindowStorage::Trace(Visitor* visitor) const { visitor->Trace(session_storage_); visitor->Trace(local_storage_); Supplement<LocalDOMWindow>::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.h b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.h index 2a0d86e04b5..a16f94d5876 100644 --- a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.h +++ b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage.h @@ -32,7 +32,7 @@ class DOMWindowStorage final : public GarbageCollected<DOMWindowStorage>, StorageArea* OptionalSessionStorage() const { return session_storage_.Get(); } StorageArea* OptionalLocalStorage() const { return local_storage_.Get(); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: mutable Member<StorageArea> session_storage_; diff --git a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.cc b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.cc index b1468d4db4b..7abaa6e0c12 100644 --- a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.cc +++ b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.cc @@ -16,7 +16,7 @@ DOMWindowStorageController::DOMWindowStorageController(Document& document) document.domWindow()->RegisterEventListenerObserver(this); } -void DOMWindowStorageController::Trace(Visitor* visitor) { +void DOMWindowStorageController::Trace(Visitor* visitor) const { Supplement<Document>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.h b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.h index 9f72492ff91..b87e78bac10 100644 --- a/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.h +++ b/chromium/third_party/blink/renderer/modules/storage/dom_window_storage_controller.h @@ -26,7 +26,7 @@ class MODULES_EXPORT DOMWindowStorageController final explicit DOMWindowStorageController(Document&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; static DOMWindowStorageController& From(Document&); diff --git a/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc b/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc index 39eda8d2829..2d7519d0d88 100644 --- a/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc +++ b/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.cc @@ -67,7 +67,7 @@ InspectorDOMStorageAgent::InspectorDOMStorageAgent( InspectorDOMStorageAgent::~InspectorDOMStorageAgent() = default; -void InspectorDOMStorageAgent::Trace(Visitor* visitor) { +void InspectorDOMStorageAgent::Trace(Visitor* visitor) const { visitor->Trace(inspected_frames_); InspectorBaseAgent::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h b/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h index d74c08e016f..2590824790e 100644 --- a/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h +++ b/chromium/third_party/blink/renderer/modules/storage/inspector_dom_storage_agent.h @@ -45,7 +45,7 @@ class MODULES_EXPORT InspectorDOMStorageAgent final public: explicit InspectorDOMStorageAgent(InspectedFrames*); ~InspectorDOMStorageAgent() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void DidDispatchDOMStorageEvent(const String& key, const String& old_value, diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_area.cc b/chromium/third_party/blink/renderer/modules/storage/storage_area.cc index cc24c65ae77..546149d6535 100644 --- a/chromium/third_party/blink/renderer/modules/storage/storage_area.cc +++ b/chromium/third_party/blink/renderer/modules/storage/storage_area.cc @@ -168,7 +168,7 @@ bool StorageArea::NamedPropertyQuery(const AtomicString& name, return found && !exception_state.HadException(); } -void StorageArea::Trace(Visitor* visitor) { +void StorageArea::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); ExecutionContextClient::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_area.h b/chromium/third_party/blink/renderer/modules/storage/storage_area.h index e9ea3308bf5..d9224e92095 100644 --- a/chromium/third_party/blink/renderer/modules/storage/storage_area.h +++ b/chromium/third_party/blink/renderer/modules/storage/storage_area.h @@ -78,7 +78,7 @@ class StorageArea final : public ScriptWrappable, bool CanAccessStorage() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // CachedStorageArea::Source: KURL GetPageUrl() const override; diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_event.cc b/chromium/third_party/blink/renderer/modules/storage/storage_event.cc index 3a7f17e2521..ce5062c5578 100644 --- a/chromium/third_party/blink/renderer/modules/storage/storage_event.cc +++ b/chromium/third_party/blink/renderer/modules/storage/storage_event.cc @@ -106,7 +106,7 @@ const AtomicString& StorageEvent::InterfaceName() const { return event_interface_names::kStorageEvent; } -void StorageEvent::Trace(Visitor* visitor) { +void StorageEvent::Trace(Visitor* visitor) const { visitor->Trace(storage_area_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_event.h b/chromium/third_party/blink/renderer/modules/storage/storage_event.h index c2eae0ebf00..fdb328b2adf 100644 --- a/chromium/third_party/blink/renderer/modules/storage/storage_event.h +++ b/chromium/third_party/blink/renderer/modules/storage/storage_event.h @@ -81,7 +81,7 @@ class StorageEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: String key_; diff --git a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc index 409c6a4f4b7..0f53d5fae71 100644 --- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc +++ b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.cc @@ -170,7 +170,7 @@ void StorageNamespace::RemoveInspectorStorageAgent( inspector_agents_.erase(agent); } -void StorageNamespace::Trace(Visitor* visitor) { +void StorageNamespace::Trace(Visitor* visitor) const { visitor->Trace(inspector_agents_); visitor->Trace(namespace_); Supplement<Page>::Trace(visitor); 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 ee978e7b8d4..4eaca73c0f0 100644 --- a/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h +++ b/chromium/third_party/blink/renderer/modules/storage/storage_namespace.h @@ -100,7 +100,7 @@ class MODULES_EXPORT StorageNamespace final void AddInspectorStorageAgent(InspectorDOMStorageAgent* agent); void RemoveInspectorStorageAgent(InspectorDOMStorageAgent* agent); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // Iterates all of the inspector agents and calls // |DidDispatchDOMStorageEvent|. diff --git a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc index eaa3592fa26..a7e4e7280b7 100644 --- a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc +++ b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.cc @@ -141,7 +141,7 @@ void NavigatorVibration::ContextDestroyed() { } } -void NavigatorVibration::Trace(Visitor* visitor) { +void NavigatorVibration::Trace(Visitor* visitor) const { visitor->Trace(controller_); Supplement<Navigator>::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); 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 c584bdd831d..f680179cd16 100644 --- a/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h +++ b/chromium/third_party/blink/renderer/modules/vibration/navigator_vibration.h @@ -68,7 +68,7 @@ class MODULES_EXPORT NavigatorVibration final VibrationController* Controller(LocalFrame&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Inherited from ExecutionContextLifecycleObserver. 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 d3655b9b169..25162ef3b05 100644 --- a/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc +++ b/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.cc @@ -188,7 +188,7 @@ void VibrationController::PageVisibilityChanged() { Cancel(); } -void VibrationController::Trace(Visitor* visitor) { +void VibrationController::Trace(Visitor* visitor) const { ExecutionContextLifecycleObserver::Trace(visitor); PageVisibilityObserver::Trace(visitor); visitor->Trace(vibration_manager_); 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 39ff943d8b7..a4c00a94de0 100644 --- a/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h +++ b/chromium/third_party/blink/renderer/modules/vibration/vibration_controller.h @@ -65,7 +65,7 @@ class MODULES_EXPORT VibrationController final VibrationPattern Pattern() const { return pattern_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Inherited from ExecutionContextLifecycleObserver. diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl b/chromium/third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl index ca09ecd43f2..65647d8b9c5 100644 --- a/chromium/third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl +++ b/chromium/third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://wicg.github.io/video-raf/. +// See https://wicg.github.io/video-rvfc/. [ RuntimeEnabled=RequestVideoFrameCallback, ImplementedAs=VideoFrameCallbackRequesterImpl diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc index 0b253403695..ea3bb08dec8 100644 --- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc +++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.cc @@ -139,30 +139,25 @@ void VideoFrameCallbackRequesterImpl::ExecuteVideoFrameCallbacks( metadata->setMediaTime(frame_metadata->media_time.InSecondsF()); - base::TimeDelta processing_duration; - if (frame_metadata->metadata.GetTimeDelta( - media::VideoFrameMetadata::PROCESSING_TIME, &processing_duration)) { - metadata->setProcessingDuration( - GetCoarseClampedTimeInSeconds(processing_duration)); + if (frame_metadata->metadata.processing_time) { + metadata->setProcessingDuration(GetCoarseClampedTimeInSeconds( + *frame_metadata->metadata.processing_time)); } - base::TimeTicks capture_time; - if (frame_metadata->metadata.GetTimeTicks( - media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, &capture_time)) { + if (frame_metadata->metadata.capture_begin_time) { metadata->setCaptureTime(GetClampedTimeInMillis( - time_converter.MonotonicTimeToZeroBasedDocumentTime(capture_time))); + time_converter.MonotonicTimeToZeroBasedDocumentTime( + *frame_metadata->metadata.capture_begin_time))); } - base::TimeTicks receive_time; - if (frame_metadata->metadata.GetTimeTicks( - media::VideoFrameMetadata::RECEIVE_TIME, &receive_time)) { + if (frame_metadata->metadata.receive_time) { metadata->setReceiveTime(GetClampedTimeInMillis( - time_converter.MonotonicTimeToZeroBasedDocumentTime(receive_time))); + time_converter.MonotonicTimeToZeroBasedDocumentTime( + *frame_metadata->metadata.receive_time))); } - double rtp_timestamp; - if (frame_metadata->metadata.GetDouble( - media::VideoFrameMetadata::RTP_TIMESTAMP, &rtp_timestamp)) { + if (frame_metadata->metadata.rtp_timestamp) { + double rtp_timestamp = *frame_metadata->metadata.rtp_timestamp; base::CheckedNumeric<uint32_t> uint_rtp_timestamp = rtp_timestamp; if (uint_rtp_timestamp.IsValid()) metadata->setRtpTimestamp(rtp_timestamp); @@ -261,7 +256,7 @@ void VideoFrameCallbackRequesterImpl::cancelVideoFrameCallback(int id) { callback_collection_->CancelFrameCallback(id); } -void VideoFrameCallbackRequesterImpl::Trace(Visitor* visitor) { +void VideoFrameCallbackRequesterImpl::Trace(Visitor* visitor) const { visitor->Trace(callback_collection_); Supplement<HTMLVideoElement>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.h b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.h index b926f645555..86b4f90a771 100644 --- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.h +++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl.h @@ -33,7 +33,7 @@ class MODULES_EXPORT VideoFrameCallbackRequesterImpl final explicit VideoFrameCallbackRequesterImpl(HTMLVideoElement&); ~VideoFrameCallbackRequesterImpl() override = default; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; int requestVideoFrameCallback(V8VideoFrameRequestCallback*); void cancelVideoFrameCallback(int); diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc index e7c3fe022ac..e122b2b5959 100644 --- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc +++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_callback_requester_impl_test.cc @@ -94,16 +94,13 @@ class MetadataHelper { metadata_.width = 320; metadata_.height = 480; metadata_.media_time = base::TimeDelta::FromSecondsD(3.14); - metadata_.metadata.SetTimeDelta(media::VideoFrameMetadata::PROCESSING_TIME, - base::TimeDelta::FromMillisecondsD(60.982)); - metadata_.metadata.SetTimeTicks( - media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, - now + base::TimeDelta::FromMillisecondsD(5.6785)); - metadata_.metadata.SetTimeTicks( - media::VideoFrameMetadata::RECEIVE_TIME, - now + base::TimeDelta::FromMillisecondsD(17.1234)); - metadata_.metadata.SetDouble(media::VideoFrameMetadata::RTP_TIMESTAMP, - 12345); + metadata_.metadata.processing_time = + base::TimeDelta::FromMillisecondsD(60.982); + metadata_.metadata.capture_begin_time = + now + base::TimeDelta::FromMillisecondsD(5.6785); + metadata_.metadata.receive_time = + now + base::TimeDelta::FromMillisecondsD(17.1234); + metadata_.metadata.rtp_timestamp = 12345; initialized = true; } @@ -135,10 +132,7 @@ class VfcRequesterParameterVerifierCallback EXPECT_EQ((unsigned int)expected->height, metadata->height()); EXPECT_EQ(expected->media_time.InSecondsF(), metadata->mediaTime()); - double rtp_timestamp; - EXPECT_TRUE(expected->metadata.GetDouble( - media::VideoFrameMetadata::RTP_TIMESTAMP, &rtp_timestamp)); - EXPECT_EQ(rtp_timestamp, metadata->rtpTimestamp()); + EXPECT_EQ(*expected->metadata.rtp_timestamp, metadata->rtpTimestamp()); // Verify that values were correctly clamped. VerifyTicksClamping(expected->presentation_time, @@ -147,19 +141,13 @@ class VfcRequesterParameterVerifierCallback metadata->expectedDisplayTime(), "expected_display_time"); - base::TimeTicks capture_time; - EXPECT_TRUE(expected->metadata.GetTimeTicks( - media::VideoFrameMetadata::CAPTURE_BEGIN_TIME, &capture_time)); - VerifyTicksClamping(capture_time, metadata->captureTime(), "capture_time"); + VerifyTicksClamping(*expected->metadata.capture_begin_time, + metadata->captureTime(), "capture_time"); - base::TimeTicks receive_time; - EXPECT_TRUE(expected->metadata.GetTimeTicks( - media::VideoFrameMetadata::RECEIVE_TIME, &receive_time)); - VerifyTicksClamping(receive_time, metadata->receiveTime(), "receive_time"); + VerifyTicksClamping(*expected->metadata.receive_time, + metadata->receiveTime(), "receive_time"); - base::TimeDelta processing_time; - EXPECT_TRUE(expected->metadata.GetTimeDelta( - media::VideoFrameMetadata::PROCESSING_TIME, &processing_time)); + base::TimeDelta processing_time = *expected->metadata.processing_time; EXPECT_EQ(ClampElapsedProcessingTime(processing_time), metadata->processingDuration()); EXPECT_NE(processing_time.InSecondsF(), metadata->processingDuration()); diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl index 1d8e03c39cd..4d21123e47c 100644 --- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl +++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://wicg.github.io/video-raf/. +// See https://wicg.github.io/video-rvfc/. dictionary VideoFrameMetadata { // The time at which the user agent submitted the frame for composition. diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl index 58f324d69a4..c2721731f4b 100644 --- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl +++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// See https://wicg.github.io/video-raf/. +// See https://wicg.github.io/video-rvfc/. [RuntimeEnabled=VideoRequestAnimationFrame] callback VideoFrameRequestCallback = void(DOMHighResTimeStamp time, VideoFrameMetadata metadata); diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc index b9676a22842..8f643de70a5 100644 --- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc +++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.cc @@ -67,7 +67,7 @@ void VideoFrameRequestCallbackCollection::ExecuteFrameCallbacks( callbacks_to_invoke_.clear(); } -void VideoFrameRequestCallbackCollection::Trace(Visitor* visitor) { +void VideoFrameRequestCallbackCollection::Trace(Visitor* visitor) const { visitor->Trace(frame_callbacks_); visitor->Trace(callbacks_to_invoke_); visitor->Trace(context_); @@ -78,7 +78,7 @@ VideoFrameRequestCallbackCollection::V8VideoFrameCallback::V8VideoFrameCallback( : callback_(callback) {} void VideoFrameRequestCallbackCollection::V8VideoFrameCallback::Trace( - blink::Visitor* visitor) { + blink::Visitor* visitor) const { visitor->Trace(callback_); VideoFrameRequestCallbackCollection::VideoFrameCallback::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h index 2cffc395e6d..d15874d78e8 100644 --- a/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h +++ b/chromium/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h @@ -17,7 +17,7 @@ namespace blink { class ExecutionContext; // Class that allows the registration and unregistration of generic -// VideoFrameCallbacks. Used to store to pending video.requestAnimationFrame +// VideoFrameCallbacks. Used to store to pending video.requestVideoFrameCallback // requests, and to propagate the results of the request once it completes. class MODULES_EXPORT VideoFrameRequestCallbackCollection final : public GarbageCollected<VideoFrameRequestCallbackCollection>, @@ -32,7 +32,7 @@ class MODULES_EXPORT VideoFrameRequestCallbackCollection final : public GarbageCollected<VideoFrameCallback>, public NameClient { public: - virtual void Trace(Visitor*) {} + virtual void Trace(Visitor*) const {} const char* NameInHeapSnapshot() const override { return "VideoFrameCallback"; } @@ -57,7 +57,7 @@ class MODULES_EXPORT VideoFrameRequestCallbackCollection final // VideoFrameCallback that can be stored and executed by this collection. class MODULES_EXPORT V8VideoFrameCallback : public VideoFrameCallback { public: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const char* NameInHeapSnapshot() const override { return "V8VideoFrameCallback"; } @@ -85,7 +85,7 @@ class MODULES_EXPORT VideoFrameRequestCallbackCollection final bool IsEmpty() const { return !frame_callbacks_.size(); } - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "VideoFrameRequestCallbackCollection"; } diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/BUILD.gn b/chromium/third_party/blink/renderer/modules/virtualkeyboard/BUILD.gn index 3178cb690c6..85b4ebfcc7f 100644 --- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/BUILD.gn @@ -10,7 +10,7 @@ blink_modules_sources("virtualkeyboard") { "navigator_virtual_keyboard.h", "virtual_keyboard.cc", "virtual_keyboard.h", - "virtual_keyboard_overlay_geometry_change_event.cc", - "virtual_keyboard_overlay_geometry_change_event.h", + "virtual_keyboard_geometry_change_event.cc", + "virtual_keyboard_geometry_change_event.h", ] } diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/idls.gni b/chromium/third_party/blink/renderer/modules/virtualkeyboard/idls.gni index c12821c4afa..2f8c334a795 100644 --- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/idls.gni +++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/idls.gni @@ -4,10 +4,10 @@ modules_idl_files = [ "virtual_keyboard.idl", - "virtual_keyboard_overlay_geometry_change_event.idl", + "virtual_keyboard_geometry_change_event.idl", ] modules_dictionary_idl_files = - [ "virtual_keyboard_overlay_geometry_change_event_init.idl" ] + [ "virtual_keyboard_geometry_change_event_init.idl" ] modules_dependency_idl_files = [ "navigator_virtual_keyboard.idl" ] diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.cc b/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.cc index a076e73fffb..6ea3348a06e 100644 --- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.cc +++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.cc @@ -29,7 +29,7 @@ VirtualKeyboard* NavigatorVirtualKeyboard::virtualKeyboard( return supplement->virtual_keyboard_; } -void NavigatorVirtualKeyboard::Trace(Visitor* visitor) { +void NavigatorVirtualKeyboard::Trace(Visitor* visitor) const { visitor->Trace(virtual_keyboard_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.h b/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.h index b34dade7ebc..c3f6e60461a 100644 --- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.h +++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.h @@ -30,7 +30,7 @@ class NavigatorVirtualKeyboard final NavigatorVirtualKeyboard(const NavigatorVirtualKeyboard&) = delete; NavigatorVirtualKeyboard operator=(const NavigatorVirtualKeyboard&) = delete; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<VirtualKeyboard> virtual_keyboard_; diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc index 97e39428930..585fe1f687b 100644 --- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc +++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.cc @@ -4,15 +4,33 @@ #include "third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.h" +#include "third_party/blink/renderer/core/css/document_style_environment_variables.h" +#include "third_party/blink/renderer/core/css/style_engine.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/editing/ime/input_method_controller.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/core/geometry/dom_rect.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/virtualkeyboard/virtual_keyboard_geometry_change_event.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/rect_f.h" namespace blink { +namespace { + +String FormatPx(int value) { + return String::Format("%dpx", value); +} + +} // namespace + VirtualKeyboard::VirtualKeyboard(LocalFrame* frame) : ExecutionContextClient(frame ? frame->DomWindow()->GetExecutionContext() - : nullptr) {} + : nullptr), + VirtualKeyboardOverlayChangedObserver(frame) {} ExecutionContext* VirtualKeyboard::GetExecutionContext() const { return ExecutionContextClient::GetExecutionContext(); @@ -28,24 +46,73 @@ bool VirtualKeyboard::overlaysContent() const { return overlays_content_; } +DOMRect* VirtualKeyboard::boundingRect() const { + return bounding_rect_; +} + void VirtualKeyboard::setOverlaysContent(bool overlays_content) { - // TODO(snianu): Fill this function. + LocalFrame* frame = GetFrame(); + if (frame && frame->IsMainFrame()) { + if (overlays_content != overlays_content_) { + auto& local_frame_host = frame->GetLocalFrameHostRemote(); + local_frame_host.SetVirtualKeyboardOverlayPolicy(overlays_content); + overlays_content_ = overlays_content; + } + } else { + GetExecutionContext()->AddConsoleMessage( + MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kJavaScript, + mojom::blink::ConsoleMessageLevel::kWarning, + "Setting overlaysContent is only supported from " + "the top level browsing context")); + } } void VirtualKeyboard::VirtualKeyboardOverlayChanged( const gfx::Rect& keyboard_rect) { - // TODO(snianu): Fill this function. + bounding_rect_ = DOMRect::FromFloatRect(FloatRect(gfx::RectF(keyboard_rect))); + LocalFrame* frame = GetFrame(); + if (frame && frame->GetDocument()) { + DocumentStyleEnvironmentVariables& vars = + frame->GetDocument()->GetStyleEngine().EnsureEnvironmentVariables(); + vars.SetVariable(UADefinedVariable::kKeyboardInsetTop, + FormatPx(keyboard_rect.y())); + vars.SetVariable(UADefinedVariable::kKeyboardInsetLeft, + FormatPx(keyboard_rect.x())); + vars.SetVariable(UADefinedVariable::kKeyboardInsetBottom, + FormatPx(keyboard_rect.bottom())); + vars.SetVariable(UADefinedVariable::kKeyboardInsetRight, + FormatPx(keyboard_rect.right())); + } + DispatchEvent(*(MakeGarbageCollected<VirtualKeyboardGeometryChangeEvent>( + event_type_names::kGeometrychange, bounding_rect_))); } void VirtualKeyboard::show() { - // TODO(snianu): Fill this function. + LocalFrame* frame = GetFrame(); + if (frame && frame->HasStickyUserActivation()) { + frame->GetInputMethodController().SetVirtualKeyboardVisibilityRequest( + ui::mojom::VirtualKeyboardVisibilityRequest::SHOW); + } else { + GetExecutionContext()->AddConsoleMessage( + MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kJavaScript, + mojom::blink::ConsoleMessageLevel::kWarning, + "Calling show is only supported if user has " + "interacted with the page")); + } } void VirtualKeyboard::hide() { - // TODO(snianu): Fill this function. + LocalFrame* frame = GetFrame(); + if (frame) { + frame->GetInputMethodController().SetVirtualKeyboardVisibilityRequest( + ui::mojom::VirtualKeyboardVisibilityRequest::HIDE); + } } -void VirtualKeyboard::Trace(Visitor* visitor) { +void VirtualKeyboard::Trace(Visitor* visitor) const { + visitor->Trace(bounding_rect_); EventTargetWithInlineData::Trace(visitor); ExecutionContextClient::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.h b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.h index db740ba1030..a65728ac10c 100644 --- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.h +++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.h @@ -8,6 +8,7 @@ #include "base/macros.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/frame/virtual_keyboard_overlay_changed_observer.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" namespace gfx { @@ -16,13 +17,15 @@ class Rect; namespace blink { +class DOMRect; class ExecutionContext; // The VirtualKeyboard API provides control of the on-screen keyboard // to JS authors. The VirtualKeyboard object lives in the Navigator. // It is exposed to JS via a new attribute virtualKeyboard in the Navigator. class VirtualKeyboard final : public EventTargetWithInlineData, - public ExecutionContextClient { + public ExecutionContextClient, + public VirtualKeyboardOverlayChangedObserver { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(VirtualKeyboard); @@ -36,21 +39,23 @@ class VirtualKeyboard final : public EventTargetWithInlineData, ExecutionContext* GetExecutionContext() const override; const AtomicString& InterfaceName() const override; - DEFINE_ATTRIBUTE_EVENT_LISTENER(overlaygeometrychange, kOverlaygeometrychange) + DEFINE_ATTRIBUTE_EVENT_LISTENER(geometrychange, kGeometrychange) bool overlaysContent() const; void setOverlaysContent(bool overlays_content); + DOMRect* boundingRect() const; - void VirtualKeyboardOverlayChanged(const gfx::Rect&); + void VirtualKeyboardOverlayChanged(const gfx::Rect&) final; // Public APIs for controlling the visibility of VirtualKeyboard. void show(); void hide(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: bool overlays_content_ = false; + Member<DOMRect> bounding_rect_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.idl b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.idl index c59d5431c29..384f023f5b7 100644 --- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.idl +++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.idl @@ -12,6 +12,7 @@ ] interface VirtualKeyboard : EventTarget { void show(); void hide(); - attribute EventHandler onoverlaygeometrychange; + readonly attribute DOMRect boundingRect; attribute boolean overlaysContent; + attribute EventHandler ongeometrychange; }; diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.cc b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.cc new file mode 100644 index 00000000000..22ddffb2642 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.cc @@ -0,0 +1,34 @@ +// Copyright 2020 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/virtualkeyboard/virtual_keyboard_geometry_change_event.h" + +#include "third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_geometry_change_event_init.h" +#include "third_party/blink/renderer/core/geometry/dom_rect.h" + +namespace blink { + +VirtualKeyboardGeometryChangeEvent* VirtualKeyboardGeometryChangeEvent::Create( + const AtomicString& type, + const VirtualKeyboardGeometryChangeEventInit* initializer) { + return MakeGarbageCollected<VirtualKeyboardGeometryChangeEvent>(type, + initializer); +} + +VirtualKeyboardGeometryChangeEvent::VirtualKeyboardGeometryChangeEvent( + const AtomicString& type, + const VirtualKeyboardGeometryChangeEventInit* initializer) + : Event(type, initializer) {} + +VirtualKeyboardGeometryChangeEvent::VirtualKeyboardGeometryChangeEvent( + const AtomicString& type, + DOMRect* rect) + : Event(type, Bubbles::kNo, Cancelable::kNo), bounding_rect_(rect) {} + +void VirtualKeyboardGeometryChangeEvent::Trace(Visitor* visitor) const { + visitor->Trace(bounding_rect_); + Event::Trace(visitor); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.h b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.h index c9dc3b2cdca..9aa2ab695db 100644 --- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.h +++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.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_VIRTUALKEYBOARD_VIRTUAL_KEYBOARD_OVERLAY_GEOMETRY_CHANGE_EVENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_VIRTUALKEYBOARD_VIRTUAL_KEYBOARD_OVERLAY_GEOMETRY_CHANGE_EVENT_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_VIRTUALKEYBOARD_VIRTUAL_KEYBOARD_GEOMETRY_CHANGE_EVENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_VIRTUALKEYBOARD_VIRTUAL_KEYBOARD_GEOMETRY_CHANGE_EVENT_H_ #include "third_party/blink/renderer/modules/event_modules.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -11,24 +11,24 @@ namespace blink { class DOMRect; -class VirtualKeyboardOverlayGeometryChangeEventInit; +class VirtualKeyboardGeometryChangeEventInit; -class VirtualKeyboardOverlayGeometryChangeEvent final : public Event { +class VirtualKeyboardGeometryChangeEvent final : public Event { DEFINE_WRAPPERTYPEINFO(); public: - static VirtualKeyboardOverlayGeometryChangeEvent* Create( + static VirtualKeyboardGeometryChangeEvent* Create( const AtomicString& type, - const VirtualKeyboardOverlayGeometryChangeEventInit*); + const VirtualKeyboardGeometryChangeEventInit*); - VirtualKeyboardOverlayGeometryChangeEvent( + VirtualKeyboardGeometryChangeEvent( const AtomicString& type, - const VirtualKeyboardOverlayGeometryChangeEventInit*); - VirtualKeyboardOverlayGeometryChangeEvent(const AtomicString& type, DOMRect*); + const VirtualKeyboardGeometryChangeEventInit*); + VirtualKeyboardGeometryChangeEvent(const AtomicString& type, DOMRect*); DOMRect* boundingRect() const { return bounding_rect_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<DOMRect> bounding_rect_; @@ -36,4 +36,4 @@ class VirtualKeyboardOverlayGeometryChangeEvent final : public Event { } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_VIRTUALKEYBOARD_VIRTUAL_KEYBOARD_OVERLAY_GEOMETRY_CHANGE_EVENT_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_VIRTUALKEYBOARD_VIRTUAL_KEYBOARD_GEOMETRY_CHANGE_EVENT_H_ diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.idl b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.idl index b46d865260b..52759368fab 100644 --- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.idl +++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.idl @@ -9,8 +9,8 @@ [ Exposed=Window, RuntimeEnabled=VirtualKeyboard -] interface VirtualKeyboardOverlayGeometryChangeEvent : Event { - constructor(DOMString type, VirtualKeyboardOverlayGeometryChangeEventInit eventInitDict); +] interface VirtualKeyboardGeometryChangeEvent : Event { + constructor(DOMString type, VirtualKeyboardGeometryChangeEventInit eventInitDict); [SameObject] readonly attribute DOMRect boundingRect; }; diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event_init.idl b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event_init.idl index 9f3164a9f97..87c91987004 100644 --- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event_init.idl +++ b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event_init.idl @@ -2,6 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -dictionary VirtualKeyboardOverlayGeometryChangeEventInit : EventInit { +dictionary VirtualKeyboardGeometryChangeEventInit : EventInit { required DOMRect boundingRect; }; diff --git a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.cc b/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.cc deleted file mode 100644 index b825f6d8da2..00000000000 --- a/chromium/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.cc +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2020 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/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.h" - -#include "third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_overlay_geometry_change_event_init.h" -#include "third_party/blink/renderer/core/geometry/dom_rect.h" - -namespace blink { - -VirtualKeyboardOverlayGeometryChangeEvent* -VirtualKeyboardOverlayGeometryChangeEvent::Create( - const AtomicString& type, - const VirtualKeyboardOverlayGeometryChangeEventInit* initializer) { - return MakeGarbageCollected<VirtualKeyboardOverlayGeometryChangeEvent>( - type, initializer); -} - -VirtualKeyboardOverlayGeometryChangeEvent:: - VirtualKeyboardOverlayGeometryChangeEvent( - const AtomicString& type, - const VirtualKeyboardOverlayGeometryChangeEventInit* initializer) - : Event(type, initializer) {} - -VirtualKeyboardOverlayGeometryChangeEvent:: - VirtualKeyboardOverlayGeometryChangeEvent(const AtomicString& type, - DOMRect* rect) - : Event(type, Bubbles::kNo, Cancelable::kNo), bounding_rect_(rect) {} - -void VirtualKeyboardOverlayGeometryChangeEvent::Trace(Visitor* visitor) { - visitor->Trace(bounding_rect_); - Event::Trace(visitor); -} - -} // namespace blink 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 index 70468444780..35c805316ce 100644 --- 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 @@ -40,7 +40,7 @@ WakeLock* NavigatorWakeLock::wakeLock(Navigator& navigator) { return NavigatorWakeLock::From(navigator).GetWakeLock(); } -void NavigatorWakeLock::Trace(Visitor* visitor) { +void NavigatorWakeLock::Trace(Visitor* visitor) const { visitor->Trace(wake_lock_); Supplement<Navigator>::Trace(visitor); } 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 index 62c54ce9c20..520f37893f2 100644 --- 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 @@ -26,7 +26,7 @@ class NavigatorWakeLock final : public GarbageCollected<NavigatorWakeLock>, explicit NavigatorWakeLock(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: WakeLock* GetWakeLock(); 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 dcb8434a192..849d669c0c4 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 @@ -279,7 +279,7 @@ PermissionService* WakeLock::GetPermissionService() { return permission_service_.get(); } -void WakeLock::Trace(Visitor* visitor) { +void WakeLock::Trace(Visitor* visitor) const { for (const WakeLockManager* manager : managers_) visitor->Trace(manager); visitor->Trace(permission_service_); 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 b2f37d62e95..567d8c1805f 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 @@ -46,7 +46,7 @@ class MODULES_EXPORT WakeLock final : public ScriptWrappable, const WTF::String& type, ExceptionState& exception_state); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // While this could be part of request() itself, having it as a separate diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.cc b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.cc index 579fdf7cccb..6e875ce03c1 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.cc +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h" -#include "base/logging.h" +#include "base/check_op.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" @@ -99,7 +99,7 @@ void WakeLockManager::OnWakeLockConnectionError() { ClearWakeLocks(); } -void WakeLockManager::Trace(Visitor* visitor) { +void WakeLockManager::Trace(Visitor* visitor) const { visitor->Trace(execution_context_); visitor->Trace(wake_lock_sentinels_); visitor->Trace(wake_lock_); diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h index 1375d9e5292..dd7ecce3dc3 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_manager.h @@ -31,7 +31,7 @@ class MODULES_EXPORT WakeLockManager final void UnregisterSentinel(WakeLockSentinel*); - void Trace(Visitor* visitor); + void Trace(Visitor* visitor) const; private: // Handle connection errors from |wake_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 index 2a6a7bbad35..182b2648631 100644 --- 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 @@ -53,7 +53,7 @@ const AtomicString& WakeLockSentinel::InterfaceName() const { return event_target_names::kWakeLockSentinel; } -void WakeLockSentinel::Trace(Visitor* visitor) { +void WakeLockSentinel::Trace(Visitor* visitor) const { visitor->Trace(manager_); EventTargetWithInlineData::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); 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 index 35e192c501f..636e0b534a6 100644 --- 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 @@ -42,7 +42,7 @@ class MODULES_EXPORT WakeLockSentinel final // EventTarget overrides. ExecutionContext* GetExecutionContext() const override; const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // ActiveScriptWrappable overrides. bool HasPendingActivity() const override; diff --git a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h index 09fe8e6dba7..21d2e65dcf5 100644 --- a/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h +++ b/chromium/third_party/blink/renderer/modules/wake_lock/wake_lock_type.h @@ -7,7 +7,6 @@ #include <stdint.h> -#include "base/logging.h" #include "services/device/public/mojom/wake_lock.mojom-blink.h" #include "third_party/blink/renderer/modules/modules_export.h" 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 index c7bbe98a4e9..ecd93b83e5b 100644 --- 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 @@ -49,7 +49,7 @@ WakeLock* WorkerNavigatorWakeLock::GetWakeLock(ScriptState* script_state) { return wake_lock_; } -void WorkerNavigatorWakeLock::Trace(Visitor* visitor) { +void WorkerNavigatorWakeLock::Trace(Visitor* visitor) const { visitor->Trace(wake_lock_); Supplement<WorkerNavigator>::Trace(visitor); } 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 index 5e11c5154af..c7bc84e84cf 100644 --- 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 @@ -28,7 +28,7 @@ class WorkerNavigatorWakeLock final explicit WorkerNavigatorWakeLock(WorkerNavigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: WakeLock* GetWakeLock(ScriptState*); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.h index a70c5f013b5..43ef43a8c89 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer.h @@ -107,7 +107,7 @@ class MODULES_EXPORT AudioBuffer final : public ScriptWrappable { void Zero(); - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(channels_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc index cc8282bfd3f..0e3c414d3f8 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.cc @@ -715,7 +715,7 @@ AudioBufferSourceNode* AudioBufferSourceNode::Create( return node; } -void AudioBufferSourceNode::Trace(Visitor* visitor) { +void AudioBufferSourceNode::Trace(Visitor* visitor) const { visitor->Trace(playback_rate_); visitor->Trace(detune_); visitor->Trace(buffer_); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.h index 9dcf0bdec3f..09b00cbf9e8 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.h @@ -202,7 +202,7 @@ class AudioBufferSourceNode final : public AudioScheduledSourceNode { AudioBufferSourceOptions*, ExceptionState&); AudioBufferSourceNode(BaseAudioContext&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; AudioBufferSourceHandler& GetAudioBufferSourceHandler() const; AudioBuffer* buffer() const; 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 c140228aa88..783ee92eeb0 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.cc @@ -62,7 +62,7 @@ AudioContext* AudioContext::Create(Document& document, return nullptr; } - document.CountUseOnlyInCrossOriginIframe( + document.domWindow()->CountUseOnlyInCrossOriginIframe( WebFeature::kAudioContextCrossOriginIframe); WebAudioLatencyHint latency_hint(WebAudioLatencyHint::kCategoryInteractive); @@ -194,7 +194,7 @@ AudioContext::~AudioContext() { #endif } -void AudioContext::Trace(Visitor* visitor) { +void AudioContext::Trace(Visitor* visitor) const { visitor->Trace(close_resolver_); visitor->Trace(audio_context_manager_); BaseAudioContext::Trace(visitor); 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 489e97515fc..1002e68ca32 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context.h @@ -44,7 +44,7 @@ class MODULES_EXPORT AudioContext : public BaseAudioContext { const WebAudioLatencyHint&, base::Optional<float> sample_rate); ~AudioContext() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // For ContextLifeCycleObserver void ContextDestroyed() final; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc index 0be3ef462de..b8eea5ca2ee 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc @@ -37,7 +37,7 @@ class MockCrossOriginLocalFrameClient final : public EmptyLocalFrameClient { public: explicit MockCrossOriginLocalFrameClient(Frame* parent) : parent_(parent) {} - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(parent_); EmptyLocalFrameClient::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.cc index 05cba348460..ef4f4d5718a 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.cc @@ -24,7 +24,7 @@ void AudioGraphTracer::ProvideAudioGraphTracerTo(Page& page) { AudioGraphTracer::AudioGraphTracer() : inspector_agent_(nullptr) {} -void AudioGraphTracer::Trace(Visitor* visitor) { +void AudioGraphTracer::Trace(Visitor* visitor) const { visitor->Trace(inspector_agent_); visitor->Trace(contexts_); Supplement<Page>::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h index b6847261dd9..f3286418ddc 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_graph_tracer.h @@ -33,7 +33,7 @@ class MODULES_EXPORT AudioGraphTracer final AudioGraphTracer(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void SetInspectorAgent(InspectorWebAudioAgent*); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.cc index be092222b5a..956a0974e30 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.cc @@ -121,7 +121,7 @@ AudioListener::AudioListener(BaseAudioContext& context) AudioListener::~AudioListener() = default; -void AudioListener::Trace(Visitor* visitor) { +void AudioListener::Trace(Visitor* visitor) const { visitor->Trace(position_x_); visitor->Trace(position_y_); visitor->Trace(position_z_); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.h index 135706c420f..7f500103f74 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_listener.h @@ -137,7 +137,7 @@ class AudioListener : public ScriptWrappable, public InspectorHelperMixin { void ReportDidCreate() final; void ReportWillBeDestroyed() final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void setPosition(const FloatPoint3D&, ExceptionState&); 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 67ac709bbfa..e1f1a068d23 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc @@ -650,7 +650,7 @@ AudioHandler& AudioNode::Handler() const { return *handler_; } -void AudioNode::Trace(Visitor* visitor) { +void AudioNode::Trace(Visitor* visitor) const { visitor->Trace(context_); visitor->Trace(connected_nodes_); visitor->Trace(connected_params_); 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 82806009d4e..ecf9d516239 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.h @@ -334,7 +334,7 @@ class MODULES_EXPORT AudioNode : public EventTargetWithInlineData, public: ~AudioNode() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; AudioHandler& Handler() const; void HandleChannelOptions(const AudioNodeOptions*, ExceptionState&); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc index 68545cc7026..c5d329479a4 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.cc @@ -367,7 +367,7 @@ AudioParam::~AudioParam() { } } -void AudioParam::Trace(Visitor* visitor) { +void AudioParam::Trace(Visitor* visitor) const { visitor->Trace(context_); InspectorHelperMixin::Trace(visitor); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h index 1c6bb1d5f0a..79ea4a76f7a 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param.h @@ -281,7 +281,7 @@ class AudioParam final : public ScriptWrappable, public InspectorHelperMixin { ~AudioParam() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // |handler| always returns a valid object. AudioParamHandler& Handler() const { return *handler_; } // |context| always returns a valid object. diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.cc index 04cc77bfcb5..2dd5f543a89 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.cc @@ -29,7 +29,7 @@ class AudioParamMapIterationSource final return true; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(parameter_objects_); PairIterable<String, AudioParam*>::IterationSource::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.h index f3da25ae3fa..ecace55dc9b 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_param_map.h @@ -31,7 +31,7 @@ class AudioParamMap final : public ScriptWrappable, const MapType& GetHashMap() const { return parameter_map_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(parameter_map_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc index c023bf3d110..95a23020fa6 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.cc @@ -72,7 +72,7 @@ const AtomicString& AudioProcessingEvent::InterfaceName() const { return event_interface_names::kAudioProcessingEvent; } -void AudioProcessingEvent::Trace(Visitor* visitor) { +void AudioProcessingEvent::Trace(Visitor* visitor) const { visitor->Trace(input_buffer_); visitor->Trace(output_buffer_); Event::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.h index 26725400cf7..1431ce7dc0e 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_processing_event.h @@ -62,7 +62,7 @@ class AudioProcessingEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<AudioBuffer> input_buffer_; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h index 407f77334d2..2258cda33fc 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.h @@ -192,7 +192,7 @@ class AudioScheduledSourceNode // ScriptWrappable: bool HasPendingActivity() const final; - void Trace(Visitor* visitor) override { AudioNode::Trace(visitor); } + void Trace(Visitor* visitor) const override { AudioNode::Trace(visitor); } AudioScheduledSourceHandler& GetAudioScheduledSourceHandler() const; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc index d219e80a222..7045f8fbdac 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.cc @@ -90,7 +90,7 @@ AudioWorkletMessagingProxy* AudioWorklet::GetMessagingProxy() { FindAvailableGlobalScope()); } -void AudioWorklet::Trace(Visitor* visitor) { +void AudioWorklet::Trace(Visitor* visitor) const { visitor->Trace(context_); Worklet::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.h index c6705f9abef..588e2725c0b 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet.h @@ -51,7 +51,7 @@ class MODULES_EXPORT AudioWorklet final : public Worklet { // are ready. bool IsReady(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Implements Worklet 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 5fec9f992bf..6af14ccb6d6 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 @@ -246,7 +246,7 @@ double AudioWorkletGlobalScope::currentTime() const { : 0.0; } -void AudioWorkletGlobalScope::Trace(Visitor* visitor) { +void AudioWorkletGlobalScope::Trace(Visitor* visitor) const { visitor->Trace(processor_definition_map_); visitor->Trace(processor_instances_); WorkletGlobalScope::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h index c898424cbe0..c9287d31b62 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.h @@ -95,7 +95,7 @@ class MODULES_EXPORT AudioWorkletGlobalScope final : public WorkletGlobalScope { double currentTime() const; float sampleRate() const { return sample_rate_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: bool is_closing_ = false; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc index 8b4ecada270..13df2e3b092 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.cc @@ -95,10 +95,9 @@ std::unique_ptr<WorkerThread> AudioWorkletMessagingProxy::CreateWorkerThread() { return AudioWorkletThread::Create(WorkletObjectProxy()); } -void AudioWorkletMessagingProxy::Trace(Visitor* visitor) { +void AudioWorkletMessagingProxy::Trace(Visitor* visitor) const { visitor->Trace(worklet_); ThreadedWorkletMessagingProxy::Trace(visitor); } - } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.h index c961ded1fc8..006ec56b231 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_messaging_proxy.h @@ -59,7 +59,7 @@ class AudioWorkletMessagingProxy final : public ThreadedWorkletMessagingProxy { // Returns a WorkerThread object backs the AudioWorkletThread instance. WorkerThread* GetBackingWorkerThread(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Implements ThreadedWorkletMessagingProxy. diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc index 46b1bec811b..9c7faf78ba6 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc @@ -440,7 +440,7 @@ scoped_refptr<AudioWorkletHandler> AudioWorkletNode::GetWorkletHandler() const { return WrapRefCounted(&static_cast<AudioWorkletHandler&>(Handler())); } -void AudioWorkletNode::Trace(Visitor* visitor) { +void AudioWorkletNode::Trace(Visitor* visitor) const { visitor->Trace(parameter_map_); visitor->Trace(node_port_); AudioNode::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h index 6dfd8a997d3..16a83b8fad8 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.h @@ -122,7 +122,7 @@ class AudioWorkletNode final : public AudioNode, void FireProcessorError(AudioWorkletProcessorErrorState); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // InspectorHelperMixin void ReportDidCreate() final; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc index 6425df584a5..9ac9bcc9196 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc @@ -83,6 +83,10 @@ bool AudioWorkletProcessor::Process( DCHECK(outputs_cloned_successfully); if (!outputs_cloned_successfully) return false; + } else { + // The reallocation was not needed, so the arrays need to be zeroed before + // passing them to the author script. + ZeroArrayBuffers(isolate, output_array_buffers_); } DCHECK(!outputs_.IsEmpty()); DCHECK(outputs_.NewLocal(isolate)->IsArray()); @@ -151,7 +155,7 @@ MessagePort* AudioWorkletProcessor::port() const { return processor_port_.Get(); } -void AudioWorkletProcessor::Trace(Visitor* visitor) { +void AudioWorkletProcessor::Trace(Visitor* visitor) const { visitor->Trace(global_scope_); visitor->Trace(processor_port_); visitor->Trace(inputs_); @@ -351,6 +355,20 @@ void AudioWorkletProcessor::CopyArrayBuffersToPort( } } +void AudioWorkletProcessor::ZeroArrayBuffers( + v8::Isolate* isolate, + const BackingArrayBuffers& array_buffers) { + for (uint32_t bus_index = 0; bus_index < array_buffers.size(); ++bus_index) { + for (uint32_t channel_index = 0; + channel_index < array_buffers[bus_index].size(); ++channel_index) { + const v8::ArrayBuffer::Contents& contents = + array_buffers[bus_index][channel_index].NewLocal(isolate) + ->GetContents(); + memset(contents.Data(), 0, contents.ByteLength()); + } + } +} + bool AudioWorkletProcessor::ParamValueMapMatchesToParamsObject( v8::Isolate* isolate, v8::Local<v8::Context> context, diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h index 5e460447d2e..ba8cec8bc82 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.h @@ -58,7 +58,7 @@ class MODULES_EXPORT AudioWorkletProcessor : public ScriptWrappable { // IDL MessagePort* port() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: using BackingArrayBuffers = @@ -110,6 +110,10 @@ class MODULES_EXPORT AudioWorkletProcessor : public ScriptWrappable { const BackingArrayBuffers& array_buffers, Vector<scoped_refptr<AudioBus>>& audio_port); + // Fills a given BackingArrayBuffers with zeros. + static void ZeroArrayBuffers(v8::Isolate*, + const BackingArrayBuffers& array_buffers); + // Returns true if the structure of |param_value_map| matches |params| object // and the underlying ArrayBuffers are not transferred. static bool ParamValueMapMatchesToParamsObject( diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.cc index 4582883825c..bc2a522af3a 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor_definition.cc @@ -50,7 +50,7 @@ const AudioParamDescriptor* return nullptr; } -void AudioWorkletProcessorDefinition::Trace(Visitor* visitor) { +void AudioWorkletProcessorDefinition::Trace(Visitor* visitor) const { visitor->Trace(constructor_); visitor->Trace(process_); visitor->Trace(audio_param_descriptors_); 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 8423067b7c7..572f529cf6a 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 @@ -56,7 +56,7 @@ class MODULES_EXPORT AudioWorkletProcessorDefinition final bool IsSynchronized() const { return is_synchronized_; } void MarkAsSynchronized() { is_synchronized_ = true; } - void Trace(Visitor* visitor); + void Trace(Visitor* visitor) const; const char* NameInHeapSnapshot() const override { return "AudioWorkletProcessorDefinition"; 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 8ab57ac7b74..e203973a516 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 @@ -808,7 +808,7 @@ void BaseAudioContext::StartRendering() { } } -void BaseAudioContext::Trace(Visitor* visitor) { +void BaseAudioContext::Trace(Visitor* visitor) const { visitor->Trace(destination_node_); visitor->Trace(listener_); visitor->Trace(resume_resolvers_); 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 4a253013fe3..db458953292 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 @@ -108,7 +108,7 @@ class MODULES_EXPORT BaseAudioContext ~BaseAudioContext() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Is the destination node initialized and ready to handle audio? bool IsDestinationInitialized() const { diff --git a/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc index aae0410c187..15017408ce8 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.cc @@ -183,7 +183,7 @@ BiquadFilterNode* BiquadFilterNode::Create(BaseAudioContext* context, return node; } -void BiquadFilterNode::Trace(Visitor* visitor) { +void BiquadFilterNode::Trace(Visitor* visitor) const { visitor->Trace(frequency_); visitor->Trace(q_); visitor->Trace(gain_); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.h b/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.h index c12bb49406a..ef402034449 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/biquad_filter_node.h @@ -93,7 +93,7 @@ class BiquadFilterNode final : public AudioNode { BiquadFilterNode(BaseAudioContext&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; String type() const; void setType(const String&); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.cc index 69457f926c6..b4c1070e7f5 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.cc @@ -156,7 +156,7 @@ ConstantSourceNode* ConstantSourceNode::Create( return node; } -void ConstantSourceNode::Trace(Visitor* visitor) { +void ConstantSourceNode::Trace(Visitor* visitor) const { visitor->Trace(offset_); AudioScheduledSourceNode::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.h b/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.h index 141100ab827..68b737a02b0 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/constant_source_node.h @@ -53,7 +53,7 @@ class ConstantSourceNode final : public AudioScheduledSourceNode { ExceptionState&); ConstantSourceNode(BaseAudioContext&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; AudioParam* offset(); 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 71fa4abd2dc..2e16a6b66dc 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.cc @@ -350,7 +350,7 @@ void ConvolverNode::setNormalize(bool normalize) { GetConvolverHandler().SetNormalize(normalize); } -void ConvolverNode::Trace(Visitor* visitor) { +void ConvolverNode::Trace(Visitor* visitor) const { visitor->Trace(buffer_); AudioNode::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h index 4545c0e793e..0eb84a5067a 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/convolver_node.h @@ -102,7 +102,7 @@ class MODULES_EXPORT ConvolverNode final : public AudioNode { bool normalize() const; void setNormalize(bool); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // InspectorHelperMixin void ReportDidCreate() final; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/delay_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/delay_node.cc index 5651d362a72..cbdc36aebf6 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/delay_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/delay_node.cc @@ -123,7 +123,7 @@ AudioParam* DelayNode::delayTime() { return delay_time_; } -void DelayNode::Trace(Visitor* visitor) { +void DelayNode::Trace(Visitor* visitor) const { visitor->Trace(delay_time_); AudioNode::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/delay_node.h b/chromium/third_party/blink/renderer/modules/webaudio/delay_node.h index e6d21497330..6020169ba64 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/delay_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/delay_node.h @@ -64,7 +64,7 @@ class DelayNode final : public AudioNode { DelayNode(BaseAudioContext&, double max_delay_time); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; AudioParam* delayTime(); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc index a867f296476..db8b38ba737 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.cc @@ -273,7 +273,7 @@ DynamicsCompressorNode* DynamicsCompressorNode::Create( return node; } -void DynamicsCompressorNode::Trace(Visitor* visitor) { +void DynamicsCompressorNode::Trace(Visitor* visitor) const { visitor->Trace(threshold_); visitor->Trace(knee_); visitor->Trace(ratio_); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.h b/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.h index ed33b6f47e7..154c36fc9d3 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.h @@ -98,7 +98,7 @@ class MODULES_EXPORT DynamicsCompressorNode final : public AudioNode { DynamicsCompressorNode(BaseAudioContext&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; AudioParam* threshold() const; AudioParam* knee() const; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc index 1ddae96adf9..7d9e1c09279 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/gain_node.cc @@ -179,7 +179,7 @@ AudioParam* GainNode::gain() const { return gain_; } -void GainNode::Trace(Visitor* visitor) { +void GainNode::Trace(Visitor* visitor) const { visitor->Trace(gain_); AudioNode::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/gain_node.h b/chromium/third_party/blink/renderer/modules/webaudio/gain_node.h index 614181d180c..22443c490be 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/gain_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/gain_node.h @@ -78,7 +78,7 @@ class GainNode final : public AudioNode { GainNode(BaseAudioContext&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; AudioParam* gain() const; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc index 750c6a0fcbf..ad1b76d7266 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.cc @@ -231,7 +231,7 @@ IIRFilterNode* IIRFilterNode::Create(BaseAudioContext* context, return node; } -void IIRFilterNode::Trace(Visitor* visitor) { +void IIRFilterNode::Trace(Visitor* visitor) const { AudioNode::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.h b/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.h index 1f9234be435..9d0bb35acfd 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/iir_filter_node.h @@ -66,7 +66,7 @@ class IIRFilterNode : public AudioNode { const Vector<double>& numerator, bool is_filter_stable); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Get the magnitude and phase response of the filter at the given // set of frequencies (in Hz). The phase response is in radians. diff --git a/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.cc b/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.cc index 8e947f093bb..594676284e5 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.cc @@ -15,7 +15,7 @@ InspectorHelperMixin::InspectorHelperMixin( uuid_(WTF::CreateCanonicalUUIDString()), parent_uuid_(parent_uuid) {} -void InspectorHelperMixin::Trace(Visitor* visitor) { +void InspectorHelperMixin::Trace(Visitor* visitor) const { visitor->Trace(graph_tracer_); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.h b/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.h index 212bcba3b68..dbc55f47b92 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/inspector_helper_mixin.h @@ -37,7 +37,7 @@ class InspectorHelperMixin : public GarbageCollectedMixin { // to be the last in this call. virtual void ReportWillBeDestroyed() = 0; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<AudioGraphTracer> graph_tracer_; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.cc b/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.cc index 5d679a895f3..fa438c200ac 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.cc @@ -243,7 +243,7 @@ InspectorWebAudioAgent::BuildProtocolContext(BaseAudioContext* context) { .build(); } -void InspectorWebAudioAgent::Trace(Visitor* visitor) { +void InspectorWebAudioAgent::Trace(Visitor* visitor) const { visitor->Trace(page_); InspectorBaseAgent::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.h b/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.h index 0b7afdae27f..7351c42ba6a 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/inspector_web_audio_agent.h @@ -61,7 +61,7 @@ class MODULES_EXPORT InspectorWebAudioAgent final AudioParam* destination_param, int32_t source_output_index = 0); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: std::unique_ptr<protocol::WebAudio::BaseAudioContext> diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc index ef239b45c28..a9ca0605ef3 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.cc @@ -285,7 +285,7 @@ MediaElementAudioSourceNode* MediaElementAudioSourceNode::Create( return Create(*context, *options->mediaElement(), exception_state); } -void MediaElementAudioSourceNode::Trace(Visitor* visitor) { +void MediaElementAudioSourceNode::Trace(Visitor* visitor) const { visitor->Trace(media_element_); AudioSourceProviderClient::Trace(visitor); AudioNode::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h index 322b61ed85e..ab0e6e28ae0 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.h @@ -127,7 +127,7 @@ class MediaElementAudioSourceNode final : public AudioNode, MediaElementAudioSourceNode(AudioContext&, HTMLMediaElement&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; MediaElementAudioSourceHandler& GetMediaElementAudioSourceHandler() const; HTMLMediaElement* mediaElement() const; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc index f903ad77418..5d38b5407bf 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.cc @@ -243,7 +243,7 @@ MediaStreamAudioDestinationNode* MediaStreamAudioDestinationNode::Create( return node; } -void MediaStreamAudioDestinationNode::Trace(Visitor* visitor) { +void MediaStreamAudioDestinationNode::Trace(Visitor* visitor) const { visitor->Trace(stream_); visitor->Trace(source_); AudioBasicInspectorNode::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h index 2da4fa378ac..599f805c877 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.h @@ -95,7 +95,7 @@ class MediaStreamAudioDestinationNode final : public AudioBasicInspectorNode { MediaStream* stream() const { return stream_; } MediaStreamSource* source() const { return source_; } - void Trace(Visitor*) final; + void Trace(Visitor*) const final; // InspectorHelperMixin void ReportDidCreate() final; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc index 253165adabe..a166d4cbfbd 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.cc @@ -185,7 +185,7 @@ MediaStreamAudioSourceNode* MediaStreamAudioSourceNode::Create( return Create(*context, *options->mediaStream(), exception_state); } -void MediaStreamAudioSourceNode::Trace(Visitor* visitor) { +void MediaStreamAudioSourceNode::Trace(Visitor* visitor) const { visitor->Trace(audio_track_); visitor->Trace(media_stream_); AudioSourceProviderClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h index ac671165da5..d74838de3c5 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.h @@ -96,7 +96,7 @@ class MediaStreamAudioSourceNode final MediaStreamTrack*, std::unique_ptr<AudioSourceProvider>); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; MediaStream* getMediaStream() const; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc index 167bf5bab30..bbd1d85307f 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.cc @@ -65,7 +65,7 @@ const AtomicString& OfflineAudioCompletionEvent::InterfaceName() const { return event_interface_names::kOfflineAudioCompletionEvent; } -void OfflineAudioCompletionEvent::Trace(Visitor* visitor) { +void OfflineAudioCompletionEvent::Trace(Visitor* visitor) const { visitor->Trace(rendered_buffer_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h index cdf26cd1f12..78b2708669e 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.h @@ -56,7 +56,7 @@ class OfflineAudioCompletionEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<AudioBuffer> rendered_buffer_; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc index 8eb3406f6c3..27acf41ef1f 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc @@ -157,7 +157,7 @@ OfflineAudioContext::~OfflineAudioContext() { #endif } -void OfflineAudioContext::Trace(Visitor* visitor) { +void OfflineAudioContext::Trace(Visitor* visitor) const { visitor->Trace(complete_resolver_); visitor->Trace(scheduled_suspends_); BaseAudioContext::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h index 5022c96be5f..fdf2080dceb 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_context.h @@ -57,7 +57,7 @@ class MODULES_EXPORT OfflineAudioContext final : public BaseAudioContext { ExceptionState&); ~OfflineAudioContext() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; uint32_t length() const { return total_render_frames_; } 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 2b0d87395ce..73494d08424 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 @@ -90,8 +90,6 @@ void OfflineAudioDestinationHandler::Uninitialize() { if (!IsInitialized()) return; - render_thread_.reset(); - AudioHandler::Uninitialize(); } @@ -384,7 +382,7 @@ OfflineAudioDestinationNode* OfflineAudioDestinationNode::Create( *context, number_of_channels, frames_to_process, sample_rate); } -void OfflineAudioDestinationNode::Trace(Visitor* visitor) { +void OfflineAudioDestinationNode::Trace(Visitor* visitor) const { visitor->Trace(destination_buffer_); AudioDestinationNode::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h index 07d80e4cff5..cc184245bb5 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/offline_audio_destination_node.h @@ -182,7 +182,7 @@ class OfflineAudioDestinationNode final : public AudioDestinationNode { destination_buffer_ = buffer; } - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<AudioBuffer> destination_buffer_; 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 98de4c362a8..08f20fc022a 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.cc @@ -26,6 +26,7 @@ #include <algorithm> #include <limits> +#include "build/build_config.h" #include "third_party/blink/renderer/modules/webaudio/audio_node_output.h" #include "third_party/blink/renderer/modules/webaudio/oscillator_node.h" #include "third_party/blink/renderer/modules/webaudio/periodic_wave.h" @@ -37,6 +38,11 @@ namespace blink { +// Breakpoints where we deicde to do linear interoplation, 3-point +// interpolation or 5-point interpolation. See DoInterpolation(). +constexpr float kInterpolate2Point = 0.3; +constexpr float kInterpolate3Point = 0.16; + OscillatorHandler::OscillatorHandler(AudioNode& node, float sample_rate, const String& oscillator_type, @@ -272,7 +278,7 @@ static float DoInterpolation(double virtual_read_index, // We use Lagrange interpolation because it's relatively simple to // implement and fairly inexpensive, and the interpolator always // passes through known points. - if (incr >= 0.3) { + if (incr >= kInterpolate2Point) { // Increment is fairly large, so we're doing no more than about 3 // points between each wave table entry. Assume linear // interpolation between points is good enough. @@ -295,7 +301,7 @@ static float DoInterpolation(double virtual_read_index, sample_lower = (1 - interpolation_factor) * sample1_lower + interpolation_factor * sample2_lower; - } else if (incr >= .16) { + } else if (incr >= kInterpolate3Point) { // We're doing about 6 interpolation values between each wave // table sample. Just use a 3-point Lagrange interpolator to get a // better estimate than just linear. @@ -351,6 +357,438 @@ static float DoInterpolation(double virtual_read_index, return sample; } +#if defined(ARCH_CPU_X86_FAMILY) +static __m128 v_wrap_virtual_index(__m128 x, + __m128 wave_size, + __m128 inv_wave_size) { + // Wrap the virtual index |x| to the range 0 to wave_size - 1. This is done + // by computing x - floor(x/wave_size)*wave_size. + // + // But there's no SSE2 SIMD instruction for this, so we do it the following + // way. + + // f = truncate(x/wave_size), truncating towards 0. + const __m128 r = _mm_mul_ps(x, inv_wave_size); + __m128i f = _mm_cvttps_epi32(r); + + // Note that if r >= 0, then f <= r. But if r < 0, then r <= f, with equality + // only if r is already an integer. Hence if r < f, we want to subtract 1 + // from f to get floor(r). + + // cmplt(a,b) returns 0xffffffff (-1) if a < b and 0 if not. So cmp is -1 or + // 0 depending on whether r < f, which is what we need to compute floor(r). + const __m128i cmp = _mm_cmplt_ps(r, _mm_cvtepi32_ps(f)); + + // This subtracts 1 if needed to get floor(r). + f = _mm_add_epi32(f, cmp); + + // Convert back to float, and scale by wave_size. And finally subtract that + // from x. + return _mm_sub_ps(x, _mm_mul_ps(_mm_cvtepi32_ps(f), wave_size)); +} + +std::tuple<int, double> OscillatorHandler::ProcessKRateVector( + int n, + float* dest_p, + double virtual_read_index, + float frequency, + float rate_scale) const { + const unsigned periodic_wave_size = periodic_wave_->PeriodicWaveSize(); + const double inv_periodic_wave_size = 1.0 / periodic_wave_size; + + float* higher_wave_data = nullptr; + float* lower_wave_data = nullptr; + float table_interpolation_factor = 0; + float incr = frequency * rate_scale; + DCHECK_GE(incr, kInterpolate2Point); + + periodic_wave_->WaveDataForFundamentalFrequency( + frequency, lower_wave_data, higher_wave_data, table_interpolation_factor); + + const __m128 v_wave_size = _mm_set1_ps(periodic_wave_size); + const __m128 v_inv_wave_size = _mm_set1_ps(1.0f / periodic_wave_size); + + // Mask to use to wrap the read indices to the proper range. + const __m128i v_read_mask = _mm_set1_epi32(periodic_wave_size - 1); + const __m128i one = _mm_set1_epi32(1); + + const __m128 v_table_factor = _mm_set1_ps(table_interpolation_factor); + + // The loop processes 4 items at a time, so we need to increment the + // virtual index by 4*incr each time. + const __m128 v_incr = _mm_set1_ps(4 * incr); + + // The virtual index vector. Ideally, to preserve accuracy, we should use + // (two) packed double vectors for this, but that degrades performance quite a + // bit. + __m128 v_virt_index = + _mm_set_ps(virtual_read_index + 3 * incr, virtual_read_index + 2 * incr, + virtual_read_index + incr, virtual_read_index); + + // It's possible that adding the incr above exceeded the bounds, so wrap them + // if needed. + v_virt_index = + v_wrap_virtual_index(v_virt_index, v_wave_size, v_inv_wave_size); + + // Temporary arrays where we can gather up the wave data we need for + // interpolation. Align these for best efficiency on older CPUs where aligned + // access is much faster than unaliged. + // TODO(1013118): Is there a faster way to do this? + float sample1_lower[4] __attribute__((aligned(16))); + float sample2_lower[4] __attribute__((aligned(16))); + float sample1_higher[4] __attribute__((aligned(16))); + float sample2_higher[4] __attribute__((aligned(16))); + + int k = 0; + int n_loops = n / 4; + + for (int loop = 0; loop < n_loops; ++loop, k += 4) { + // Compute indices for the samples and contain within the valid range. + const __m128i read_index_0 = + _mm_and_si128(_mm_cvttps_epi32(v_virt_index), v_read_mask); + const __m128i read_index_1 = + _mm_and_si128(_mm_add_epi32(read_index_0, one), v_read_mask); + + // Extract the components of the indices so we can get the samples + // associated with the lower and higher wave data. + const uint32_t* r0 = reinterpret_cast<const uint32_t*>(&read_index_0); + const uint32_t* r1 = reinterpret_cast<const uint32_t*>(&read_index_1); + + // Get the samples from the wave tables and save them in work arrays so we + // can load them into simd registers. + for (int m = 0; m < 4; ++m) { + sample1_lower[m] = lower_wave_data[r0[m]]; + sample2_lower[m] = lower_wave_data[r1[m]]; + sample1_higher[m] = higher_wave_data[r0[m]]; + sample2_higher[m] = higher_wave_data[r1[m]]; + } + + const __m128 s1_low = _mm_load_ps(sample1_lower); + const __m128 s2_low = _mm_load_ps(sample2_lower); + const __m128 s1_high = _mm_load_ps(sample1_higher); + const __m128 s2_high = _mm_load_ps(sample2_higher); + + // Linearly interpolate within each table (lower and higher). + const __m128 interpolation_factor = + _mm_sub_ps(v_virt_index, _mm_cvtepi32_ps(read_index_0)); + const __m128 sample_higher = _mm_add_ps( + s1_high, + _mm_mul_ps(interpolation_factor, _mm_sub_ps(s2_high, s1_high))); + const __m128 sample_lower = _mm_add_ps( + s1_low, _mm_mul_ps(interpolation_factor, _mm_sub_ps(s2_low, s1_low))); + + // Then interpolate between the two tables. + const __m128 sample = _mm_add_ps( + sample_higher, + _mm_mul_ps(v_table_factor, _mm_sub_ps(sample_lower, sample_higher))); + + // WARNING: dest_p may not be aligned! + _mm_storeu_ps(dest_p + k, sample); + + // Increment virtual read index and wrap virtualReadIndex into the range + // 0 -> periodicWaveSize. + v_virt_index = _mm_add_ps(v_virt_index, v_incr); + v_virt_index = + v_wrap_virtual_index(v_virt_index, v_wave_size, v_inv_wave_size); + } + + // There's a bit of round-off above, so update the index more accurately so at + // least the next render starts over with a more accurate value. + virtual_read_index += k * incr; + virtual_read_index -= + floor(virtual_read_index * inv_periodic_wave_size) * periodic_wave_size; + + return std::make_tuple(k, virtual_read_index); +} +#elif defined(CPU_ARM_NEON) +static float32x4_t v_wrap_virtual_index(float32x4_t x, + float32x4_t wave_size, + float32x4_t inv_wave_size) { + // r = x/wave_size, f = truncate(r), truncating towards 0 + const float32x4_t r = vmulq_f32(x, inv_wave_size); + int32x4_t f = vcvtq_s32_f32(r); + + // vcltq_f32 returns returns all 0xfffffff (-1) if a < b and if if not. + const uint32x4_t cmp = vcltq_f32(r, vcvtq_f32_s32(f)); + f = vaddq_s32(f, static_cast<int32x4_t>(cmp)); + + return vsubq_f32(x, vmulq_f32(vcvtq_f32_s32(f), wave_size)); +} + +std::tuple<int, double> OscillatorHandler::ProcessKRateVector( + int n, + float* dest_p, + double virtual_read_index, + float frequency, + float rate_scale) const { + const unsigned periodic_wave_size = periodic_wave_->PeriodicWaveSize(); + const double inv_periodic_wave_size = 1.0 / periodic_wave_size; + + float* higher_wave_data = nullptr; + float* lower_wave_data = nullptr; + float table_interpolation_factor = 0; + const float incr = frequency * rate_scale; + DCHECK_GE(incr, kInterpolate2Point); + + periodic_wave_->WaveDataForFundamentalFrequency( + frequency, lower_wave_data, higher_wave_data, table_interpolation_factor); + + const float32x4_t v_wave_size = vdupq_n_f32(periodic_wave_size); + const float32x4_t v_inv_wave_size = vdupq_n_f32(1.0f / periodic_wave_size); + + const uint32x4_t v_read_mask = vdupq_n_s32(periodic_wave_size - 1); + const uint32x4_t v_one = vdupq_n_s32(1); + + const float32x4_t v_table_factor = vdupq_n_f32(table_interpolation_factor); + + const float32x4_t v_incr = vdupq_n_f32(4 * incr); + + float32x4_t v_virt_index = { + virtual_read_index + 0 * incr, virtual_read_index + 1 * incr, + virtual_read_index + 2 * incr, virtual_read_index + 3 * incr}; + + // Temporary arrsys to hold the read indices so we can access them + // individually to get the samples needed for interpolation. + uint32_t r0[4] __attribute__((aligned(16))); + uint32_t r1[4] __attribute__((aligned(16))); + + // Temporary arrays where we can gather up the wave data we need for + // interpolation. Align these for best efficiency on older CPUs where aligned + // access is much faster than unaliged. TODO(rtoy): Is there a faster way to + // do this? + float sample1_lower[4] __attribute__((aligned(16))); + float sample2_lower[4] __attribute__((aligned(16))); + float sample1_higher[4] __attribute__((aligned(16))); + float sample2_higher[4] __attribute__((aligned(16))); + + // It's possible that adding the incr above exceeded the bounds, so wrap them + // if needed. + v_virt_index = + v_wrap_virtual_index(v_virt_index, v_wave_size, v_inv_wave_size); + + int k = 0; + int n_loops = n / 4; + + for (int loop = 0; loop < n_loops; ++loop, k += 4) { + // Compute indices for the samples and contain within the valid range. + const uint32x4_t read_index_0 = + vandq_u32(vcvtq_u32_f32(v_virt_index), v_read_mask); + const uint32x4_t read_index_1 = + vandq_u32(vaddq_u32(read_index_0, v_one), v_read_mask); + + // Extract the components of the indices so we can get the samples + // associated with the lower and higher wave data. + vst1q_u32(r0, read_index_0); + vst1q_u32(r1, read_index_1); + + for (int m = 0; m < 4; ++m) { + sample1_lower[m] = lower_wave_data[r0[m]]; + sample2_lower[m] = lower_wave_data[r1[m]]; + sample1_higher[m] = higher_wave_data[r0[m]]; + sample2_higher[m] = higher_wave_data[r1[m]]; + } + + const float32x4_t s1_low = vld1q_f32(sample1_lower); + const float32x4_t s2_low = vld1q_f32(sample2_lower); + const float32x4_t s1_high = vld1q_f32(sample1_higher); + const float32x4_t s2_high = vld1q_f32(sample2_higher); + + const float32x4_t interpolation_factor = + vsubq_f32(v_virt_index, vcvtq_f32_u32(read_index_0)); + const float32x4_t sample_higher = vaddq_f32( + s1_high, vmulq_f32(interpolation_factor, vsubq_f32(s2_high, s1_high))); + const float32x4_t sample_lower = vaddq_f32( + s1_low, vmulq_f32(interpolation_factor, vsubq_f32(s2_low, s1_low))); + const float32x4_t sample = vaddq_f32( + sample_higher, + vmulq_f32(v_table_factor, vsubq_f32(sample_lower, sample_higher))); + + vst1q_f32(dest_p + k, sample); + + // Increment virtual read index and wrap virtualReadIndex into the range + // 0 -> periodicWaveSize. + v_virt_index = vaddq_f32(v_virt_index, v_incr); + v_virt_index = + v_wrap_virtual_index(v_virt_index, v_wave_size, v_inv_wave_size); + } + + // There's a bit of round-off above, so update the index more accurately so at + // least the next render starts over with a more accurate value. + virtual_read_index += k * incr; + virtual_read_index -= + floor(virtual_read_index * inv_periodic_wave_size) * periodic_wave_size; + + return std::make_tuple(k, virtual_read_index); +} +#else + +// Vector operations not supported, so there's nothing to do except return 0 and +// virtual_read_index. The scalar version will do the necessary processing. +std::tuple<int, double> OscillatorHandler::ProcessKRateVector( + int n, + float* dest_p, + double virtual_read_index, + float frequency, + float rate_scale) const { + DCHECK_GE(frequency * rate_scale, kInterpolate2Point); + return std::make_tuple(0, virtual_read_index); +} +#endif + +double OscillatorHandler::ProcessKRateScalar(int start, + int n, + float* dest_p, + double virtual_read_index, + float frequency, + float rate_scale) const { + const unsigned periodic_wave_size = periodic_wave_->PeriodicWaveSize(); + const double inv_periodic_wave_size = 1.0 / periodic_wave_size; + const unsigned read_index_mask = periodic_wave_size - 1; + + float* higher_wave_data = nullptr; + float* lower_wave_data = nullptr; + float table_interpolation_factor = 0; + + periodic_wave_->WaveDataForFundamentalFrequency( + frequency, lower_wave_data, higher_wave_data, table_interpolation_factor); + + const float incr = frequency * rate_scale; + DCHECK_GE(incr, kInterpolate2Point); + + for (int k = start; k < n; ++k) { + // Get indices for the current and next sample, and contain them within the + // valid range + const unsigned read_index_0 = + static_cast<unsigned>(virtual_read_index) & read_index_mask; + const unsigned read_index_1 = (read_index_0 + 1) & read_index_mask; + + const float sample1_lower = lower_wave_data[read_index_0]; + const float sample2_lower = lower_wave_data[read_index_1]; + const float sample1_higher = higher_wave_data[read_index_0]; + const float sample2_higher = higher_wave_data[read_index_1]; + + // Linearly interpolate within each table (lower and higher). + const float interpolation_factor = + static_cast<float>(virtual_read_index) - read_index_0; + const float sample_higher = + sample1_higher + + interpolation_factor * (sample2_higher - sample1_higher); + const float sample_lower = + sample1_lower + interpolation_factor * (sample2_lower - sample1_lower); + + // Then interpolate between the two tables. + const float sample = sample_higher + table_interpolation_factor * + (sample_lower - sample_higher); + + dest_p[k] = sample; + + // Increment virtual read index and wrap virtualReadIndex into the range + // 0 -> periodicWaveSize. + virtual_read_index += incr; + virtual_read_index -= + floor(virtual_read_index * inv_periodic_wave_size) * periodic_wave_size; + } + + return virtual_read_index; +} + +double OscillatorHandler::ProcessKRate(int n, + float* dest_p, + double virtual_read_index) const { + const unsigned periodic_wave_size = periodic_wave_->PeriodicWaveSize(); + const double inv_periodic_wave_size = 1.0 / periodic_wave_size; + const unsigned read_index_mask = periodic_wave_size - 1; + + float* higher_wave_data = nullptr; + float* lower_wave_data = nullptr; + float table_interpolation_factor = 0; + + float frequency = frequency_->FinalValue(); + const float detune_scale = DetuneToFrequencyMultiplier(detune_->FinalValue()); + frequency *= detune_scale; + ClampFrequency(&frequency, 1, Context()->sampleRate() / 2); + periodic_wave_->WaveDataForFundamentalFrequency( + frequency, lower_wave_data, higher_wave_data, table_interpolation_factor); + + const float rate_scale = periodic_wave_->RateScale(); + const float incr = frequency * rate_scale; + + if (incr >= kInterpolate2Point) { + int k; + double v_index = virtual_read_index; + + std::tie(k, v_index) = + ProcessKRateVector(n, dest_p, v_index, frequency, rate_scale); + + if (k < n) { + // In typical cases, this won't be run because the number of frames is 128 + // so the vector version will process all the samples. + v_index = + ProcessKRateScalar(k, n, dest_p, v_index, frequency, rate_scale); + } + + // Recompute to reduce round-off introduced when processing the samples + // above. + virtual_read_index += n * incr; + virtual_read_index -= + floor(virtual_read_index * inv_periodic_wave_size) * periodic_wave_size; + } else { + for (int k = 0; k < n; ++k) { + float sample = DoInterpolation( + virtual_read_index, fabs(incr), read_index_mask, + table_interpolation_factor, lower_wave_data, higher_wave_data); + + *dest_p++ = sample; + + // Increment virtual read index and wrap virtualReadIndex into the range + // 0 -> periodicWaveSize. + virtual_read_index += incr; + virtual_read_index -= floor(virtual_read_index * inv_periodic_wave_size) * + periodic_wave_size; + } + } + + return virtual_read_index; +} + +double OscillatorHandler::ProcessARate(int n, + float* dest_p, + double virtual_read_index, + float* phase_increments) const { + float rate_scale = periodic_wave_->RateScale(); + float inv_rate_scale = 1 / rate_scale; + unsigned periodic_wave_size = periodic_wave_->PeriodicWaveSize(); + double inv_periodic_wave_size = 1.0 / periodic_wave_size; + unsigned read_index_mask = periodic_wave_size - 1; + + float* higher_wave_data = nullptr; + float* lower_wave_data = nullptr; + float table_interpolation_factor = 0; + + for (int k = 0; k < n; ++k) { + float incr = *phase_increments++; + + float frequency = inv_rate_scale * incr; + periodic_wave_->WaveDataForFundamentalFrequency(frequency, lower_wave_data, + higher_wave_data, + table_interpolation_factor); + + float sample = DoInterpolation(virtual_read_index, fabs(incr), + read_index_mask, table_interpolation_factor, + lower_wave_data, higher_wave_data); + + *dest_p++ = sample; + + // Increment virtual read index and wrap virtualReadIndex into the range + // 0 -> periodicWaveSize. + virtual_read_index += incr; + virtual_read_index -= + floor(virtual_read_index * inv_periodic_wave_size) * periodic_wave_size; + } + + return virtual_read_index; +} + void OscillatorHandler::Process(uint32_t frames_to_process) { AudioBus* output_bus = Output(0).Bus(); @@ -390,7 +828,6 @@ void OscillatorHandler::Process(uint32_t frames_to_process) { } unsigned periodic_wave_size = periodic_wave_->PeriodicWaveSize(); - double inv_periodic_wave_size = 1.0 / periodic_wave_size; float* dest_p = output_bus->Channel(0)->MutableData(); @@ -400,7 +837,6 @@ void OscillatorHandler::Process(uint32_t frames_to_process) { double virtual_read_index = virtual_read_index_; float rate_scale = periodic_wave_->RateScale(); - float inv_rate_scale = 1 / rate_scale; bool has_sample_accurate_values = CalculateSampleAccuratePhaseIncrements(frames_to_process); @@ -420,11 +856,8 @@ void OscillatorHandler::Process(uint32_t frames_to_process) { table_interpolation_factor); } - float incr = frequency * rate_scale; float* phase_increments = phase_increments_.Data(); - unsigned read_index_mask = periodic_wave_size - 1; - // Start rendering at the correct offset. dest_p += quantum_frame_offset; int n = non_silent_frames_to_process; @@ -442,27 +875,11 @@ void OscillatorHandler::Process(uint32_t frames_to_process) { virtual_read_index = -start_frame_offset * frequency * rate_scale; } - while (n--) { - if (has_sample_accurate_values) { - incr = *phase_increments++; - - frequency = inv_rate_scale * incr; - periodic_wave_->WaveDataForFundamentalFrequency( - frequency, lower_wave_data, higher_wave_data, - table_interpolation_factor); - } - - float sample = DoInterpolation(virtual_read_index, fabs(incr), - read_index_mask, table_interpolation_factor, - lower_wave_data, higher_wave_data); - - *dest_p++ = sample; - - // Increment virtual read index and wrap virtualReadIndex into the range - // 0 -> periodicWaveSize. - virtual_read_index += incr; - virtual_read_index -= - floor(virtual_read_index * inv_periodic_wave_size) * periodic_wave_size; + if (has_sample_accurate_values) { + virtual_read_index = + ProcessARate(n, dest_p, virtual_read_index, phase_increments); + } else { + virtual_read_index = ProcessKRate(n, dest_p, virtual_read_index); } virtual_read_index_ = virtual_read_index; @@ -549,8 +966,11 @@ OscillatorNode* OscillatorNode::Create(BaseAudioContext* context, return nullptr; } - OscillatorNode* node = Create(*context, options->type(), - options->periodicWave(), exception_state); + // TODO(crbug.com/1070871): Use periodicWaveOr(nullptr). + OscillatorNode* node = + Create(*context, options->type(), + options->hasPeriodicWave() ? options->periodicWave() : nullptr, + exception_state); if (!node) return nullptr; @@ -563,7 +983,7 @@ OscillatorNode* OscillatorNode::Create(BaseAudioContext* context, return node; } -void OscillatorNode::Trace(Visitor* visitor) { +void OscillatorNode::Trace(Visitor* visitor) const { visitor->Trace(frequency_); visitor->Trace(detune_); visitor->Trace(periodic_wave_); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.h b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.h index e763c404e0a..816b9e8b351 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/oscillator_node.h @@ -86,6 +86,33 @@ class OscillatorHandler final : public AudioScheduledSourceHandler { bool PropagatesSilence() const override; + // Compute the output for k-rate AudioParams + double ProcessKRate(int n, float* dest_p, double virtual_read_index) const; + + // Scalar version for the main loop in ProcessKRate(). Returns the updated + // virtual_read_index. + double ProcessKRateScalar(int start_index, + int n, + float* dest_p, + double virtual_read_index, + float frequency, + float rate_scale) const; + + // Vectorized version (if available) for the main loop in ProcessKRate(). + // Returns the number of elements processed and the updated + // virtual_read_index. + std::tuple<int, double> ProcessKRateVector(int n, + float* dest_p, + double virtual_read_index, + float frequency, + float rate_scale) const; + + // Compute the output for a-rate AudioParams + double ProcessARate(int n, + float* dest_p, + double virtual_read_index, + float* phase_increments) const; + // One of the waveform types defined in the enum. uint8_t type_; @@ -125,7 +152,7 @@ class OscillatorNode final : public AudioScheduledSourceNode { OscillatorNode(BaseAudioContext&, const String& oscillator_type, PeriodicWave* wave_table); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; String type() const; void setType(const String&, ExceptionState&); 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 f5416deae3c..8e219f33d4a 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.cc @@ -956,7 +956,7 @@ void PannerNode::setConeOuterGain(double gain, GetPannerHandler().SetConeOuterGain(gain); } -void PannerNode::Trace(Visitor* visitor) { +void PannerNode::Trace(Visitor* visitor) const { visitor->Trace(position_x_); visitor->Trace(position_y_); visitor->Trace(position_z_); 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 4c405b2d55a..4161ec6f1ba 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/panner_node.h @@ -232,7 +232,7 @@ class PannerNode final : public AudioNode { PannerNode(BaseAudioContext&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Uses a 3D cartesian coordinate system AudioParam* positionX() const { return position_x_; } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc index 33d5b11733d..b1ca691b07b 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.cc @@ -509,7 +509,7 @@ bool ScriptProcessorNode::HasPendingActivity() const { return false; } -void ScriptProcessorNode::Trace(Visitor* visitor) { +void ScriptProcessorNode::Trace(Visitor* visitor) const { visitor->Trace(input_buffers_); visitor->Trace(output_buffers_); AudioNode::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h index 4691e7c79fc..a93dbacc707 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/script_processor_node.h @@ -160,7 +160,7 @@ class ScriptProcessorNode final // ScriptWrappable bool HasPendingActivity() const final; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // InspectorHelperMixin void ReportDidCreate() final; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc index d58c60d3b04..7f6c2450e9e 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.cc @@ -182,7 +182,7 @@ StereoPannerNode* StereoPannerNode::Create(BaseAudioContext* context, return node; } -void StereoPannerNode::Trace(Visitor* visitor) { +void StereoPannerNode::Trace(Visitor* visitor) const { visitor->Trace(pan_); AudioNode::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.h b/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.h index 8dfaf04d969..4efbdf773e5 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/stereo_panner_node.h @@ -59,7 +59,7 @@ class StereoPannerNode final : public AudioNode { StereoPannerNode(BaseAudioContext&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; AudioParam* pan() const; diff --git a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc index 22a6fddddcd..b7db5bb27f7 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.cc @@ -36,7 +36,14 @@ namespace blink { WaveShaperDSPKernel::WaveShaperDSPKernel(WaveShaperProcessor* processor) - : AudioDSPKernel(processor), tail_time_(0) { + : AudioDSPKernel(processor), + tail_time_(0), + // 4 times render size to handle 4x oversampling. + virtual_index_(4 * audio_utilities::kRenderQuantumFrames), + index_(4 * audio_utilities::kRenderQuantumFrames), + v1_(4 * audio_utilities::kRenderQuantumFrames), + v2_(4 * audio_utilities::kRenderQuantumFrames), + f_(4 * audio_utilities::kRenderQuantumFrames) { if (processor->Oversample() != WaveShaperProcessor::kOverSampleNone) LazyInitializeOversampling(); } @@ -114,8 +121,9 @@ void WaveShaperDSPKernel::WaveShaperCurveValues(float* destination, uint32_t frames_to_process, const float* curve_data, int curve_length) const { + DCHECK_LE(frames_to_process, virtual_index_.size()); // Index into the array computed from the source value. - float virtual_index[frames_to_process]; + float* virtual_index = virtual_index_.Data(); // virtual_index[k] = // clampTo(0.5 * (source[k] + 1) * (curve_length - 1), @@ -134,16 +142,20 @@ void WaveShaperDSPKernel::WaveShaperCurveValues(float* destination, frames_to_process); // index = floor(virtual_index) - float index[frames_to_process]; + DCHECK_LE(frames_to_process, index_.size()); + float* index = index_.Data(); // v1 and v2 hold the curve_data corresponding to the closest curve // values to the source sample. To save memory, v1 will use the // destination array. - float* v1 = destination; - float v2[frames_to_process]; + DCHECK_LE(frames_to_process, v1_.size()); + DCHECK_LE(frames_to_process, v2_.size()); + float* v1 = v1_.Data(); + float* v2 = v2_.Data(); // Interpolation factor: virtual_index - index. - float f[frames_to_process]; + DCHECK_LE(frames_to_process, f_.size()); + float* f = f_.Data(); int max_index = curve_length - 1; unsigned k = 0; @@ -216,9 +228,10 @@ void WaveShaperDSPKernel::WaveShaperCurveValues(float* destination, int32x4_t index2 = vaddq_s32(index1, one); index2 = vmaxq_s32(vminq_s32(index2, max), zero); - // Save index1/2 so we can get the individual parts. - int32_t i1[4]; - int32_t i2[4]; + // Save index1/2 so we can get the individual parts. Aligned to + // 16 bytes for vst1q instruction. + int32_t i1[4] __attribute__((aligned(16))); + int32_t i2[4] __attribute__((aligned(16))); vst1q_s32(i1, index1); vst1q_s32(i2, index2); @@ -257,7 +270,7 @@ void WaveShaperDSPKernel::WaveShaperCurveValues(float* destination, // = v1[k] + f[k]*(v2[k] - v1[k]) vector_math::Vsub(v2, 1, v1, 1, v2, 1, frames_to_process); vector_math::Vmul(f, 1, v2, 1, v2, 1, frames_to_process); - vector_math::Vadd(v2, 1, destination, 1, destination, 1, frames_to_process); + vector_math::Vadd(v2, 1, v1, 1, destination, 1, frames_to_process); } void WaveShaperDSPKernel::ProcessCurve(const float* source, diff --git a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h index 2714e0aaf4d..1fc42c0ce2d 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h +++ b/chromium/third_party/blink/renderer/modules/webaudio/wave_shaper_dsp_kernel.h @@ -104,6 +104,16 @@ class WaveShaperDSPKernel final : public AudioDSPKernel { // has an infinite tail so that silent input continues to produce non-silent // output. double tail_time_; + + // Work arrays needed by WaveShaperCurveValues(). Mutable so this + // const function can modify these arrays. There's no state or + // anything kept here. See WaveShaperCurveValues() for details on + // what these hold. + mutable AudioFloatArray virtual_index_; + mutable AudioFloatArray index_; + mutable AudioFloatArray v1_; + mutable AudioFloatArray v2_; + mutable AudioFloatArray f_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn b/chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn index 8f73abc2323..a67e2519080 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/webcodecs/BUILD.gn @@ -6,6 +6,8 @@ import("//third_party/blink/renderer/modules/modules.gni") blink_modules_sources("webcodecs") { sources = [ + "decoder_selector.cc", + "decoder_selector.h", "encoded_video_chunk.cc", "encoded_video_chunk.h", "encoded_video_metadata.h", @@ -13,6 +15,8 @@ blink_modules_sources("webcodecs") { "image_decoder_external.h", "video_decoder.cc", "video_decoder.h", + "video_decoder_broker.cc", + "video_decoder_broker.h", "video_encoder.cc", "video_encoder.h", "video_frame.cc", @@ -22,12 +26,20 @@ blink_modules_sources("webcodecs") { "video_track_writer.cc", "video_track_writer.h", ] + deps = [ + "//media", + "//media/mojo:buildflags", + "//media/mojo/clients", + "//media/mojo/mojom", + ] } source_set("unit_tests") { testonly = true sources = [ + "decoder_selector_test.cc", "encoded_video_chunk_test.cc", + "video_decoder_broker_test.cc", "video_frame_test.cc", "video_track_reader_writer_test.cc", ] @@ -39,7 +51,9 @@ source_set("unit_tests") { ] deps = [ - "//base", + "//base/test:test_support", + "//gpu/command_buffer/common", + "//media:test_support", "//testing/gmock", "//testing/gtest", "//third_party/blink/renderer/modules", diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/DEPS b/chromium/third_party/blink/renderer/modules/webcodecs/DEPS index ccb5201264c..5e434f48069 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/DEPS +++ b/chromium/third_party/blink/renderer/modules/webcodecs/DEPS @@ -1,10 +1,32 @@ include_rules = [ - "+base", + "+base/threading/thread_task_runner_handle.h", + + "+components/viz/common/gpu/raster_context_provider.h", + "+components/viz/common/resources/single_release_callback.h", + + "+gpu/command_buffer/client/shared_image_interface.h", + "+media/base", "+media/filters", "+media/media_buildflags.h", + "+media/mojo", + "+media/renderers", "+media/video", + "+third_party/libyuv", + + "+ui/gfx/color_space.h", "+ui/gfx/geometry/rect.h", "+ui/gfx/geometry/size.h", ] + +specific_include_rules = { + "video_track_reader_writer_test\.cc": [ + "+base/run_loop.h", + ], + "video_decoder_broker_test\.cc": [ + "+base/run_loop.h", + "+base/threading/thread.h", + "+gpu/command_buffer/common/mailbox_holder.h", + ], +} diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/OWNERS b/chromium/third_party/blink/renderer/modules/webcodecs/OWNERS index cc72639d7c4..0695ffdb082 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/OWNERS +++ b/chromium/third_party/blink/renderer/modules/webcodecs/OWNERS @@ -1,3 +1,4 @@ mlamouri@chromium.org sandersd@chromium.org dalecurtis@chromium.org +chcunningham@chromium.org diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl b/chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl new file mode 100644 index 00000000000..90ef65f54ce --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl @@ -0,0 +1,60 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://github.com/WICG/web-codecs + +[ + Exposed=(Window,Worker), + RuntimeEnabled=WebCodecs +] interface AudioDecoder { + // |init| includes an |output| callback for emitting AudioBuffers and an + // |error| callback for emitting decode errors. All errors are permanent; + // construct a new decoder to recover. + // + // TODO(sandersd): Consider adding a state or last error attribute. + [CallWith=ScriptState, RaisesException] constructor(AudioDecoderInit init); + + // The number of pending decode requests. This does not include requests that + // have been sent to the underlying codec. + // + // Applications can minimize underflow by enqueueing decode requests until + // |decodeQueueSize| is greater than a constant. + readonly attribute long decodeQueueSize; + + // Set the stream configuration for future decode() requests. + // + // The next decode request must be for a keyframe. + // + // TODO(chcunningham): Move the keyframe rule into the bytestream registry. + [RaisesException] void configure(EncodedAudioConfig config); + + // Request decoding of an input chunk. + // + // You must call configure() before calling decode() for the first time. + // + // TODO(chcunningham): Change to a dictionary type. + [RaisesException] void decode(EncodedAudioChunk chunk); + + // Request output from all previous decode requests. + // + // Resolved after all output for earlier decode requests has been emitted. + // + // The next decode request must be for a keyframe. + // + // TODO(chcunningham): Consider relaxing the keyframe requirement. + // TODO(chcunningham): Indicate whether the flush() completed successfully or due + // to a reset. + [RaisesException] Promise<void> flush(); + + // Reset all codec state, including all pending requests. + // + // You must call configure() before submitting the next decode. + [RaisesException] void reset(); + + // Immediately shut down the decoder and free its resources. All pending + // decode requests are aborted. + // + // Not recoverable: make a new AudioDecoder if needed. + void close(); +}; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder_init.idl b/chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder_init.idl new file mode 100644 index 00000000000..c3cf975001c --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/audio_decoder_init.idl @@ -0,0 +1,10 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://github.com/WICG/web-codecs + +dictionary AudioDecoderInit { + AudioFrameOutputCallback output; + WebCodecsErrorCallback error; +}; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame.idl b/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame.idl new file mode 100644 index 00000000000..1254781b5d3 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame.idl @@ -0,0 +1,16 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://github.com/WICG/web-codecs +[ + Exposed=(Window,Worker), + RuntimeEnabled=WebCodecs +] interface AudioFrame { + [RaisesException] constructor(AudioFrameInit init); + + void close(); + + readonly attribute unsigned long long timestamp; // microseconds + readonly attribute AudioBuffer buffer; +}; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame_init.idl b/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame_init.idl new file mode 100644 index 00000000000..f806d970b69 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame_init.idl @@ -0,0 +1,10 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://github.com/WICG/web-codecs + +dictionary AudioFrameInit { + unsigned long long timestamp; // microseconds + AudioBuffer buffer; +};
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_output_callback.idl b/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame_output_callback.idl index 3daff3e415d..145fbf8c76e 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_output_callback.idl +++ b/chromium/third_party/blink/renderer/modules/webcodecs/audio_frame_output_callback.idl @@ -5,4 +5,4 @@ // https://github.com/WICG/web-codecs [RuntimeEnabled=WebCodecs] -callback VideoDecoderOutputCallback = void(VideoFrame output); +callback AudioFrameOutputCallback = void(AudioFrame output); diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.cc b/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.cc new file mode 100644 index 00000000000..a8ffe46bb42 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.cc @@ -0,0 +1,142 @@ +// Copyright 2020 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/webcodecs/decoder_selector.h" + +#include "base/bind.h" +#include "base/check_op.h" +#include "base/notreached.h" +#include "base/single_thread_task_runner.h" +#include "media/base/channel_layout.h" +#include "media/base/demuxer_stream.h" +#include "media/filters/decrypting_demuxer_stream.h" +#include "third_party/blink/renderer/modules/modules_export.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" + +namespace blink { + +// Demuxing isn't part of WebCodecs. This shim allows us to reuse decoder +// selection logic from <video>. +// TODO(chcunningham): Maybe refactor DecoderSelector to separate dependency on +// media::DemuxerStream. DecoderSelection doesn't conceptually require a +// Demuxer. The tough part is re-working Decryptingmedia::DemuxerStream. +template <media::DemuxerStream::Type StreamType> +class NullDemuxerStream : public media::DemuxerStream { + public: + using DecoderConfigType = + typename media::DecoderStreamTraits<StreamType>::DecoderConfigType; + + ~NullDemuxerStream() override = default; + + void Read(ReadCB read_cb) override { NOTREACHED(); } + bool IsReadPending() const override { + NOTREACHED(); + return false; + } + + void Configure(DecoderConfigType config); + + media::AudioDecoderConfig audio_decoder_config() override { + DCHECK_EQ(type(), media::DemuxerStream::AUDIO); + return audio_decoder_config_; + } + + media::VideoDecoderConfig video_decoder_config() override { + DCHECK_EQ(type(), media::DemuxerStream::VIDEO); + return video_decoder_config_; + } + + Type type() const override { return stream_type; } + + bool SupportsConfigChanges() override { + NOTREACHED(); + return true; + } + + private: + static const media::DemuxerStream::Type stream_type = StreamType; + + media::AudioDecoderConfig audio_decoder_config_; + media::VideoDecoderConfig video_decoder_config_; +}; + +template <> +void NullDemuxerStream<media::DemuxerStream::AUDIO>::Configure( + DecoderConfigType config) { + audio_decoder_config_ = config; +} + +template <> +void NullDemuxerStream<media::DemuxerStream::VIDEO>::Configure( + DecoderConfigType config) { + video_decoder_config_ = config; +} + +template <media::DemuxerStream::Type StreamType> +DecoderSelector<StreamType>::DecoderSelector( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + CreateDecodersCB create_decoders_cb, + typename Decoder::OutputCB output_cb) + : impl_(std::move(task_runner), + std::move(create_decoders_cb), + &null_media_log_), + demuxer_stream_(new NullDemuxerStream<StreamType>()), + stream_traits_(CreateStreamTraits()), + output_cb_(output_cb) { + impl_.Initialize(stream_traits_.get(), demuxer_stream_.get(), + nullptr /*CdmContext*/, media::WaitingCB()); +} + +template <media::DemuxerStream::Type StreamType> +DecoderSelector<StreamType>::~DecoderSelector() = default; + +template <media::DemuxerStream::Type StreamType> +void DecoderSelector<StreamType>::SelectDecoder( + const DecoderConfig& config, + SelectDecoderCB select_decoder_cb) { + // |impl_| will internally use this the |config| from our NullDemuxerStream. + demuxer_stream_->Configure(config); + + // Destroying |impl_| will cancel pending operations, so it's safe to use + // Unretained() with |select_decoder_cb|. + impl_.SelectDecoder( + WTF::Bind(&DecoderSelector<StreamType>::OnDecoderSelected, + WTF::Unretained(this), std::move(select_decoder_cb)), + output_cb_); +} + +template <> +std::unique_ptr<WebCodecsAudioDecoderSelector::StreamTraits> +DecoderSelector<media::DemuxerStream::AUDIO>::CreateStreamTraits() { + // TODO(chcunningham): Consider plumbing real hw channel layout. + return std::make_unique<DecoderSelector::StreamTraits>( + &null_media_log_, media::CHANNEL_LAYOUT_NONE); +} + +template <> +std::unique_ptr<WebCodecsVideoDecoderSelector::StreamTraits> +DecoderSelector<media::DemuxerStream::VIDEO>::CreateStreamTraits() { + return std::make_unique<DecoderSelector::StreamTraits>(&null_media_log_); +} + +template <media::DemuxerStream::Type StreamType> +void DecoderSelector<StreamType>::OnDecoderSelected( + SelectDecoderCB select_decoder_cb, + std::unique_ptr<Decoder> decoder, + std::unique_ptr<media::DecryptingDemuxerStream> decrypting_demuxer_stream) { + DCHECK(!decrypting_demuxer_stream); + + // We immediately finalize decoder selection. + // TODO(chcunningham): Rework this to do finalize after first frame + // successfully decoded. This updates to match latest plans for spec + // (configure() no longer takes a promise). + impl_.FinalizeDecoderSelection(); + + std::move(select_decoder_cb).Run(std::move(decoder)); +} + +template class MODULES_EXPORT DecoderSelector<media::DemuxerStream::VIDEO>; +template class MODULES_EXPORT DecoderSelector<media::DemuxerStream::AUDIO>; + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.h b/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.h new file mode 100644 index 00000000000..60f3f1d48ef --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector.h @@ -0,0 +1,90 @@ +// Copyright 2020 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_WEBCODECS_DECODER_SELECTOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_DECODER_SELECTOR_H_ + +#include <memory> + +#include "media/base/demuxer_stream.h" +#include "media/base/media_util.h" +#include "media/filters/decoder_selector.h" +#include "media/filters/decoder_stream_traits.h" +#include "third_party/blink/renderer/modules/modules_export.h" + +namespace blink { + +template <media::DemuxerStream::Type StreamType> +class NullDemuxerStream; + +template <media::DemuxerStream::Type StreamType> +class DecoderSelector { + public: + typedef media::DecoderStreamTraits<StreamType> StreamTraits; + typedef typename StreamTraits::DecoderType Decoder; + typedef typename StreamTraits::DecoderConfigType DecoderConfig; + + // Callback to create a list of decoders to select from. + using CreateDecodersCB = + base::RepeatingCallback<std::vector<std::unique_ptr<Decoder>>()>; + + // Emits the result of a single call to SelectDecoder(). Parameter is + // the initialized Decoder. nullptr if selection failed. The caller owns the + // Decoder. + using SelectDecoderCB = base::OnceCallback<void(std::unique_ptr<Decoder>)>; + + // Construction can happen on any thread, but all subsequent API calls + // including destruction must use |task_runner| thread. + // Provided callbacks will be called on |task_runner|. |output_cb| will always + // be Post()'ed. + DecoderSelector(scoped_refptr<base::SingleThreadTaskRunner> task_runner, + CreateDecodersCB create_decoders_cb, + typename Decoder::OutputCB output_cb); + + // Aborts any pending decoder selection. + ~DecoderSelector(); + + // Disallow copy and assign. + DecoderSelector(const DecoderSelector&) = delete; + DecoderSelector& operator=(const DecoderSelector&) = delete; + + // Selects and initializes a decoder using |config|. Decoder will + // be returned via |select_decoder_cb| posted to |task_runner_|. Subsequent + // calls will again select from the full list of decoders. + void SelectDecoder(const DecoderConfig& config, + SelectDecoderCB select_decoder_cb); + + private: + // Helper to create |stream_traits_|. + std::unique_ptr<StreamTraits> CreateStreamTraits(); + + // Proxy SelectDecoderCB from impl_ to our |select_decoder_cb|. + void OnDecoderSelected(SelectDecoderCB select_decoder_cb, + std::unique_ptr<Decoder> decoder, + std::unique_ptr<media::DecryptingDemuxerStream>); + + // Implements heavy lifting for decoder selection. + media::DecoderSelector<StreamType> impl_; + + // Shim to satisfy dependencies of |impl_|. Provides DecoderConfig to |impl_|. + std::unique_ptr<NullDemuxerStream<StreamType>> demuxer_stream_; + + // Helper to unify API for configuring audio/video decoders. + std::unique_ptr<StreamTraits> stream_traits_; + + // Repeating callback for decoder outputs. + typename Decoder::OutputCB output_cb_; + + // TODO(chcunningham): Route MEDIA_LOG for WebCodecs. + media::NullMediaLog null_media_log_; +}; + +typedef DecoderSelector<media::DemuxerStream::VIDEO> + WebCodecsVideoDecoderSelector; +typedef DecoderSelector<media::DemuxerStream::AUDIO> + WebCodecsAudioDecoderSelector; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_DECODER_SELECTOR_H_ diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector_test.cc b/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector_test.cc new file mode 100644 index 00000000000..2ff7dd6620b --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/decoder_selector_test.cc @@ -0,0 +1,250 @@ +// Copyright 2020 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 <vector> + +#include "media/base/demuxer_stream.h" +#include "media/base/media_util.h" +#include "media/base/mock_filters.h" +#include "media/base/status.h" +#include "media/base/test_helpers.h" +#include "media/base/video_decoder.h" +#include "media/filters/decoder_stream.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" +#include "third_party/blink/renderer/platform/testing/testing_platform_support.h" + +#include "third_party/blink/renderer/modules/webcodecs/decoder_selector.h" + +using ::testing::_; +using ::testing::IsNull; +using ::testing::StrictMock; + +namespace blink { + +namespace { + +enum DecoderCapability { + kFail, + kSucceed, +}; + +const char kNoDecoder[] = ""; +const char kDecoder1[] = "Decoder1"; +const char kDecoder2[] = "Decoder2"; + +// Specializations for the AUDIO version of the test. +class AudioDecoderSelectorTestParam { + public: + static constexpr media::DemuxerStream::Type kStreamType = + media::DemuxerStream::AUDIO; + + using DecoderSelector = DecoderSelector<media::DemuxerStream::AUDIO>; + using MockDecoder = media::MockAudioDecoder; + using Output = media::AudioBuffer; + + static media::AudioDecoderConfig CreateConfig() { + return media::TestAudioConfig::Normal(); + } + + // Create a config that won't match the return of CreateConfig(). + static media::AudioDecoderConfig CreateAlternateConfig() { + return media::TestAudioConfig::NormalEncrypted(); + } + + // Decoder::Initialize() takes different parameters depending on the type. + static void ExpectInitialize(MockDecoder* decoder, + DecoderCapability capability, + media::AudioDecoderConfig expected_config) { + EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _)) + .WillRepeatedly([capability, expected_config]( + const media::AudioDecoderConfig& config, + media::CdmContext*, + media::AudioDecoder::InitCB& init_cb, + const media::AudioDecoder::OutputCB&, + const media::WaitingCB&) { + EXPECT_TRUE(config.Matches(expected_config)); + std::move(init_cb).Run(capability == kSucceed + ? media::OkStatus() + : media::StatusCode::kCodeOnlyForTesting); + }); + } +}; + +// Specializations for the VIDEO version of the test. +class VideoDecoderSelectorTestParam { + public: + static constexpr media::DemuxerStream::Type kStreamType = + media::DemuxerStream::VIDEO; + + using DecoderSelector = DecoderSelector<media::DemuxerStream::VIDEO>; + using MockDecoder = media::MockVideoDecoder; + using Output = media::VideoFrame; + + static media::VideoDecoderConfig CreateConfig() { + return media::TestVideoConfig::Normal(); + } + + // Create a config that won't match the return of CreateConfig(). + static media::VideoDecoderConfig CreateAlternateConfig() { + return media::TestVideoConfig::LargeEncrypted(); + } + + static void ExpectInitialize(MockDecoder* decoder, + DecoderCapability capability, + media::VideoDecoderConfig expected_config) { + EXPECT_CALL(*decoder, Initialize_(_, _, _, _, _, _)) + .WillRepeatedly([capability, expected_config]( + const media::VideoDecoderConfig& config, + bool low_delay, media::CdmContext*, + media::VideoDecoder::InitCB& init_cb, + const media::VideoDecoder::OutputCB&, + const media::WaitingCB&) { + EXPECT_TRUE(config.Matches(expected_config)); + std::move(init_cb).Run(capability == kSucceed + ? media::OkStatus() + : media::StatusCode::kCodeOnlyForTesting); + }); + } +}; + +// Allocate storage for the member variables. +constexpr media::DemuxerStream::Type AudioDecoderSelectorTestParam::kStreamType; +constexpr media::DemuxerStream::Type VideoDecoderSelectorTestParam::kStreamType; + +} // namespace + +// Note: The parameter is called TypeParam in the test cases regardless of what +// we call it here. It's been named the same for convenience. +// Note: The test fixtures inherit from this class. Inside the test cases the +// test fixture class is called TestFixture. +template <typename TypeParam> +class WebCodecsDecoderSelectorTest : public ::testing::Test { + public: + // Convenience aliases. + using Self = WebCodecsDecoderSelectorTest<TypeParam>; + using Decoder = typename TypeParam::DecoderSelector::Decoder; + using DecoderConfig = typename TypeParam::DecoderSelector::DecoderConfig; + using MockDecoder = typename TypeParam::MockDecoder; + using Output = typename TypeParam::Output; + + WebCodecsDecoderSelectorTest() { CreateDecoderSelector(); } + + void OnOutput(scoped_refptr<Output> output) { NOTREACHED(); } + + MOCK_METHOD1_T(OnDecoderSelected, void(std::string)); + + void OnDecoderSelectedThunk(std::unique_ptr<Decoder> decoder) { + // Report only the name of the decoder, since that's what the tests care + // about. The decoder will be destructed immediately. + OnDecoderSelected(decoder ? decoder->GetDisplayName() : kNoDecoder); + } + + void AddMockDecoder(const std::string& decoder_name, + DecoderCapability capability) { + // Actual decoders are created in CreateDecoders(), which may be called + // multiple times by the DecoderSelector. + mock_decoders_to_create_.emplace_back(decoder_name, capability); + } + + std::vector<std::unique_ptr<Decoder>> CreateDecoders() { + std::vector<std::unique_ptr<Decoder>> decoders; + + for (const auto& info : mock_decoders_to_create_) { + std::unique_ptr<StrictMock<MockDecoder>> decoder = + std::make_unique<StrictMock<MockDecoder>>(info.first); + TypeParam::ExpectInitialize(decoder.get(), info.second, + last_set_decoder_config_); + decoders.push_back(std::move(decoder)); + } + + return decoders; + } + + void CreateDecoderSelector() { + decoder_selector_ = + std::make_unique<DecoderSelector<TypeParam::kStreamType>>( + scheduler::GetSingleThreadTaskRunnerForTesting(), + base::BindRepeating(&Self::CreateDecoders, base::Unretained(this)), + base::BindRepeating(&Self::OnOutput, base::Unretained(this))); + } + + void SelectDecoder(DecoderConfig config = TypeParam::CreateConfig()) { + last_set_decoder_config_ = config; + decoder_selector_->SelectDecoder( + config, + base::BindOnce(&Self::OnDecoderSelectedThunk, base::Unretained(this))); + RunUntilIdle(); + } + + void RunUntilIdle() { platform_->RunUntilIdle(); } + + ScopedTestingPlatformSupport<TestingPlatformSupport> platform_; + media::NullMediaLog media_log_; + + DecoderConfig last_set_decoder_config_; + + std::unique_ptr<DecoderSelector<TypeParam::kStreamType>> decoder_selector_; + + std::vector<std::pair<std::string, DecoderCapability>> + mock_decoders_to_create_; + + private: + DISALLOW_COPY_AND_ASSIGN(WebCodecsDecoderSelectorTest); +}; + +using WebCodecsDecoderSelectorTestParams = + ::testing::Types<AudioDecoderSelectorTestParam, + VideoDecoderSelectorTestParam>; +TYPED_TEST_SUITE(WebCodecsDecoderSelectorTest, + WebCodecsDecoderSelectorTestParams); + +TYPED_TEST(WebCodecsDecoderSelectorTest, NoDecoders) { + EXPECT_CALL(*this, OnDecoderSelected(kNoDecoder)); + this->SelectDecoder(); +} + +TYPED_TEST(WebCodecsDecoderSelectorTest, OneDecoder) { + this->AddMockDecoder(kDecoder1, kSucceed); + + EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); + this->SelectDecoder(); +} + +TYPED_TEST(WebCodecsDecoderSelectorTest, TwoDecoders) { + this->AddMockDecoder(kDecoder1, kFail); + this->AddMockDecoder(kDecoder2, kSucceed); + + EXPECT_CALL(*this, OnDecoderSelected(kDecoder2)); + this->SelectDecoder(); +} + +TYPED_TEST(WebCodecsDecoderSelectorTest, TwoDecoders_SelectAgain) { + this->AddMockDecoder(kDecoder1, kSucceed); + this->AddMockDecoder(kDecoder2, kSucceed); + + EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); + this->SelectDecoder(); + + // Selecting again should give (a new instance of) the same decoder. + EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); + this->SelectDecoder(); +} + +TYPED_TEST(WebCodecsDecoderSelectorTest, TwoDecoders_NewConfigSelectAgain) { + this->AddMockDecoder(kDecoder1, kSucceed); + this->AddMockDecoder(kDecoder2, kSucceed); + + EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); + this->SelectDecoder(TypeParam::CreateConfig()); + + // Selecting again should give (a new instance of) the same decoder. + EXPECT_CALL(*this, OnDecoderSelected(kDecoder1)); + // Select again with a different config. Expected config verified during + // CreateDecoders() the SelectDecoder() call. + this->SelectDecoder(TypeParam::CreateAlternateConfig()); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk.idl b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk.idl new file mode 100644 index 00000000000..2ec3c2e7718 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk.idl @@ -0,0 +1,18 @@ +// Copyright 2020 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. + +enum EncodedAudioChunkType { + "key", + "delta", +}; + +[ + Exposed=(Window,Worker), + RuntimeEnabled=WebCodecs +] interface EncodedAudioChunk { + constructor(EncodedAudioChunkType type, unsigned long long timestamp, BufferSource data); + readonly attribute EncodedAudioChunkType type; + readonly attribute unsigned long long timestamp; // microseconds + readonly attribute ArrayBuffer data; +}; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_config.idl b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_config.idl new file mode 100644 index 00000000000..1a5ac10ee87 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_audio_config.idl @@ -0,0 +1,20 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://github.com/WICG/web-codecs + +dictionary EncodedAudioConfig { + // TODO(chcunningham): reference spec registry. + required DOMString codec; + + // 44100, 48000, etc. + unsigned long samplesPerSecond; + + // 1, 2, etc. + unsigned long numChannels; + + // Optional byte data required to initialize audio decoders such as Vorbis + // codebooks. + BufferSource extraData; +}; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h index 6e3df79bbe3..c756a4cc1c7 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h +++ b/chromium/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h @@ -34,7 +34,7 @@ class MODULES_EXPORT EncodedVideoChunk final : public ScriptWrappable { base::Optional<uint64_t> duration() const; DOMArrayBuffer* data() const; - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(buffer_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/idls.gni b/chromium/third_party/blink/renderer/modules/webcodecs/idls.gni index 718169a9537..dc0894e7f33 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/idls.gni +++ b/chromium/third_party/blink/renderer/modules/webcodecs/idls.gni @@ -13,8 +13,8 @@ modules_idl_files = [ ] modules_callback_function_idl_files = [ - "video_decoder_output_callback.idl", "video_encoder_output_callback.idl", + "video_frame_output_callback.idl", "web_codecs_error_callback.idl", ] @@ -23,9 +23,9 @@ modules_dictionary_idl_files = [ "image_decoder_init.idl", "image_frame.idl", "video_decoder_init.idl", + "video_encoder_config.idl", "video_encoder_init.idl", "video_encoder_encode_options.idl", - "video_encoder_tune_options.idl", "video_frame_init.idl", "video_track_writer_parameters.idl", ] diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder.idl b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder.idl index 2d13429f5f2..cd50b4820c2 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder.idl +++ b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder.idl @@ -12,6 +12,9 @@ ] interface ImageDecoder { [CallWith=ScriptState, RaisesException] constructor(ImageDecoderInit init); + // Returns true if ImageDecoder supports decoding of the given mime type. + static boolean canDecodeType(USVString type); + // Decodes the frame at the given index. If we're still receiving data, this // method will wait to resolve the promise until the given |frameIndex| is // available or reject the promise if we receive all data or fail before @@ -23,23 +26,27 @@ Promise<ImageFrame> decode(optional unsigned long frameIndex = 0, optional boolean completeFramesOnly = true); + // Decodes only the metadata for an image; resolves the promise when metadata + // can be decoded. Normally this is done automatically at construction time. + // However when using a ReadableStream, there may not be enough data to decode + // metadata at the time of construction. + Promise<void> decodeMetadata(); + // The number of frames in the image. // // When decoding a ReadableStream the value will be 0 until enough data to - // decode the frame count has been received. If the format has no fixed count, - // the value will increase as frames are received by the decoder. + // decode metadata has been received. If the format has no fixed count, the + // value will increase as frames are received by the decoder. readonly attribute unsigned long frameCount; - // The detected mime type for the decoded image. - // - // When decoding a ReadableStream the value will be an empty string until - // enough data to detect the mime type has been received. + // The mime type for the decoded image. This reflects the value provided + // during construction. readonly attribute USVString type; // The image's preferred repetition count. // // When decoding a ReadableStream the value will be 0 until enough data to - // decode the repetition count has been received. + // decode metadata has been received. readonly attribute unsigned long repetitionCount; // True if all available frames have been received by the decoder. diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc index cc082117cf4..e42ceaf3703 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc +++ b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.cc @@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/time/time.h" +#include "third_party/blink/public/common/mime_util/mime_util.h" #include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_image_decoder_init.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_image_frame.h" @@ -41,10 +42,16 @@ ImageDecoderExternal::DecodeRequest::DecodeRequest( frame_index(frame_index), complete_frames_only(complete_frames_only) {} -void ImageDecoderExternal::DecodeRequest::Trace(Visitor* visitor) { +void ImageDecoderExternal::DecodeRequest::Trace(Visitor* visitor) const { visitor->Trace(resolver); } +// static +bool ImageDecoderExternal::canDecodeType(String type) { + return type.ContainsOnlyASCIIOrEmpty() && + IsSupportedImageMimeType(type.Ascii()); +} + ImageDecoderExternal::ImageDecoderExternal(ScriptState* script_state, const ImageDecoderInit* init, ExceptionState& exception_state) @@ -56,6 +63,13 @@ ImageDecoderExternal::ImageDecoderExternal(ScriptState* script_state, options_ = init->hasOptions() ? init->options() : ImageBitmapOptions::Create(); + mime_type_ = init->type(); + if (!canDecodeType(mime_type_)) { + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + "Unsupported image format."); + return; + } + if (init->data().IsReadableStream()) { consumer_ = MakeGarbageCollected<ReadableStreamBytesConsumer>( script_state, init->data().GetAsReadableStream(), exception_state); @@ -63,11 +77,11 @@ ImageDecoderExternal::ImageDecoderExternal(ScriptState* script_state, return; stream_buffer_ = WTF::SharedBuffer::Create(); - consumer_->SetClient(this); + CreateImageDecoder(); - // We can't create the ImageDecoder until we have some data, so we may be - // done for now; we need one initial call to OnStateChange(), but thereafter - // calls will be driven by the ReadableStreamBytesConsumer. + // We need one initial call to OnStateChange() to start reading, but + // thereafter calls will be driven by the ReadableStreamBytesConsumer. + consumer_->SetClient(this); OnStateChange(); return; } @@ -88,23 +102,18 @@ ImageDecoderExternal::ImageDecoderExternal(ScriptState* script_state, // TODO: Data is owned by the caller who may be free to manipulate it. We will // probably need to make a copy to our own internal data or neuter the buffers // as seen by JS. - auto sr = SegmentReader::CreateFromSkData( + segment_reader_ = SegmentReader::CreateFromSkData( SkData::MakeWithoutCopy(buffer.Data(), buffer.ByteLengthAsSizeT())); - if (!sr) { + if (!segment_reader_) { exception_state.ThrowDOMException(DOMExceptionCode::kConstraintError, "Failed to read image data"); return; } data_complete_ = true; - MaybeCreateImageDecoder(std::move(sr)); - if (!decoder_) { - exception_state.ThrowDOMException(DOMExceptionCode::kConstraintError, - "Failed to create image decoder"); - return; - } - UpdateFrameAndRepetitionCount(); + CreateImageDecoder(); + MaybeUpdateMetadata(); if (decoder_->Failed()) { exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, "Image decoding failed"); @@ -128,6 +137,16 @@ ScriptPromise ImageDecoderExternal::decode(uint32_t frame_index, return promise; } +ScriptPromise ImageDecoderExternal::decodeMetadata() { + DVLOG(1) << __func__; + + auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state_); + auto promise = resolver->Promise(); + pending_metadata_decodes_.push_back(resolver); + MaybeSatisfyPendingMetadataDecodes(); + return promise; +} + uint32_t ImageDecoderExternal::frameCount() const { return frame_count_; } @@ -164,12 +183,9 @@ void ImageDecoderExternal::OnStateChange() { } data_complete_ = result == BytesConsumer::Result::kDone; - if (!decoder_) - MaybeCreateImageDecoder(nullptr); - else - decoder_->SetData(stream_buffer_, data_complete_); + decoder_->SetData(stream_buffer_, data_complete_); - UpdateFrameAndRepetitionCount(); + MaybeUpdateMetadata(); MaybeSatisfyPendingDecodes(); } } @@ -178,24 +194,65 @@ String ImageDecoderExternal::DebugName() const { return "ImageDecoderExternal"; } -void ImageDecoderExternal::Trace(Visitor* visitor) { +void ImageDecoderExternal::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(consumer_); visitor->Trace(pending_decodes_); + visitor->Trace(pending_metadata_decodes_); visitor->Trace(init_data_); visitor->Trace(options_); ScriptWrappable::Trace(visitor); } +void ImageDecoderExternal::CreateImageDecoder() { + DCHECK(!decoder_); + + // TODO: We should probably call ImageDecoder::SetMemoryAllocator() so that + // we can recycle frame buffers for decoded images. + + constexpr char kNoneOption[] = "none"; + + auto color_behavior = ColorBehavior::Tag(); + if (options_->colorSpaceConversion() == kNoneOption) + color_behavior = ColorBehavior::Ignore(); + + auto premultiply_alpha = ImageDecoder::kAlphaPremultiplied; + if (options_->premultiplyAlpha() == kNoneOption) + premultiply_alpha = ImageDecoder::kAlphaNotPremultiplied; + + // TODO: Is it okay to use resize size like this? + auto desired_size = SkISize::MakeEmpty(); + if (options_->hasResizeWidth() && options_->hasResizeHeight()) { + desired_size = + SkISize::Make(options_->resizeWidth(), options_->resizeHeight()); + } + + if (stream_buffer_) { + if (!segment_reader_) + segment_reader_ = SegmentReader::CreateFromSharedBuffer(stream_buffer_); + } else { + DCHECK(data_complete_); + } + + DCHECK(canDecodeType(mime_type_)); + decoder_ = ImageDecoder::CreateByMimeType( + mime_type_, segment_reader_, data_complete_, premultiply_alpha, + ImageDecoder::kHighBitDepthToHalfFloat, color_behavior, + ImageDecoder::OverrideAllowDecodeToYuv::kDeny, desired_size); + + // CreateByImageType() can't fail if we use a supported image type. Which we + // DCHECK above via canDecodeType(). + DCHECK(decoder_); +} + void ImageDecoderExternal::MaybeSatisfyPendingDecodes() { + DCHECK(decoder_); for (auto& request : pending_decodes_) { if (!data_complete_) { // We can't fulfill this promise at this time. if (request->frame_index >= frame_count_) continue; - - DCHECK(decoder_); - } else if (!decoder_ || request->frame_index >= frame_count_) { + } else if (request->frame_index >= frame_count_) { request->complete = true; // TODO: Include frameIndex in rejection? request->resolver->Reject(MakeGarbageCollected<DOMException>( @@ -268,62 +325,27 @@ void ImageDecoderExternal::MaybeSatisfyPendingDecodes() { static_cast<wtf_size_t>(new_end - pending_decodes_.begin())); } -void ImageDecoderExternal::MaybeCreateImageDecoder( - scoped_refptr<SegmentReader> sr) { - // TODO: This does not handle SVG Images since they use another "decoder." It - // is highly coupled with the DOM today, so isn't suitable for this API. - - // TODO: We should probably call ImageDecoder::SetMemoryAllocator() so that - // we can recycle frame buffers for decoded images. - - constexpr char kNoneOption[] = "none"; - - auto color_behavior = ColorBehavior::Tag(); - if (options_->colorSpaceConversion() == kNoneOption) - color_behavior = ColorBehavior::Ignore(); - - auto premultiply_alpha = ImageDecoder::kAlphaPremultiplied; - if (options_->premultiplyAlpha() == kNoneOption) - premultiply_alpha = ImageDecoder::kAlphaNotPremultiplied; - - // TODO: Is it okay to use resize size like this? - auto desired_size = SkISize::MakeEmpty(); - if (options_->hasResizeWidth() && options_->hasResizeHeight()) { - desired_size = - SkISize::Make(options_->resizeWidth(), options_->resizeHeight()); - } - - if (stream_buffer_) { - // TODO: If mime-type is supplied we must use that instead of sniffing. - if (!ImageDecoder::HasSufficientDataToSniffImageType(*stream_buffer_)) - return; - - DCHECK(!sr); - decoder_ = ImageDecoder::Create( - stream_buffer_, data_complete_, premultiply_alpha, - ImageDecoder::kHighBitDepthToHalfFloat, color_behavior, - ImageDecoder::OverrideAllowDecodeToYuv::kDeny, desired_size); - return; - } - - DCHECK(data_complete_); - decoder_ = ImageDecoder::Create( - std::move(sr), data_complete_, premultiply_alpha, - ImageDecoder::kHighBitDepthToHalfFloat, color_behavior, - ImageDecoder::OverrideAllowDecodeToYuv::kDeny, desired_size); +void ImageDecoderExternal::MaybeSatisfyPendingMetadataDecodes() { + DCHECK(decoder_); + DCHECK(decoder_->Failed() || decoder_->IsDecodedSizeAvailable()); + for (auto& resolver : pending_metadata_decodes_) + resolver->Resolve(); + pending_metadata_decodes_.clear(); } -void ImageDecoderExternal::UpdateFrameAndRepetitionCount() { - if (!decoder_) +void ImageDecoderExternal::MaybeUpdateMetadata() { + const size_t decoded_frame_count = decoder_->FrameCount(); + if (decoder_->Failed()) { + MaybeSatisfyPendingMetadataDecodes(); return; + } - const size_t decoded_frame_count = decoder_->FrameCount(); - if (decoder_->Failed()) + // Since we always create the decoder at construction, we need to wait until + // at least the size is available before signaling that metadata has been + // retrieved. + if (!decoder_->IsSizeAvailable()) return; - // TODO: Is this useful? We should have each decoder indicate its own mime - // type then. - mime_type_ = "image/todo"; frame_count_ = static_cast<uint32_t>(decoded_frame_count); // The internal value has some magic negative numbers; for external purposes @@ -332,6 +354,8 @@ void ImageDecoderExternal::UpdateFrameAndRepetitionCount() { const int decoded_repetition_count = decoder_->RepetitionCount(); if (decoded_repetition_count > 0) repetition_count_ = decoded_repetition_count; + + MaybeSatisfyPendingMetadataDecodes(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h index a9f8767a34c..1b4ac0ce7ea 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h +++ b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_external.h @@ -37,8 +37,11 @@ class MODULES_EXPORT ImageDecoderExternal final : public ScriptWrappable, ImageDecoderExternal(ScriptState*, const ImageDecoderInit*, ExceptionState&); ~ImageDecoderExternal() override; + static bool canDecodeType(String type); + // image_decoder.idl implementation. ScriptPromise decode(uint32_t frame_index, bool complete_frames_only); + ScriptPromise decodeMetadata(); uint32_t frameCount() const; String type() const; uint32_t repetitionCount() const; @@ -49,12 +52,14 @@ class MODULES_EXPORT ImageDecoderExternal final : public ScriptWrappable, String DebugName() const override; // GarbageCollected override. - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: + void CreateImageDecoder(); + void MaybeSatisfyPendingDecodes(); - void MaybeCreateImageDecoder(scoped_refptr<SegmentReader> sr); - void UpdateFrameAndRepetitionCount(); + void MaybeSatisfyPendingMetadataDecodes(); + void MaybeUpdateMetadata(); Member<ScriptState> script_state_; @@ -62,6 +67,9 @@ class MODULES_EXPORT ImageDecoderExternal final : public ScriptWrappable, Member<ReadableStreamBytesConsumer> consumer_; scoped_refptr<SharedBuffer> stream_buffer_; + // Used when all data is provided at construction time. + scoped_refptr<SegmentReader> segment_reader_; + // Construction parameters. Member<const ImageDecoderInit> init_data_; Member<const ImageBitmapOptions> options_; @@ -78,7 +86,7 @@ class MODULES_EXPORT ImageDecoderExternal final : public ScriptWrappable, DecodeRequest(ScriptPromiseResolver* resolver, uint32_t frame_index, bool complete_frames_only); - void Trace(Visitor*); + void Trace(Visitor*) const; Member<ScriptPromiseResolver> resolver; uint32_t frame_index; @@ -86,6 +94,7 @@ class MODULES_EXPORT ImageDecoderExternal final : public ScriptWrappable, bool complete = false; }; HeapVector<Member<DecodeRequest>> pending_decodes_; + HeapVector<Member<ScriptPromiseResolver>> pending_metadata_decodes_; // When decode() of incomplete frames has been requested, we need to track the // generation id for each SkBitmap that we've handed out. So that we can defer diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_init.idl b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_init.idl index 1b553936a55..0a61db3af98 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_init.idl +++ b/chromium/third_party/blink/renderer/modules/webcodecs/image_decoder_init.idl @@ -7,5 +7,13 @@ typedef (ArrayBuffer or ArrayBufferView or ReadableStream) ImageBufferSource; dictionary ImageDecoderInit { required ImageBufferSource data; + + // Mime type for |data|. Providing the wrong mime type will lead to a decoding + // failure. + required USVString type; + + // Options to use when creating ImageBitmap objects from decoded frames. The + // resize width and height are additionally used to facilitate reduced + // resolution decoding. ImageBitmapOptions options; }; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc index d8aa2dba352..428219043c4 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.cc @@ -15,11 +15,13 @@ #include "media/base/video_decoder.h" #include "media/filters/ffmpeg_video_decoder.h" #include "media/media_buildflags.h" +#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_config.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_init.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h" +#include "third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h" #include "third_party/blink/renderer/modules/webcodecs/video_frame.h" #include "third_party/blink/renderer/platform/bindings/exception_code.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -64,15 +66,6 @@ media::VideoDecoderConfig ToVideoDecoderConfig( media::EncryptionScheme::kUnencrypted); } -std::unique_ptr<media::VideoDecoder> CreateVideoDecoder( - media::MediaLog* media_log) { -#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) - return std::make_unique<media::FFmpegVideoDecoder>(media_log); -#else - return nullptr; -#endif // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) -} - } // namespace // static @@ -101,51 +94,45 @@ int32_t VideoDecoder::decodeQueueSize() { return requested_decodes_; } -int32_t VideoDecoder::decodeProcessingCount() { - return pending_decodes_.size(); -} - -ScriptPromise VideoDecoder::configure(const EncodedVideoConfig* config, - ExceptionState&) { +void VideoDecoder::configure(const EncodedVideoConfig* config, + ExceptionState&) { DVLOG(1) << __func__; Request* request = MakeGarbageCollected<Request>(); request->type = Request::Type::kConfigure; request->config = config; - return EnqueueRequest(request); + requests_.push_back(request); + ProcessRequests(); } -ScriptPromise VideoDecoder::decode(const EncodedVideoChunk* chunk, - ExceptionState&) { +void VideoDecoder::decode(const EncodedVideoChunk* chunk, ExceptionState&) { DVLOG(3) << __func__; - requested_decodes_++; Request* request = MakeGarbageCollected<Request>(); request->type = Request::Type::kDecode; request->chunk = chunk; - return EnqueueRequest(request); + requests_.push_back(request); + ++requested_decodes_; + ProcessRequests(); } ScriptPromise VideoDecoder::flush(ExceptionState&) { DVLOG(3) << __func__; Request* request = MakeGarbageCollected<Request>(); request->type = Request::Type::kFlush; - return EnqueueRequest(request); + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state_); + request->resolver = resolver; + requests_.push_back(request); + ProcessRequests(); + return resolver->Promise(); } -ScriptPromise VideoDecoder::reset(ExceptionState&) { +void VideoDecoder::reset(ExceptionState&) { DVLOG(3) << __func__; - requested_resets_++; Request* request = MakeGarbageCollected<Request>(); request->type = Request::Type::kReset; - return EnqueueRequest(request); -} - -ScriptPromise VideoDecoder::EnqueueRequest(Request* request) { - ScriptPromiseResolver* resolver = - MakeGarbageCollected<ScriptPromiseResolver>(script_state_); - request->resolver = resolver; requests_.push_back(request); + ++requested_resets_; ProcessRequests(); - return resolver->Promise(); } void VideoDecoder::ProcessRequests() { @@ -189,16 +176,9 @@ bool VideoDecoder::ProcessConfigureRequest(Request* request) { if (!decoder_) { media_log_ = std::make_unique<media::NullMediaLog>(); - decoder_ = CreateVideoDecoder(media_log_.get()); - if (!decoder_) { - request->resolver.Release()->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotSupportedError, - "Codec initialization failed.")); - // TODO(sandersd): This is a bit awkward because |request| is still in the - // queue. - HandleError(); - return false; - } + decoder_ = std::make_unique<VideoDecoderBroker>( + *ExecutionContext::From(script_state_), + Platform::Current()->GetGpuFactories()); // Processing continues in OnInitializeDone(). // TODO(sandersd): OnInitializeDone() may be called reentrantly, in which @@ -236,11 +216,10 @@ bool VideoDecoder::ProcessDecodeRequest(Request* request) { DCHECK(request->chunk); DCHECK_GT(requested_decodes_, 0); - // TODO(sandersd): If a reset has been requested, resolve immediately. + // TODO(sandersd): If a reset has been requested, complete immediately. if (!decoder_) { - // TODO(sandersd): Add explanation (no valid configuration). - request->resolver.Release()->Reject(); + // TODO(sandersd): Emit an error? return true; } @@ -348,14 +327,11 @@ void VideoDecoder::OnInitializeDone(media::Status status) { if (!status.is_ok()) { // TODO(tmathmeyer) this drops the media error - should we consider logging // it or converting it to the DOMException type somehow? - pending_request_.Release()->resolver.Release()->Reject( - MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, - "Codec initialization failed.")); HandleError(); return; } - pending_request_.Release()->resolver.Release()->Resolve(); + pending_request_.Release(); ProcessRequests(); } @@ -370,7 +346,6 @@ void VideoDecoder::OnDecodeDone(uint32_t id, media::DecodeStatus status) { } auto it = pending_decodes_.find(id); - it->value->resolver.Release()->Resolve(); pending_decodes_.erase(it); ProcessRequests(); } @@ -394,7 +369,7 @@ void VideoDecoder::OnResetDone() { DCHECK(pending_request_); DCHECK_EQ(pending_request_->type, Request::Type::kReset); - pending_request_.Release()->resolver.Release()->Resolve(); + pending_request_.Release(); ProcessRequests(); } @@ -404,7 +379,7 @@ void VideoDecoder::OnOutput(scoped_refptr<media::VideoFrame> frame) { MakeGarbageCollected<VideoFrame>(frame)); } -void VideoDecoder::Trace(Visitor* visitor) { +void VideoDecoder::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(output_cb_); visitor->Trace(error_cb_); @@ -414,7 +389,7 @@ void VideoDecoder::Trace(Visitor* visitor) { ScriptWrappable::Trace(visitor); } -void VideoDecoder::Request::Trace(Visitor* visitor) { +void VideoDecoder::Request::Trace(Visitor* visitor) const { visitor->Trace(config); visitor->Trace(chunk); visitor->Trace(resolver); diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h index 3a35f24383f..5b0dc98339b 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.h @@ -13,7 +13,7 @@ #include "media/base/video_decoder.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/modules/v8/v8_video_decoder_output_callback.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_output_callback.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_codecs_error_callback.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -43,14 +43,13 @@ class MODULES_EXPORT VideoDecoder final : public ScriptWrappable { // video_decoder.idl implementation. int32_t decodeQueueSize(); - int32_t decodeProcessingCount(); - ScriptPromise configure(const EncodedVideoConfig*, ExceptionState&); - ScriptPromise decode(const EncodedVideoChunk*, ExceptionState&); + void configure(const EncodedVideoConfig*, ExceptionState&); + void decode(const EncodedVideoChunk*, ExceptionState&); ScriptPromise flush(ExceptionState&); - ScriptPromise reset(ExceptionState&); + void reset(ExceptionState&); // GarbageCollected override. - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: struct Request : public GarbageCollected<Request> { @@ -61,11 +60,17 @@ class MODULES_EXPORT VideoDecoder final : public ScriptWrappable { kReset, }; - void Trace(Visitor*); + void Trace(Visitor*) const; Type type; + + // For kConfigure Requests. Member<const EncodedVideoConfig> config; + + // For kDecode Requests. Member<const EncodedVideoChunk> chunk; + + // For kFlush Requests. Member<ScriptPromiseResolver> resolver; }; @@ -86,7 +91,7 @@ class MODULES_EXPORT VideoDecoder final : public ScriptWrappable { void OnOutput(scoped_refptr<media::VideoFrame>); Member<ScriptState> script_state_; - Member<V8VideoDecoderOutputCallback> output_cb_; + Member<V8VideoFrameOutputCallback> output_cb_; Member<V8WebCodecsErrorCallback> error_cb_; HeapDeque<Member<Request>> requests_; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl index 863cf86d2ab..a6611ba6ab8 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder.idl @@ -21,69 +21,50 @@ // When in an error state, methods other than reset() will fail. // // TODO(sandersd): Consider adding a state or last error attribute. - // TODO(sandersd): Consider aborting pending decodes on error, rather than - // waiting for reset(). [CallWith=ScriptState, RaisesException] constructor(VideoDecoderInit init); - // The number of queued decode requests. This does not include requests that - // have been taken for processing. + // The number of pending decode requests. This does not include requests that + // have been sent to the underlying codec. // // Applications can minimize underflow by enqueueing decode requests until // |decodeQueueSize| is greater than a constant. - readonly attribute long decodeQueueSize; - - // The number of decode requests currently being processed. // - // Applications can minimize resource consumption and decode latency by - // enqueueing decode requests only when |decodeQueueSize| and - // |decodeProcessingCount| are small. - // - // TODO(sandersd): Consider counting queued decode requests as well. This - // could be simpler for apps. - readonly attribute long decodeProcessingCount; + // TODO(sandersd): Consider adding a predicted output count or other + // backpressure mechanism that considers the state of the underlying codec. + // TODO(sandersd): Consider emitting an event when this number decreases. + readonly attribute long decodeQueueSize; - // Enqueue a request to set or change the stream configuration. + // Set the stream configuration for future decode() requests. // - // The next enqueued decode request must be for a keyframe. + // The next decode request must be for a keyframe. // - // Resolved after emitting output for all earlier decode requests. - // - // TODO(sandersd): Test that resolution (a microtask) interleaves between - // outputs callback calls in all cases. // TODO(sandersd): Move the keyframe rule into the bytestream registry. - [RaisesException] Promise<void> configure(EncodedVideoConfig config); + [RaisesException] void configure(EncodedVideoConfig config); - // Enqueue a request to decode an input chunk. - // - // You must call configure() before calling enqueue() for the first time. + // Request decoding of an input chunk. // - // Resolved after decoding of the input chunk has started (that is, after - // decreasing |decodeQueueSize|). + // You must call configure() before calling decode() for the first time. // // TODO(sandersd): Change to a dictionary type. - // TODO(sandersd): Should we guarantee that resolution occurs in order? - // TODO(sandersd): Add status to result. - // TODO(sandersd): Buffer return. - [RaisesException] Promise<void> decode(EncodedVideoChunk chunk); + [RaisesException] void decode(EncodedVideoChunk chunk); - // Enqueue a request to finish decoding queued input chunks. + // Request output from all previous decode requests. // - // The next enqueued input chunk must be a keyframe. + // Resolved after all output for earlier decode requests has been emitted. // - // Resolved after emitting output for all earlier decode requests. + // The next decode request must be for a keyframe. // // TODO(sandersd): Consider relaxing the keyframe requirement. + // TODO(sandersd): Indicate whether the flush() completed successfully or due + // to a reset. [RaisesException] Promise<void> flush(); - // Discard all pending work. - // - // Output for earlier decode requests will not be emitted, even if processing - // has already started. - // - // The next enqueued input chunk must be a keyframe. + // Discard all pending decode requests. // - // Resolved after all earlier enqueue() promises have been resolved. + // The next decode request must be for a keyframe. // - // TODO(sandersd): Require configure() after reset()? - [RaisesException] Promise<void> reset(); + // Note: It may be possible to call reset() after a flush() promise has been + // resolved but before it is fulfilled. In that case the flush() promise will + // be fulfilled successfully even though reset() was called. + [RaisesException] void reset(); }; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc new file mode 100644 index 00000000000..a40192f9822 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.cc @@ -0,0 +1,418 @@ +// Copyright (c) 2020 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/webcodecs/video_decoder_broker.h" + +#include <memory> +#include <string> + +#include "base/memory/weak_ptr.h" +#include "build/buildflag.h" +#include "media/base/decoder_factory.h" +#include "media/base/media_util.h" +#include "media/base/status_codes.h" +#include "media/base/video_decoder_config.h" +#include "media/mojo/buildflags.h" +#include "media/mojo/clients/mojo_decoder_factory.h" +#include "media/mojo/mojom/interface_factory.mojom.h" +#include "media/renderers/default_decoder_factory.h" +#include "mojo/public/cpp/bindings/remote.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/execution_context/execution_context.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/core/page/chrome_client.h" +#include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/modules/webcodecs/decoder_selector.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" +#include "third_party/blink/renderer/platform/wtf/functional.h" +#include "ui/gfx/color_space.h" + +using DecoderDetails = blink::VideoDecoderBroker::DecoderDetails; + +namespace WTF { + +template <> +struct CrossThreadCopier<media::VideoDecoderConfig> + : public CrossThreadCopierPassThrough<media::VideoDecoderConfig> { + STATIC_ONLY(CrossThreadCopier); +}; + +template <> +struct CrossThreadCopier<media::Status> + : public CrossThreadCopierPassThrough<media::Status> { + STATIC_ONLY(CrossThreadCopier); +}; + +template <> +struct CrossThreadCopier<base::Optional<DecoderDetails>> + : public CrossThreadCopierPassThrough<base::Optional<DecoderDetails>> { + STATIC_ONLY(CrossThreadCopier); +}; + +} // namespace WTF + +namespace blink { + +// Wrapper class for state and API calls that must be made from the +// |media_task_runner_|. Construction must happen on blink main thread to safely +// make use of ExecutionContext and Document. These GC blink types must not be +// stored/referenced by any other method. +class MediaVideoTaskWrapper { + public: + using CrossThreadOnceInitCB = + WTF::CrossThreadOnceFunction<void(media::Status status, + base::Optional<DecoderDetails>)>; + using CrossThreadOnceDecodeCB = + WTF::CrossThreadOnceFunction<void(media::DecodeStatus)>; + using CrossThreadOnceResetCB = WTF::CrossThreadOnceClosure; + + MediaVideoTaskWrapper( + base::WeakPtr<CrossThreadVideoDecoderClient> weak_client, + ExecutionContext& execution_context, + media::GpuVideoAcceleratorFactories* gpu_factories, + scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) + : weak_client_(weak_client), + media_task_runner_(std::move(media_task_runner)), + main_task_runner_(std::move(main_task_runner)), + gpu_factories_(gpu_factories) { + DVLOG(2) << __func__; + DETACH_FROM_SEQUENCE(sequence_checker_); + + // TODO(chcunningham): Enable this for workers. Currently only a + // frame-binding (RenderFrameHostImpl) is exposed. + // TODO(chcunningham): set_disconnect_handler? + // Mojo connection setup must occur here on the main thread where its safe + // to use |execution_context| APIs. + mojo::PendingRemote<media::mojom::InterfaceFactory> media_interface_factory; + execution_context.GetBrowserInterfaceBroker().GetInterface( + media_interface_factory.InitWithNewPipeAndPassReceiver()); + + // Mojo remote must be bound on media thread where it will be used. + //|Unretained| is safe because |this| must be destroyed on the media task + // runner. + PostCrossThreadTask( + *media_task_runner_, FROM_HERE, + WTF::CrossThreadBindOnce(&MediaVideoTaskWrapper::BindOnTaskRunner, + WTF::CrossThreadUnretained(this), + std::move(media_interface_factory))); + + // TODO(chcunningham): Research usage of this and consider how to unify for + // worker context (no document). What follows is borrowed from + // HTMLMediaElement. + Document* document = To<LocalDOMWindow>(execution_context).document(); + if (document && document->GetFrame()) { + LocalFrame* frame = document->GetFrame(); + target_color_space_ = + frame->GetPage()->GetChromeClient().GetScreenInfo(*frame).color_space; + } + } + + virtual ~MediaVideoTaskWrapper() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + } + + MediaVideoTaskWrapper(const MediaVideoTaskWrapper&) = delete; + MediaVideoTaskWrapper& operator=(const MediaVideoTaskWrapper&) = delete; + + void Initialize(const media::VideoDecoderConfig& config, + CrossThreadOnceInitCB init_cb) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + selector_ = std::make_unique<WebCodecsVideoDecoderSelector>( + media_task_runner_, + WTF::BindRepeating(&MediaVideoTaskWrapper::OnCreateDecoders, + WTF::Unretained(this)), + WTF::BindRepeating(&MediaVideoTaskWrapper::OnDecodeOutput, + WTF::Unretained(this))); + + selector_->SelectDecoder( + config, WTF::Bind(&MediaVideoTaskWrapper::OnDecoderSelected, + WTF::Unretained(this), std::move(init_cb))); + } + + void Decode(scoped_refptr<media::DecoderBuffer> buffer, + CrossThreadOnceDecodeCB decode_cb) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!decoder_) { + std::move(decode_cb).Run(media::DecodeStatus::DECODE_ERROR); + return; + } + + decoder_->Decode(buffer, + WTF::Bind(&MediaVideoTaskWrapper::OnDecodeDone, + WTF::Unretained(this), std::move(decode_cb))); + } + + void Reset(CrossThreadOnceResetCB reset_cb) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!decoder_) { + std::move(reset_cb).Run(); + return; + } + + decoder_->Reset(WTF::Bind(&MediaVideoTaskWrapper::OnReset, + WTF::Unretained(this), std::move(reset_cb))); + } + + private: + void BindOnTaskRunner( + mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + media_interface_factory_.Bind(std::move(interface_factory)); + + // This setup is blocked on the Bind() above. + std::unique_ptr<media::DecoderFactory> external_decoder_factory; +#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) + external_decoder_factory = std::make_unique<media::MojoDecoderFactory>( + media_interface_factory_.get()); +#endif + decoder_factory_ = std::make_unique<media::DefaultDecoderFactory>( + std::move(external_decoder_factory)); + } + + std::vector<std::unique_ptr<media::VideoDecoder>> OnCreateDecoders() { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // TODO(chcunningham): Add plumbing to enable overlays on Android. See + // handling in WebMediaPlayerImpl. + media::RequestOverlayInfoCB request_overlay_info_cb; + + std::vector<std::unique_ptr<media::VideoDecoder>> video_decoders; + decoder_factory_->CreateVideoDecoders( + media_task_runner_, gpu_factories_, &null_media_log_, + request_overlay_info_cb, target_color_space_, &video_decoders); + + return video_decoders; + } + + void OnDecoderSelected(CrossThreadOnceInitCB init_cb, + std::unique_ptr<media::VideoDecoder> decoder) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // We're done with it. + DCHECK(selector_); + selector_.reset(); + + decoder_ = std::move(decoder); + + media::Status status(media::StatusCode::kDecoderUnsupportedConfig); + base::Optional<DecoderDetails> decoder_details; + if (decoder_) { + status = media::OkStatus(); + decoder_details = DecoderDetails({decoder_->GetDisplayName(), + decoder_->IsPlatformDecoder(), + decoder_->NeedsBitstreamConversion(), + decoder_->GetMaxDecodeRequests()}); + } + + // Fire |init_cb|. + PostCrossThreadTask( + *main_task_runner_, FROM_HERE, + WTF::CrossThreadBindOnce(std::move(init_cb), status, decoder_details)); + } + + void OnDecodeOutput(scoped_refptr<media::VideoFrame> frame) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + PostCrossThreadTask( + *main_task_runner_, FROM_HERE, + WTF::CrossThreadBindOnce(&CrossThreadVideoDecoderClient::OnDecodeOutput, + weak_client_, std::move(frame), + decoder_->CanReadWithoutStalling())); + } + + void OnDecodeDone(CrossThreadOnceDecodeCB decode_cb, + media::DecodeStatus status) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + PostCrossThreadTask(*main_task_runner_, FROM_HERE, + WTF::CrossThreadBindOnce(std::move(decode_cb), status)); + } + + void OnReset(CrossThreadOnceResetCB reset_cb) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + PostCrossThreadTask(*main_task_runner_, FROM_HERE, std::move(reset_cb)); + } + + base::WeakPtr<CrossThreadVideoDecoderClient> weak_client_; + scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + media::GpuVideoAcceleratorFactories* gpu_factories_; + mojo::Remote<media::mojom::InterfaceFactory> media_interface_factory_; + std::unique_ptr<WebCodecsVideoDecoderSelector> selector_; + std::unique_ptr<media::DefaultDecoderFactory> decoder_factory_; + std::unique_ptr<media::VideoDecoder> decoder_; + gfx::ColorSpace target_color_space_; + + // TODO(chcunningham): Route MEDIA_LOG for WebCodecs. + media::NullMediaLog null_media_log_; + + SEQUENCE_CHECKER(sequence_checker_); +}; + +constexpr char VideoDecoderBroker::kDefaultDisplayName[]; + +VideoDecoderBroker::VideoDecoderBroker( + ExecutionContext& execution_context, + media::GpuVideoAcceleratorFactories* gpu_factories) + : media_task_runner_( + gpu_factories + ? gpu_factories->GetTaskRunner() + // TODO(chcunningham): Consider adding a new single thread task + // runner just for WebCodecs. This is still using the main thread, + // albeit at a lower priority than things like user gestures. + // http://crbug.com/1095786 + // TODO(chcunningham): Should this be kInternalMediaRealTime? Why + // does WebAudio use that task type? + : execution_context.GetTaskRunner(TaskType::kInternalMedia)) { + DVLOG(2) << __func__; + media_tasks_ = std::make_unique<MediaVideoTaskWrapper>( + weak_factory_.GetWeakPtr(), execution_context, gpu_factories, + media_task_runner_, + execution_context.GetTaskRunner(TaskType::kInternalMedia)); +} + +VideoDecoderBroker::~VideoDecoderBroker() { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + media_task_runner_->DeleteSoon(FROM_HERE, std::move(media_tasks_)); +} + +std::string VideoDecoderBroker::GetDisplayName() const { + return decoder_details_ ? decoder_details_->display_name + : VideoDecoderBroker::kDefaultDisplayName; +} + +bool VideoDecoderBroker::IsPlatformDecoder() const { + return decoder_details_ ? decoder_details_->is_platform_decoder : false; +} + +void VideoDecoderBroker::Initialize(const media::VideoDecoderConfig& config, + bool low_delay, + media::CdmContext* cdm_context, + InitCB init_cb, + const OutputCB& output_cb, + const media::WaitingCB& waiting_cb) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // The following are not currently supported in WebCodecs. + // TODO(chcunningham): Should |low_delay| be supported? Should it be + // hard-coded to true? + DCHECK(!low_delay); + DCHECK(!cdm_context); + DCHECK(!waiting_cb); + + output_cb_ = output_cb; + + // Clear details from previously initialized decoder. New values will arrive + // via OnInitialize(). + decoder_details_.reset(); + + MediaVideoTaskWrapper::CrossThreadOnceInitCB main_loop_init_cb( + WTF::Bind(&VideoDecoderBroker::OnInitialize, weak_factory_.GetWeakPtr(), + std::move(init_cb))); + + PostCrossThreadTask( + *media_task_runner_, FROM_HERE, + WTF::CrossThreadBindOnce(&MediaVideoTaskWrapper::Initialize, + WTF::CrossThreadUnretained(media_tasks_.get()), + config, std::move(main_loop_init_cb))); +} + +void VideoDecoderBroker::OnInitialize(InitCB init_cb, + media::Status status, + base::Optional<DecoderDetails> details) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + decoder_details_ = details; + std::move(init_cb).Run(status); +} + +void VideoDecoderBroker::Decode(scoped_refptr<media::DecoderBuffer> buffer, + DecodeCB decode_cb) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + MediaVideoTaskWrapper::CrossThreadOnceDecodeCB main_loop_cb( + WTF::Bind(&VideoDecoderBroker::OnDecodeDone, weak_factory_.GetWeakPtr(), + std::move(decode_cb))); + + PostCrossThreadTask( + *media_task_runner_, FROM_HERE, + WTF::CrossThreadBindOnce(&MediaVideoTaskWrapper::Decode, + WTF::CrossThreadUnretained(media_tasks_.get()), + buffer, std::move(main_loop_cb))); +} + +void VideoDecoderBroker::OnDecodeDone(DecodeCB decode_cb, + media::DecodeStatus status) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + std::move(decode_cb).Run(status); +} + +void VideoDecoderBroker::Reset(base::OnceClosure reset_cb) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + MediaVideoTaskWrapper::CrossThreadOnceResetCB main_loop_cb( + WTF::Bind(&VideoDecoderBroker::OnReset, weak_factory_.GetWeakPtr(), + std::move(reset_cb))); + + PostCrossThreadTask( + *media_task_runner_, FROM_HERE, + WTF::CrossThreadBindOnce(&MediaVideoTaskWrapper::Reset, + WTF::CrossThreadUnretained(media_tasks_.get()), + std::move(main_loop_cb))); +} + +bool VideoDecoderBroker::NeedsBitstreamConversion() const { + return decoder_details_ ? decoder_details_->needs_bitstream_conversion + : false; +} + +bool VideoDecoderBroker::CanReadWithoutStalling() const { + return can_read_without_stalling_; +} + +int VideoDecoderBroker::GetMaxDecodeRequests() const { + return decoder_details_ ? decoder_details_->max_decode_requests : 1; +} + +void VideoDecoderBroker::OnReset(base::OnceClosure reset_cb) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + std::move(reset_cb).Run(); +} + +void VideoDecoderBroker::OnDecodeOutput(scoped_refptr<media::VideoFrame> frame, + bool can_read_without_stalling) { + DVLOG(2) << __func__; + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(output_cb_); + + can_read_without_stalling_ = can_read_without_stalling; + + output_cb_.Run(std::move(frame)); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h new file mode 100644 index 00000000000..7e01787f77a --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h @@ -0,0 +1,129 @@ +// Copyright (c) 2020 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_WEBCODECS_VIDEO_DECODER_BROKER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_DECODER_BROKER_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" +#include "base/optional.h" +#include "base/sequence_checker.h" +#include "base/single_thread_task_runner.h" +#include "media/base/decode_status.h" +#include "media/base/video_decoder.h" +#include "media/base/video_frame.h" +#include "media/video/gpu_video_accelerator_factories.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/modules/modules_export.h" + +namespace blink { + +// Implementation detail of VideoDecoderBroker. Helps safely perform decoder +// tasks on the media thread. +class MediaVideoTaskWrapper; + +// Client interface for MediaVideoTaskWrapper. Implementation detail of +// VideoDecoderBroker, but we need to define it here to implement it below. +class CrossThreadVideoDecoderClient { + public: + virtual void OnDecodeOutput(scoped_refptr<media::VideoFrame> frame, + bool can_read_without_stalling) = 0; +}; + +// This class brokers the connection between WebCodecs and an underlying +// media::VideoDecoder. It abstracts away details of construction and selection +// of the media/ decoder. It also handles thread-hopping as required by +// underlying APIS. +// +// A new underlying decoder is selected anytime Initialize() is called. +// TODO(chcunningham): Elide re-selection if the config has not significantly +// changed. +// +// All API calls and callbacks must occur on the main thread. +class MODULES_EXPORT VideoDecoderBroker : public media::VideoDecoder, + public CrossThreadVideoDecoderClient { + public: + static constexpr char kDefaultDisplayName[] = "EmptyWebCodecsVideoDecoder"; + + struct DecoderDetails { + std::string display_name; + bool is_platform_decoder; + bool needs_bitstream_conversion; + int max_decode_requests; + }; + + // |gpu_factories| may be null when GPU accelerated decoding is not available. + explicit VideoDecoderBroker( + ExecutionContext& execution_context, + media::GpuVideoAcceleratorFactories* gpu_factories); + ~VideoDecoderBroker() override; + + // Disallow copy and assign. + VideoDecoderBroker(const VideoDecoderBroker&) = delete; + VideoDecoderBroker& operator=(const VideoDecoderBroker&) = delete; + + // VideoDecoder implementation. + std::string GetDisplayName() const override; + bool IsPlatformDecoder() const override; + void Initialize(const media::VideoDecoderConfig& config, + bool low_delay, + media::CdmContext* cdm_context, + InitCB init_cb, + const OutputCB& output_cb, + const media::WaitingCB& waiting_cb) override; + void Decode(scoped_refptr<media::DecoderBuffer> buffer, + DecodeCB decode_cb) override; + void Reset(base::OnceClosure reset_cb) override; + bool NeedsBitstreamConversion() const override; + bool CanReadWithoutStalling() const override; + int GetMaxDecodeRequests() const override; + + private: + void OnInitialize(InitCB init_cb, + media::Status status, + base::Optional<DecoderDetails> details); + void OnDecodeDone(DecodeCB decode_cb, media::DecodeStatus status); + void OnReset(base::OnceClosure reset_cb); + + // MediaVideoTaskWrapper::CrossThreadVideoDecoderClient + void OnDecodeOutput(scoped_refptr<media::VideoFrame> frame, + bool can_read_without_stalling) override; + + // When media::GpuVideoAcceleratorFactories is provided, its API requires + // that we use its TaskRunner (the media thread). When not provided, this task + // runner will still be used to reduce contention on the main thread. + // TODO(chcunningham): Try to eliminate the Post(). Most of the + // underlying::VideoDecoders already offload their work, so this just adds + // overhead. + scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; + + // Owner of state and methods to be used on media_task_runner_; + std::unique_ptr<MediaVideoTaskWrapper> media_tasks_; + + // Display name for current underlying decoder. Will be kDefaultDisplayName + // if no decoder is currently initialized. + std::string display_name_ = kDefaultDisplayName; + + // Wrapper state for GetDisplayName(), IsPlatformDecoder() and others. + base::Optional<DecoderDetails> decoder_details_; + + // Set to match the underlying decoder's answer at every OnDecodeOutput(). + bool can_read_without_stalling_ = true; + + // OutputCB saved from last call to Initialize(). + OutputCB output_cb_; + + SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory<VideoDecoderBroker> weak_factory_{this}; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_DECODER_BROKER_H_ diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc new file mode 100644 index 00000000000..9504632d176 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_broker_test.cc @@ -0,0 +1,347 @@ +// Copyright 2020 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 <memory> +#include <vector> + +#include "base/run_loop.h" +#include "base/threading/thread.h" +#include "build/build_config.h" +#include "gpu/command_buffer/common/mailbox_holder.h" +#include "media/base/decode_status.h" +#include "media/base/decoder_buffer.h" +#include "media/base/test_data_util.h" +#include "media/base/test_helpers.h" +#include "media/base/video_frame.h" +#include "media/filters/fake_video_decoder.h" +#include "media/mojo/buildflags.h" +#include "media/mojo/mojom/interface_factory.mojom.h" +#include "media/mojo/mojom/video_decoder.mojom.h" +#include "media/mojo/services/interface_factory_impl.h" +#include "media/mojo/services/mojo_cdm_service_context.h" +#include "media/mojo/services/mojo_video_decoder_service.h" +#include "media/video/mock_gpu_video_accelerator_factories.h" +#include "mojo/public/cpp/bindings/unique_receiver_set.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/renderer/bindings/core/v8/v8_binding_for_testing.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" + +#include "third_party/blink/renderer/modules/webcodecs/video_decoder_broker.h" + +using ::testing::_; +using ::testing::Return; + +namespace blink { + +namespace { + +// Fake decoder intended to simulate platform specific hw accelerated decoders +// running in the GPU process. +// * Initialize() will succeed for any given config. +// * MakeVideoFrame() is overridden to create frames frame with a mailbox and +// power_efficient flag. This simulates hw decoder output and satisfies +// requirements of MojoVideoDecoder. +class FakeGpuVideoDecoder : public media::FakeVideoDecoder { + public: + FakeGpuVideoDecoder() + : FakeVideoDecoder("FakeGpuVideoDecoder" /* display_name */, + 0 /* decoding_delay */, + 13 /* max_parallel_decoding_requests */, + media::BytesDecodedCB()) {} + ~FakeGpuVideoDecoder() override = default; + + scoped_refptr<media::VideoFrame> MakeVideoFrame( + const media::DecoderBuffer& buffer) override { + gpu::MailboxHolder mailbox_holders[media::VideoFrame::kMaxPlanes]; + mailbox_holders[0].mailbox.name[0] = 1; + scoped_refptr<media::VideoFrame> frame = + media::VideoFrame::WrapNativeTextures( + media::PIXEL_FORMAT_ARGB, mailbox_holders, + media::VideoFrame::ReleaseMailboxCB(), current_config_.coded_size(), + current_config_.visible_rect(), current_config_.natural_size(), + buffer.timestamp()); + frame->metadata()->power_efficient = true; + return frame; + } + + // Override these methods to provide non-default values for testing. + bool IsPlatformDecoder() const override { return true; } + bool NeedsBitstreamConversion() const override { return true; } + bool CanReadWithoutStalling() const override { return false; } +}; + +// Client to MojoVideoDecoderService vended by FakeInterfaceFactory. Creates a +// FakeGpuVideoDecoder when requested. +class FakeMojoMediaClient : public media::MojoMediaClient { + public: + // MojoMediaClient implementation. + std::unique_ptr<media::VideoDecoder> CreateVideoDecoder( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + media::MediaLog* media_log, + media::mojom::CommandBufferIdPtr command_buffer_id, + media::VideoDecoderImplementation implementation, + media::RequestOverlayInfoCB request_overlay_info_cb, + const gfx::ColorSpace& target_color_space) override { + return std::make_unique<FakeGpuVideoDecoder>(); + } +}; + +// Other end of remote InterfaceFactory requested by VideoDecoderBroker. Used +// to create our (fake) media::mojom::VideoDecoder. +class FakeInterfaceFactory : public media::mojom::InterfaceFactory { + public: + FakeInterfaceFactory() = default; + ~FakeInterfaceFactory() override = default; + + void BindRequest(mojo::ScopedMessagePipeHandle handle) { + receiver_.Bind(mojo::PendingReceiver<media::mojom::InterfaceFactory>( + std::move(handle))); + receiver_.set_disconnect_handler(WTF::Bind( + &FakeInterfaceFactory::OnConnectionError, base::Unretained(this))); + } + + void OnConnectionError() { receiver_.reset(); } + + // Implement this one interface from mojom::InterfaceFactory. Using the real + // MojoVideoDecoderService allows us to reuse buffer conversion code. The + // FakeMojoMediaClient will create a FakeGpuVideoDecoder. + void CreateVideoDecoder( + mojo::PendingReceiver<media::mojom::VideoDecoder> receiver) override { + video_decoder_receivers_.Add( + std::make_unique<media::MojoVideoDecoderService>(&mojo_media_client_, + &cdm_service_context_), + std::move(receiver)); + } + + // Stub out other mojom::InterfaceFactory interfaces. + void CreateAudioDecoder( + mojo::PendingReceiver<media::mojom::AudioDecoder> receiver) override {} + void CreateDefaultRenderer( + const std::string& audio_device_id, + mojo::PendingReceiver<media::mojom::Renderer> receiver) override {} +#if BUILDFLAG(ENABLE_CAST_RENDERER) + void CreateCastRenderer( + const base::UnguessableToken& overlay_plane_id, + mojo::PendingReceiver<media::mojom::Renderer> receiver) override {} +#endif +#if defined(OS_ANDROID) + void CreateMediaPlayerRenderer( + mojo::PendingRemote<media::mojom::MediaPlayerRendererClientExtension> + client_extension_remote, + mojo::PendingReceiver<media::mojom::Renderer> receiver, + mojo::PendingReceiver<media::mojom::MediaPlayerRendererExtension> + renderer_extension_receiver) override {} + void CreateFlingingRenderer( + const std::string& presentation_id, + mojo::PendingRemote<media::mojom::FlingingRendererClientExtension> + client_extension, + mojo::PendingReceiver<media::mojom::Renderer> receiver) override {} +#endif // defined(OS_ANDROID + void CreateCdm(const std::string& key_system, + mojo::PendingReceiver<media::mojom::ContentDecryptionModule> + receiver) override {} + + private: + media::MojoCdmServiceContext cdm_service_context_; + FakeMojoMediaClient mojo_media_client_; + mojo::Receiver<media::mojom::InterfaceFactory> receiver_{this}; + mojo::UniqueReceiverSet<media::mojom::VideoDecoder> video_decoder_receivers_; +}; + +} // namespace + +class VideoDecoderBrokerTest : public testing::Test { + public: + VideoDecoderBrokerTest() = default; + ~VideoDecoderBrokerTest() override { + if (media_thread_) + media_thread_->Stop(); + } + + void OnInitWithClosure(base::RepeatingClosure done_cb, media::Status status) { + OnInit(status); + done_cb.Run(); + } + void OnDecodeDoneWithClosure(base::RepeatingClosure done_cb, + media::DecodeStatus status) { + OnDecodeDone(status); + done_cb.Run(); + } + + void OnResetDoneWithClosure(base::RepeatingClosure done_cb) { + OnResetDone(); + done_cb.Run(); + } + + MOCK_METHOD1(OnInit, void(media::Status status)); + MOCK_METHOD1(OnDecodeDone, void(media::DecodeStatus)); + MOCK_METHOD0(OnResetDone, void()); + + void OnOutput(scoped_refptr<media::VideoFrame> frame) { + output_frames_.push_back(std::move(frame)); + } + + void SetupMojo(ExecutionContext& execution_context) { + // Register FakeInterfaceFactory as impl for media::mojom::InterfaceFactory + // required by MojoVideoDecoder. The factory will vend FakeGpuVideoDecoders + // that simulate gpu-accelerated decode. + interface_factory_ = std::make_unique<FakeInterfaceFactory>(); + EXPECT_TRUE( + execution_context.GetBrowserInterfaceBroker().SetBinderForTesting( + media::mojom::InterfaceFactory::Name_, + WTF::BindRepeating(&FakeInterfaceFactory::BindRequest, + base::Unretained(interface_factory_.get())))); + + // |gpu_factories_| requires API calls be made using it's GetTaskRunner(). + // We use a separate |media_thread_| (as opposed to a separate task runner + // on the main thread) to simulate cross-thread production behavior. + media_thread_ = std::make_unique<base::Thread>("media_thread"); + media_thread_->Start(); + + // |gpu_factories_| is a dependency of MojoVideoDecoder (and associated code + // paths). Setup |gpu_factories_| to say "yes" to any decoder config to + // ensure MojoVideoDecoder will be selected as the underlying decoder upon + // VideoDecoderBroker::Initialize(). The + gpu_factories_ = + std::make_unique<media::MockGpuVideoAcceleratorFactories>(nullptr); + EXPECT_CALL(*gpu_factories_, GetTaskRunner()) + .WillRepeatedly(Return(media_thread_->task_runner())); + EXPECT_CALL(*gpu_factories_, IsDecoderConfigSupported(_, _)) + .WillRepeatedly( + Return(media::GpuVideoAcceleratorFactories::Supported::kTrue)); + } + + void ConstructDecoder(ExecutionContext& execution_context) { + decoder_broker_ = std::make_unique<VideoDecoderBroker>( + execution_context, gpu_factories_.get()); + } + + void InitializeDecoder(media::VideoDecoderConfig config) { + base::RunLoop run_loop; + EXPECT_CALL(*this, OnInit(media::SameStatusCode(media::OkStatus()))); + decoder_broker_->Initialize( + config, false /*low_delay*/, nullptr /* cdm_context */, + WTF::Bind(&VideoDecoderBrokerTest::OnInitWithClosure, + WTF::Unretained(this), run_loop.QuitClosure()), + WTF::BindRepeating(&VideoDecoderBrokerTest::OnOutput, + WTF::Unretained(this)), + media::WaitingCB()); + run_loop.Run(); + testing::Mock::VerifyAndClearExpectations(this); + } + + void DecodeBuffer( + scoped_refptr<media::DecoderBuffer> buffer, + media::DecodeStatus expected_status = media::DecodeStatus::OK) { + base::RunLoop run_loop; + EXPECT_CALL(*this, OnDecodeDone(expected_status)); + decoder_broker_->Decode( + buffer, WTF::Bind(&VideoDecoderBrokerTest::OnDecodeDoneWithClosure, + WTF::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + testing::Mock::VerifyAndClearExpectations(this); + } + + void ResetDecoder() { + base::RunLoop run_loop; + EXPECT_CALL(*this, OnResetDone()); + decoder_broker_->Reset( + WTF::Bind(&VideoDecoderBrokerTest::OnResetDoneWithClosure, + WTF::Unretained(this), run_loop.QuitClosure())); + run_loop.Run(); + testing::Mock::VerifyAndClearExpectations(this); + } + + std::string GetDisplayName() { return decoder_broker_->GetDisplayName(); } + + bool IsPlatformDecoder() { return decoder_broker_->IsPlatformDecoder(); } + + bool NeedsBitstreamConversion() { + return decoder_broker_->NeedsBitstreamConversion(); + } + + bool CanReadWithoutStalling() { + return decoder_broker_->CanReadWithoutStalling(); + } + + int GetMaxDecodeRequests() { return decoder_broker_->GetMaxDecodeRequests(); } + + protected: + std::unique_ptr<VideoDecoderBroker> decoder_broker_; + std::vector<scoped_refptr<media::VideoFrame>> output_frames_; + std::unique_ptr<media::MockGpuVideoAcceleratorFactories> gpu_factories_; + std::unique_ptr<FakeInterfaceFactory> interface_factory_; + std::unique_ptr<base::Thread> media_thread_; +}; + +TEST_F(VideoDecoderBrokerTest, Decode_Uninitialized) { + V8TestingScope v8_scope; + + ConstructDecoder(*v8_scope.GetExecutionContext()); + EXPECT_EQ(GetDisplayName(), "EmptyWebCodecsVideoDecoder"); + + // No call to Initialize. Other APIs should fail gracefully. + + DecodeBuffer(media::ReadTestDataFile("vp8-I-frame-320x120"), + media::DecodeStatus::DECODE_ERROR); + DecodeBuffer(media::DecoderBuffer::CreateEOSBuffer(), + media::DecodeStatus::DECODE_ERROR); + ASSERT_EQ(0U, output_frames_.size()); + + ResetDecoder(); +} + +TEST_F(VideoDecoderBrokerTest, Decode_NoMojoDecoder) { + V8TestingScope v8_scope; + + ConstructDecoder(*v8_scope.GetExecutionContext()); + EXPECT_EQ(GetDisplayName(), "EmptyWebCodecsVideoDecoder"); + + InitializeDecoder(media::TestVideoConfig::Normal()); + EXPECT_NE(GetDisplayName(), "EmptyWebCodecsVideoDecoder"); + + DecodeBuffer(media::ReadTestDataFile("vp8-I-frame-320x120")); + DecodeBuffer(media::DecoderBuffer::CreateEOSBuffer()); + ASSERT_EQ(1U, output_frames_.size()); + + ResetDecoder(); + + DecodeBuffer(media::ReadTestDataFile("vp8-I-frame-320x120")); + DecodeBuffer(media::DecoderBuffer::CreateEOSBuffer()); + ASSERT_EQ(2U, output_frames_.size()); + + ResetDecoder(); +} + +#if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) +TEST_F(VideoDecoderBrokerTest, Decode_WithMojoDecoder) { + V8TestingScope v8_scope; + ExecutionContext* execution_context = v8_scope.GetExecutionContext(); + + SetupMojo(*execution_context); + ConstructDecoder(*execution_context); + EXPECT_EQ(GetDisplayName(), "EmptyWebCodecsVideoDecoder"); + + media::VideoDecoderConfig config = media::TestVideoConfig::Normal(); + InitializeDecoder(config); + EXPECT_EQ(GetDisplayName(), "MojoVideoDecoder"); + + DecodeBuffer(media::CreateFakeVideoBufferForTest( + config, base::TimeDelta(), base::TimeDelta::FromMilliseconds(33))); + DecodeBuffer(media::DecoderBuffer::CreateEOSBuffer()); + ASSERT_EQ(1U, output_frames_.size()); + + // Backing FakeVideoDecoder will return interesting values for these APIs. + EXPECT_TRUE(IsPlatformDecoder()); + EXPECT_TRUE(NeedsBitstreamConversion()); + EXPECT_FALSE(CanReadWithoutStalling()); + EXPECT_EQ(GetMaxDecodeRequests(), 13); + + ResetDecoder(); +} +#endif // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER) + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl index 5335bbaebd5..fb4a05fc46e 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl @@ -5,6 +5,6 @@ // https://github.com/WICG/web-codecs dictionary VideoDecoderInit { - VideoDecoderOutputCallback output; + VideoFrameOutputCallback output; WebCodecsErrorCallback error; }; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.cc index 1d2b924a8d7..ce04e3957e7 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.cc +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.cc @@ -19,9 +19,9 @@ #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/v8_dom_exception.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_config.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_encode_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_init.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_tune_options.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/streams/readable_stream.h" #include "third_party/blink/renderer/core/streams/writable_stream.h" @@ -32,73 +32,64 @@ namespace blink { -namespace { - -ScriptPromise RejectedPromise(ScriptState* script_state, - DOMExceptionCode code, - const String& message) { - return ScriptPromise::RejectWithDOMException( - script_state, MakeGarbageCollected<DOMException>(code, message)); -} - -} // namespace - // static VideoEncoder* VideoEncoder::Create(ScriptState* script_state, + const VideoEncoderInit* init, ExceptionState& exception_state) { - return MakeGarbageCollected<VideoEncoder>(script_state, exception_state); + return MakeGarbageCollected<VideoEncoder>(script_state, init, + exception_state); } VideoEncoder::VideoEncoder(ScriptState* script_state, + const VideoEncoderInit* init, ExceptionState& exception_state) - : script_state_(script_state) {} - -VideoEncoder::~VideoEncoder() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + : script_state_(script_state) { + output_callback_ = init->output(); + if (init->hasError()) + error_callback_ = init->error(); } -ScriptPromise VideoEncoder::tune(const VideoEncoderTuneOptions* params, - ExceptionState&) { +VideoEncoder::~VideoEncoder() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return RejectedPromise(script_state_, DOMExceptionCode::kNotSupportedError, - "tune() is not implemented yet"); } -ScriptPromise VideoEncoder::configure(const VideoEncoderInit* init, - ExceptionState& exception_state) { +void VideoEncoder::configure(const VideoEncoderConfig* config, + ExceptionState& exception_state) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - auto* tune_options = init->tuneOptions(); - DCHECK(tune_options); - if (tune_options->height() == 0) { - return RejectedPromise(script_state_, DOMExceptionCode::kInvalidStateError, - "Invalid height."); + if (config->height() == 0) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "Invalid height."); + return; } - if (tune_options->width() == 0) { - return RejectedPromise(script_state_, DOMExceptionCode::kInvalidStateError, - "Invalid width."); + if (config->width() == 0) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "Invalid width."); + return; } Request* request = MakeGarbageCollected<Request>(); request->type = Request::Type::kConfigure; - request->config = init; - return EnqueueRequest(request); + request->config = config; + EnqueueRequest(request); } -ScriptPromise VideoEncoder::encode(const VideoFrame* frame, - const VideoEncoderEncodeOptions* opts, - ExceptionState&) { +void VideoEncoder::encode(const VideoFrame* frame, + const VideoEncoderEncodeOptions* opts, + ExceptionState& exception_state) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!media_encoder_) { - return RejectedPromise(script_state_, DOMExceptionCode::kInvalidStateError, - "Encoder is not configured yet."); + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "Encoder is not configured yet."); + return; } if (frame->visibleWidth() != uint32_t{frame_size_.width()} || frame->visibleHeight() != uint32_t{frame_size_.height()}) { - return RejectedPromise( - script_state_, DOMExceptionCode::kOperationError, + exception_state.ThrowDOMException( + DOMExceptionCode::kOperationError, "Frame size doesn't match initial encoder parameters."); + return; } Request* request = MakeGarbageCollected<Request>(); @@ -108,26 +99,46 @@ ScriptPromise VideoEncoder::encode(const VideoFrame* frame, return EnqueueRequest(request); } -ScriptPromise VideoEncoder::close() { +void VideoEncoder::close(ExceptionState& exception_state) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!media_encoder_) - return ScriptPromise::CastUndefined(script_state_); + return; - Request* request = MakeGarbageCollected<Request>(); - request->type = Request::Type::kClose; - return EnqueueRequest(request); + reset(exception_state); + media_encoder_.reset(); + output_callback_.Clear(); + error_callback_.Clear(); } -ScriptPromise VideoEncoder::flush() { +ScriptPromise VideoEncoder::flush(ExceptionState&) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!media_encoder_) { - return RejectedPromise(script_state_, DOMExceptionCode::kInvalidStateError, - "Encoder is not configured yet."); + auto* ex = MakeGarbageCollected<DOMException>( + DOMExceptionCode::kInvalidStateError, "Encoder is not configured yet."); + return ScriptPromise::RejectWithDOMException(script_state_, ex); } Request* request = MakeGarbageCollected<Request>(); + request->resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state_); request->type = Request::Type::kFlush; - return EnqueueRequest(request); + EnqueueRequest(request); + return request->resolver->Promise(); +} + +void VideoEncoder::reset(ExceptionState&) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // TODO: Not fully implemented yet + + while (!requests_.empty()) { + Request* pending_req = requests_.TakeFirst(); + DCHECK(pending_req); + if (pending_req->resolver) { + auto* ex = MakeGarbageCollected<DOMException>( + DOMExceptionCode::kOperationError, "reset() was called."); + pending_req->resolver.Release()->Reject(ex); + } + } } void VideoEncoder::CallOutputCallback(EncodedVideoChunk* chunk) { @@ -144,16 +155,17 @@ void VideoEncoder::CallErrorCallback(DOMException* ex) { error_callback_->InvokeAndReportException(nullptr, ex); } -ScriptPromise VideoEncoder::EnqueueRequest(Request* request) { - ScriptPromiseResolver* resolver = - MakeGarbageCollected<ScriptPromiseResolver>(script_state_); - request->resolver = resolver; +void VideoEncoder::CallErrorCallback(DOMExceptionCode code, + const String& message) { + auto* ex = MakeGarbageCollected<DOMException>(code, message); + CallErrorCallback(ex); +} + +void VideoEncoder::EnqueueRequest(Request* request) { requests_.push_back(request); if (requests_.size() == 1) ProcessRequests(); - - return resolver->Promise(); } void VideoEncoder::ProcessRequests() { @@ -162,7 +174,6 @@ void VideoEncoder::ProcessRequests() { Request* request = requests_.TakeFirst(); DCHECK(request); - DCHECK(request->resolver); switch (request->type) { case Request::Type::kConfigure: ProcessConfigure(request); @@ -173,9 +184,6 @@ void VideoEncoder::ProcessRequests() { case Request::Type::kFlush: ProcessFlush(request); break; - case Request::Type::kClose: - ProcessClose(request); - break; default: NOTREACHED(); } @@ -188,22 +196,18 @@ void VideoEncoder::ProcessEncode(Request* request) { auto done_callback = [](VideoEncoder* self, Request* req, media::Status status) { - DCHECK(req->resolver); if (!self) return; DCHECK_CALLED_ON_VALID_SEQUENCE(self->sequence_checker_); - if (status.is_ok()) { - req->Resolve(); - } else { + if (!status.is_ok()) { std::string msg = "Encoding error: " + status.message(); - auto* ex = req->Reject(DOMExceptionCode::kOperationError, msg.c_str()); - self->CallErrorCallback(ex); + self->CallErrorCallback(DOMExceptionCode::kOperationError, msg.c_str()); } self->ProcessRequests(); }; - bool keyframe = - request->encodeOpts->hasKeyFrame() && request->encodeOpts->keyFrame(); + bool keyframe = request->encodeOpts->hasKeyFrameNonNull() && + request->encodeOpts->keyFrameNonNull(); media_encoder_->Encode(request->frame->frame(), keyframe, WTF::Bind(done_callback, WrapWeakPersistent(this), WrapPersistentIfNeeded(request))); @@ -213,16 +217,17 @@ void VideoEncoder::ProcessConfigure(Request* request) { DCHECK(request->config); DCHECK_EQ(request->type, Request::Type::kConfigure); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auto* config = request->config.Get(); if (media_encoder_) { - request->Reject(DOMExceptionCode::kOperationError, - "Encoder has already been congfigured"); + CallErrorCallback(DOMExceptionCode::kOperationError, + "Encoder has already been congfigured"); return; } - auto codec_type = media::StringToVideoCodec(request->config->codec().Utf8()); + auto codec_type = media::StringToVideoCodec(config->codec().Utf8()); if (codec_type == media::kUnknownVideoCodec) { - request->Reject(DOMExceptionCode::kNotFoundError, "Unknown codec type"); + CallErrorCallback(DOMExceptionCode::kNotFoundError, "Unknown codec type"); return; } media::VideoCodecProfile profile = media::VIDEO_CODEC_PROFILE_UNKNOWN; @@ -233,9 +238,10 @@ void VideoEncoder::ProcessConfigure(Request* request) { } else if (codec_type == media::kCodecVP9) { uint8_t level = 0; media::VideoColorSpace color_space; - if (!ParseNewStyleVp9CodecID(request->config->profile().Utf8(), &profile, - &level, &color_space)) { - request->Reject(DOMExceptionCode::kNotFoundError, "Invalid vp9 profile"); + if (!ParseNewStyleVp9CodecID(config->profile().Utf8(), &profile, &level, + &color_space)) { + CallErrorCallback(DOMExceptionCode::kNotFoundError, + "Invalid vp9 profile"); return; } media_encoder_ = std::make_unique<media::VpxVideoEncoder>(); @@ -243,63 +249,41 @@ void VideoEncoder::ProcessConfigure(Request* request) { #endif // BUILDFLAG(ENABLE_LIBVPX) if (!media_encoder_) { - request->Reject(DOMExceptionCode::kNotFoundError, "Unsupported codec type"); + CallErrorCallback(DOMExceptionCode::kNotFoundError, + "Unsupported codec type"); return; } - auto* tune_options = request->config->tuneOptions(); - output_callback_ = request->config->output(); - error_callback_ = request->config->error(); - frame_size_ = gfx::Size(tune_options->width(), tune_options->height()); + frame_size_ = gfx::Size(config->width(), config->height()); auto output_cb = WTF::BindRepeating(&VideoEncoder::MediaEncoderOutputCallback, WrapWeakPersistent(this)); auto done_callback = [](VideoEncoder* self, Request* req, media::Status status) { - DCHECK(req->resolver); if (!self) return; DCHECK_CALLED_ON_VALID_SEQUENCE(self->sequence_checker_); - if (status.is_ok()) { - req->Resolve(); - } else { + if (!status.is_ok()) { self->media_encoder_.reset(); self->output_callback_.Clear(); self->error_callback_.Clear(); std::string msg = "Encoder initialization error: " + status.message(); - req->Reject(DOMExceptionCode::kOperationError, msg.c_str()); + self->CallErrorCallback(DOMExceptionCode::kOperationError, msg.c_str()); } }; media::VideoEncoder::Options options; - options.bitrate = tune_options->bitrate(); + options.bitrate = config->bitrate(); options.height = frame_size_.height(); options.width = frame_size_.width(); - options.framerate = tune_options->framerate(); + options.framerate = config->framerate(); options.threads = 1; media_encoder_->Initialize(profile, options, output_cb, WTF::Bind(done_callback, WrapWeakPersistent(this), WrapPersistent(request))); } -void VideoEncoder::ProcessClose(Request* request) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(request->type, Request::Type::kClose); - - media_encoder_.reset(); - output_callback_.Clear(); - error_callback_.Clear(); - request->Resolve(); - - while (!requests_.empty()) { - Request* pending_req = requests_.TakeFirst(); - DCHECK(pending_req); - DCHECK(pending_req->resolver); - pending_req->Reject(DOMExceptionCode::kOperationError, "Encoder closed."); - } -} - void VideoEncoder::ProcessFlush(Request* request) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(request->type, Request::Type::kFlush); @@ -312,11 +296,13 @@ void VideoEncoder::ProcessFlush(Request* request) { return; DCHECK_CALLED_ON_VALID_SEQUENCE(self->sequence_checker_); if (status.is_ok()) { - req->Resolve(); + req->resolver.Release()->Resolve(); } else { std::string msg = "Flushing error: " + status.message(); - auto* ex = req->Reject(DOMExceptionCode::kOperationError, msg.c_str()); + auto* ex = MakeGarbageCollected<DOMException>( + DOMExceptionCode::kOperationError, msg.c_str()); self->CallErrorCallback(ex); + req->resolver.Release()->Reject(ex); } self->ProcessRequests(); }; @@ -339,7 +325,7 @@ void VideoEncoder::MediaEncoderOutputCallback( CallOutputCallback(chunk); } -void VideoEncoder::Trace(Visitor* visitor) { +void VideoEncoder::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(output_callback_); visitor->Trace(error_callback_); @@ -347,21 +333,11 @@ void VideoEncoder::Trace(Visitor* visitor) { ScriptWrappable::Trace(visitor); } -void VideoEncoder::Request::Trace(Visitor* visitor) { +void VideoEncoder::Request::Trace(Visitor* visitor) const { visitor->Trace(config); visitor->Trace(frame); visitor->Trace(encodeOpts); visitor->Trace(resolver); } -DOMException* VideoEncoder::Request::Reject(DOMExceptionCode code, - const String& message) { - auto* ex = MakeGarbageCollected<DOMException>(code, message); - resolver.Release()->Reject(ex); - return ex; -} -void VideoEncoder::Request::Resolve() { - resolver.Release()->Resolve(); -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.h index 36702a7eb65..9524e840329 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.h +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.h @@ -25,8 +25,8 @@ namespace blink { class ExceptionState; enum class DOMExceptionCode; +class VideoEncoderConfig; class VideoEncoderInit; -class VideoEncoderTuneOptions; class VideoEncoderEncodeOptions; class Visitor; @@ -34,25 +34,27 @@ class MODULES_EXPORT VideoEncoder final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - static VideoEncoder* Create(ScriptState*, ExceptionState&); - VideoEncoder(ScriptState*, ExceptionState&); + static VideoEncoder* Create(ScriptState*, + const VideoEncoderInit*, + ExceptionState&); + VideoEncoder(ScriptState*, const VideoEncoderInit*, ExceptionState&); ~VideoEncoder() override; // video_encoder.idl implementation. - ScriptPromise encode(const VideoFrame* frame, - const VideoEncoderEncodeOptions*, - ExceptionState&); + void encode(const VideoFrame* frame, + const VideoEncoderEncodeOptions*, + ExceptionState&); - ScriptPromise configure(const VideoEncoderInit* init, ExceptionState&); + void configure(const VideoEncoderConfig*, ExceptionState&); - ScriptPromise tune(const VideoEncoderTuneOptions* params, ExceptionState&); + ScriptPromise flush(ExceptionState&); - ScriptPromise close(); + void reset(ExceptionState&); - ScriptPromise flush(); + void close(ExceptionState&); // GarbageCollected override. - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: struct Request : public GarbageCollected<Request> { @@ -60,27 +62,24 @@ class MODULES_EXPORT VideoEncoder final : public ScriptWrappable { kConfigure, kEncode, kFlush, - kClose, }; - void Trace(Visitor*); - DOMException* Reject(DOMExceptionCode code, const String& message); - void Resolve(); + void Trace(Visitor*) const; Type type; - Member<const VideoEncoderInit> config; // used by kConfigure + Member<const VideoEncoderConfig> config; // used by kConfigure Member<const VideoFrame> frame; // used by kEncode Member<const VideoEncoderEncodeOptions> encodeOpts; // used by kEncode - Member<ScriptPromiseResolver> resolver; + Member<ScriptPromiseResolver> resolver; // used by kFlush }; void CallOutputCallback(EncodedVideoChunk* chunk); void CallErrorCallback(DOMException* ex); - ScriptPromise EnqueueRequest(Request* request); + void CallErrorCallback(DOMExceptionCode code, const String& message); + void EnqueueRequest(Request* request); void ProcessRequests(); void ProcessEncode(Request* request); void ProcessConfigure(Request* request); - void ProcessClose(Request* request); void ProcessFlush(Request* request); void MediaEncoderOutputCallback(media::VideoEncoderOutput output); diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.idl index f5db564e8ce..a9b518b563d 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.idl +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.idl @@ -9,15 +9,14 @@ RuntimeEnabled=WebCodecs ] interface VideoEncoder { [CallWith=ScriptState, RaisesException] - constructor(); + constructor(VideoEncoderInit init); // Performs original configuration of the encoder. // Resolved after configuration is done. It should be called only // once per encoder instance, before calling any other methods. [RaisesException] - Promise<void> configure(VideoEncoderInit init); + void configure(VideoEncoderConfig config); - [RaisesException] // Enqueues a request to encode a frame. // Results of the encoding (EncodedVideoChunk) are returned via // the output callback provided in configure(). @@ -25,23 +24,27 @@ // The output callback can be called before or after the result is resolved. // Several encoded requests can be resolved before even a single output // is produced. - Promise<void> encode(VideoFrame frame, + [RaisesException] + void encode(VideoFrame frame, optional VideoEncoderEncodeOptions options = {}); - [RaisesException] - // Enqueues a request to change certain parameters of the encoder. - // Resolved after the parameters are adjusted. - // All following encode requests will be executed according to - // the new parameters. - // Should be preceded by flush(). - Promise<void> tune(VideoEncoderTuneOptions options); // Enqueues a request to produce outputs for all already encoded frames. // Resolved after emitting outputs for all previously encoded frames. + [RaisesException] Promise<void> flush(); + // Discard all pending work and current encoder configuration. + // + // Output for earlier encoding requests will not be emitted. + // The next encoded frame will be a keyframe. + // Required a configure() to be call to set configuration once again. + [RaisesException] + void reset(); + // Enqueues a request to shut down the encoder and free its resources. // Resolved after all resources are released and all following requests // rejected. - Promise<void> close(); + [RaisesException] + void close(); }; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_tune_options.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_config.idl index b972f9748c5..460590a8125 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_tune_options.idl +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_config.idl @@ -4,7 +4,10 @@ // https://github.com/WICG/web-codecs -dictionary VideoEncoderTuneOptions { +dictionary VideoEncoderConfig { + required DOMString codec; + DOMString profile; + unsigned long long bitrate; double framerate; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_init.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_init.idl index 83ec4c88cb7..1e4e69c89dd 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_init.idl +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_encoder_init.idl @@ -5,11 +5,6 @@ // https://github.com/WICG/web-codecs dictionary VideoEncoderInit { - required DOMString codec; - DOMString profile; - - required VideoEncoderTuneOptions tuneOptions; - // Called whenever there is a new encoded video chunk available. required VideoEncoderOutputCallback output; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.cc index 8b490eb5d0e..d099cc5a492 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.cc +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.cc @@ -6,12 +6,23 @@ #include <utility> +#include "components/viz/common/gpu/raster_context_provider.h" +#include "components/viz/common/resources/single_release_callback.h" +#include "gpu/command_buffer/client/shared_image_interface.h" #include "media/base/video_frame.h" #include "media/base/video_frame_metadata.h" +#include "media/renderers/paint_canvas_video_renderer.h" +#include "media/renderers/yuv_util.h" +#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_init.h" #include "third_party/blink/renderer/core/html/canvas/image_data.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" +#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_factories.h" +#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h" +#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" #include "third_party/blink/renderer/platform/graphics/image.h" +#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" +#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h" #include "third_party/libyuv/include/libyuv.h" namespace blink { @@ -36,11 +47,9 @@ uint64_t VideoFrame::timestamp() const { } base::Optional<uint64_t> VideoFrame::duration() const { - base::TimeDelta result; - if (frame_->metadata()->GetTimeDelta( - media::VideoFrameMetadata::FRAME_DURATION, &result)) { - return result.InMicroseconds(); - } + if (frame_ && frame_->metadata()->frame_duration.has_value()) + return frame_->metadata()->frame_duration->InMicroseconds(); + return base::Optional<uint64_t>(); } @@ -124,8 +133,116 @@ VideoFrame* VideoFrame::Create(VideoFrameInit* init, "ARGB to YUV420 conversion error"); return nullptr; } + // TODO(jie.a.chen@intel.com): Figure out the right colorspace and conversion + // according to source ImageBitmap. + // libyuv::ABGRToI420 seems to assume Bt.601. + frame->set_color_space(gfx::ColorSpace::CreateREC601()); auto* result = MakeGarbageCollected<VideoFrame>(std::move(frame)); return result; } +ScriptPromise VideoFrame::createImageBitmap(ScriptState* script_state, + const ImageBitmapOptions* options, + ExceptionState& exception_state) { + return ImageBitmapFactories::CreateImageBitmap( + script_state, this, base::Optional<IntRect>(), options, exception_state); +} + +IntSize VideoFrame::BitmapSourceSize() const { + return IntSize(visibleWidth(), visibleHeight()); +} + +bool VideoFrame::preferAcceleratedImageBitmap() const { + return BitmapSourceSize().Area() > kCpuEfficientFrameSize || + frame_->HasTextures(); +} + +ScriptPromise VideoFrame::CreateImageBitmap(ScriptState* script_state, + base::Optional<IntRect> crop_rect, + const ImageBitmapOptions* options, + ExceptionState& exception_state) { + if ((frame_->IsMappable() || frame_->HasTextures()) && + (frame_->format() == media::PIXEL_FORMAT_I420 || + (frame_->format() == media::PIXEL_FORMAT_NV12 && + frame_->HasTextures()))) { + scoped_refptr<StaticBitmapImage> image; + if (!preferAcceleratedImageBitmap()) { + size_t bytes_per_row = sizeof(SkColor) * visibleWidth(); + size_t image_pixels_size = bytes_per_row * visibleHeight(); + + sk_sp<SkData> image_pixels = TryAllocateSkData(image_pixels_size); + if (!image_pixels) { + exception_state.ThrowDOMException(DOMExceptionCode::kBufferOverrunError, + "Out of memory."); + return ScriptPromise(); + } + media::PaintCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( + frame_.get(), image_pixels->writable_data(), bytes_per_row); + + // TODO(jie.a.chen@intel.com): Figure out the correct SkColorSpace. + sk_sp<SkColorSpace> skColorSpace = SkColorSpace::MakeSRGB(); + SkImageInfo info = + SkImageInfo::Make(visibleWidth(), visibleHeight(), kN32_SkColorType, + kUnpremul_SkAlphaType, std::move(skColorSpace)); + sk_sp<SkImage> skImage = + SkImage::MakeRasterData(info, image_pixels, bytes_per_row); + image = UnacceleratedStaticBitmapImage::Create(std::move(skImage)); + } else { + viz::RasterContextProvider* raster_context_provider = + Platform::Current()->SharedMainThreadContextProvider(); + gpu::SharedImageInterface* shared_image_interface = + raster_context_provider->SharedImageInterface(); + uint32_t usage = gpu::SHARED_IMAGE_USAGE_GLES2; + if (raster_context_provider->ContextCapabilities().supports_oop_raster) { + usage |= gpu::SHARED_IMAGE_USAGE_RASTER | + gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION; + } + + gpu::MailboxHolder dest_holder; + // Use coded_size() to comply with media::ConvertFromVideoFrameYUV. + dest_holder.mailbox = shared_image_interface->CreateSharedImage( + viz::ResourceFormat::RGBA_8888, frame_->coded_size(), + gfx::ColorSpace(), usage); + dest_holder.sync_token = shared_image_interface->GenUnverifiedSyncToken(); + dest_holder.texture_target = GL_TEXTURE_2D; + + media::ConvertFromVideoFrameYUV(frame_.get(), raster_context_provider, + dest_holder); + gpu::SyncToken sync_token; + raster_context_provider->RasterInterface() + ->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); + + auto release_callback = viz::SingleReleaseCallback::Create(base::BindOnce( + [](gpu::SharedImageInterface* sii, gpu::Mailbox mailbox, + const gpu::SyncToken& sync_token, bool is_lost) { + // Ideally the SharedImage could be release here this way: + // sii->DestroySharedImage(sync_token, mailbox); + // But AcceleratedStaticBitmapImage leaks it when + // PaintImageForCurrentFrame() is called by ImageBitmap. So the + // 'sync_token' is not precise to destroy the mailbox. + }, + base::Unretained(shared_image_interface), dest_holder.mailbox)); + + const SkImageInfo sk_image_info = + SkImageInfo::MakeN32Premul(codedWidth(), codedHeight()); + + image = AcceleratedStaticBitmapImage::CreateFromCanvasMailbox( + dest_holder.mailbox, sync_token, 0u, sk_image_info, + dest_holder.texture_target, true, + SharedGpuContext::ContextProviderWrapper(), + base::PlatformThread::CurrentRef(), + Thread::Current()->GetTaskRunner(), std::move(release_callback)); + } + + ImageBitmap* image_bitmap = + MakeGarbageCollected<ImageBitmap>(image, crop_rect, options); + return ImageBitmapSource::FulfillImageBitmap(script_state, image_bitmap, + exception_state); + } + + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + "Unsupported VideoFrame."); + return ScriptPromise(); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.h index 2fb76c8b00e..79e3978289a 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.h +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.h @@ -7,16 +7,19 @@ #include "base/optional.h" #include "media/base/video_frame.h" +#include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.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/wtf/text/wtf_string.h" namespace blink { class ImageBitmap; class ExceptionState; class VideoFrameInit; +class ScriptPromise; +class ScriptState; -class MODULES_EXPORT VideoFrame final : public ScriptWrappable { +class MODULES_EXPORT VideoFrame final : public ScriptWrappable, + public ImageBitmapSource { DEFINE_WRAPPERTYPEINFO(); public: @@ -24,6 +27,16 @@ class MODULES_EXPORT VideoFrame final : public ScriptWrappable { // video_frame.idl implementation. static VideoFrame* Create(VideoFrameInit*, ImageBitmap*, ExceptionState&); + ScriptPromise createImageBitmap(ScriptState*, + const ImageBitmapOptions*, + ExceptionState&); + + // ImageBitmapSource implementation + IntSize BitmapSourceSize() const override; + ScriptPromise CreateImageBitmap(ScriptState*, + base::Optional<IntRect> crop_rect, + const ImageBitmapOptions*, + ExceptionState&) override; uint64_t timestamp() const; base::Optional<uint64_t> duration() const; @@ -40,6 +53,8 @@ class MODULES_EXPORT VideoFrame final : public ScriptWrappable { scoped_refptr<const media::VideoFrame> frame() const; private: + static constexpr uint64_t kCpuEfficientFrameSize = 480u * 320u; + bool preferAcceleratedImageBitmap() const; scoped_refptr<media::VideoFrame> frame_; }; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl index aefb0b0c714..36438bdc6cf 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame.idl @@ -11,6 +11,9 @@ void release(); + [CallWith=ScriptState, RaisesException] Promise<ImageBitmap> createImageBitmap( + optional ImageBitmapOptions options = {}); + readonly attribute unsigned long long timestamp; // microseconds readonly attribute unsigned long long? duration; // microseconds diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_frame_output_callback.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame_output_callback.idl new file mode 100644 index 00000000000..c7ee06f4a54 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_frame_output_callback.idl @@ -0,0 +1,8 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://github.com/WICG/web-codecs + +[RuntimeEnabled=WebCodecs] +callback VideoFrameOutputCallback = void(VideoFrame output); diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc index d1b603f0dfb..2acbc624063 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.cc @@ -4,12 +4,10 @@ #include "third_party/blink/renderer/modules/webcodecs/video_track_reader.h" +#include "base/threading/thread_task_runner_handle.h" #include "media/base/video_frame.h" -#include "third_party/blink/public/web/modules/mediastream/media_stream_video_sink.h" #include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h" -#include "third_party/blink/renderer/core/streams/readable_stream.h" -#include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h" -#include "third_party/blink/renderer/core/streams/underlying_source_base.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/webcodecs/video_frame.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" @@ -18,70 +16,93 @@ namespace blink { -class VideoTrackReadableStreamSource final : public UnderlyingSourceBase, - public MediaStreamVideoSink { - public: - VideoTrackReadableStreamSource(ScriptState* script_state, - MediaStreamTrack* track) - : UnderlyingSourceBase(script_state), - task_runner_(ExecutionContext::From(script_state) - ->GetTaskRunner(TaskType::kInternalMedia)) { - ConnectToTrack(track->Component(), - ConvertToBaseRepeatingCallback(CrossThreadBindRepeating( - &VideoTrackReadableStreamSource::OnFrameFromVideoTrack, - WrapCrossThreadPersistent(this))), - false /* is_sink_secure */); +VideoTrackReader::VideoTrackReader(ScriptState* script_state, + MediaStreamTrack* track) + : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)), + started_(false), + real_time_media_task_runner_( + ExecutionContext::From(script_state) + ->GetTaskRunner(TaskType::kInternalMediaRealTime)), + track_(track) {} + +void VideoTrackReader::start(V8VideoFrameOutputCallback* callback, + ExceptionState& exception_state) { + DCHECK(real_time_media_task_runner_->BelongsToCurrentThread()); + + if (started_) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "The VideoTrackReader has already been started."); + return; } - // Callback of MediaStreamVideoSink::ConnectToTrack - void OnFrameFromVideoTrack(scoped_refptr<media::VideoFrame> media_frame, - base::TimeTicks estimated_capture_time) { - // The value of estimated_capture_time here seems to almost always be the - // system clock and most implementations of this callback ignore it. - // So, we will also ignore it. - DCHECK(media_frame); - PostCrossThreadTask( - *task_runner_.get(), FROM_HERE, - CrossThreadBindOnce( - &VideoTrackReadableStreamSource::OnFrameFromVideoTrackOnTaskRunner, - WrapCrossThreadPersistent(this), std::move(media_frame))); - } + started_ = true; + callback_ = callback; + ConnectToTrack(track_->Component(), + ConvertToBaseRepeatingCallback(CrossThreadBindRepeating( + &VideoTrackReader::OnFrameFromVideoTrack, + WrapCrossThreadPersistent(this))), + false /* is_sink_secure */); +} - void OnFrameFromVideoTrackOnTaskRunner( - scoped_refptr<media::VideoFrame> media_frame) { - Controller()->Enqueue( - MakeGarbageCollected<VideoFrame>(std::move(media_frame))); - } +void VideoTrackReader::stop(ExceptionState& exception_state) { + DCHECK(real_time_media_task_runner_->BelongsToCurrentThread()); - // MediaStreamVideoSink override - void OnReadyStateChanged(WebMediaStreamSource::ReadyState state) override { - if (state == WebMediaStreamSource::kReadyStateEnded) - Close(); + if (!started_) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "The VideoTrackReader has already been stopped."); + return; } - // UnderlyingSourceBase overrides. - ScriptPromise pull(ScriptState* script_state) override { - // Since video tracks are all push-based with no back pressure, there's - // nothing to do here. - return ScriptPromise::CastUndefined(script_state); - } + StopInternal(); +} - ScriptPromise Cancel(ScriptState* script_state, ScriptValue reason) override { - Close(); - return ScriptPromise::CastUndefined(script_state); - } +void VideoTrackReader::StopInternal() { + DCHECK(real_time_media_task_runner_->BelongsToCurrentThread()); + started_ = false; + callback_ = nullptr; + DisconnectFromTrack(); +} + +void VideoTrackReader::OnFrameFromVideoTrack( + scoped_refptr<media::VideoFrame> media_frame, + base::TimeTicks estimated_capture_time) { + // The value of estimated_capture_time here seems to almost always be the + // system clock and most implementations of this callback ignore it. + // So, we will also ignore it. + DCHECK(media_frame); + PostCrossThreadTask( + *real_time_media_task_runner_.get(), FROM_HERE, + CrossThreadBindOnce(&VideoTrackReader::ExecuteCallbackOnMainThread, + WrapCrossThreadPersistent(this), + std::move(media_frame))); +} - void ContextDestroyed() override { DisconnectFromTrack(); } +void VideoTrackReader::ExecuteCallbackOnMainThread( + scoped_refptr<media::VideoFrame> media_frame) { + DCHECK(real_time_media_task_runner_->BelongsToCurrentThread()); - void Close() { - if (Controller()) - Controller()->Close(); - DisconnectFromTrack(); + if (!callback_) { + // We may have already been stopped. + return; } - // VideoFrames will be queue on this task runner. - const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; -}; + // If |track_|'s constraints changed (e.g. the resolution changed from a call + // to MediaStreamTrack.applyConstraints() in JS), this |media_frame| might + // still have the old constraints, due to the thread hop. + // We may want to invalidate |media_frames| when constraints change, but it's + // unclear whether this is a problem for now. + + callback_->InvokeAndReportException( + nullptr, MakeGarbageCollected<VideoFrame>(std::move(media_frame))); +} + +void VideoTrackReader::OnReadyStateChanged( + WebMediaStreamSource::ReadyState state) { + if (state == WebMediaStreamSource::kReadyStateEnded) + StopInternal(); +} VideoTrackReader* VideoTrackReader::Create(ScriptState* script_state, MediaStreamTrack* track, @@ -99,23 +120,14 @@ VideoTrackReader* VideoTrackReader::Create(ScriptState* script_state, return nullptr; } - auto* source = - MakeGarbageCollected<VideoTrackReadableStreamSource>(script_state, track); - auto* readable = - ReadableStream::CreateWithCountQueueingStrategy(script_state, source, 0); - return MakeGarbageCollected<VideoTrackReader>(readable); -} - -VideoTrackReader::VideoTrackReader(ReadableStream* readable) - : readable_(readable) {} - -ReadableStream* VideoTrackReader::readable() const { - return readable_; + return MakeGarbageCollected<VideoTrackReader>(script_state, track); } -void VideoTrackReader::Trace(Visitor* visitor) { - visitor->Trace(readable_); +void VideoTrackReader::Trace(Visitor* visitor) const { + visitor->Trace(track_); + visitor->Trace(callback_); ScriptWrappable::Trace(visitor); + ExecutionContextLifecycleObserver::Trace(visitor); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.h index 1928a08ba6f..0d888b777ee 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.h +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.h @@ -5,32 +5,65 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_TRACK_READER_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_TRACK_READER_H_ +#include "third_party/blink/public/web/modules/mediastream/media_stream_video_sink.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame_output_callback.h" +#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" #include "third_party/blink/renderer/modules/mediastream/media_stream_track.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" namespace blink { -class ReadableStream; class ScriptState; -class MODULES_EXPORT VideoTrackReader final : public ScriptWrappable { +class MODULES_EXPORT VideoTrackReader final + : public ScriptWrappable, + public ExecutionContextLifecycleObserver, + public MediaStreamVideoSink { DEFINE_WRAPPERTYPEINFO(); + USING_GARBAGE_COLLECTED_MIXIN(VideoTrackReader); public: - static VideoTrackReader* Create(ScriptState* script_state, - MediaStreamTrack* track, - ExceptionState& exception_state); - explicit VideoTrackReader(ReadableStream* readable); - ReadableStream* readable() const; + static VideoTrackReader* Create(ScriptState*, + MediaStreamTrack*, + ExceptionState&); + VideoTrackReader(ScriptState*, MediaStreamTrack*); - void Trace(Visitor* visitor) override; + // Connects |this| to |track_| and starts delivering frames via |callback_|. + void start(V8VideoFrameOutputCallback*, ExceptionState&); + + // Disconnects from |track_| and clears |callback_|. + void stop(ExceptionState&); + + void Trace(Visitor* visitor) const override; private: VideoTrackReader(const VideoTrackReader&) = delete; VideoTrackReader& operator=(const VideoTrackReader&) = delete; - Member<ReadableStream> readable_; + // ExecutionContextLifecycleObserver implementation. + void ContextDestroyed() override { DisconnectFromTrack(); } + + // MediaStreamVideoSink implementation. + void OnReadyStateChanged(WebMediaStreamSource::ReadyState) override; + + // Callback For MediaStreamVideoSink::ConnectToTrack. + void OnFrameFromVideoTrack(scoped_refptr<media::VideoFrame> media_frame, + base::TimeTicks estimated_capture_time); + + void StopInternal(); + + void ExecuteCallbackOnMainThread( + scoped_refptr<media::VideoFrame> media_frame); + + // Whether we are connected to |track_| and using |callback_| to deliver + // frames. + bool started_; + + const scoped_refptr<base::SingleThreadTaskRunner> + real_time_media_task_runner_; + Member<V8VideoFrameOutputCallback> callback_; + Member<MediaStreamTrack> track_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.idl b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.idl index bb98fde5c46..6c47c378e2f 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.idl +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader.idl @@ -10,5 +10,10 @@ ] interface VideoTrackReader { [CallWith=ScriptState, RaisesException] constructor(MediaStreamTrack track); - readonly attribute ReadableStream readable; // of VideoFrame + + [RaisesException] + void start(VideoFrameOutputCallback callback); + + [RaisesException] + void stop(); }; diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc index f576da4559f..c784aa6b4dd 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_reader_writer_test.cc @@ -3,7 +3,9 @@ // found in the LICENSE file. #include "base/run_loop.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_frame.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_track_writer_parameters.h" @@ -15,10 +17,27 @@ #include "third_party/blink/renderer/modules/webcodecs/video_track_writer.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/to_v8.h" #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" namespace blink { +class MockFunction : public ScriptFunction { + public: + static testing::StrictMock<MockFunction>* Create(ScriptState* script_state) { + return MakeGarbageCollected<testing::StrictMock<MockFunction>>( + script_state); + } + + v8::Local<v8::Function> Bind() { return BindToV8Function(); } + + MOCK_METHOD1(Call, ScriptValue(ScriptValue)); + + protected: + explicit MockFunction(ScriptState* script_state) + : ScriptFunction(script_state) {} +}; + class VideoTrackReaderWriterTest : public testing::Test { public: void TearDown() override { @@ -42,6 +61,10 @@ class VideoTrackReaderWriterTest : public testing::Test { base::RunLoop().RunUntilIdle(); } + V8VideoFrameOutputCallback* GetCallback(MockFunction* function) { + return V8VideoFrameOutputCallback::Create(function->Bind()); + } + private: ScopedTestingPlatformSupport<IOTaskRunnerTestingPlatformSupport> platform_; }; @@ -54,9 +77,13 @@ TEST_F(VideoTrackReaderWriterTest, WriteAndRead) { params.setReleaseFrames(false); auto* writer = VideoTrackWriter::Create(script_state, ¶ms, ASSERT_NO_EXCEPTION); + + auto* read_output_function = MockFunction::Create(script_state); auto* reader = VideoTrackReader::Create(script_state, writer->track(), ASSERT_NO_EXCEPTION); + reader->start(GetCallback(read_output_function), ASSERT_NO_EXCEPTION); + auto* frame = CreateBlackVideoFrame(); writer->writable() ->getWriter(script_state, ASSERT_NO_EXCEPTION) @@ -64,24 +91,23 @@ TEST_F(VideoTrackReaderWriterTest, WriteAndRead) { ScriptValue(scope.GetIsolate(), ToV8(frame, script_state)), ASSERT_NO_EXCEPTION); - auto read_promise = reader->readable() - ->getReader(script_state, ASSERT_NO_EXCEPTION) - ->read(script_state, ASSERT_NO_EXCEPTION); - auto v8_read_promise = read_promise.V8Value().As<v8::Promise>(); - - EXPECT_EQ(v8::Promise::kPending, v8_read_promise->State()); + ScriptValue v8_frame; + // We don't care about Call()'s return value, so we use undefined. + ScriptValue undefined_value = + ScriptValue::From(script_state, ToV8UndefinedGenerator()); + EXPECT_CALL(*read_output_function, Call(testing::_)) + .WillOnce( + testing::DoAll(testing::SaveArg<0>(&v8_frame), + testing::Return(testing::ByMove(undefined_value)))); RunIOUntilIdle(); - EXPECT_EQ(v8::Promise::kFulfilled, v8_read_promise->State()); + testing::Mock::VerifyAndClear(read_output_function); + + auto* read_frame = + V8VideoFrame::ToImplWithTypeCheck(scope.GetIsolate(), v8_frame.V8Value()); - auto* read_frame = V8VideoFrame::ToImplWithTypeCheck( - scope.GetIsolate(), - v8_read_promise->Result() - ->ToObject(scope.GetContext()) - .ToLocalChecked() - ->Get(scope.GetContext(), V8String(scope.GetIsolate(), "value")) - .ToLocalChecked()); + reader->stop(ASSERT_NO_EXCEPTION); ASSERT_TRUE(frame); EXPECT_EQ(frame->frame(), read_frame->frame()); diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.cc b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.cc index 1d3089a2c52..d4be3614e2f 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.cc +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.cc @@ -185,7 +185,7 @@ MediaStreamTrack* VideoTrackWriter::track() { return track_; } -void VideoTrackWriter::Trace(Visitor* visitor) { +void VideoTrackWriter::Trace(Visitor* visitor) const { visitor->Trace(track_); visitor->Trace(writable_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.h b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.h index 1b925f6b80c..33a96b4a130 100644 --- a/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.h +++ b/chromium/third_party/blink/renderer/modules/webcodecs/video_track_writer.h @@ -28,7 +28,7 @@ class MODULES_EXPORT VideoTrackWriter final : public ScriptWrappable { WritableStream* writable(); // GarbageCollected override - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<MediaStreamTrack> track_; diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database.cc index e43a58782f7..8c4b50829b0 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/database.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/database.cc @@ -278,7 +278,7 @@ Database::~Database() { DCHECK(!Opened()); } -void Database::Trace(Visitor* visitor) { +void Database::Trace(Visitor* visitor) const { visitor->Trace(database_context_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database.h b/chromium/third_party/blink/renderer/modules/webdatabase/database.h index 3ba86877b08..99fc289b022 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/database.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/database.h @@ -60,7 +60,7 @@ class Database final : public ScriptWrappable { const String& display_name, uint32_t estimated_size); ~Database() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool OpenAndVerifyVersion(bool set_version_in_new_database, DatabaseError&, diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc index 8b6c08b3a69..3b2f6b844da 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_client.cc @@ -41,7 +41,7 @@ namespace blink { DatabaseClient::DatabaseClient() : inspector_agent_(nullptr) {} -void DatabaseClient::Trace(Visitor* visitor) { +void DatabaseClient::Trace(Visitor* visitor) const { visitor->Trace(inspector_agent_); Supplement<Page>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_client.h b/chromium/third_party/blink/renderer/modules/webdatabase/database_client.h index a365f41fd4e..3935ba35266 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/database_client.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_client.h @@ -54,7 +54,7 @@ class MODULES_EXPORT DatabaseClient : public GarbageCollected<DatabaseClient>, DatabaseClient(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool AllowDatabase(ExecutionContext*); diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc index a0f411d4afb..5b779cadcd9 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.cc @@ -116,7 +116,7 @@ DatabaseContext::~DatabaseContext() { DatabaseManager::Manager().DidDestructDatabaseContext(); } -void DatabaseContext::Trace(Visitor* visitor) { +void DatabaseContext::Trace(Visitor* visitor) const { visitor->Trace(database_thread_); ExecutionContextLifecycleObserver::Trace(visitor); } 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 ec86707519d..832f5869f5c 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/database_context.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_context.h @@ -49,7 +49,7 @@ class DatabaseContext final : public GarbageCollected<DatabaseContext>, explicit DatabaseContext(ExecutionContext*); ~DatabaseContext(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // For life-cycle management (inherited from // ExecutionContextLifecycleObserver): diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc b/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc index f2f35ff8091..4d3b89e0442 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.cc @@ -53,7 +53,7 @@ DatabaseThread::~DatabaseThread() { DCHECK(!thread_); } -void DatabaseThread::Trace(Visitor* visitor) {} +void DatabaseThread::Trace(Visitor* visitor) const {} void DatabaseThread::Start() { DCHECK(IsMainThread()); 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 5fc1d1919f2..00f34a0a0c1 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/database_thread.h @@ -47,7 +47,7 @@ class DatabaseThread final : public GarbageCollected<DatabaseThread> { public: DatabaseThread(); ~DatabaseThread(); - void Trace(Visitor*); + void Trace(Visitor*) const; // Callable only from the main thread. void Start(); diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.cc b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.cc index 8f15d7530af..8d56da79148 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.cc @@ -319,7 +319,7 @@ blink::Database* InspectorDatabaseAgent::DatabaseForId( return it->value->GetDatabase(); } -void InspectorDatabaseAgent::Trace(Visitor* visitor) { +void InspectorDatabaseAgent::Trace(Visitor* visitor) const { visitor->Trace(page_); visitor->Trace(resources_); InspectorBaseAgent::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.h b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.h index ac8b61500ab..47ef96231b9 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_agent.h @@ -48,7 +48,7 @@ class MODULES_EXPORT InspectorDatabaseAgent final public: explicit InspectorDatabaseAgent(Page*); ~InspectorDatabaseAgent() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protocol::Response disable() override; void Restore() override; diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.cc b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.cc index 99adeecae35..7d1b85b7fcd 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/inspector_database_resource.cc @@ -46,7 +46,7 @@ InspectorDatabaseResource::InspectorDatabaseResource(Database* database, name_(name), version_(version) {} -void InspectorDatabaseResource::Trace(Visitor* visitor) { +void InspectorDatabaseResource::Trace(Visitor* visitor) const { visitor->Trace(database_); } 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 942e78c55f9..0aee125655a 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 @@ -46,7 +46,7 @@ class InspectorDatabaseResource final const String& domain, const String& name, const String& version); - void Trace(Visitor*); + void Trace(Visitor*) const; void Bind(protocol::Database::Frontend*); Database* GetDatabase() { return database_.Get(); } diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.cc index 4a5cc455390..dafa8dadf9f 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.cc @@ -42,7 +42,7 @@ SQLResultSet::SQLResultSet() DCHECK(IsMainThread()); } -void SQLResultSet::Trace(Visitor* visitor) { +void SQLResultSet::Trace(Visitor* visitor) const { visitor->Trace(rows_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.h index 12d6155180f..f749732d5f6 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_result_set.h @@ -43,7 +43,7 @@ class SQLResultSet final : public ScriptWrappable { public: SQLResultSet(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; SQLResultSetRowList* rows() const; diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.cc index d0b2a1f4d71..4012abfd457 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.cc @@ -41,7 +41,7 @@ namespace blink { -void SQLStatement::OnSuccessV8Impl::Trace(Visitor* visitor) { +void SQLStatement::OnSuccessV8Impl::Trace(Visitor* visitor) const { visitor->Trace(callback_); OnSuccessCallback::Trace(visitor); } @@ -56,7 +56,7 @@ bool SQLStatement::OnSuccessV8Impl::OnSuccess(SQLTransaction* transaction, return callback_->handleEvent(nullptr, transaction, result_set).IsJust(); } -void SQLStatement::OnErrorV8Impl::Trace(Visitor* visitor) { +void SQLStatement::OnErrorV8Impl::Trace(Visitor* visitor) const { visitor->Trace(callback_); OnErrorCallback::Trace(visitor); } @@ -94,7 +94,7 @@ SQLStatement::SQLStatement(Database* database, } } -void SQLStatement::Trace(Visitor* visitor) { +void SQLStatement::Trace(Visitor* visitor) const { visitor->Trace(backend_); visitor->Trace(success_callback_); visitor->Trace(error_callback_); 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 5bae74b432a..ec8fef70def 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement.h @@ -48,7 +48,7 @@ class SQLStatement final : public GarbageCollected<SQLStatement> { class OnSuccessCallback : public GarbageCollected<OnSuccessCallback> { public: virtual ~OnSuccessCallback() = default; - virtual void Trace(Visitor*) {} + virtual void Trace(Visitor*) const {} virtual bool OnSuccess(SQLTransaction*, SQLResultSet*) = 0; protected: @@ -65,7 +65,7 @@ class SQLStatement final : public GarbageCollected<SQLStatement> { explicit OnSuccessV8Impl(V8SQLStatementCallback* callback) : callback_(callback) {} - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool OnSuccess(SQLTransaction*, SQLResultSet*) override; private: @@ -75,7 +75,7 @@ class SQLStatement final : public GarbageCollected<SQLStatement> { class OnErrorCallback : public GarbageCollected<OnErrorCallback> { public: virtual ~OnErrorCallback() = default; - virtual void Trace(Visitor*) {} + virtual void Trace(Visitor*) const {} virtual bool OnError(SQLTransaction*, SQLError*) = 0; protected: @@ -91,7 +91,7 @@ class SQLStatement final : public GarbageCollected<SQLStatement> { explicit OnErrorV8Impl(V8SQLStatementErrorCallback* callback) : callback_(callback) {} - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool OnError(SQLTransaction*, SQLError*) override; private: @@ -102,7 +102,7 @@ class SQLStatement final : public GarbageCollected<SQLStatement> { SQLStatement(Database*, OnSuccessCallback*, OnErrorCallback*); - void Trace(Visitor*); + void Trace(Visitor*) const; bool PerformCallback(SQLTransaction*); diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc index 9dbfb876585..171c63fc0ad 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_statement_backend.cc @@ -97,7 +97,7 @@ SQLStatementBackend::SQLStatementBackend(SQLStatement* frontend, frontend_->SetBackend(this); } -void SQLStatementBackend::Trace(Visitor* visitor) { +void SQLStatementBackend::Trace(Visitor* visitor) const { visitor->Trace(frontend_); visitor->Trace(result_set_); } 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 96fe7ac6d2e..a16201fdfdf 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 @@ -49,7 +49,7 @@ class SQLStatementBackend final : public GarbageCollected<SQLStatementBackend> { const Vector<SQLValue>& arguments, int permissions); - void Trace(Visitor*); + void Trace(Visitor*) const; bool Execute(Database*); bool LastExecutionFailedDueToQuota() const; 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 b1a68bc895d..196ea34518f 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.cc @@ -44,7 +44,7 @@ namespace blink { -void SQLTransaction::OnProcessV8Impl::Trace(Visitor* visitor) { +void SQLTransaction::OnProcessV8Impl::Trace(Visitor* visitor) const { visitor->Trace(callback_); OnProcessCallback::Trace(visitor); } @@ -58,7 +58,7 @@ bool SQLTransaction::OnProcessV8Impl::OnProcess(SQLTransaction* transaction) { return callback_->handleEvent(nullptr, transaction).IsJust(); } -void SQLTransaction::OnSuccessV8Impl::Trace(Visitor* visitor) { +void SQLTransaction::OnSuccessV8Impl::Trace(Visitor* visitor) const { visitor->Trace(callback_); OnSuccessCallback::Trace(visitor); } @@ -67,7 +67,7 @@ void SQLTransaction::OnSuccessV8Impl::OnSuccess() { callback_->InvokeAndReportException(nullptr); } -void SQLTransaction::OnErrorV8Impl::Trace(Visitor* visitor) { +void SQLTransaction::OnErrorV8Impl::Trace(Visitor* visitor) const { visitor->Trace(callback_); OnErrorCallback::Trace(visitor); } @@ -109,7 +109,7 @@ SQLTransaction::SQLTransaction(Database* db, SQLTransaction::~SQLTransaction() = default; -void SQLTransaction::Trace(Visitor* visitor) { +void SQLTransaction::Trace(Visitor* visitor) const { visitor->Trace(database_); visitor->Trace(backend_); visitor->Trace(callback_); 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 3ee9e458216..6f4ebc16494 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction.h @@ -59,7 +59,7 @@ class SQLTransaction final : public ScriptWrappable, class OnProcessCallback : public GarbageCollected<OnProcessCallback> { public: virtual ~OnProcessCallback() = default; - virtual void Trace(Visitor*) {} + virtual void Trace(Visitor*) const {} virtual bool OnProcess(SQLTransaction*) = 0; protected: @@ -76,7 +76,7 @@ class SQLTransaction final : public ScriptWrappable, explicit OnProcessV8Impl(V8SQLTransactionCallback* callback) : callback_(callback) {} - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool OnProcess(SQLTransaction*) override; private: @@ -86,7 +86,7 @@ class SQLTransaction final : public ScriptWrappable, class OnSuccessCallback : public GarbageCollected<OnSuccessCallback> { public: virtual ~OnSuccessCallback() = default; - virtual void Trace(Visitor*) {} + virtual void Trace(Visitor*) const {} virtual void OnSuccess() = 0; protected: @@ -102,7 +102,7 @@ class SQLTransaction final : public ScriptWrappable, explicit OnSuccessV8Impl(V8VoidCallback* callback) : callback_(callback) {} - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void OnSuccess() override; private: @@ -112,7 +112,7 @@ class SQLTransaction final : public ScriptWrappable, class OnErrorCallback : public GarbageCollected<OnErrorCallback> { public: virtual ~OnErrorCallback() = default; - virtual void Trace(Visitor*) {} + virtual void Trace(Visitor*) const {} virtual bool OnError(SQLError*) = 0; protected: @@ -128,7 +128,7 @@ class SQLTransaction final : public ScriptWrappable, explicit OnErrorV8Impl(V8SQLTransactionErrorCallback* callback) : callback_(callback) {} - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool OnError(SQLError*) override; private: @@ -147,7 +147,7 @@ class SQLTransaction final : public ScriptWrappable, OnErrorCallback*, bool read_only); ~SQLTransaction() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void PerformPendingCallback(); diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc index 24dfe898d33..82835c01f0b 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_backend.cc @@ -391,7 +391,7 @@ SQLTransactionBackend::~SQLTransactionBackend() { DCHECK(!sqlite_transaction_); } -void SQLTransactionBackend::Trace(Visitor* visitor) { +void SQLTransactionBackend::Trace(Visitor* visitor) const { visitor->Trace(wrapper_); } 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 aa5b1fbd5b6..e7de5b4a030 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 @@ -50,7 +50,7 @@ class SQLValue; class SQLTransactionWrapper : public GarbageCollected<SQLTransactionWrapper> { public: virtual ~SQLTransactionWrapper() = default; - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} virtual bool PerformPreflight(SQLTransactionBackend*) = 0; virtual bool PerformPostflight(SQLTransactionBackend*) = 0; virtual SQLErrorData* SqlError() const = 0; @@ -66,7 +66,7 @@ class SQLTransactionBackend final SQLTransactionWrapper*, bool read_only); ~SQLTransactionBackend() override; - void Trace(Visitor*); + void Trace(Visitor*) const; void LockAcquired(); void PerformNextStep(); diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.cc index 0be02921b2b..b35743c0e50 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_coordinator.cc @@ -45,7 +45,7 @@ static String GetDatabaseIdentifier(SQLTransactionBackend* transaction) { SQLTransactionCoordinator::SQLTransactionCoordinator() : is_shutting_down_(false) {} -void SQLTransactionCoordinator::Trace(Visitor* visitor) {} +void SQLTransactionCoordinator::Trace(Visitor* visitor) const {} void SQLTransactionCoordinator::ProcessPendingTransactions( CoordinationInfo& info) { 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 823da7e53bc..946163fc267 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 @@ -48,7 +48,7 @@ class SQLTransactionCoordinator final : public GarbageCollected<SQLTransactionCoordinator> { public: SQLTransactionCoordinator(); - void Trace(Visitor*); + void Trace(Visitor*) const; void AcquireLock(SQLTransactionBackend*); void ReleaseLock(SQLTransactionBackend*); void Shutdown(); diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_state_machine.h b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_state_machine.h index 9d8c4606bc5..44258305b11 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_state_machine.h +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sql_transaction_state_machine.h @@ -26,6 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQL_TRANSACTION_STATE_MACHINE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBDATABASE_SQL_TRANSACTION_STATE_MACHINE_H_ +#include "base/check_op.h" #include "third_party/blink/renderer/modules/webdatabase/sql_transaction_state.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc index 2523802b27c..f9786322ab8 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.cc @@ -26,6 +26,7 @@ #include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_database.h" +#include "base/notreached.h" #include "third_party/blink/renderer/modules/webdatabase/database_authorizer.h" #include "third_party/blink/renderer/modules/webdatabase/sqlite/sandboxed_vfs.h" #include "third_party/blink/renderer/modules/webdatabase/sqlite/sql_log.h" diff --git a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc index d91fbf0438e..2aa897b89de 100644 --- a/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc +++ b/chromium/third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.cc @@ -26,6 +26,8 @@ #include "third_party/blink/renderer/modules/webdatabase/sqlite/sqlite_statement.h" #include <memory> + +#include "base/notreached.h" #include "third_party/blink/renderer/modules/webdatabase/sqlite/sql_log.h" #include "third_party/blink/renderer/modules/webdatabase/sqlite/sql_value.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" diff --git a/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn b/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn index e64e0c2e102..f7d6b046c1d 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn +++ b/chromium/third_party/blink/renderer/modules/webgl/BUILD.gn @@ -37,6 +37,8 @@ blink_modules_sources("webgl") { "gl_string_query.h", "khr_parallel_shader_compile.cc", "khr_parallel_shader_compile.h", + "oes_draw_buffers_indexed.cc", + "oes_draw_buffers_indexed.h", "oes_element_index_uint.cc", "oes_element_index_uint.h", "oes_fbo_render_mipmap.cc", diff --git a/chromium/third_party/blink/renderer/modules/webgl/DEPS b/chromium/third_party/blink/renderer/modules/webgl/DEPS index d0ca58d0939..0cac6d5da5e 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/DEPS +++ b/chromium/third_party/blink/renderer/modules/webgl/DEPS @@ -1,5 +1,6 @@ include_rules = [ "+base/containers/mru_cache.h", + "+device/vr/public/mojom/vr_service.mojom-blink.h", "+gpu/GLES2/gl2extchromium.h", "+gpu/command_buffer/client/gles2_interface.h", "+gpu/command_buffer/client/raster_interface.h", 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 4470f4dd747..8d0097e2c10 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 @@ -201,7 +201,7 @@ ScriptValue EXTDisjointTimerQuery::getQueryObjectEXT(ScriptState* script_state, return ScriptValue::CreateNull(script_state->GetIsolate()); } -void EXTDisjointTimerQuery::Trace(Visitor* visitor) { +void EXTDisjointTimerQuery::Trace(Visitor* visitor) const { visitor->Trace(current_elapsed_query_); WebGLExtension::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h index 1cbb778a40f..402b4e22185 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h +++ b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.h @@ -34,7 +34,7 @@ class EXTDisjointTimerQuery final : public WebGLExtension { ScriptValue getQueryEXT(ScriptState*, GLenum, GLenum); ScriptValue getQueryObjectEXT(ScriptState*, WebGLTimerQueryEXT*, GLenum); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class WebGLTimerQueryEXT; diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.cc b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.cc index 972eb8a0217..b80af8ff28c 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.cc @@ -51,7 +51,7 @@ void EXTDisjointTimerQueryWebGL2::queryCounterEXT(WebGLQuery* query, query->ResetCachedResult(); } -void EXTDisjointTimerQueryWebGL2::Trace(Visitor* visitor) { +void EXTDisjointTimerQueryWebGL2::Trace(Visitor* visitor) const { WebGLExtension::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.h b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.h index e383cff3902..1033c130323 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.h +++ b/chromium/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.h @@ -28,7 +28,7 @@ class EXTDisjointTimerQueryWebGL2 final : public WebGLExtension { void queryCounterEXT(WebGLQuery*, GLenum); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webgl/idls.gni b/chromium/third_party/blink/renderer/modules/webgl/idls.gni index 8338ea61e5a..2bf128c9be9 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/idls.gni +++ b/chromium/third_party/blink/renderer/modules/webgl/idls.gni @@ -30,6 +30,7 @@ modules_idl_files = [ "ext_texture_filter_anisotropic.idl", "ext_texture_norm_16.idl", "khr_parallel_shader_compile.idl", + "oes_draw_buffers_indexed.idl", "oes_element_index_uint.idl", "oes_fbo_render_mipmap.idl", "oes_standard_derivatives.idl", diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.cc b/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.cc new file mode 100644 index 00000000000..edcfddaedb2 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.cc @@ -0,0 +1,96 @@ +// 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/webgl/oes_draw_buffers_indexed.h" + +namespace blink { + +OESDrawBuffersIndexed::OESDrawBuffersIndexed(WebGLRenderingContextBase* context) + : WebGLExtension(context) { + context->ExtensionsUtil()->EnsureExtensionEnabled( + "GL_OES_draw_buffers_indexed"); +} + +WebGLExtensionName OESDrawBuffersIndexed::GetName() const { + return kOESDrawBuffersIndexed; +} + +bool OESDrawBuffersIndexed::Supported(WebGLRenderingContextBase* context) { + return context->ExtensionsUtil()->SupportsExtension( + "GL_OES_draw_buffers_indexed"); +} + +const char* OESDrawBuffersIndexed::ExtensionName() { + return "OES_draw_buffers_indexed"; +} + +void OESDrawBuffersIndexed::enableiOES(GLenum target, GLuint index) { + WebGLExtensionScopedContext scoped(this); + if (scoped.IsLost()) + return; + scoped.Context()->ContextGL()->EnableiOES(target, index); +} + +void OESDrawBuffersIndexed::disableiOES(GLenum target, GLuint index) { + WebGLExtensionScopedContext scoped(this); + if (scoped.IsLost()) + return; + scoped.Context()->ContextGL()->DisableiOES(target, index); +} + +void OESDrawBuffersIndexed::blendEquationiOES(GLuint buf, GLenum mode) { + WebGLExtensionScopedContext scoped(this); + if (scoped.IsLost()) + return; + scoped.Context()->ContextGL()->BlendEquationiOES(buf, mode); +} + +void OESDrawBuffersIndexed::blendEquationSeparateiOES(GLuint buf, + GLenum modeRGB, + GLenum modeAlpha) { + WebGLExtensionScopedContext scoped(this); + if (scoped.IsLost()) + return; + scoped.Context()->ContextGL()->BlendEquationSeparateiOES(buf, modeRGB, + modeAlpha); +} + +void OESDrawBuffersIndexed::blendFunciOES(GLuint buf, GLenum src, GLenum dst) { + WebGLExtensionScopedContext scoped(this); + if (scoped.IsLost()) + return; + scoped.Context()->ContextGL()->BlendFunciOES(buf, src, dst); +} + +void OESDrawBuffersIndexed::blendFuncSeparateiOES(GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha) { + WebGLExtensionScopedContext scoped(this); + if (scoped.IsLost()) + return; + scoped.Context()->ContextGL()->BlendFuncSeparateiOES(buf, srcRGB, dstRGB, + srcAlpha, dstAlpha); +} + +void OESDrawBuffersIndexed::colorMaskiOES(GLuint buf, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a) { + WebGLExtensionScopedContext scoped(this); + if (scoped.IsLost()) + return; + scoped.Context()->ContextGL()->ColorMaskiOES(buf, r, g, b, a); +} + +GLboolean OESDrawBuffersIndexed::isEnablediOES(GLenum target, GLuint index) { + WebGLExtensionScopedContext scoped(this); + if (scoped.IsLost()) + return 0; + return scoped.Context()->ContextGL()->IsEnablediOES(target, index); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h b/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h new file mode 100644 index 00000000000..79778d7a0d0 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h @@ -0,0 +1,51 @@ +// Copyright 2020 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_WEBGL_OES_DRAW_BUFFERS_INDEXED_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OES_DRAW_BUFFERS_INDEXED_H_ + +// #include "base/memory/scoped_refptr.h" +#include "third_party/blink/renderer/modules/webgl/webgl_extension.h" + +namespace blink { + +class OESDrawBuffersIndexed final : public WebGLExtension { + DEFINE_WRAPPERTYPEINFO(); + + public: + static bool Supported(WebGLRenderingContextBase*); + static const char* ExtensionName(); + + explicit OESDrawBuffersIndexed(WebGLRenderingContextBase*); + + WebGLExtensionName GetName() const override; + + void enableiOES(GLenum target, GLuint index); + + void disableiOES(GLenum target, GLuint index); + + void blendEquationiOES(GLuint buf, GLenum mode); + + void blendEquationSeparateiOES(GLuint buf, GLenum modeRGB, GLenum modeAlpha); + + void blendFunciOES(GLuint buf, GLenum src, GLenum dst); + + void blendFuncSeparateiOES(GLuint buf, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha); + + void colorMaskiOES(GLuint buf, + GLboolean r, + GLboolean g, + GLboolean b, + GLboolean a); + + GLboolean isEnablediOES(GLenum target, GLuint index); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OES_DRAW_BUFFERS_INDEXED_H_ diff --git a/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.idl b/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.idl new file mode 100644 index 00000000000..84ed0781c10 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.idl @@ -0,0 +1,39 @@ +// Copyright 2020 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://www.khronos.org/registry/webgl/extensions/OES_draw_buffers_indexed/ + +[ + NoInterfaceObject, + DoNotCheckConstants +] interface OESDrawBuffersIndexed { + void enableiOES(GLenum target, GLuint index); + + void disableiOES(GLenum target, GLuint index); + + void blendEquationiOES(GLuint buf, GLenum mode); + + void blendEquationSeparateiOES(GLuint buf, + GLenum modeRGB, GLenum modeAlpha); + + void blendFunciOES(GLuint buf, + GLenum src, GLenum dst); + + void blendFuncSeparateiOES(GLuint buf, + GLenum srcRGB, GLenum dstRGB, + GLenum srcAlpha, GLenum dstAlpha); + + void colorMaskiOES(GLuint buf, + GLboolean r, GLboolean g, GLboolean b, GLboolean a); + + GLboolean isEnablediOES(GLenum target, GLuint index); + + const unsigned long BLEND_EQUATION_RGB = 0x8009; + const unsigned long BLEND_EQUATION_ALPHA = 0x883D; + const unsigned long BLEND_SRC_RGB = 0x80C9; + const unsigned long BLEND_SRC_ALPHA = 0x80CB; + const unsigned long BLEND_DST_RGB = 0x80C8; + const unsigned long BLEND_DST_ALPHA = 0x80CA; + const unsigned long COLOR_WRITEMASK = 0x0C23; +}; diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.cc index 6a533d40da2..d316d115b7a 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.cc @@ -137,7 +137,7 @@ void WebGL2ComputeRenderingContext::RegisterContextExtensions() { RegisterExtension(webgl_video_texture_, kDraftExtension); } -void WebGL2ComputeRenderingContext::Trace(Visitor* visitor) { +void WebGL2ComputeRenderingContext::Trace(Visitor* visitor) const { visitor->Trace(ext_color_buffer_float_); visitor->Trace(ext_disjoint_timer_query_web_gl2_); visitor->Trace(ext_float_blend_); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h index 7cf9ae4b6dc..e7cb23845fa 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context.h @@ -60,7 +60,7 @@ class WebGL2ComputeRenderingContext : public WebGL2ComputeRenderingContextBase { void SetCanvasGetContextResult(RenderingContext&) final; void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: Member<EXTColorBufferFloat> ext_color_buffer_float_; 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 9a6ca48241d..a88b94ed6f0 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 @@ -484,7 +484,7 @@ ScriptValue WebGL2ComputeRenderingContextBase::getIndexedParameter( } } -void WebGL2ComputeRenderingContextBase::Trace(Visitor* visitor) { +void WebGL2ComputeRenderingContextBase::Trace(Visitor* visitor) const { visitor->Trace(bound_dispatch_indirect_buffer_); visitor->Trace(bound_draw_indirect_buffer_); visitor->Trace(bound_atomic_counter_buffer_); 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 7b8ab3b5566..f085dabfafb 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 @@ -69,7 +69,7 @@ class WebGL2ComputeRenderingContextBase : public WebGL2RenderingContextBase { GLenum target, GLuint index) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: WebGL2ComputeRenderingContextBase( 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 722a86ca719..e41dd7238ed 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 @@ -22,6 +22,7 @@ #include "third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.h" #include "third_party/blink/renderer/modules/webgl/ext_texture_norm_16.h" #include "third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h" +#include "third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.h" #include "third_party/blink/renderer/modules/webgl/oes_texture_float_linear.h" #include "third_party/blink/renderer/modules/webgl/ovr_multiview_2.h" #include "third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.h" @@ -135,6 +136,7 @@ void WebGL2RenderingContext::RegisterContextExtensions() { RegisterExtension(ext_texture_filter_anisotropic_); RegisterExtension(ext_texture_norm16_, kDraftExtension); RegisterExtension(khr_parallel_shader_compile_); + RegisterExtension(oes_draw_buffers_indexed_, kDraftExtension); RegisterExtension(oes_texture_float_linear_); RegisterExtension(webgl_compressed_texture_astc_); RegisterExtension(webgl_compressed_texture_etc_); @@ -154,7 +156,7 @@ void WebGL2RenderingContext::RegisterContextExtensions() { RegisterExtension(ovr_multiview2_); } -void WebGL2RenderingContext::Trace(Visitor* visitor) { +void WebGL2RenderingContext::Trace(Visitor* visitor) const { visitor->Trace(ext_color_buffer_float_); visitor->Trace(ext_disjoint_timer_query_web_gl2_); visitor->Trace(ext_float_blend_); @@ -163,6 +165,7 @@ void WebGL2RenderingContext::Trace(Visitor* visitor) { visitor->Trace(ext_texture_filter_anisotropic_); visitor->Trace(ext_texture_norm16_); visitor->Trace(khr_parallel_shader_compile_); + visitor->Trace(oes_draw_buffers_indexed_); visitor->Trace(oes_texture_float_linear_); visitor->Trace(ovr_multiview2_); visitor->Trace(webgl_compressed_texture_astc_); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h index dfe4ac4d5f9..087ee21eb12 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h @@ -20,6 +20,7 @@ class EXTTextureCompressionBPTC; class EXTTextureCompressionRGTC; class EXTTextureFilterAnisotropic; class EXTTextureNorm16; +class OESDrawBuffersIndexed; class OESTextureFloatLinear; class OVRMultiview2; class WebGLDebugRendererInfo; @@ -66,7 +67,7 @@ class WebGL2RenderingContext : public WebGL2RenderingContextBase { void SetCanvasGetContextResult(RenderingContext&) final; void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: Member<EXTColorBufferFloat> ext_color_buffer_float_; @@ -77,6 +78,7 @@ class WebGL2RenderingContext : public WebGL2RenderingContextBase { Member<EXTTextureFilterAnisotropic> ext_texture_filter_anisotropic_; Member<EXTTextureNorm16> ext_texture_norm16_; Member<KHRParallelShaderCompile> khr_parallel_shader_compile_; + Member<OESDrawBuffersIndexed> oes_draw_buffers_indexed_; Member<OESTextureFloatLinear> oes_texture_float_linear_; Member<OVRMultiview2> ovr_multiview2_; Member<WebGLCompressedTextureASTC> webgl_compressed_texture_astc_; 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 a8cae56cbe4..e468c6f0412 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 @@ -4696,6 +4696,36 @@ ScriptValue WebGL2RenderingContextBase::getIndexedParameter( ContextGL()->GetInteger64i_v(target, index, &value); return WebGLAny(script_state, value); } + case GL_BLEND_EQUATION_RGB: + case GL_BLEND_EQUATION_ALPHA: + case GL_BLEND_SRC_RGB: + case GL_BLEND_SRC_ALPHA: + case GL_BLEND_DST_RGB: + case GL_BLEND_DST_ALPHA: { + if (!ExtensionEnabled(kOESDrawBuffersIndexed)) { + // return null + SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter", + "invalid parameter name"); + return ScriptValue::CreateNull(script_state->GetIsolate()); + } + GLint value = -1; + ContextGL()->GetIntegeri_v(target, index, &value); + return WebGLAny(script_state, value); + } + case GL_COLOR_WRITEMASK: { + if (!ExtensionEnabled(kOESDrawBuffersIndexed)) { + // Enum validation has to happen here to return null + // instead of an array to pass + // conformance2/state/gl-object-get-calls.html + SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter", + "invalid parameter name"); + return ScriptValue::CreateNull(script_state->GetIsolate()); + } + Vector<bool> values(4); + ContextGL()->GetBooleani_v(target, index, + reinterpret_cast<GLboolean*>(values.data())); + return WebGLAny(script_state, values); + } default: SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter", "invalid parameter name"); @@ -5737,7 +5767,7 @@ ScriptValue WebGL2RenderingContextBase::getFramebufferAttachmentParameter( return ScriptValue::CreateNull(script_state->GetIsolate()); } -void WebGL2RenderingContextBase::Trace(Visitor* visitor) { +void WebGL2RenderingContextBase::Trace(Visitor* visitor) const { visitor->Trace(read_framebuffer_binding_); visitor->Trace(transform_feedback_binding_); visitor->Trace(default_transform_feedback_); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h index 1906f0e66e9..64138dd7fae 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h @@ -970,7 +970,7 @@ class WebGL2RenderingContextBase : public WebGLRenderingContextBase { /* Helpers */ GLint GetMaxTransformFeedbackSeparateAttribs() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: friend class V8WebGL2RenderingContext; diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.cc index 7bfb22a7b4f..02409daf3d6 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.cc @@ -47,7 +47,7 @@ const AtomicString& WebGLContextEvent::InterfaceName() const { return event_interface_names::kWebGLContextEvent; } -void WebGLContextEvent::Trace(Visitor* visitor) { +void WebGLContextEvent::Trace(Visitor* visitor) const { Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.h index beac6933836..c331f89c7b7 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_event.h @@ -56,7 +56,7 @@ class WebGLContextEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: String status_message_; diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_group.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_group.h index 355434b9d20..c5295832b4d 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_group.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_group.h @@ -60,7 +60,7 @@ class WebGLContextGroup final : public GarbageCollected<WebGLContextGroup>, // created, in order to validate itself. uint32_t NumberOfContextLosses() const; - void Trace(Visitor* visitor) { visitor->Trace(contexts_); } + void Trace(Visitor* visitor) const { visitor->Trace(contexts_); } const char* NameInHeapSnapshot() const override { return "WebGLContextGroup"; } diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.cc index 4ed4e0b7141..308656bca3a 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.cc @@ -50,7 +50,7 @@ gpu::gles2::GLES2Interface* WebGLContextObject::GetAGLInterface() const { return context_->ContextGL(); } -void WebGLContextObject::Trace(Visitor* visitor) { +void WebGLContextObject::Trace(Visitor* visitor) const { visitor->Trace(context_); WebGLObject::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.h index 15fce90b530..efe7eedee0b 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_context_object.h @@ -41,7 +41,7 @@ class WebGLContextObject : public WebGLObject { bool Validate(const WebGLContextGroup*, const WebGLRenderingContextBase*) const final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: explicit WebGLContextObject(WebGLRenderingContextBase*); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.cc index 71a521f322a..86d142f37fa 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.cc @@ -34,7 +34,7 @@ WebGLExtensionScopedContext::WebGLExtensionScopedContext( WebGLExtension::WebGLExtension(WebGLRenderingContextBase* context) : context_(context) {} -void WebGLExtension::Trace(Visitor* visitor) { +void WebGLExtension::Trace(Visitor* visitor) const { visitor->Trace(context_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.h index b1f25d189a0..ed3e7ef64b5 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension.h @@ -61,7 +61,7 @@ class WebGLExtension : public ScriptWrappable { bool IsLost() { return !context_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: explicit WebGLExtension(WebGLRenderingContextBase*); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h index d67dea6c0e1..54b02a1859d 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_extension_name.h @@ -24,6 +24,7 @@ enum WebGLExtensionName { kEXTTextureFilterAnisotropicName, kEXTTextureNorm16Name, kKHRParallelShaderCompileName, + kOESDrawBuffersIndexed, kOESElementIndexUintName, kOESFboRenderMipmapName, kOESStandardDerivativesName, diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc index d284827c9f5..822f435e6d4 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc @@ -43,7 +43,7 @@ class WebGLRenderbufferAttachment final public: explicit WebGLRenderbufferAttachment(WebGLRenderbuffer*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const char* NameInHeapSnapshot() const override { return "WebGLAttachment"; } private: @@ -61,7 +61,7 @@ class WebGLRenderbufferAttachment final Member<WebGLRenderbuffer> renderbuffer_; }; -void WebGLRenderbufferAttachment::Trace(Visitor* visitor) { +void WebGLRenderbufferAttachment::Trace(Visitor* visitor) const { visitor->Trace(renderbuffer_); WebGLFramebuffer::WebGLAttachment::Trace(visitor); } @@ -107,7 +107,7 @@ class WebGLTextureAttachment final : public WebGLFramebuffer::WebGLAttachment { GLint level, GLint layer); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const char* NameInHeapSnapshot() const override { return "WebGLTextureAttachment"; } @@ -130,7 +130,7 @@ class WebGLTextureAttachment final : public WebGLFramebuffer::WebGLAttachment { GLint layer_; }; -void WebGLTextureAttachment::Trace(Visitor* visitor) { +void WebGLTextureAttachment::Trace(Visitor* visitor) const { visitor->Trace(texture_); WebGLFramebuffer::WebGLAttachment::Trace(visitor); } @@ -547,7 +547,7 @@ GLenum WebGLFramebuffer::GetDrawBuffer(GLenum draw_buffer) { return GL_NONE; } -void WebGLFramebuffer::Trace(Visitor* visitor) { +void WebGLFramebuffer::Trace(Visitor* visitor) const { visitor->Trace(attachments_); WebGLContextObject::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h index d379ed20a99..f579f7ee591 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_framebuffer.h @@ -59,7 +59,7 @@ class WebGLFramebuffer final : public WebGLContextObject { GLenum target, GLenum attachment) = 0; - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} protected: WebGLAttachment(); @@ -122,7 +122,7 @@ class WebGLFramebuffer final : public WebGLContextObject { GLenum GetReadBuffer() const { return read_buffer_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const char* NameInHeapSnapshot() const override { return "WebGLFramebuffer"; } protected: diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc index 974e0b31744..ccceae37018 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.cc @@ -173,7 +173,7 @@ void WebGLProgram::setLinkStatus(bool link_status) { info_valid_ = true; } -void WebGLProgram::Trace(Visitor* visitor) { +void WebGLProgram::Trace(Visitor* visitor) const { visitor->Trace(vertex_shader_); visitor->Trace(fragment_shader_); visitor->Trace(compute_shader_); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h index 39ac2478493..a66ca32e428 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_program.h @@ -71,7 +71,7 @@ class WebGLProgram final : public WebGLSharedPlatform3DObject { bool AttachShader(WebGLShader*); bool DetachShader(WebGLShader*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: void DeleteObjectImpl(gpu::gles2::GLES2Interface*) override; diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.cc index 13a26a1b357..17192407896 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.cc @@ -59,7 +59,7 @@ int WebGLRenderbuffer::UpdateMultisampleState(bool multisampled) { return result; } -void WebGLRenderbuffer::Trace(Visitor* visitor) { +void WebGLRenderbuffer::Trace(Visitor* visitor) const { WebGLSharedPlatform3DObject::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h index f23439ffce6..12b2a49f00b 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.h @@ -61,7 +61,7 @@ class WebGLRenderbuffer final : public WebGLSharedPlatform3DObject { bool HasEverBeenBound() const { return Object() && has_ever_been_bound_; } void SetHasEverBeenBound() { has_ever_been_bound_ = true; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: void DeleteObjectImpl(gpu::gles2::GLES2Interface*) override; diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc index 372521b1e0c..f2c177f88f9 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.cc @@ -98,16 +98,32 @@ static bool ShouldCreateContext( CanvasRenderingContext* WebGLRenderingContext::Factory::Create( CanvasRenderingContextHost* host, const CanvasContextCreationAttributesCore& attrs) { + // Create a copy of attrs so flags can be modified if needed before passing + // into the WebGLRenderingContext constructor. + CanvasContextCreationAttributesCore attribs = attrs; + + // The xr_compatible attribute needs to be handled before creating the context + // because the GPU process may potentially be restarted in order to be XR + // compatible. This scenario occurs if the GPU process is not using the GPU + // that the VR headset is plugged into. If the GPU process is restarted, the + // WebGraphicsContext3DProvider must be created using the new one. + if (attribs.xr_compatible && + !WebGLRenderingContextBase::MakeXrCompatibleSync(host)) { + // If xr compatibility is requested and we can't be xr compatible, return a + // context with the flag set to false. + attribs.xr_compatible = false; + } + bool using_gpu_compositing; std::unique_ptr<WebGraphicsContext3DProvider> context_provider( CreateWebGraphicsContext3DProvider( - host, attrs, Platform::kWebGL1ContextType, &using_gpu_compositing)); + host, attribs, Platform::kWebGL1ContextType, &using_gpu_compositing)); if (!ShouldCreateContext(context_provider.get())) return nullptr; WebGLRenderingContext* rendering_context = MakeGarbageCollected<WebGLRenderingContext>( - host, std::move(context_provider), using_gpu_compositing, attrs); + host, std::move(context_provider), using_gpu_compositing, attribs); if (!rendering_context->GetDrawingBuffer()) { host->HostDispatchEvent( WebGLContextEvent::Create(event_type_names::kWebglcontextcreationerror, @@ -197,7 +213,7 @@ void WebGLRenderingContext::RegisterContextExtensions() { RegisterExtension(webgl_video_texture_, kDraftExtension); } -void WebGLRenderingContext::Trace(Visitor* visitor) { +void WebGLRenderingContext::Trace(Visitor* visitor) const { visitor->Trace(angle_instanced_arrays_); visitor->Trace(ext_blend_min_max_); visitor->Trace(ext_color_buffer_half_float_); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h index a4fe51d91ca..6264f9c8d1c 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_rendering_context.h @@ -96,7 +96,7 @@ class WebGLRenderingContext final : public WebGLRenderingContextBase { void SetCanvasGetContextResult(RenderingContext&) final; void SetOffscreenCanvasGetContextResult(OffscreenRenderingContext&) final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Enabled extension objects. 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 39d00937e8a..457b7c3d2be 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 @@ -37,6 +37,10 @@ #include "gpu/command_buffer/common/capabilities.h" #include "gpu/config/gpu_feature_info.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_study_participation.h" +#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/gpu/gpu.mojom-blink.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/html_canvas_element_or_offscreen_canvas.h" @@ -101,6 +105,8 @@ #include "third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.h" #include "third_party/blink/renderer/modules/webgl/webgl_video_texture.h" #include "third_party/blink/renderer/modules/webgl/webgl_video_texture_enum.h" +#include "third_party/blink/renderer/modules/xr/navigator_xr.h" +#include "third_party/blink/renderer/modules/xr/xr_system.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/v8_binding_macros.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" @@ -748,7 +754,7 @@ void WebGLRenderingContextBase::commit() { int height = GetDrawingBuffer()->Size().Height(); if (PaintRenderingResultsToCanvas(kBackBuffer)) { - if (Host()->GetOrCreateCanvasResourceProvider(kPreferAcceleration)) { + if (Host()->GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)) { Host()->Commit(Host()->ResourceProvider()->ProduceCanvasResource(), SkIRect::MakeWH(width, height)); } @@ -756,8 +762,7 @@ void WebGLRenderingContextBase::commit() { MarkLayerComposited(); } -scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage( - AccelerationHint hint) { +scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage() { if (!GetDrawingBuffer()) return nullptr; @@ -776,9 +781,10 @@ scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage( CanvasResourceProvider::CreateSharedImageProvider( size, SharedGpuContext::ContextProviderWrapper(), GetDrawingBuffer()->FilterQuality(), color_params, - is_origin_top_left_, CanvasResourceProvider::RasterMode::kGPU, + is_origin_top_left_, RasterMode::kGPU, 0u /*shared_image_usage_flags*/); - // todo(bug 1035589) Check if this cpu fallback is really needed here + // todo(bug 1090962) This CPU fallback is needed as it would break + // webgl_conformance_gles_passthrough_tests on Android FYI for Nexus 5x. if (!resource_provider || !resource_provider->IsValid()) { resource_provider = CanvasResourceProvider::CreateBitmapProvider( size, GetDrawingBuffer()->FilterQuality(), color_params); @@ -789,9 +795,7 @@ scoped_refptr<StaticBitmapImage> WebGLRenderingContextBase::GetImage( if (!CopyRenderingResultsFromDrawingBuffer(resource_provider.get(), kBackBuffer)) { - // copyRenderingResultsFromDrawingBuffer is expected to always succeed - // because we've explicitly created an Accelerated surface and have - // already validated it. + // CopyRenderingResultsFromDrawingBuffer will handle both CPU and GPU cases. NOTREACHED(); return nullptr; } @@ -807,28 +811,108 @@ ScriptPromise WebGLRenderingContextBase::makeXRCompatible( return ScriptPromise(); } - if (xr_compatible_) { - // Returns a script promise resolved with undefined. + // Return a resolved promise if we're already xr compatible. Once we're + // compatible, we should always be compatible unless a context lost occurs. + // DispatchContextLostEvent() resets this flag to false. + if (xr_compatible_) return ScriptPromise::CastUndefined(script_state); - } - if (ContextCreatedOnXRCompatibleAdapter()) { + if (!base::FeatureList::IsEnabled(features::kWebXrMultiGpu)) { xr_compatible_ = true; return ScriptPromise::CastUndefined(script_state); } - // TODO(http://crbug.com/876140) Trigger context loss and recreate on - // compatible GPU. - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - "Context is not compatible. Switching not yet implemented."); - return ScriptPromise(); + // If there's a request currently in progress, return the same promise. + if (make_xr_compatible_resolver_) + return make_xr_compatible_resolver_->Promise(); + + make_xr_compatible_resolver_ = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = make_xr_compatible_resolver_->Promise(); + + MakeXrCompatibleAsync(); + + return promise; } -bool WebGLRenderingContextBase::IsXRCompatible() { +bool WebGLRenderingContextBase::IsXRCompatible() const { return xr_compatible_; } +bool WebGLRenderingContextBase::IsXrCompatibleFromResult( + device::mojom::blink::XrCompatibleResult result) { + return result == + device::mojom::blink::XrCompatibleResult::kAlreadyCompatible || + result == + device::mojom::blink::XrCompatibleResult::kCompatibleAfterRestart; +} + +bool WebGLRenderingContextBase::DidGpuRestart( + device::mojom::blink::XrCompatibleResult result) { + return result == device::mojom::blink::XrCompatibleResult:: + kCompatibleAfterRestart || + result == device::mojom::blink::XrCompatibleResult:: + kNotCompatibleAfterRestart; +} + +bool WebGLRenderingContextBase::MakeXrCompatibleSync( + CanvasRenderingContextHost* host) { + if (!base::FeatureList::IsEnabled(features::kWebXrMultiGpu)) + return true; + + device::mojom::blink::XrCompatibleResult xr_compatible_result = + device::mojom::blink::XrCompatibleResult::kNotCompatible; + HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(host); + NavigatorXR* navigator_xr = NavigatorXR::From(canvas->GetDocument()); + if (navigator_xr) + navigator_xr->xr()->MakeXrCompatibleSync(&xr_compatible_result); + + return IsXrCompatibleFromResult(xr_compatible_result); +} + +void WebGLRenderingContextBase::MakeXrCompatibleAsync() { + if (!canvas()) { + xr_compatible_ = false; + CompleteXrCompatiblePromiseIfPending(); + return; + } + + NavigatorXR* navigator_xr = NavigatorXR::From(canvas()->GetDocument()); + if (!navigator_xr) { + xr_compatible_ = false; + CompleteXrCompatiblePromiseIfPending(); + return; + } + + // The promise will be completed on the callback. + navigator_xr->xr()->MakeXrCompatibleAsync( + WTF::Bind(&WebGLRenderingContextBase::OnMakeXrCompatibleFinished, + WrapWeakPersistent(this))); +} + +void WebGLRenderingContextBase::OnMakeXrCompatibleFinished( + device::mojom::blink::XrCompatibleResult xr_compatible_result) { + xr_compatible_ = IsXrCompatibleFromResult(xr_compatible_result); + + // If the gpu is restarted, MaybeRestoreContext will resolve the promise on + // the subsequent restore. + if (!DidGpuRestart(xr_compatible_result)) + CompleteXrCompatiblePromiseIfPending(); +} + +void WebGLRenderingContextBase::CompleteXrCompatiblePromiseIfPending() { + if (make_xr_compatible_resolver_) { + if (xr_compatible_) { + make_xr_compatible_resolver_->Resolve(); + } else { + make_xr_compatible_resolver_->Reject( + MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError)); + } + + make_xr_compatible_resolver_ = nullptr; + } +} + void WebGLRenderingContextBase:: UpdateNumberOfUserAllocatedMultisampledRenderbuffers(int delta) { DCHECK(delta >= -1 && delta <= 1); @@ -840,12 +924,14 @@ namespace { // Exposed by GL_ANGLE_depth_texture static const GLenum kSupportedInternalFormatsOESDepthTex[] = { - GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, + GL_DEPTH_COMPONENT, + GL_DEPTH_STENCIL, }; // Exposed by GL_EXT_sRGB static const GLenum kSupportedInternalFormatsEXTsRGB[] = { - GL_SRGB, GL_SRGB_ALPHA_EXT, + GL_SRGB, + GL_SRGB_ALPHA_EXT, }; // ES3 enums supported by both CopyTexImage and TexImage. @@ -916,12 +1002,14 @@ static const GLenum kSupportedFormatsES2[] = { // Exposed by GL_ANGLE_depth_texture static const GLenum kSupportedFormatsOESDepthTex[] = { - GL_DEPTH_COMPONENT, GL_DEPTH_STENCIL, + GL_DEPTH_COMPONENT, + GL_DEPTH_STENCIL, }; // Exposed by GL_EXT_sRGB static const GLenum kSupportedFormatsEXTsRGB[] = { - GL_SRGB, GL_SRGB_ALPHA_EXT, + GL_SRGB, + GL_SRGB_ALPHA_EXT, }; // ES3 enums @@ -940,7 +1028,9 @@ static const GLenum kSupportedFormatsTexImageSourceES3[] = { // ES2 enums static const GLenum kSupportedTypesES2[] = { - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4, + GL_UNSIGNED_BYTE, + GL_UNSIGNED_SHORT_5_6_5, + GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_SHORT_5_5_5_1, }; @@ -956,7 +1046,9 @@ static const GLenum kSupportedTypesOESTexHalfFloat[] = { // Exposed by GL_ANGLE_depth_texture static const GLenum kSupportedTypesOESDepthTex[] = { - GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, GL_UNSIGNED_INT_24_8, + GL_UNSIGNED_SHORT, + GL_UNSIGNED_INT, + GL_UNSIGNED_INT_24_8, }; // ES3 enums @@ -977,7 +1069,9 @@ static const GLenum kSupportedTypesES3[] = { // ES3 enums supported by TexImageSource static const GLenum kSupportedTypesTexImageSourceES3[] = { - GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_10F_11F_11F_REV, + GL_HALF_FLOAT, + GL_FLOAT, + GL_UNSIGNED_INT_10F_11F_11F_REV, GL_UNSIGNED_INT_2_10_10_10_REV, }; @@ -1025,8 +1119,6 @@ WebGLRenderingContextBase::WebGLRenderingContextBase( number_of_user_allocated_multisampled_renderbuffers_(0) { DCHECK(context_provider); - // TODO(http://crbug.com/876140) Make sure this is being created on a - // compatible adapter. xr_compatible_ = requested_attributes.xr_compatible; context_group_->AddContext(this); @@ -1118,17 +1210,14 @@ scoped_refptr<DrawingBuffer> WebGLRenderingContextBase::CreateDrawingBuffer( std::move(context_provider), using_gpu_compositing, using_swap_chain, this, ClampedCanvasSize(), premultiplied_alpha, want_alpha_channel, want_depth_buffer, want_stencil_buffer, want_antialiasing, preserve, - web_gl_version, chromium_image_usage, ColorParams(), - PowerPreferenceToGpuPreference(attrs.power_preference)); + web_gl_version, chromium_image_usage, Host()->FilterQuality(), + ColorParams(), PowerPreferenceToGpuPreference(attrs.power_preference)); } void WebGLRenderingContextBase::InitializeNewContext() { DCHECK(!isContextLost()); DCHECK(GetDrawingBuffer()); - // TODO(http://crbug.com/876140) Does compatible_xr_device needs to be taken - // into account here? - marked_canvas_dirty_ = false; must_paint_to_canvas_ = false; active_texture_unit_ = 0; @@ -1414,7 +1503,7 @@ void WebGLRenderingContextBase::DidDraw() { bool WebGLRenderingContextBase::PushFrame() { int submitted_frame = false; if (PaintRenderingResultsToCanvas(kBackBuffer)) { - if (Host()->GetOrCreateCanvasResourceProvider(kPreferAcceleration)) { + if (Host()->GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)) { int width = GetDrawingBuffer()->Size().Width(); int height = GetDrawingBuffer()->Size().Height(); submitted_frame = @@ -1588,7 +1677,7 @@ bool WebGLRenderingContextBase::PaintRenderingResultsToCanvas( } CanvasResourceProvider* resource_provider = - Host()->GetOrCreateCanvasResourceProvider(kPreferAcceleration); + Host()->GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU); if (!resource_provider) return false; @@ -1626,12 +1715,6 @@ bool WebGLRenderingContextBase::PaintRenderingResultsToCanvas( return true; } -bool WebGLRenderingContextBase::ContextCreatedOnXRCompatibleAdapter() { - // TODO(http://crbug.com/876140) Determine if device is compatible with - // current context. - return true; -} - bool WebGLRenderingContextBase::CopyRenderingResultsFromDrawingBuffer( CanvasResourceProvider* resource_provider, SourceDrawingBuffer source_buffer) { @@ -1665,7 +1748,7 @@ bool WebGLRenderingContextBase::CopyRenderingResultsFromDrawingBuffer( // Note: This code path could work for all cases. The only reason there // is a separate path for the accelerated case is that we assume texture // copying is faster than drawImage. - scoped_refptr<StaticBitmapImage> image = GetImage(kPreferAcceleration); + scoped_refptr<StaticBitmapImage> image = GetImage(); if (!image || !image->PaintImageForCurrentFrame()) return false; cc::PaintFlags paint_flags; @@ -3009,7 +3092,8 @@ GLenum WebGLRenderingContextBase::getError() { const char* const* WebGLRenderingContextBase::ExtensionTracker::Prefixes() const { static const char* const kUnprefixed[] = { - "", nullptr, + "", + nullptr, }; return prefixes_ ? prefixes_ : kUnprefixed; } @@ -4424,6 +4508,17 @@ void WebGLRenderingContextBase::readPixels( GLenum format, GLenum type, MaybeShared<DOMArrayBufferView> pixels) { + if (IsUserInIdentifiabilityStudy()) { + base::Optional<UkmParameters> ukm_params = ukm_parameters(); + if (ukm_params) { + blink::IdentifiabilityMetricBuilder(ukm_params->source_id) + .Set(blink::IdentifiableSurface::FromTypeAndInput( + blink::IdentifiableSurface::Type::kCanvasReadback, + GetContextType()), + 0) + .Record(ukm_params->ukm_recorder); + } + } ReadPixelsHelper(x, y, width, height, format, type, pixels.View(), 0); } @@ -5454,7 +5549,7 @@ void WebGLRenderingContextBase::TexImageHelperCanvasRenderingContextHost( To<WebGLRenderingContextBase>(context_host->RenderingContext()); } else { image = context_host->GetSourceImageForCanvas( - &source_image_status, kPreferAcceleration, + &source_image_status, FloatSize(source_sub_rectangle.Width(), source_sub_rectangle.Height())); if (source_image_status != kNormalSourceImageStatus) return; @@ -5814,21 +5909,32 @@ void WebGLRenderingContextBase::TexImageHelperImageBitmap( // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. type = GL_FLOAT; } + WebGLImageConversion::DataFormat data_format; + if (is_pixel_data_rgba) { + data_format = WebGLImageConversion::DataFormat::kDataFormatRGBA8; + } else { + switch (pixmap.colorType()) { + case SkColorType::kBGRA_8888_SkColorType: + data_format = WebGLImageConversion::DataFormat::kDataFormatBGRA8; + break; + case SkColorType::kRGBA_F16_SkColorType: + // Used in ImageBitmap's ApplyColorSpaceConversion. + data_format = WebGLImageConversion::DataFormat::kDataFormatRGBA16F; + break; + default: + // Can not handle this ImageBitmap's format. + SynthesizeGLError(GL_INVALID_VALUE, func_name, + "unsupported color type / space in ImageBitmap"); + return; + } + } // In the case of ImageBitmap, we do not need to apply flipY or // premultiplyAlpha. - bool is_pixel_data_bgra = - pixmap.colorType() == SkColorType::kBGRA_8888_SkColorType; - if ((is_pixel_data_bgra && - !WebGLImageConversion::ExtractImageData( - pixel_data_ptr, WebGLImageConversion::DataFormat::kDataFormatBGRA8, - bitmap->Size(), source_sub_rect, depth, unpack_image_height, - format, type, false, false, data)) || - (is_pixel_data_rgba && - !WebGLImageConversion::ExtractImageData( - pixel_data_ptr, WebGLImageConversion::DataFormat::kDataFormatRGBA8, - bitmap->Size(), source_sub_rect, depth, unpack_image_height, - format, type, false, false, data))) { - SynthesizeGLError(GL_INVALID_VALUE, func_name, "bad image data"); + if (!WebGLImageConversion::ExtractImageData( + pixel_data_ptr, data_format, bitmap->Size(), source_sub_rect, depth, + unpack_image_height, format, type, false, false, data)) { + SynthesizeGLError(GL_INVALID_VALUE, func_name, + "error extracting data from ImageBitmap"); return; } } @@ -6815,6 +6921,15 @@ void WebGLRenderingContextBase::DrawingBufferClientRestoreTexture2DBinding() { } void WebGLRenderingContextBase:: + DrawingBufferClientRestoreTextureCubeMapBinding() { + if (destruction_in_progress_) + return; + if (!ContextGL()) + return; + RestoreCurrentTextureCubeMap(); +} + +void WebGLRenderingContextBase:: DrawingBufferClientRestoreRenderbufferBinding() { if (destruction_in_progress_) return; @@ -7955,6 +8070,10 @@ void WebGLRenderingContextBase::OnBeforeDrawCall() { } void WebGLRenderingContextBase::DispatchContextLostEvent(TimerBase*) { + // WebXR spec: When the WebGL context is lost, set the xr compatible boolean + // to false prior to firing the webglcontextlost event. + xr_compatible_ = false; + WebGLContextEvent* event = WebGLContextEvent::Create(event_type_names::kWebglcontextlost, ""); Host()->HostDispatchEvent(event); @@ -7963,6 +8082,14 @@ void WebGLRenderingContextBase::DispatchContextLostEvent(TimerBase*) { if (auto_recovery_method_ == kAuto) restore_timer_.StartOneShot(base::TimeDelta(), FROM_HERE); } + + if (!restore_allowed_) { + // Per WebXR spec, reject the promise with an AbortError if the default + // behavior wasn't prevented. CompleteXrCompatiblePromiseIfPending rejects + // the promise if xr_compatible_ is false, which was set at the beginning of + // this method. + CompleteXrCompatiblePromiseIfPending(); + } } void WebGLRenderingContextBase::MaybeRestoreContext(TimerBase*) { @@ -7983,7 +8110,11 @@ void WebGLRenderingContextBase::MaybeRestoreContext(TimerBase*) { return; bool blocked = false; - frame->GetLocalFrameHostRemote().Are3DAPIsBlocked(&blocked); + mojo::Remote<mojom::blink::GpuDataManager> gpu_data_manager; + Platform::Current()->GetBrowserInterfaceBroker()->GetInterface( + gpu_data_manager.BindNewPipeAndPassReceiver()); + gpu_data_manager->Are3DAPIsBlockedForUrl(canvas()->GetDocument().Url(), + &blocked); if (blocked) return; @@ -8054,6 +8185,8 @@ void WebGLRenderingContextBase::MaybeRestoreContext(TimerBase*) { WebGLContextEvent* event = WebGLContextEvent::Create(event_type_names::kWebglcontextrestored, ""); Host()->HostDispatchEvent(event); + + CompleteXrCompatiblePromiseIfPending(); } String WebGLRenderingContextBase::EnsureNotNull(const String& text) const { @@ -8238,6 +8371,12 @@ void WebGLRenderingContextBase::RestoreCurrentTexture2D() { texture_units_[active_texture_unit_].texture2d_binding_.Get()); } +void WebGLRenderingContextBase::RestoreCurrentTextureCubeMap() { + bindTexture( + GL_TEXTURE_CUBE_MAP, + texture_units_[active_texture_unit_].texture_cube_map_binding_.Get()); +} + void WebGLRenderingContextBase::FindNewMaxNonDefaultTextureUnit() { // Trace backwards from the current max to find the new max non-default // texture unit @@ -8253,7 +8392,7 @@ void WebGLRenderingContextBase::FindNewMaxNonDefaultTextureUnit() { } void WebGLRenderingContextBase::TextureUnitState::Trace( - blink::Visitor* visitor) { + blink::Visitor* visitor) const { visitor->Trace(texture2d_binding_); visitor->Trace(texture_cube_map_binding_); visitor->Trace(texture3d_binding_); @@ -8261,7 +8400,7 @@ void WebGLRenderingContextBase::TextureUnitState::Trace( visitor->Trace(texture_video_image_binding_); } -void WebGLRenderingContextBase::Trace(Visitor* visitor) { +void WebGLRenderingContextBase::Trace(Visitor* visitor) const { visitor->Trace(context_group_); visitor->Trace(bound_array_buffer_); visitor->Trace(default_vertex_array_object_); @@ -8271,6 +8410,7 @@ void WebGLRenderingContextBase::Trace(Visitor* visitor) { visitor->Trace(renderbuffer_binding_); visitor->Trace(texture_units_); visitor->Trace(extensions_); + visitor->Trace(make_xr_compatible_resolver_); CanvasRenderingContext::Trace(visitor); } 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 cf1727cac24..bbdf3c848f0 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 @@ -33,6 +33,7 @@ #include "base/numerics/checked_math.h" #include "base/optional.h" #include "base/single_thread_task_runner.h" +#include "device/vr/public/mojom/vr_service.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" @@ -40,6 +41,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h" #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" +#include "third_party/blink/renderer/core/html/canvas/ukm_parameters.h" #include "third_party/blink/renderer/core/layout/content_change_type.h" #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" @@ -67,7 +69,7 @@ namespace gpu { namespace gles2 { class GLES2Interface; } -} +} // namespace gpu namespace blink { @@ -139,6 +141,10 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, return static_cast<HTMLCanvasElement*>(Host()); } + base::Optional<UkmParameters> ukm_parameters() const { + return Host()->ukm_parameters(); + } + virtual String ContextName() const = 0; virtual void RegisterContextExtensions() = 0; @@ -572,7 +578,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, unsigned MaxVertexAttribs() const { return max_vertex_attribs_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Returns approximate gpu memory allocated per pixel. int ExternallyAllocatedBufferCountPerPixel() override; @@ -592,11 +598,10 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, Member<WebGLTexture> texture2d_array_binding_; Member<WebGLTexture> texture_video_image_binding_; - void Trace(Visitor*); + void Trace(Visitor*) const; }; - scoped_refptr<StaticBitmapImage> GetImage( - AccelerationHint = kPreferAcceleration) override; + scoped_refptr<StaticBitmapImage> GetImage() override; void SetFilterQuality(SkFilterQuality) override; bool IsWebGL2OrHigher() { return context_type_ == Platform::kWebGL2ContextType || @@ -608,7 +613,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, void commit(); ScriptPromise makeXRCompatible(ScriptState*, ExceptionState&); - bool IsXRCompatible(); + bool IsXRCompatible() const; void UpdateNumberOfUserAllocatedMultisampledRenderbuffers(int delta); @@ -681,6 +686,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, void DrawingBufferClientRestoreMaskAndClearValues() override; void DrawingBufferClientRestorePixelPackParameters() override; void DrawingBufferClientRestoreTexture2DBinding() override; + void DrawingBufferClientRestoreTextureCubeMapBinding() override; void DrawingBufferClientRestoreRenderbufferBinding() override; void DrawingBufferClientRestoreFramebufferBinding() override; void DrawingBufferClientRestorePixelUnpackBufferBinding() override; @@ -788,7 +794,16 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, Member<WebGLFramebuffer> framebuffer_binding_; Member<WebGLRenderbuffer> renderbuffer_binding_; + static bool MakeXrCompatibleSync(CanvasRenderingContextHost* host); + static bool IsXrCompatibleFromResult( + device::mojom::blink::XrCompatibleResult result); + static bool DidGpuRestart(device::mojom::blink::XrCompatibleResult result); + void MakeXrCompatibleAsync(); + void OnMakeXrCompatibleFinished( + device::mojom::blink::XrCompatibleResult xr_compatible_result); + void CompleteXrCompatiblePromiseIfPending(); bool xr_compatible_; + Member<ScriptPromiseResolver> make_xr_compatible_resolver_; HeapVector<TextureUnitState> texture_units_; wtf_size_t active_texture_unit_; @@ -886,7 +901,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, // This is only used for keeping the JS wrappers of extensions alive. virtual WebGLExtension* GetExtensionObjectIfAlreadyEnabled() = 0; - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} const char* NameInHeapSnapshot() const override { return "ExtensionTracker"; } @@ -932,7 +947,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, return extension_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(extension_); ExtensionTracker::Trace(visitor); } @@ -1593,6 +1608,7 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, virtual void RestoreCurrentFramebuffer(); void RestoreCurrentTexture2D(); + void RestoreCurrentTextureCubeMap(); void FindNewMaxNonDefaultTextureUnit(); @@ -1765,10 +1781,6 @@ class MODULES_EXPORT WebGLRenderingContextBase : public CanvasRenderingContext, bool IsPaintable() const final { return GetDrawingBuffer(); } - // Returns true if the context is compatible with the XR device as defined - // by https://immersive-web.github.io/webxr/spec/latest/#contextcompatibility - bool ContextCreatedOnXRCompatibleAdapter(); - bool CopyRenderingResultsFromDrawingBuffer(CanvasResourceProvider*, SourceDrawingBuffer); void HoldReferenceToDrawingBuffer(DrawingBuffer*); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.cc index 29b519b17be..83541df5989 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.cc @@ -51,7 +51,7 @@ gpu::gles2::GLES2Interface* WebGLSharedObject::GetAGLInterface() const { return context_group_->GetAGLInterface(); } -void WebGLSharedObject::Trace(Visitor* visitor) { +void WebGLSharedObject::Trace(Visitor* visitor) const { visitor->Trace(context_group_); WebGLObject::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.h index 0385495dc75..82fff6b0795 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_shared_object.h @@ -51,7 +51,7 @@ class WebGLSharedObject : public WebGLObject { bool Validate(const WebGLContextGroup* context_group, const WebGLRenderingContextBase*) const final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: explicit WebGLSharedObject(WebGLRenderingContextBase*); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.cc index dc9adfac1d2..9591a7375cd 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.cc @@ -133,7 +133,7 @@ void WebGLTransformFeedback::UnbindBuffer(WebGLBuffer* buffer) { } } -void WebGLTransformFeedback::Trace(Visitor* visitor) { +void WebGLTransformFeedback::Trace(Visitor* visitor) const { visitor->Trace(bound_indexed_transform_feedback_buffers_); visitor->Trace(program_); WebGLContextObject::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h index 570e11dad4c..43c408cc119 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.h @@ -49,7 +49,7 @@ class WebGLTransformFeedback : public WebGLContextObject { bool UsesBuffer(WebGLBuffer*); void UnbindBuffer(WebGLBuffer*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool active() const { return active_; } bool paused() const { return paused_; } diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.cc index 4203c0c4194..9a83401e6f9 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.cc @@ -50,7 +50,7 @@ GLint WebGLUniformLocation::Location() const { return location_; } -void WebGLUniformLocation::Trace(Visitor* visitor) { +void WebGLUniformLocation::Trace(Visitor* visitor) const { visitor->Trace(program_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.h index 15673dbf9f2..3e016dc5b5c 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_uniform_location.h @@ -42,7 +42,7 @@ class WebGLUniformLocation final : public ScriptWrappable { GLint Location() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<WebGLProgram> program_; diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.cc index f929c1ae523..caeb18cbbbb 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.cc @@ -124,7 +124,7 @@ void WebGLVertexArrayObjectBase::UnbindBuffer(WebGLBuffer* buffer) { UpdateAttribBufferBoundStatus(); } -void WebGLVertexArrayObjectBase::Trace(Visitor* visitor) { +void WebGLVertexArrayObjectBase::Trace(Visitor* visitor) const { visitor->Trace(bound_element_array_buffer_); visitor->Trace(array_buffer_list_); WebGLContextObject::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.h index 4c3c1238193..b79087916cb 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_base.h @@ -41,7 +41,7 @@ class WebGLVertexArrayObjectBase : public WebGLContextObject { } void UnbindBuffer(WebGLBuffer*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: WebGLVertexArrayObjectBase(WebGLRenderingContextBase*, VaoType); diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc index c781b522ae8..468ae30e7f6 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.cc @@ -35,7 +35,7 @@ const char* WebGLVideoTexture::ExtensionName() { return "WEBGL_video_texture"; } -void WebGLVideoTexture::Trace(Visitor* visitor) { +void WebGLVideoTexture::Trace(Visitor* visitor) const { visitor->Trace(current_frame_metadata_); WebGLExtension::Trace(visitor); } @@ -119,7 +119,8 @@ VideoFrameMetadata* WebGLVideoTexture::shareVideoImageWEBGL( frame_metadata_ptr->timestamp.InSecondsF()); // This is a required field. It is supposed to be monotonically increasing for - // video.requestAnimationFrame, but it isn't used yet for WebGLVideoTexture. + // video.requestVideoFrameCallback, but it isn't used yet for + // WebGLVideoTexture. current_frame_metadata_->setPresentedFrames(0); return current_frame_metadata_; #endif // defined OS_ANDROID diff --git a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.h b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.h index bbd9af6d628..2530b5a02ed 100644 --- a/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.h +++ b/chromium/third_party/blink/renderer/modules/webgl/webgl_video_texture.h @@ -23,7 +23,7 @@ class WebGLVideoTexture final : public WebGLExtension { WebGLExtensionName GetName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Get video frame from video frame compositor and bind it to platform // texture. 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 a668a87edc7..b98a9fc92bc 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.cc @@ -11,6 +11,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_enforce_range_sequence_or_gpu_origin_3d_dict.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_programmable_stage_descriptor.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_copy_view.h" +#include "third_party/blink/renderer/modules/webgpu/gpu_device.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/platform/wtf/text/wtf_string.h" @@ -750,7 +751,8 @@ WGPUOrigin3D AsDawnType( return dawn_origin; } -WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view) { +WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view, + GPUDevice* device) { DCHECK(webgpu_view); DCHECK(webgpu_view->texture()); @@ -758,9 +760,17 @@ WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view) { dawn_view.nextInChain = nullptr; 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()); + if (webgpu_view->hasArrayLayer()) { + device->AddConsoleWarning( + "GPUTextureCopyView.arrayLayer deprecated: use .origin.z"); + dawn_view.arrayLayer = webgpu_view->arrayLayer(); + } else { + dawn_view.arrayLayer = dawn_view.origin.z; + dawn_view.origin.z = 0; + } + return dawn_view; } 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 53bd0cad347..693e1d89298 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_conversions.h @@ -9,7 +9,7 @@ #include <memory> -#include "base/logging.h" +#include "base/check.h" #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" #include "third_party/blink/renderer/platform/heap/heap_allocator.h" #include "third_party/blink/renderer/platform/heap/member.h" @@ -46,7 +46,8 @@ WGPUExtent3D AsDawnType( const UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict*); WGPUOrigin3D AsDawnType( const UnsignedLongEnforceRangeSequenceOrGPUOrigin3DDict*); -WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view); +WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view, + GPUDevice* device); using OwnedProgrammableStageDescriptor = std::tuple<WGPUProgrammableStageDescriptor, std::unique_ptr<char[]>>; OwnedProgrammableStageDescriptor AsDawnType( 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 8436a25a4f3..c8e137b636c 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.cc @@ -43,15 +43,32 @@ DawnDeviceClientSerializerHolder::~DawnDeviceClientSerializerHolder() { dawn_control_client_->GetInterface()->RemoveDevice(device_client_id_); } +const scoped_refptr<DawnControlClientHolder>& +DeviceTreeObject::GetDawnControlClient() const { + return device_client_serializer_holder_->dawn_control_client_; +} + +bool DeviceTreeObject::IsDawnControlClientDestroyed() const { + return GetDawnControlClient()->IsDestroyed(); +} +gpu::webgpu::WebGPUInterface* DeviceTreeObject::GetInterface() const { + return GetDawnControlClient()->GetInterface(); +} +const DawnProcTable& DeviceTreeObject::GetProcs() const { + return GetDawnControlClient()->GetProcs(); +} + +uint64_t DeviceTreeObject::GetDeviceClientID() const { + return device_client_serializer_holder_->device_client_id_; +} + DawnObjectImpl::DawnObjectImpl(GPUDevice* device) - : DawnObjectBase(device->GetDawnControlClient()), - device_(device), - device_client_serializer_holder_( - device->GetDeviceClientSerializerHolder()) {} + : DeviceTreeObject(device->GetDeviceClientSerializerHolder()), + device_(device) {} DawnObjectImpl::~DawnObjectImpl() = default; -void DawnObjectImpl::Trace(Visitor* visitor) { +void DawnObjectImpl::Trace(Visitor* visitor) const { 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 559f97966d6..92c302699eb 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/dawn_object.h @@ -31,7 +31,8 @@ class Visitor; // destroyed, we should not call any Dawn functions. class DawnObjectBase { public: - DawnObjectBase(scoped_refptr<DawnControlClientHolder> dawn_control_client); + explicit DawnObjectBase( + scoped_refptr<DawnControlClientHolder> dawn_control_client); const scoped_refptr<DawnControlClientHolder>& GetDawnControlClient() const; bool IsDawnControlClientDestroyed() const; @@ -58,28 +59,51 @@ class DawnDeviceClientSerializerHolder private: friend class RefCounted<DawnDeviceClientSerializerHolder>; + friend class DeviceTreeObject; ~DawnDeviceClientSerializerHolder(); scoped_refptr<DawnControlClientHolder> dawn_control_client_; uint64_t device_client_id_; }; -// TODO(jiawei.shao@intel.com): Remove the redundant reference of -// scoped_refptr<DawnControlClientHolder> inherited from DawnObjectBase as now -// we can access it from device_client_serializer_holder_. -class DawnObjectImpl : public ScriptWrappable, public DawnObjectBase { +// This class is the parent of GPUDevice and all the WebGPU objects that are +// created from a GPUDevice, which holds a +// scoped_refptr<DawnDeviceClientSerializerHolder> and provides functions to +// access all the members inside it. When a GPUDevice and all the WebGPU +// objects created from it are destroyed, the refcount of +// DawnDeviceClientSerializerHolder will become 0 and the clean-ups to the +// corresponding WebGPUSerailzer and other data structures in the GPU process +// will be triggered. +class DeviceTreeObject { public: - DawnObjectImpl(GPUDevice* device); - ~DawnObjectImpl() override; + explicit DeviceTreeObject(scoped_refptr<DawnDeviceClientSerializerHolder> + device_client_seralizer_holder) + : device_client_serializer_holder_( + std::move(device_client_seralizer_holder)) {} - void Trace(Visitor* visitor) override; + const scoped_refptr<DawnControlClientHolder>& GetDawnControlClient() const; + bool IsDawnControlClientDestroyed() const; + gpu::webgpu::WebGPUInterface* GetInterface() const; + const DawnProcTable& GetProcs() const; + + uint64_t GetDeviceClientID() const; protected: - Member<GPUDevice> device_; scoped_refptr<DawnDeviceClientSerializerHolder> device_client_serializer_holder_; }; +class DawnObjectImpl : public ScriptWrappable, public DeviceTreeObject { + public: + explicit DawnObjectImpl(GPUDevice* device); + ~DawnObjectImpl() override; + + void Trace(Visitor* visitor) const override; + + protected: + Member<GPUDevice> device_; +}; + template <typename Handle> class DawnObject : public DawnObjectImpl { public: @@ -93,21 +117,16 @@ class DawnObject : public DawnObjectImpl { Handle const handle_; }; -// TODO(jiawei.shao@intel.com): Remove the redundant reference of -// scoped_refptr<DawnControlClientHolder> inherited from DawnObjectBase as now -// we can access it from device_client_serializer_holder_. template <> -class DawnObject<WGPUDevice> : public DawnObjectBase { +class DawnObject<WGPUDevice> : public DeviceTreeObject { public: DawnObject(scoped_refptr<DawnControlClientHolder> dawn_control_client, uint64_t device_client_id, WGPUDevice handle) - : DawnObjectBase(std::move(dawn_control_client)), - handle_(handle), - device_client_serializer_holder_( - base::MakeRefCounted<DawnDeviceClientSerializerHolder>( - GetDawnControlClient(), - device_client_id)) {} + : DeviceTreeObject(base::MakeRefCounted<DawnDeviceClientSerializerHolder>( + std::move(dawn_control_client), + device_client_id)), + handle_(handle) {} WGPUDevice GetHandle() const { return handle_; } @@ -118,8 +137,6 @@ class DawnObject<WGPUDevice> : public DawnObjectBase { private: WGPUDevice const handle_; - scoped_refptr<DawnDeviceClientSerializerHolder> - device_client_serializer_holder_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc index 23176e95f33..954963ec80d 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu.cc @@ -93,7 +93,7 @@ GPU::GPU(ExecutionContext& execution_context, GPU::~GPU() = default; -void GPU::Trace(Visitor* visitor) { +void GPU::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu.h index f9e8b33b314..bd89c0bc7a3 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu.h @@ -33,7 +33,7 @@ class GPU final : public ScriptWrappable, ~GPU() override; // ScriptWrappable overrides - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // ExecutionContextLifecycleObserver overrides void ContextDestroyed() override; 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 4933688c357..e0fd1b4ccb8 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 @@ -51,24 +51,11 @@ GPUBindGroup* GPUBindGroup::Create(GPUDevice* device, DCHECK(device); DCHECK(webgpu_desc); - if (webgpu_desc->hasBindings()) { - device->AddConsoleWarning( - "GPUBindGroupDescriptor.bindings is deprecated: renamed to entries"); - } - uint32_t entry_count = 0; std::unique_ptr<WGPUBindGroupEntry[]> entries; - if (webgpu_desc->hasEntries()) { - entry_count = static_cast<uint32_t>(webgpu_desc->entries().size()); - entries = entry_count != 0 ? AsDawnType(webgpu_desc->entries()) : nullptr; - } else { - if (!webgpu_desc->hasBindings()) { - exception_state.ThrowTypeError("required member entries is undefined."); - return nullptr; - } - - entry_count = static_cast<uint32_t>(webgpu_desc->bindings().size()); - entries = entry_count != 0 ? AsDawnType(webgpu_desc->bindings()) : nullptr; + entry_count = static_cast<uint32_t>(webgpu_desc->entries().size()); + if (entry_count > 0) { + entries = AsDawnType(webgpu_desc->entries()); } WGPUBindGroupDescriptor dawn_desc = {}; 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 167fa9db56d..d58fa6cfbf7 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 @@ -6,8 +6,5 @@ dictionary GPUBindGroupDescriptor : GPUObjectDescriptorBase { required GPUBindGroupLayout layout; - - // TODO(crbug.com/1069302): bindings is deprecated; remove it, make entries required. - sequence<GPUBindGroupEntry> bindings; - sequence<GPUBindGroupEntry> entries; + required sequence<GPUBindGroupEntry> entries; }; 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 be9b79509ec..7472dfbf63e 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 @@ -21,20 +21,8 @@ WGPUBindGroupLayoutEntry AsDawnType( dawn_binding.type = AsDawnEnum<WGPUBindingType>(webgpu_binding->type()); dawn_binding.visibility = AsDawnEnum<WGPUShaderStage>(webgpu_binding->visibility()); - - // Note: in this case we check for the deprecated member first, because - // the new member is optional so we can't check for its presence. - if (webgpu_binding->hasTextureDimension()) { - device->AddConsoleWarning( - "GPUBindGroupLayoutEntry.textureDimension is deprecated: renamed to " - "viewDimension"); - dawn_binding.viewDimension = AsDawnEnum<WGPUTextureViewDimension>( - webgpu_binding->textureDimension()); - } else { - dawn_binding.viewDimension = - AsDawnEnum<WGPUTextureViewDimension>(webgpu_binding->viewDimension()); - } - + dawn_binding.viewDimension = + AsDawnEnum<WGPUTextureViewDimension>(webgpu_binding->viewDimension()); dawn_binding.textureComponentType = AsDawnEnum<WGPUTextureComponentType>( webgpu_binding->textureComponentType()); dawn_binding.multisampled = webgpu_binding->multisampled(); @@ -66,27 +54,11 @@ GPUBindGroupLayout* GPUBindGroupLayout::Create( DCHECK(device); DCHECK(webgpu_desc); - if (webgpu_desc->hasBindings()) { - device->AddConsoleWarning( - "GPUBindGroupLayoutDescriptor.bindings is deprecated: renamed to " - "entries"); - } - uint32_t entry_count = 0; std::unique_ptr<WGPUBindGroupLayoutEntry[]> entries; - if (webgpu_desc->hasEntries()) { - entry_count = static_cast<uint32_t>(webgpu_desc->entries().size()); - entries = - entry_count != 0 ? AsDawnType(webgpu_desc->entries(), device) : nullptr; - } else { - if (!webgpu_desc->hasBindings()) { - exception_state.ThrowTypeError("required member entries is undefined."); - return nullptr; - } - - entry_count = static_cast<uint32_t>(webgpu_desc->bindings().size()); - entries = entry_count != 0 ? AsDawnType(webgpu_desc->bindings(), device) - : nullptr; + entry_count = static_cast<uint32_t>(webgpu_desc->entries().size()); + if (entry_count > 0) { + entries = AsDawnType(webgpu_desc->entries(), device); } WGPUBindGroupLayoutDescriptor dawn_desc = {}; 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 38cfd6d302b..6fc3dd1cad1 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 @@ -5,7 +5,5 @@ // https://gpuweb.github.io/gpuweb/ dictionary GPUBindGroupLayoutDescriptor : GPUObjectDescriptorBase { - // TODO(crbug.com/1069302): bindings is deprecated; remove it, make entries required. - sequence<GPUBindGroupLayoutEntry> bindings; - sequence<GPUBindGroupLayoutEntry> entries; + required sequence<GPUBindGroupLayoutEntry> entries; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl index a4084166bb0..afe95d8781e 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl @@ -9,8 +9,6 @@ dictionary GPUBindGroupLayoutEntry { required GPUShaderStageFlags visibility; required GPUBindingType type; GPUTextureViewDimension viewDimension = "2d"; - // TODO(crbug.com/1069302): textureDimension is deprecated; remove it. - GPUTextureViewDimension textureDimension; GPUTextureComponentType textureComponentType = "float"; boolean multisampled = false; boolean hasDynamicOffset = false; 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 2ec1fb71566..7fa564434d9 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.cc @@ -121,7 +121,7 @@ GPUBuffer::~GPUBuffer() { GetProcs().bufferRelease(GetHandle()); } -void GPUBuffer::Trace(Visitor* visitor) { +void GPUBuffer::Trace(Visitor* visitor) const { visitor->Trace(mapped_buffer_); DawnObject<WGPUBuffer>::Trace(visitor); } @@ -132,9 +132,8 @@ void GPUBuffer::setSubData(uint64_t dst_byte_offset, uint64_t byte_length, ExceptionState& exception_state) { device_->AddConsoleWarning( - "GPUBuffer.setSubData is deprecated: use createBufferMapped " - "(with copyBufferToBuffer if needed) " - "(but note the design/spec of this API is still in flux)"); + "GPUBuffer.setSubData is deprecated: use GPUQueue.writeBuffer instead"); + const uint8_t* src_base = reinterpret_cast<const uint8_t*>(src.BaseAddressMaybeOnStack()); size_t src_byte_length = src.ByteLengthAsSizeT(); diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.h index b7266242464..59664ef260d 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_buffer.h @@ -30,7 +30,7 @@ class GPUBuffer : public DawnObject<WGPUBuffer> { explicit GPUBuffer(GPUDevice* device, uint64_t size, WGPUBuffer buffer); ~GPUBuffer() override; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // gpu_buffer.idl void setSubData(uint64_t dst_byte_offset, 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 89eb5bc9f2f..94e76c1f3a0 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 @@ -4,15 +4,6 @@ // https://gpuweb.github.io/gpuweb/ -dictionary GPUBufferCopyView { +dictionary GPUBufferCopyView : GPUTextureDataLayout { required GPUBuffer buffer; - GPUSize64 offset = 0; - - // TODO(crbug.com/1069302): rowPitch is deprecated; remove it, make bytesPerRow required. - GPUSize32 bytesPerRow; - unsigned long rowPitch; - - GPUSize32 rowsPerImage = 0; - // TODO(crbug.com/1069302): imageHeight is deprecated; remove it. - unsigned long imageHeight; }; 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 a6c68cc595f..da360cf1016 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 @@ -32,7 +32,7 @@ GPUCanvasContext::GPUCanvasContext( GPUCanvasContext::~GPUCanvasContext() {} -void GPUCanvasContext::Trace(Visitor* visitor) { +void GPUCanvasContext::Trace(Visitor* visitor) const { visitor->Trace(swapchain_); CanvasRenderingContext::Trace(visitor); } 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 7f577fa7056..788635a2aff 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 @@ -39,15 +39,13 @@ class GPUCanvasContext : public CanvasRenderingContext { const CanvasContextCreationAttributesCore&); ~GPUCanvasContext() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const IntSize& CanvasSize() const; // CanvasRenderingContext implementation ContextType GetContextType() const override; void SetCanvasGetContextResult(RenderingContext&) final; - scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final { - return nullptr; - } + scoped_refptr<StaticBitmapImage> GetImage() final { return nullptr; } void SetIsInHiddenPage(bool) override {} void SetIsBeingDisplayed(bool) override {} bool isContextLost() const override { return false; } 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 6969bc8f4ec..935c1a899b3 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 @@ -108,10 +108,7 @@ WGPURenderPassDepthStencilAttachmentDescriptor AsDawnType( return dawn_desc; } -base::Optional<WGPUBufferCopyView> AsDawnType( - const GPUBufferCopyView* webgpu_view, - GPUDevice* device, - ExceptionState& exception_state) { +WGPUBufferCopyView AsDawnType(const GPUBufferCopyView* webgpu_view) { DCHECK(webgpu_view); DCHECK(webgpu_view->buffer()); @@ -119,32 +116,8 @@ base::Optional<WGPUBufferCopyView> AsDawnType( dawn_view.nextInChain = nullptr; dawn_view.buffer = webgpu_view->buffer()->GetHandle(); dawn_view.offset = webgpu_view->offset(); - - if (webgpu_view->hasRowPitch()) { - device->AddConsoleWarning( - "GPUBufferCopyView.rowPitch is deprecated: renamed to bytesPerRow"); - } - if (webgpu_view->hasBytesPerRow()) { - dawn_view.bytesPerRow = webgpu_view->bytesPerRow(); - } else { - if (!webgpu_view->hasRowPitch()) { - exception_state.ThrowTypeError( - "required member bytesPerRow is undefined."); - return base::nullopt; - } - dawn_view.bytesPerRow = webgpu_view->rowPitch(); - } - - // Note: in this case we check for the deprecated member first, because it is - // required, while the new member is optional. - if (webgpu_view->hasImageHeight()) { - device->AddConsoleWarning( - "GPUBufferCopyView.imageHeight is deprecated: renamed to rowsPerImage"); - dawn_view.rowsPerImage = webgpu_view->imageHeight(); - } else { - dawn_view.rowsPerImage = webgpu_view->rowsPerImage(); - } - + dawn_view.bytesPerRow = webgpu_view->bytesPerRow(); + dawn_view.rowsPerImage = webgpu_view->rowsPerImage(); return dawn_view; } @@ -277,12 +250,11 @@ void GPUCommandEncoder::copyBufferToTexture( return; } - base::Optional<WGPUBufferCopyView> dawn_source = - AsDawnType(source, device_, exception_state); + base::Optional<WGPUBufferCopyView> dawn_source = AsDawnType(source); if (!dawn_source) { return; } - WGPUTextureCopyView dawn_destination = AsDawnType(destination); + WGPUTextureCopyView dawn_destination = AsDawnType(destination, device_); WGPUExtent3D dawn_copy_size = AsDawnType(©_size); GetProcs().commandEncoderCopyBufferToTexture( @@ -299,9 +271,8 @@ void GPUCommandEncoder::copyTextureToBuffer( return; } - WGPUTextureCopyView dawn_source = AsDawnType(source); - base::Optional<WGPUBufferCopyView> dawn_destination = - AsDawnType(destination, device_, exception_state); + WGPUTextureCopyView dawn_source = AsDawnType(source, device_); + base::Optional<WGPUBufferCopyView> dawn_destination = AsDawnType(destination); if (!dawn_destination) { return; } @@ -322,8 +293,8 @@ void GPUCommandEncoder::copyTextureToTexture( return; } - WGPUTextureCopyView dawn_source = AsDawnType(source); - WGPUTextureCopyView dawn_destination = AsDawnType(destination); + WGPUTextureCopyView dawn_source = AsDawnType(source, device_); + WGPUTextureCopyView dawn_destination = AsDawnType(destination, device_); WGPUExtent3D dawn_copy_size = AsDawnType(©_size); GetProcs().commandEncoderCopyTextureToTexture( 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 3e9897a5e81..97600ac9f5b 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 @@ -32,9 +32,9 @@ GPUTextureCopyView destination, GPUExtent3D copySize); - void pushDebugGroup(DOMString groupLabel); + void pushDebugGroup(USVString groupLabel); void popDebugGroup(); - void insertDebugMarker(DOMString markerLabel); + void insertDebugMarker(USVString markerLabel); GPUCommandBuffer finish(optional GPUCommandBufferDescriptor descriptor = {}); }; 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 22c2d30eab9..3173f20cd72 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.cc @@ -48,8 +48,7 @@ GPUDevice::GPUDevice(ExecutionContext* execution_context, GetProcs().deviceGetDefaultQueue(GetHandle()))), lost_property_(MakeGarbageCollected<LostProperty>(execution_context)), error_callback_(BindRepeatingDawnCallback(&GPUDevice::OnUncapturedError, - WrapWeakPersistent(this))), - client_id_(client_id) { + WrapWeakPersistent(this))) { DCHECK(dawn_control_client->GetInterface()->GetDevice(client_id)); GetProcs().deviceSetUncapturedErrorCallback( GetHandle(), error_callback_->UnboundRepeatingCallback(), @@ -64,10 +63,6 @@ GPUDevice::~GPUDevice() { GetProcs().deviceRelease(GetHandle()); } -uint64_t GPUDevice::GetClientID() const { - return client_id_; -} - void GPUDevice::AddConsoleWarning(const char* message) { ExecutionContext* execution_context = GetExecutionContext(); if (execution_context && allowed_console_warnings_remaining_ > 0) { @@ -261,7 +256,7 @@ const AtomicString& GPUDevice::InterfaceName() const { return event_target_names::kGPUDevice; } -void GPUDevice::Trace(Visitor* visitor) { +void GPUDevice::Trace(Visitor* visitor) const { visitor->Trace(adapter_); visitor->Trace(queue_); visitor->Trace(lost_property_); 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 e27314bfa10..5ef8c3fd12b 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_device.h @@ -61,9 +61,7 @@ class GPUDevice final : public EventTargetWithInlineData, const GPUDeviceDescriptor* descriptor); ~GPUDevice() override; - void Trace(Visitor* visitor) override; - - uint64_t GetClientID() const; + void Trace(Visitor* visitor) const override; // gpu_device.idl GPUAdapter* adapter() const; @@ -129,8 +127,6 @@ class GPUDevice final : public EventTargetWithInlineData, DawnCallback<base::RepeatingCallback<void(WGPUErrorType, const char*)>>> error_callback_; - uint64_t client_id_; - static constexpr int kMaxAllowedConsoleWarnings = 500; int allowed_console_warnings_remaining_ = kMaxAllowedConsoleWarnings; 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 index 020c0e21584..b694771acbd 100644 --- 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 @@ -5,5 +5,5 @@ // https://gpuweb.github.io/gpuweb/ dictionary GPUObjectDescriptorBase { - DOMString? label; + USVString? label; }; 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 index 801d45ad3c4..a3876898701 100644 --- 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 @@ -16,7 +16,7 @@ GPUSize64 dynamicOffsetsDataStart, GPUSize32 dynamicOffsetsDataLength); - void pushDebugGroup(DOMString groupLabel); + void pushDebugGroup(USVString groupLabel); void popDebugGroup(); - void insertDebugMarker(DOMString markerLabel); + void insertDebugMarker(USVString markerLabel); }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl index a2cdfd81029..3c645977721 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_programmable_stage_descriptor.idl @@ -6,5 +6,5 @@ dictionary GPUProgrammableStageDescriptor { required GPUShaderModule module; - required DOMString entryPoint; + required USVString 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 45b35ab8fb1..2ad51cd5309 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.cc @@ -16,8 +16,10 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_image_bitmap_copy_view.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_copy_view.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" #include "third_party/blink/renderer/modules/webgpu/client_validation.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_command_buffer.h" #include "third_party/blink/renderer/modules/webgpu/gpu_device.h" #include "third_party/blink/renderer/modules/webgpu/gpu_fence.h" @@ -55,6 +57,8 @@ WGPUOrigin3D GPUOrigin2DToWGPUOrigin3D( return dawn_origin; } +// TODO(shaobo.yan@intel.com): This function will be removed when +// dawn has the copyTextureCHROMIUM like API. bool AreCompatibleFormatForImageBitmapGPUCopy( SkColorType sk_color_type, WGPUTextureFormat dawn_texture_format) { @@ -78,6 +82,23 @@ bool AreCompatibleFormatForImageBitmapGPUCopy( } } +bool IsValidCopyIB2TDestinationFormat(WGPUTextureFormat dawn_texture_format) { + switch (dawn_texture_format) { + case WGPUTextureFormat_RGBA8Unorm: + case WGPUTextureFormat_RGBA8UnormSrgb: + case WGPUTextureFormat_BGRA8Unorm: + case WGPUTextureFormat_BGRA8UnormSrgb: + case WGPUTextureFormat_RGB10A2Unorm: + case WGPUTextureFormat_RGBA16Float: + case WGPUTextureFormat_RGBA32Float: + case WGPUTextureFormat_RG8Unorm: + case WGPUTextureFormat_RG16Float: + return true; + default: + return false; + } +} + bool CanUploadThroughGPU(StaticBitmapImage* image, const CanvasColorParams& color_param, GPUTexture* dest_texture) { @@ -108,7 +129,7 @@ bool CanUploadThroughGPU(StaticBitmapImage* image, GPUQueue::GPUQueue(GPUDevice* device, WGPUQueue queue) : DawnObject<WGPUQueue>(device, queue) { produce_dawn_texture_handler_ = base::AdoptRef(new DawnTextureFromImageBitmap( - GetDawnControlClient(), device_->GetClientID())); + GetDawnControlClient(), GetDeviceClientID())); } GPUQueue::~GPUQueue() { @@ -151,6 +172,106 @@ GPUFence* GPUQueue::createFence(const GPUFenceDescriptor* descriptor) { device_, GetProcs().queueCreateFence(GetHandle(), &desc)); } +void GPUQueue::writeBuffer(GPUBuffer* buffer, + uint64_t buffer_offset, + const MaybeShared<DOMArrayBufferView>& data, + uint64_t data_byte_offset, + ExceptionState& exception_state) { + WriteBufferImpl(buffer, buffer_offset, data->byteLengthAsSizeT(), + data->BaseAddressMaybeShared(), data->TypeSize(), + data_byte_offset, {}, exception_state); +} + +void GPUQueue::writeBuffer(GPUBuffer* buffer, + uint64_t buffer_offset, + const MaybeShared<DOMArrayBufferView>& data, + uint64_t data_byte_offset, + uint64_t byte_size, + ExceptionState& exception_state) { + WriteBufferImpl(buffer, buffer_offset, data->byteLengthAsSizeT(), + data->BaseAddressMaybeShared(), data->TypeSize(), + data_byte_offset, byte_size, exception_state); +} + +void GPUQueue::writeBuffer(GPUBuffer* buffer, + uint64_t buffer_offset, + const DOMArrayBufferBase* data, + uint64_t data_byte_offset, + ExceptionState& exception_state) { + WriteBufferImpl(buffer, buffer_offset, data->ByteLengthAsSizeT(), + data->DataMaybeShared(), 1, data_byte_offset, {}, + exception_state); +} + +void GPUQueue::writeBuffer(GPUBuffer* buffer, + uint64_t buffer_offset, + const DOMArrayBufferBase* data, + uint64_t data_byte_offset, + uint64_t byte_size, + ExceptionState& exception_state) { + WriteBufferImpl(buffer, buffer_offset, data->ByteLengthAsSizeT(), + data->DataMaybeShared(), 1, data_byte_offset, byte_size, + exception_state); +} + +void GPUQueue::WriteBufferImpl(GPUBuffer* buffer, + uint64_t buffer_offset, + uint64_t data_byte_length, + const void* data_base_ptr, + unsigned data_bytes_per_element, + uint64_t data_byte_offset, + base::Optional<uint64_t> byte_size, + ExceptionState& exception_state) { + if (buffer_offset % 4 != 0) { + exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, + "bufferOffset must be a multiple of 4"); + return; + } + + if (data_byte_offset % data_bytes_per_element != 0) { + exception_state.ThrowDOMException( + DOMExceptionCode::kOperationError, + "dataByteOffset must be a multiple of data.BYTES_PER_ELEMENT"); + return; + } + + if (data_byte_offset > data_byte_length) { + exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, + "dataByteOffset is too large"); + return; + } + uint64_t max_write_size = data_byte_length - data_byte_offset; + + uint64_t write_byte_size = max_write_size; + if (byte_size.has_value()) { + write_byte_size = byte_size.value(); + if (write_byte_size > max_write_size) { + exception_state.ThrowDOMException(DOMExceptionCode::kOperationError, + "byteSize is too large"); + return; + } + } + if (write_byte_size % std::max(4u, data_bytes_per_element) != 0) { + exception_state.ThrowRangeError( + "byteSize must be a multiple of max(4, data.BYTES_PER_ELEMENT)"); + return; + } + + // Check that the write size can be cast to a size_t. This should always be + // the case since data_byte_length comes from an ArrayBuffer size. + if (write_byte_size > uint64_t(std::numeric_limits<size_t>::max())) { + exception_state.ThrowRangeError( + "writeSize larger than size_t (please report a bug if you see this)"); + return; + } + + const uint8_t* data_base_ptr_bytes = + static_cast<const uint8_t*>(data_base_ptr); + const uint8_t* data_ptr = data_base_ptr_bytes + data_byte_offset; + GetProcs().queueWriteBuffer(GetHandle(), buffer->GetHandle(), buffer_offset, + data_ptr, static_cast<size_t>(write_byte_size)); +} + // TODO(shaobo.yan@intel.com): Implement this function void GPUQueue::copyImageBitmapToTexture( GPUImageBitmapCopyView* source, @@ -198,7 +319,12 @@ void GPUQueue::copyImageBitmapToTexture( return; } - WGPUTextureCopyView dawn_destination = AsDawnType(destination); + WGPUTextureCopyView dawn_destination = AsDawnType(destination, device_); + + if (!IsValidCopyIB2TDestinationFormat(destination->texture()->Format())) { + return exception_state.ThrowTypeError("Invalid gpu texture format."); + return; + } const CanvasColorParams& color_params = source->imageBitmap()->GetCanvasColorParams(); @@ -218,7 +344,8 @@ void GPUQueue::copyImageBitmapToTexture( } // CPU path is the fallback path and should always work. if (!CopyContentFromCPU(image.get(), color_params, origin_in_image_bitmap, - dawn_copy_size, dawn_destination)) { + dawn_copy_size, dawn_destination, + destination->texture()->Format())) { exception_state.ThrowTypeError("Failed to copy content from imageBitmap."); return; } @@ -228,12 +355,14 @@ bool GPUQueue::CopyContentFromCPU(StaticBitmapImage* image, const CanvasColorParams& color_params, const WGPUOrigin3D& origin, const WGPUExtent3D& copy_size, - const WGPUTextureCopyView& destination) { + const WGPUTextureCopyView& destination, + const WGPUTextureFormat dest_texture_format) { // Prepare for uploading CPU data. IntRect image_data_rect(origin.x, origin.y, copy_size.width, copy_size.height); - WebGPUImageUploadSizeInfo info = - ComputeImageBitmapWebGPUUploadSizeInfo(image_data_rect, color_params); + + WebGPUImageUploadSizeInfo info = ComputeImageBitmapWebGPUUploadSizeInfo( + image_data_rect, dest_texture_format); // Create a mapped buffer to receive image bitmap contents WGPUBufferDescriptor buffer_desc; @@ -249,7 +378,7 @@ bool GPUQueue::CopyContentFromCPU(StaticBitmapImage* image, image, base::span<uint8_t>(reinterpret_cast<uint8_t*>(result.data), static_cast<size_t>(result.dataLength)), - image_data_rect, color_params)) { + image_data_rect, color_params, dest_texture_format)) { // Release the buffer. GetProcs().bufferRelease(result.buffer); return false; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.h index d39ed4db5aa..4b29aabdca8 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_QUEUE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGPU_GPU_QUEUE_H_ +#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h" #include "third_party/blink/renderer/modules/webgpu/dawn_object.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" @@ -13,6 +14,7 @@ namespace blink { class CanvasColorParams; class DawnTextureFromImageBitmap; class ExceptionState; +class GPUBuffer; class GPUCommandBuffer; class GPUFence; class GPUFenceDescriptor; @@ -32,6 +34,36 @@ class GPUQueue : public DawnObject<WGPUQueue> { void submit(const HeapVector<Member<GPUCommandBuffer>>& buffers); void signal(GPUFence* fence, uint64_t signal_value); GPUFence* createFence(const GPUFenceDescriptor* descriptor); + void writeBuffer(GPUBuffer* buffer, + uint64_t buffer_offset, + const MaybeShared<DOMArrayBufferView>& data, + uint64_t data_byte_offset, + ExceptionState& exception_state); + void writeBuffer(GPUBuffer* buffer, + uint64_t buffer_offset, + const MaybeShared<DOMArrayBufferView>& data, + uint64_t data_byte_offset, + uint64_t byte_size, + ExceptionState& exception_state); + void writeBuffer(GPUBuffer* buffer, + uint64_t buffer_offset, + const DOMArrayBufferBase* data, + uint64_t data_byte_offset, + ExceptionState& exception_state); + void writeBuffer(GPUBuffer* buffer, + uint64_t buffer_offset, + const DOMArrayBufferBase* data, + uint64_t data_byte_offset, + uint64_t byte_size, + ExceptionState& exception_state); + void WriteBufferImpl(GPUBuffer* buffer, + uint64_t buffer_offset, + uint64_t data_byte_length, + const void* data_base_ptr, + unsigned data_bytes_per_element, + uint64_t data_byte_offset, + base::Optional<uint64_t> byte_size, + ExceptionState& exception_state); void copyImageBitmapToTexture( GPUImageBitmapCopyView* source, GPUTextureCopyView* destination, @@ -43,7 +75,8 @@ class GPUQueue : public DawnObject<WGPUQueue> { const CanvasColorParams& color_params, const WGPUOrigin3D& origin, const WGPUExtent3D& copy_size, - const WGPUTextureCopyView& destination); + const WGPUTextureCopyView& destination, + const WGPUTextureFormat dest_texture_format); bool CopyContentFromGPU(StaticBitmapImage* image, const WGPUOrigin3D& origin, const WGPUExtent3D& copy_size, 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 63fc25a09fe..5e5a687ff93 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_queue.idl @@ -11,6 +11,23 @@ GPUFence createFence(optional GPUFenceDescriptor descriptor = {}); void signal(GPUFence fence, GPUFenceValue signalValue); + + // TODO(crbug.com/1088107): Merge these overloads into one with + // [AllowShared] BufferSource (or whatever the upstream spec has), which + // would expand this to allow SharedArrayBuffer (can't be implemented now). + [RaisesException] void writeBuffer( + GPUBuffer buffer, + GPUSize64 bufferOffset, + [AllowShared] ArrayBufferView data, + optional GPUSize64 dataByteOffset = 0, + optional GPUSize64 byteSize); + [RaisesException] void writeBuffer( + GPUBuffer buffer, + GPUSize64 bufferOffset, + ArrayBuffer data, + optional GPUSize64 dataByteOffset = 0, + optional GPUSize64 byteSize); + [RaisesException] void copyImageBitmapToTexture( GPUImageBitmapCopyView source, GPUTextureCopyView destination, 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 57643e7cbf4..8e40d485333 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 @@ -23,8 +23,8 @@ GPUShaderModule* GPUShaderModule::Create( WGPUShaderModuleSPIRVDescriptor spirv_desc = {}; auto wgsl_or_spirv = webgpu_desc->code(); - if (wgsl_or_spirv.IsString()) { - std::string code = wgsl_or_spirv.GetAsString().Utf8(); + if (wgsl_or_spirv.IsUSVString()) { + std::string code = wgsl_or_spirv.GetAsUSVString().Utf8(); wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor; wgsl_desc.source = code.c_str(); 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 4988f4f6711..a14bd3891d7 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 @@ -5,6 +5,6 @@ // https://gpuweb.github.io/gpuweb/ dictionary GPUShaderModuleDescriptor : GPUObjectDescriptorBase { - // TODO(crbug.com/1069302): Remove SPIR-V support, change this to DOMString. - required (DOMString or Uint32Array) code; + // TODO(crbug.com/1069302): Remove SPIR-V support, change this to USVString. + required (USVString or Uint32Array) code; }; 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 b0c23d22ff8..3afa50c8458 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 @@ -16,14 +16,14 @@ GPUSwapChain::GPUSwapChain(GPUCanvasContext* context, WGPUTextureUsage usage, WGPUTextureFormat format, SkFilterQuality filter_quality) - : DawnObjectBase(device->GetDawnControlClient()), + : DeviceTreeObject(device->GetDeviceClientSerializerHolder()), device_(device), context_(context), usage_(usage), format_(format) { // TODO: Use label from GPUObjectDescriptorBase. swap_buffers_ = base::AdoptRef(new WebGPUSwapBufferProvider( - this, GetDawnControlClient(), device_->GetClientID(), usage_, format)); + this, GetDawnControlClient(), GetDeviceClientID(), usage_, format)); swap_buffers_->SetFilterQuality(filter_quality); } @@ -31,7 +31,7 @@ GPUSwapChain::~GPUSwapChain() { Neuter(); } -void GPUSwapChain::Trace(Visitor* visitor) { +void GPUSwapChain::Trace(Visitor* visitor) const { visitor->Trace(device_); visitor->Trace(context_); visitor->Trace(texture_); 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 2c8da4d603e..42f66b8d9d5 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,7 @@ class GPUDevice; class GPUTexture; class GPUSwapChain : public ScriptWrappable, - public DawnObjectBase, + public DeviceTreeObject, public WebGPUSwapBufferProvider::Client { DEFINE_WRAPPERTYPEINFO(); @@ -31,7 +31,7 @@ class GPUSwapChain : public ScriptWrappable, SkFilterQuality); ~GPUSwapChain() override; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; void Neuter(); cc::Layer* CcLayer(); 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 b303bddc560..1d913ba53bf 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 @@ -7,6 +7,6 @@ dictionary GPUTextureCopyView { required GPUTexture texture; GPUSize32 mipLevel = 0; - GPUSize32 arrayLayer = 0; + GPUSize32 arrayLayer; GPUOrigin3D origin = {}; }; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_data_layout.idl b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_data_layout.idl new file mode 100644 index 00000000000..384c64889fd --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_texture_data_layout.idl @@ -0,0 +1,11 @@ +// Copyright 2020 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/#dictdef-gputexturedatalayout + +dictionary GPUTextureDataLayout { + GPUSize64 offset = 0; + required GPUSize32 bytesPerRow; + GPUSize32 rowsPerImage = 0; +}; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc b/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc index ca53b3d38ca..68397822990 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.cc @@ -23,7 +23,7 @@ GPUUncapturedErrorEvent::GPUUncapturedErrorEvent( error_ = gpuUncapturedErrorEventInitDict->error(); } -void GPUUncapturedErrorEvent::Trace(Visitor* visitor) { +void GPUUncapturedErrorEvent::Trace(Visitor* visitor) const { visitor->Trace(error_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h b/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h index c305c812d3c..1ad83e9b5bd 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.h @@ -22,7 +22,7 @@ class GPUUncapturedErrorEvent : public Event { GPUUncapturedErrorEvent(const AtomicString& type, const GPUUncapturedErrorEventInit*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // gpu_uncaptured_error_event.idl void error(GPUOutOfMemoryErrorOrGPUValidationError&) const; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/idls.gni b/chromium/third_party/blink/renderer/modules/webgpu/idls.gni index 04e12c9fc18..4bce96a2bdb 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/idls.gni +++ b/chromium/third_party/blink/renderer/modules/webgpu/idls.gni @@ -37,20 +37,20 @@ modules_idl_files = [ ] modules_dictionary_idl_files = [ - "gpu_bind_group_entry.idl", "gpu_bind_group_descriptor.idl", - "gpu_bind_group_layout_entry.idl", + "gpu_bind_group_entry.idl", "gpu_bind_group_layout_descriptor.idl", + "gpu_bind_group_layout_entry.idl", "gpu_blend_descriptor.idl", "gpu_buffer_binding.idl", - "gpu_command_buffer_descriptor.idl", "gpu_buffer_copy_view.idl", "gpu_buffer_descriptor.idl", "gpu_color_dict.idl", "gpu_color_state_descriptor.idl", + "gpu_command_buffer_descriptor.idl", "gpu_command_encoder_descriptor.idl", - "gpu_compute_pipeline_descriptor.idl", "gpu_compute_pass_descriptor.idl", + "gpu_compute_pipeline_descriptor.idl", "gpu_depth_stencil_state_descriptor.idl", "gpu_device_descriptor.idl", "gpu_extent_3d_dict.idl", @@ -76,6 +76,7 @@ modules_dictionary_idl_files = [ "gpu_stencil_state_face_descriptor.idl", "gpu_swap_chain_descriptor.idl", "gpu_texture_copy_view.idl", + "gpu_texture_data_layout.idl", "gpu_texture_descriptor.idl", "gpu_texture_view_descriptor.idl", "gpu_uncaptured_error_event_init.idl", diff --git a/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.cc b/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.cc index 5095f6713b2..67659bf4d2a 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.cc @@ -37,7 +37,7 @@ GPU* NavigatorGPU::gpu(ScriptState* script_state) { return gpu_; } -void NavigatorGPU::Trace(Visitor* visitor) { +void NavigatorGPU::Trace(Visitor* visitor) const { visitor->Trace(gpu_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.h b/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.h index 0b1f91a6165..e7214a864ed 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/navigator_gpu.h @@ -30,7 +30,7 @@ class NavigatorGPU final : public GarbageCollected<NavigatorGPU>, explicit NavigatorGPU(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<GPU> gpu_; diff --git a/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.cc b/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.cc index ee687c44388..05762efec8f 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.cc +++ b/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.cc @@ -36,7 +36,7 @@ GPU* WorkerNavigatorGPU::gpu(ScriptState* script_state) { return gpu_; } -void WorkerNavigatorGPU::Trace(Visitor* visitor) { +void WorkerNavigatorGPU::Trace(Visitor* visitor) const { visitor->Trace(gpu_); Supplement<WorkerNavigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.h b/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.h index edde4bd8916..a3ff920c7f0 100644 --- a/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.h +++ b/chromium/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.h @@ -30,7 +30,7 @@ class WorkerNavigatorGPU final : public GarbageCollected<WorkerNavigatorGPU>, explicit WorkerNavigatorGPU(WorkerNavigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<GPU> gpu_; diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc index bafeeba1060..25681853b66 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.cc @@ -206,7 +206,7 @@ void MIDIAccess::ContextDestroyed() { dispatcher_.reset(); } -void MIDIAccess::Trace(Visitor* visitor) { +void MIDIAccess::Trace(Visitor* visitor) const { visitor->Trace(inputs_); visitor->Trace(outputs_); EventTargetWithInlineData::Trace(visitor); 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 bbc5d585898..e44f4e1cc41 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access.h +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access.h @@ -122,7 +122,7 @@ class MIDIAccess final : public EventTargetWithInlineData, // Eager finalization needed to promptly release m_accessor. Otherwise // its client back reference could end up being unsafely used during // the lazy sweeping phase. - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void Dispose(); diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc index 2f7c04ff60c..549b63ae541 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_access_initializer.cc @@ -124,7 +124,7 @@ void MIDIAccessInitializer::DidStartSession(Result result) { "Unknown internal error occurred.")); } -void MIDIAccessInitializer::Trace(Visitor* visitor) { +void MIDIAccessInitializer::Trace(Visitor* visitor) const { visitor->Trace(options_); visitor->Trace(permission_service_); ScriptPromiseResolver::Trace(visitor); 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 e548999022e..7ca6b29a6b4 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 @@ -84,7 +84,7 @@ class MODULES_EXPORT MIDIAccessInitializer : public ScriptPromiseResolver, wtf_size_t length, base::TimeTicks time_stamp) override {} - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ExecutionContext* GetExecutionContext() const; diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.cc index 94b12a6f4ee..2c4760f09cc 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.cc +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.cc @@ -42,7 +42,7 @@ MIDIConnectionEvent::MIDIConnectionEvent( port_ = initializer->port(); } -void MIDIConnectionEvent::Trace(Visitor* visitor) { +void MIDIConnectionEvent::Trace(Visitor* visitor) const { visitor->Trace(port_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.h index 71954524822..2eb393dd9b2 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.h +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_connection_event.h @@ -62,7 +62,7 @@ class MIDIConnectionEvent final : public Event { return event_interface_names::kMIDIConnectionEvent; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<MIDIPort> port_; diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc index 0269504c271..159c281f308 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.cc @@ -97,7 +97,7 @@ void MIDIInput::DidReceiveMIDIData(unsigned port_index, UseCounter::Count(GetExecutionContext(), WebFeature::kMIDIMessageEvent); } -void MIDIInput::Trace(Visitor* visitor) { +void MIDIInput::Trace(Visitor* visitor) const { MIDIPort::Trace(visitor); } 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 f63efbe3770..8ad24e10e97 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_input.h +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_input.h @@ -64,7 +64,7 @@ class MIDIInput final : public MIDIPort { size_t length, base::TimeTicks time_stamp); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: void AddedEventListener(const AtomicString& event_type, diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.h index fedc10888a5..0c88539cfe6 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.h +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_message_event.h @@ -64,7 +64,7 @@ class MIDIMessageEvent final : public Event { return event_interface_names::kMIDIMessageEvent; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(data_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc index 4949f8658d5..688cd61e92b 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_output.cc @@ -322,7 +322,7 @@ void MIDIOutput::DidOpen(bool opened) { DCHECK(pending_data_.IsEmpty()); } -void MIDIOutput::Trace(Visitor* visitor) { +void MIDIOutput::Trace(Visitor* visitor) const { MIDIPort::Trace(visitor); visitor->Trace(pending_data_); } diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_output.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_output.h index 52dab7b6180..72872b77c5b 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_output.h +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_output.h @@ -63,7 +63,7 @@ class MIDIOutput final : public MIDIPort { void send(NotShared<DOMUint8Array>, ExceptionState&); void send(Vector<unsigned>, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void DidOpen(bool opened) override; diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc index 17f6bfa371a..843e2757e5f 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.cc @@ -187,7 +187,7 @@ void MIDIPort::ContextDestroyed() { connection_ = kConnectionStateClosed; } -void MIDIPort::Trace(Visitor* visitor) { +void MIDIPort::Trace(Visitor* visitor) const { visitor->Trace(access_); EventTargetWithInlineData::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); 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 a9c4d65d3ea..723d6503b09 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_port.h +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_port.h @@ -75,7 +75,7 @@ class MIDIPort : public EventTargetWithInlineData, void SetState(midi::mojom::PortState); ConnectionState GetConnection() const { return connection_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; DEFINE_ATTRIBUTE_EVENT_LISTENER(statechange, kStatechange) diff --git a/chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h b/chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h index 79f0fea64bf..93e8e7a5696 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h +++ b/chromium/third_party/blink/renderer/modules/webmidi/midi_port_map.h @@ -23,7 +23,7 @@ class MIDIPortMap : public ScriptWrappable, public Maplike<String, T*> { // IDL attributes / methods uint32_t size() const { return entries_.size(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(entries_); ScriptWrappable::Trace(visitor); } @@ -77,7 +77,7 @@ class MIDIPortMap : public ScriptWrappable, public Maplike<String, T*> { return true; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(map_); PairIterable<String, T*>::IterationSource::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc b/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc index aaf89a9874d..4bbe6d74c77 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc +++ b/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.cc @@ -34,7 +34,6 @@ #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/modules/v8/v8_midi_options.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/deprecation.h" @@ -61,7 +60,7 @@ const char kFeaturePolicyConsoleWarning[] = NavigatorWebMIDI::NavigatorWebMIDI(Navigator& navigator) : Supplement<Navigator>(navigator) {} -void NavigatorWebMIDI::Trace(Visitor* visitor) { +void NavigatorWebMIDI::Trace(Visitor* visitor) const { Supplement<Navigator>::Trace(visitor); } @@ -101,7 +100,7 @@ ScriptPromise NavigatorWebMIDI::requestMIDIAccess( UseCounter::Count( window, WebFeature::kRequestMIDIAccessWithSysExOption_ObscuredByFootprinting); - window->document()->CountUseOnlyInCrossOriginIframe( + window->CountUseOnlyInCrossOriginIframe( WebFeature:: kRequestMIDIAccessIframeWithSysExOption_ObscuredByFootprinting); } else { @@ -114,7 +113,7 @@ ScriptPromise NavigatorWebMIDI::requestMIDIAccess( window, WebFeature::kNoSysexWebMIDIWithoutPermission); } } - window->document()->CountUseOnlyInCrossOriginIframe( + window->CountUseOnlyInCrossOriginIframe( WebFeature::kRequestMIDIAccessIframe_ObscuredByFootprinting); if (!window->IsFeatureEnabled( diff --git a/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.h b/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.h index e31bd0a6476..601ff7f0e9a 100644 --- a/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.h +++ b/chromium/third_party/blink/renderer/modules/webmidi/navigator_web_midi.h @@ -60,7 +60,7 @@ class NavigatorWebMIDI final : public GarbageCollected<NavigatorWebMIDI>, explicit NavigatorWebMIDI(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webrtc/DEPS b/chromium/third_party/blink/renderer/modules/webrtc/DEPS index d12ed386c0a..f9e5e6dd262 100644 --- a/chromium/third_party/blink/renderer/modules/webrtc/DEPS +++ b/chromium/third_party/blink/renderer/modules/webrtc/DEPS @@ -10,6 +10,7 @@ include_rules = [ "+media/base/audio_parameters.h", "+media/base/audio_pull_fifo.h", "+media/base/audio_renderer_sink.h", + "+media/base/bind_to_current_loop.h", "+media/base/channel_layout.h", "+media/base/sample_rates.h", diff --git a/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.cc b/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.cc index f7d392e7b0d..11a807683a8 100644 --- a/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.cc +++ b/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.cc @@ -13,14 +13,18 @@ #include "base/threading/thread_checker.h" #include "build/build_config.h" #include "media/audio/audio_sink_parameters.h" +#include "media/base/audio_bus.h" #include "media/base/audio_capturer_source.h" #include "media/base/audio_latency.h" #include "media/base/audio_parameters.h" +#include "media/base/bind_to_current_loop.h" +#include "media/base/channel_layout.h" #include "media/base/sample_rates.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_stream_track.h" #include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_local_frame_client.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_track.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" @@ -316,6 +320,15 @@ WebRtcAudioRenderer::WebRtcAudioRenderer( sink_params_(kFormat, media::CHANNEL_LAYOUT_STEREO, 0, 0), output_device_id_(device_id), on_render_error_callback_(std::move(on_render_error_callback)) { + if (web_frame && web_frame->Client()) { + speech_recognition_client_ = + web_frame->Client()->CreateSpeechRecognitionClient( + media::BindToCurrentLoop( + ConvertToBaseOnceCallback(CrossThreadBindOnce( + &WebRtcAudioRenderer::EnableSpeechRecognition, + weak_factory_.GetWeakPtr())))); + } + SendLogMessage( String::Format("%s({session_id=%s}, {device_id=%s})", __func__, session_id.is_empty() ? "" : session_id.ToString().c_str(), @@ -589,6 +602,14 @@ void WebRtcAudioRenderer::SwitchOutputDevice( std::move(callback).Run(media::OUTPUT_DEVICE_STATUS_OK); } +void WebRtcAudioRenderer::TranscribeAudio( + std::unique_ptr<media::AudioBus> audio_bus, + int sample_rate, + media::ChannelLayout channel_layout) { + speech_recognition_client_->AddAudio(std::move(audio_bus), sample_rate, + channel_layout); +} + int WebRtcAudioRenderer::Render(base::TimeDelta delay, base::TimeTicks delay_timestamp, int prior_frames_skipped, @@ -634,6 +655,15 @@ int WebRtcAudioRenderer::Render(base::TimeDelta delay, audio_stream_tracker_->MeasurePower(*audio_bus, audio_bus->frames()); } + if (transcribe_audio_callback_) { + auto audio_bus_copy = + media::AudioBus::Create(audio_bus->channels(), audio_bus->frames()); + audio_bus->CopyTo(audio_bus_copy.get()); + transcribe_audio_callback_.Run(std::move(audio_bus_copy), + sink_params_.sample_rate(), + sink_params_.channel_layout()); + } + return (state_ == PLAYING) ? audio_bus->frames() : 0; } @@ -925,4 +955,14 @@ void WebRtcAudioRenderer::SendLogMessage(const WTF::String& message) { .Utf8()); } +void WebRtcAudioRenderer::EnableSpeechRecognition() { + if (speech_recognition_client_ && + speech_recognition_client_->IsSpeechRecognitionAvailable()) { + transcribe_audio_callback_ = + media::BindToCurrentLoop(ConvertToBaseRepeatingCallback( + CrossThreadBindRepeating(&WebRtcAudioRenderer::TranscribeAudio, + weak_factory_.GetWeakPtr()))); + } +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h b/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h index f7c9cf496c5..42e1684d2fe 100644 --- a/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h +++ b/chromium/third_party/blink/renderer/modules/webrtc/webrtc_audio_renderer.h @@ -35,6 +35,10 @@ #include "third_party/blink/renderer/platform/webrtc/webrtc_source.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +namespace media { +class SpeechRecognitionClient; +} // namespace media + namespace webrtc { class AudioSourceInterface; } // namespace webrtc @@ -50,6 +54,10 @@ class MODULES_EXPORT WebRtcAudioRenderer : public media::AudioRendererSink::RenderCallback, public blink::WebMediaStreamAudioRenderer { public: + // Send the audio to the speech recognition service for caption transcription. + using TranscribeAudioCallback = base::RepeatingCallback< + void(std::unique_ptr<media::AudioBus>, int, media::ChannelLayout)>; + // This is a little utility class that holds the configured state of an audio // stream. // It is used by both WebRtcAudioRenderer and SharedAudioRenderer (see cc @@ -245,6 +253,10 @@ class MODULES_EXPORT WebRtcAudioRenderer // Flag to keep track the state of the renderer. State state_; + void TranscribeAudio(std::unique_ptr<media::AudioBus> audio_bus, + int sample_rate, + media::ChannelLayout channel_layout); + // media::AudioRendererSink::RenderCallback implementation. // These two methods are called on the AudioOutputDevice worker thread. int Render(base::TimeDelta delay, @@ -291,6 +303,8 @@ class MODULES_EXPORT WebRtcAudioRenderer void SendLogMessage(const WTF::String& message); + void EnableSpeechRecognition(); + // The WebLocalFrame in which the audio is rendered into |sink_|. // // TODO(crbug.com/704136): Replace |source_internal_frame_| with regular @@ -369,6 +383,11 @@ class MODULES_EXPORT WebRtcAudioRenderer base::RepeatingCallback<void()> on_render_error_callback_; + std::unique_ptr<media::SpeechRecognitionClient> speech_recognition_client_; + TranscribeAudioCallback transcribe_audio_callback_; + + base::WeakPtrFactory<WebRtcAudioRenderer> weak_factory_{this}; + DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioRenderer); }; 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 71a72016f9b..bf29ffc8c7e 100644 --- a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc +++ b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.cc @@ -49,35 +49,46 @@ String ErrorToString(mojom::blink::ShareError error) { return String(); } -bool HasFiles(const ShareData& share_data) { - if (!RuntimeEnabledFeatures::WebShareV2Enabled() || !share_data.hasFiles()) +bool HasFiles(const ShareData& data) { + if (!RuntimeEnabledFeatures::WebShareV2Enabled() || !data.hasFiles()) return false; - const HeapVector<Member<File>>& files = share_data.files(); - return !files.IsEmpty(); + return !data.files().IsEmpty(); } -// Returns a message for a TypeError if share(share_data) would reject with -// TypeError. https://w3c.github.io/web-share/level-2/#canshare-method -// Otherwise returns an empty string. -// Populates full_url with the result of running the URL parser on -// share_data.url -String CheckForTypeError(const LocalDOMWindow& window, - const ShareData& share_data, - KURL* full_url) { - if (!share_data.hasTitle() && !share_data.hasText() && !share_data.hasUrl() && - !HasFiles(share_data)) { - return "No known share data fields supplied. If using only new fields " - "(other than title, text and url), you must feature-detect " - "them first."; +// Returns true unless |share(data)| would reject with TypeError. +// Populates |url| with the result of running the URL parser on |data.url|. +// If the return value is false and |exception_state| is non null, throws +// TypeError. +// +// https://w3c.github.io/web-share/level-2/#canshare-method +// https://w3c.github.io/web-share/level-2/#share-method +bool CanShareInternal(const LocalDOMWindow& window, + const ShareData& data, + KURL& url, + ExceptionState* exception_state) { + if (!data.hasTitle() && !data.hasText() && !data.hasUrl() && + !HasFiles(data)) { + if (exception_state) { + exception_state->ThrowTypeError( + "No known share data fields supplied. If using only new fields " + "(other than title, text and url), you must feature-detect " + "them first."); + } + return false; } - *full_url = window.CompleteURL(share_data.url()); - if (!full_url->IsNull() && !full_url->IsValid()) { - return "Invalid URL"; + if (data.hasUrl()) { + url = window.CompleteURL(data.url()); + if (!url.IsValid()) { + if (exception_state) { + exception_state->ThrowTypeError("Invalid URL"); + } + return false; + } } - return g_empty_string; + return true; } } // namespace @@ -91,7 +102,7 @@ class NavigatorShare::ShareClientImpl final void OnConnectionError(); - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(navigator_); visitor->Trace(resolver_); } @@ -147,8 +158,6 @@ void NavigatorShare::ShareClientImpl::OnConnectionError() { "Internal error: could not connect to Web Share interface.")); } -NavigatorShare::~NavigatorShare() = default; - NavigatorShare& NavigatorShare::From(Navigator& navigator) { NavigatorShare* supplement = Supplement<Navigator>::From<NavigatorShare>(navigator); @@ -159,35 +168,31 @@ NavigatorShare& NavigatorShare::From(Navigator& navigator) { return *supplement; } -void NavigatorShare::Trace(Visitor* visitor) { +void NavigatorShare::Trace(Visitor* visitor) const { visitor->Trace(service_remote_); visitor->Trace(clients_); Supplement<Navigator>::Trace(visitor); } -NavigatorShare::NavigatorShare() - : // |NavigatorShare| is not ExecutionContext-associated. - service_remote_(nullptr) {} - const char NavigatorShare::kSupplementName[] = "NavigatorShare"; bool NavigatorShare::canShare(ScriptState* script_state, - const ShareData* share_data) { + const ShareData* data) { if (!script_state->ContextIsValid()) return false; LocalDOMWindow* window = LocalDOMWindow::From(script_state); - KURL full_url; - return CheckForTypeError(*window, *share_data, &full_url).IsEmpty(); + KURL unused_url; + return CanShareInternal(*window, *data, unused_url, nullptr); } bool NavigatorShare::canShare(ScriptState* script_state, Navigator& navigator, - const ShareData* share_data) { - return From(navigator).canShare(script_state, share_data); + const ShareData* data) { + return From(navigator).canShare(script_state, data); } ScriptPromise NavigatorShare::share(ScriptState* script_state, - const ShareData* share_data, + const ShareData* data, ExceptionState& exception_state) { if (!script_state->ContextIsValid()) { exception_state.ThrowDOMException( @@ -198,10 +203,9 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state, } LocalDOMWindow* window = LocalDOMWindow::From(script_state); - KURL full_url; - String error_message = CheckForTypeError(*window, *share_data, &full_url); - if (!error_message.IsEmpty()) { - exception_state.ThrowTypeError(error_message); + KURL url; + if (!CanShareInternal(*window, *data, url, &exception_state)) { + DCHECK(exception_state.HadException()); return ScriptPromise(); } @@ -222,7 +226,7 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state, DCHECK(service_remote_.is_bound()); } - bool has_files = HasFiles(*share_data); + bool has_files = HasFiles(*data); auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ShareClientImpl* client = MakeGarbageCollected<ShareClientImpl>(this, has_files, resolver); @@ -232,8 +236,8 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state, WTF::Vector<mojom::blink::SharedFilePtr> files; uint64_t total_bytes = 0; if (has_files) { - files.ReserveInitialCapacity(share_data->files().size()); - for (const blink::Member<blink::File>& file : share_data->files()) { + files.ReserveInitialCapacity(data->files().size()); + for (const blink::Member<blink::File>& file : data->files()) { total_bytes += file->size(); files.push_back(mojom::blink::SharedFile::New(file->name(), file->GetBlobDataHandle())); @@ -248,9 +252,8 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state, } service_remote_->Share( - share_data->hasTitle() ? share_data->title() : g_empty_string, - share_data->hasText() ? share_data->text() : g_empty_string, full_url, - std::move(files), + data->hasTitle() ? data->title() : g_empty_string, + data->hasText() ? data->text() : g_empty_string, url, std::move(files), WTF::Bind(&ShareClientImpl::Callback, WrapPersistent(client))); return promise; @@ -258,9 +261,9 @@ ScriptPromise NavigatorShare::share(ScriptState* script_state, ScriptPromise NavigatorShare::share(ScriptState* script_state, Navigator& navigator, - const ShareData* share_data, + const ShareData* data, ExceptionState& exception_state) { - return From(navigator).share(script_state, share_data, exception_state); + return From(navigator).share(script_state, data, exception_state); } void NavigatorShare::OnConnectionError() { 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 1c497a723ba..06917da66ad 100644 --- a/chromium/third_party/blink/renderer/modules/webshare/navigator_share.h +++ b/chromium/third_party/blink/renderer/modules/webshare/navigator_share.h @@ -33,8 +33,8 @@ class MODULES_EXPORT NavigatorShare final public: static const char kSupplementName[]; - NavigatorShare(); - ~NavigatorShare(); + NavigatorShare() = default; + ~NavigatorShare() = default; // Gets, or creates, NavigatorShare supplement on Navigator. // See platform/Supplementable.h @@ -49,16 +49,17 @@ class MODULES_EXPORT NavigatorShare final const ShareData*, ExceptionState&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: class ShareClientImpl; void OnConnectionError(); + // |NavigatorShare| is not ExecutionContext-associated. HeapMojoRemote<blink::mojom::blink::ShareService, HeapMojoWrapperMode::kWithoutContextObserver> - service_remote_; + service_remote_{nullptr}; HeapHashSet<Member<ShareClientImpl>> clients_; }; diff --git a/chromium/third_party/blink/renderer/modules/websockets/close_event.h b/chromium/third_party/blink/renderer/modules/websockets/close_event.h index 6880c91dfa8..6cb8794524f 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/close_event.h +++ b/chromium/third_party/blink/renderer/modules/websockets/close_event.h @@ -70,7 +70,7 @@ class CloseEvent final : public Event { return event_interface_names::kCloseEvent; } - void Trace(Visitor* visitor) override { Event::Trace(visitor); } + void Trace(Visitor* visitor) const override { Event::Trace(visitor); } private: bool was_clean_; diff --git a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc index 7cc63e5d1ba..0e9c87462e3 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc +++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.cc @@ -165,7 +165,7 @@ void DOMWebSocket::EventQueue::UnpauseTask() { DispatchQueuedEvents(); } -void DOMWebSocket::EventQueue::Trace(Visitor* visitor) { +void DOMWebSocket::EventQueue::Trace(Visitor* visitor) const { visitor->Trace(target_); visitor->Trace(events_); } @@ -690,7 +690,7 @@ void DOMWebSocket::RecordReceiveMessageSizeHistogram(WebSocketReceiveType type, NOTREACHED(); } -void DOMWebSocket::Trace(Visitor* visitor) { +void DOMWebSocket::Trace(Visitor* visitor) const { visitor->Trace(channel_); visitor->Trace(event_queue_); WebSocketChannelClient::Trace(visitor); 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 2082fe9c0e7..b9b69cf43ff 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h +++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket.h @@ -149,7 +149,7 @@ class MODULES_EXPORT DOMWebSocket uint16_t code, const String& reason) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // FIXME: This should inherit blink::EventQueue. @@ -175,7 +175,7 @@ class MODULES_EXPORT DOMWebSocket bool IsPaused(); - void Trace(Visitor*); + void Trace(Visitor*) const; private: enum State { diff --git a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc index a49fff11608..4c50ae0990b 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc +++ b/chromium/third_party/blink/renderer/modules/websockets/dom_websocket_test.cc @@ -66,7 +66,7 @@ class DOMWebSocketWithMockChannel final : public DOMWebSocket { return channel_.Get(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(channel_); DOMWebSocket::Trace(visitor); } 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 ee745730879..daa131625b0 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 @@ -60,7 +60,7 @@ class WebPepperSocketChannelClientProxy final impl->DidClose(status, code, reason); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { WebSocketChannelClient::Trace(visitor); } 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 5c31fe8c0c0..e981932df4c 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel.h @@ -115,7 +115,7 @@ class MODULES_EXPORT WebSocketChannel // to indicate that they are ready to receive new messages. virtual void RemoveBackpressure() = 0; - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} private: DISALLOW_COPY_AND_ASSIGN(WebSocketChannel); diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_client.h b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_client.h index 33a5e98b116..7d025132385 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_client.h +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_channel_client.h @@ -59,7 +59,7 @@ class MODULES_EXPORT WebSocketChannelClient : public GarbageCollectedMixin { virtual void DidClose(ClosingHandshakeCompletionStatus, uint16_t /* code */, const String& /* reason */) {} - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} protected: WebSocketChannelClient() = default; 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 54729067b5e..a324546acb3 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 @@ -33,8 +33,10 @@ #include <memory> #include "base/callback.h" +#include "base/compiler_specific.h" #include "base/location.h" #include "base/memory/ptr_util.h" +#include "base/util/type_safety/strong_alias.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/websockets/websocket_connector.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" @@ -97,7 +99,7 @@ class WebSocketChannelImpl::BlobLoader final void DidFinishLoading() override; void DidFail(FileErrorCode) override; - void Trace(Visitor* visitor) { visitor->Trace(channel_); } + void Trace(Visitor* visitor) const { visitor->Trace(channel_); } private: Member<WebSocketChannelImpl> channel_; @@ -107,19 +109,30 @@ class WebSocketChannelImpl::BlobLoader final class WebSocketChannelImpl::Message final : public GarbageCollected<WebSocketChannelImpl::Message> { public: - Message(const std::string&, base::OnceClosure completion_callback); + using DidCallSendMessage = + util::StrongAlias<class DidCallSendMessageTag, bool>; + Message(const std::string&, + base::OnceClosure completion_callback, + DidCallSendMessage did_call_send_message); explicit Message(scoped_refptr<BlobDataHandle>); - Message(DOMArrayBuffer*, base::OnceClosure completion_callback); + Message(DOMArrayBuffer*, + base::OnceClosure completion_callback, + DidCallSendMessage did_call_send_message); + Message(MessageType type, + base::span<const char> message, + base::OnceClosure completion_callback); // Close message Message(uint16_t code, const String& reason); - void Trace(Visitor* visitor) { visitor->Trace(array_buffer); } + void Trace(Visitor* visitor) const { visitor->Trace(array_buffer); } MessageType type; std::string text; scoped_refptr<BlobDataHandle> blob_data_handle; Member<DOMArrayBuffer> array_buffer; + base::span<const char> pending_payload; + DidCallSendMessage did_call_send_message = DidCallSendMessage(false); uint16_t code; String reason; base::OnceClosure completion_callback; @@ -200,6 +213,10 @@ WebSocketChannelImpl::WebSocketChannelImpl( FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, execution_context->GetTaskRunner(TaskType::kNetworking)), + writable_watcher_( + FROM_HERE, + mojo::SimpleWatcher::ArmingPolicy::MANUAL, + execution_context->GetTaskRunner(TaskType::kNetworking)), file_reading_task_runner_( execution_context->GetTaskRunner(TaskType::kFileReading)) { if (auto* scope = DynamicTo<WorkerGlobalScope>(*execution_context_)) @@ -296,15 +313,23 @@ WebSocketChannel::SendResult WebSocketChannelImpl::Send( probe::DidSendWebSocketMessage(execution_context_, identifier_, WebSocketOpCode::kOpCodeText, true, message.c_str(), message.length()); - if (messages_.empty() && - MaybeSendSynchronously(network::mojom::blink::WebSocketMessageType::TEXT, - message)) { - return SendResult::SENT_SYNCHRONOUSLY; + + bool did_attempt_to_send = false; + base::span<const char> data = message; + if (messages_.empty() && !wait_for_writable_) { + did_attempt_to_send = true; + if (MaybeSendSynchronously( + network::mojom::blink::WebSocketMessageType::TEXT, &data)) { + return SendResult::SENT_SYNCHRONOUSLY; + } } - messages_.push_back( - MakeGarbageCollected<Message>(message, std::move(completion_callback))); + messages_.push_back(MakeGarbageCollected<Message>( + message.substr(message.size() - data.size(), data.size()), + std::move(completion_callback), + Message::DidCallSendMessage(did_attempt_to_send))); + // ProcessSendQueue() will do nothing when MaybeSendSynchronously() is called. ProcessSendQueue(); // If we managed to flush this message synchronously after all, it would mean @@ -341,19 +366,27 @@ WebSocketChannel::SendResult WebSocketChannelImpl::Send( probe::DidSendWebSocketMessage( execution_context_, identifier_, WebSocketOpCode::kOpCodeBinary, true, static_cast<const char*>(buffer.Data()) + byte_offset, byte_length); - if (messages_.empty() && - MaybeSendSynchronously( - network::mojom::blink::WebSocketMessageType::BINARY, - base::make_span(static_cast<const char*>(buffer.Data()) + byte_offset, - byte_length))) { - return SendResult::SENT_SYNCHRONOUSLY; + + bool did_attempt_to_send = false; + base::span<const char> message = base::make_span( + static_cast<const char*>(buffer.Data()) + byte_offset, byte_length); + if (messages_.empty() && !wait_for_writable_) { + did_attempt_to_send = true; + if (MaybeSendSynchronously( + network::mojom::blink::WebSocketMessageType::BINARY, &message)) { + return SendResult::SENT_SYNCHRONOUSLY; + } + byte_offset += byte_length - message.size(); + byte_length = message.size(); } // buffer.Slice copies its contents. messages_.push_back(MakeGarbageCollected<Message>( buffer.Slice(byte_offset, byte_offset + byte_length), - std::move(completion_callback))); + std::move(completion_callback), + Message::DidCallSendMessage(did_attempt_to_send))); + // ProcessSendQueue() will do nothing when MaybeSendSynchronously() is called. ProcessSendQueue(); // If we managed to flush this message synchronously after all, it would mean @@ -496,6 +529,13 @@ void WebSocketChannelImpl::OnConnectionEstablished( WrapWeakPersistent(this))); DCHECK_EQ(mojo_result, MOJO_RESULT_OK); + const MojoResult mojo_writable_result = writable_watcher_.Watch( + writable_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, + MOJO_WATCH_CONDITION_SATISFIED, + WTF::BindRepeating(&WebSocketChannelImpl::OnWritable, + WrapWeakPersistent(this))); + DCHECK_EQ(mojo_writable_result, MOJO_RESULT_OK); + if (!throttle_passed_) { connect_info_ = std::make_unique<ConnectInfo>(protocol, extensions); return; @@ -519,15 +559,6 @@ void WebSocketChannelImpl::OnDataFrame( ConsumePendingDataFrames(); } -void WebSocketChannelImpl::AddSendFlowControlQuota(int64_t quota) { - // TODO(yhirano): This should be DCHECK_EQ(GetState(), State::kOpen). - DCHECK(GetState() == State::kOpen || GetState() == State::kConnecting); - NETWORK_DVLOG(1) << this << " AddSendFlowControlQuota(" << quota << ")"; - - sending_quota_ += quota; - ProcessSendQueue(); -} - void WebSocketChannelImpl::OnDropChannel(bool was_clean, uint16_t code, const String& reason) { @@ -554,7 +585,7 @@ void WebSocketChannelImpl::OnClosingHandshake() { client_->DidStartClosingHandshake(); } -void WebSocketChannelImpl::Trace(Visitor* visitor) { +void WebSocketChannelImpl::Trace(Visitor* visitor) const { visitor->Trace(blob_loader_); visitor->Trace(messages_); visitor->Trace(client_); @@ -566,9 +597,12 @@ void WebSocketChannelImpl::Trace(Visitor* visitor) { } WebSocketChannelImpl::Message::Message(const std::string& text, - base::OnceClosure completion_callback) + base::OnceClosure completion_callback, + DidCallSendMessage did_call_send_message) : type(kMessageTypeText), text(text), + pending_payload(this->text), + did_call_send_message(did_call_send_message), completion_callback(std::move(completion_callback)) {} WebSocketChannelImpl::Message::Message( @@ -576,14 +610,26 @@ WebSocketChannelImpl::Message::Message( : type(kMessageTypeBlob), blob_data_handle(std::move(blob_data_handle)) {} WebSocketChannelImpl::Message::Message(DOMArrayBuffer* array_buffer, - base::OnceClosure completion_callback) + base::OnceClosure completion_callback, + DidCallSendMessage did_call_send_message) : type(kMessageTypeArrayBuffer), array_buffer(array_buffer), + pending_payload( + base::make_span(static_cast<const char*>(array_buffer->Data()), + array_buffer->ByteLengthAsSizeT())), + did_call_send_message(did_call_send_message), completion_callback(std::move(completion_callback)) {} WebSocketChannelImpl::Message::Message(uint16_t code, const String& reason) : type(kMessageTypeClose), code(code), reason(reason) {} +WebSocketChannelImpl::Message::Message(MessageType type, + base::span<const char> pending_payload, + base::OnceClosure completion_callback) + : type(type), + pending_payload(pending_payload), + completion_callback(std::move(completion_callback)) {} + WebSocketChannelImpl::State WebSocketChannelImpl::GetState() const { if (!has_initiated_opening_handshake_) { return State::kConnecting; @@ -597,81 +643,43 @@ WebSocketChannelImpl::State WebSocketChannelImpl::GetState() const { return State::kDisconnected; } -void WebSocketChannelImpl::SendInternal( - network::mojom::blink::WebSocketMessageType message_type, - const char* data, - size_t total_size, - uint64_t* consumed_buffered_amount) { - network::mojom::blink::WebSocketMessageType frame_type = - sent_size_of_top_message_ - ? network::mojom::blink::WebSocketMessageType::CONTINUATION - : message_type; - DCHECK_GE(total_size, sent_size_of_top_message_); - // The cast is safe since the result of min() never exceeds the range of - // size_t. - size_t size = static_cast<size_t>(std::min<uint64_t>( - sending_quota_, total_size - sent_size_of_top_message_)); - bool final = (sent_size_of_top_message_ + size == total_size); - - SendAndAdjustQuota(final, frame_type, - base::make_span(data + sent_size_of_top_message_, size), - consumed_buffered_amount); - - sent_size_of_top_message_ += size; - - if (final) { - base::OnceClosure completion_callback = - std::move(messages_.front()->completion_callback); - if (!completion_callback.is_null()) - std::move(completion_callback).Run(); - messages_.pop_front(); - sent_size_of_top_message_ = 0; - } -} - -void WebSocketChannelImpl::SendAndAdjustQuota( - bool fin, - network::mojom::blink::WebSocketMessageType type, - base::span<const char> data, - uint64_t* consumed_buffered_amount) { - 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(); - *consumed_buffered_amount += data.size(); -} - bool WebSocketChannelImpl::MaybeSendSynchronously( network::mojom::blink::WebSocketMessageType frame_type, - base::span<const char> data) { + base::span<const char>* data) { DCHECK(messages_.empty()); - if (data.size() > sending_quota_) - return false; + DCHECK(!wait_for_writable_); - uint64_t consumed_buffered_amount = 0; - SendAndAdjustQuota(true, frame_type, data, &consumed_buffered_amount); - if (client_ && consumed_buffered_amount > 0) - client_->DidConsumeBufferedAmount(consumed_buffered_amount); - - return true; + websocket_->SendMessage(frame_type, data->size()); + return SendMessageData(data); } void WebSocketChannelImpl::ProcessSendQueue() { // TODO(yhirano): This should be DCHECK_EQ(GetState(), State::kOpen). DCHECK(GetState() == State::kOpen || GetState() == State::kConnecting); - uint64_t consumed_buffered_amount = 0; - while (!messages_.IsEmpty() && !blob_loader_) { + while (!messages_.IsEmpty() && !blob_loader_ && !wait_for_writable_) { Message* message = messages_.front().Get(); + network::mojom::blink::WebSocketMessageType message_type = + network::mojom::blink::WebSocketMessageType::BINARY; CHECK(message); - if (sending_quota_ == 0 && message->type != kMessageTypeClose) - break; switch (message->type) { case kMessageTypeText: - SendInternal(network::mojom::blink::WebSocketMessageType::TEXT, - message->text.data(), message->text.length(), - &consumed_buffered_amount); + message_type = network::mojom::blink::WebSocketMessageType::TEXT; + FALLTHROUGH; + case kMessageTypeArrayBuffer: { + base::span<const char>& data_frame = message->pending_payload; + if (!message->did_call_send_message) { + websocket_->SendMessage(message_type, data_frame.size()); + message->did_call_send_message = Message::DidCallSendMessage(true); + } + if (!SendMessageData(&data_frame)) + return; + base::OnceClosure completion_callback = + std::move(messages_.front()->completion_callback); + if (!completion_callback.is_null()) + std::move(completion_callback).Run(); + messages_.pop_front(); break; + } case kMessageTypeBlob: CHECK(!blob_loader_); CHECK(message); @@ -679,13 +687,6 @@ void WebSocketChannelImpl::ProcessSendQueue() { blob_loader_ = MakeGarbageCollected<BlobLoader>( message->blob_data_handle, this, file_reading_task_runner_); break; - case kMessageTypeArrayBuffer: - CHECK(message->array_buffer); - SendInternal(network::mojom::blink::WebSocketMessageType::BINARY, - static_cast<const char*>(message->array_buffer->Data()), - message->array_buffer->ByteLengthAsSizeT(), - &consumed_buffered_amount); - break; case kMessageTypeClose: { // No message should be sent from now on. DCHECK_EQ(messages_.size(), 1u); @@ -699,8 +700,38 @@ void WebSocketChannelImpl::ProcessSendQueue() { } } } - if (client_ && consumed_buffered_amount > 0) - client_->DidConsumeBufferedAmount(consumed_buffered_amount); +} + +bool WebSocketChannelImpl::SendMessageData(base::span<const char>* data) { + if (data->size() > 0) { + uint64_t consumed_buffered_amount = 0; + ProduceData(data, &consumed_buffered_amount); + if (client_ && consumed_buffered_amount > 0) + client_->DidConsumeBufferedAmount(consumed_buffered_amount); + if (data->size() > 0) { + // The |writable_| datapipe is full. + wait_for_writable_ = true; + if (writable_) { + writable_watcher_.ArmOrNotify(); + } else { + // This is to maintain backwards compatibility with the legacy + // code, where it requires Send to be complete even if the + // datapipe is closed. To overcome this, call + // DidConsumeBufferedAmount() and ack as the message is correctly + // passed on to the network service. + // + // The corresponding bug for this is + // https://bugs.chromium.org/p/chromium/issues/detail?id=937790 + // The corresponding test case is + // browser_tests WebRequestApiTest.WebSocketCleanClose. + if (client_) { + client_->DidConsumeBufferedAmount(data->size()); + } + } + return false; + } + } + return true; } void WebSocketChannelImpl::AbortAsyncOperations() { @@ -755,8 +786,9 @@ void WebSocketChannelImpl::DidFinishLoadingBlob(DOMArrayBuffer* buffer) { DCHECK_GT(messages_.size(), 0u); DCHECK_EQ(messages_.front()->type, kMessageTypeBlob); // We replace it with the loaded blob. - messages_.front() = - MakeGarbageCollected<Message>(buffer, base::OnceClosure()); + messages_.front() = MakeGarbageCollected<Message>( + buffer, base::OnceClosure(), Message::DidCallSendMessage(false)); + ProcessSendQueue(); } @@ -929,6 +961,52 @@ void WebSocketChannelImpl::ConsumeDataFrame( received_text_is_all_ascii_ = true; } +void WebSocketChannelImpl::OnWritable(MojoResult result, + const mojo::HandleSignalsState& state) { + DCHECK_EQ(GetState(), State::kOpen); + NETWORK_DVLOG(2) << this << " OnWritable mojo_result=" << result; + if (result != MOJO_RESULT_OK) { + // We don't detect mojo errors on data pipe. Mojo connection errors will + // be detected via |client_receiver_|. + return; + } + wait_for_writable_ = false; + ProcessSendQueue(); +} + +MojoResult WebSocketChannelImpl::ProduceData( + base::span<const char>* data, + uint64_t* consumed_buffered_amount) { + MojoResult begin_result = MOJO_RESULT_OK; + void* buffer; + uint32_t writable_size = 0; + while (data->size() > 0 && + (begin_result = writable_->BeginWriteData( + &buffer, &writable_size, MOJO_WRITE_DATA_FLAG_NONE)) == + MOJO_RESULT_OK) { + // Since |writable_size| is definitely within uint32_t range, + // |size_to_write| will also be within uint32_t range. Hence, it is safe to + // cast |size_to_write| to uint32_t here. + const uint32_t size_to_write = static_cast<uint32_t>( + std::min(static_cast<size_t>(writable_size), data->size())); + DCHECK_GT(size_to_write, 0u); + + memcpy(buffer, data->data(), size_to_write); + *data = data->subspan(size_to_write); + + const MojoResult end_result = writable_->EndWriteData(size_to_write); + DCHECK_EQ(end_result, MOJO_RESULT_OK); + *consumed_buffered_amount += size_to_write; + } + if (begin_result != MOJO_RESULT_OK && + begin_result != MOJO_RESULT_SHOULD_WAIT) { + DVLOG(1) << "WebSocket::OnWritable mojo error=" << begin_result; + DCHECK_EQ(begin_result, MOJO_RESULT_FAILED_PRECONDITION); + writable_.reset(); + } + return begin_result; +} + String WebSocketChannelImpl::GetTextMessage( const Vector<base::span<const char>>& chunks, wtf_size_t size) { @@ -995,6 +1073,7 @@ void WebSocketChannelImpl::Dispose() { handshake_throttle_.reset(); websocket_.reset(); readable_watcher_.Cancel(); + writable_watcher_.Cancel(); handshake_client_receiver_.reset(); client_receiver_.reset(); identifier_ = 0; 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 446db71f101..a9a4be7a0c0 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 @@ -127,13 +127,12 @@ class MODULES_EXPORT WebSocketChannelImpl final void OnDataFrame(bool fin, network::mojom::blink::WebSocketMessageType, uint64_t data_length) override; - void AddSendFlowControlQuota(int64_t quota) override; void OnDropChannel(bool was_clean, uint16_t code, const String& reason) override; void OnClosingHandshake() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: struct DataFrame final { @@ -189,17 +188,10 @@ class MODULES_EXPORT WebSocketChannelImpl final }; State GetState() const; - void SendInternal(network::mojom::blink::WebSocketMessageType, - const char* data, - size_t total_size, - uint64_t* consumed_buffered_amount); - void SendAndAdjustQuota(bool final, - network::mojom::blink::WebSocketMessageType, - base::span<const char>, - uint64_t* consumed_buffered_amount); bool MaybeSendSynchronously(network::mojom::blink::WebSocketMessageType, - base::span<const char>); + base::span<const char>* data); void ProcessSendQueue(); + bool SendMessageData(base::span<const char>* data); void FailAsError(const String& reason) { Fail(reason, mojom::ConsoleMessageLevel::kError, location_at_construction_->Clone()); @@ -226,6 +218,10 @@ class MODULES_EXPORT WebSocketChannelImpl final network::mojom::blink::WebSocketMessageType type, const char* data, size_t data_size); + // Called when |writable_| becomes writable. + void OnWritable(MojoResult result, const mojo::HandleSignalsState& state); + MojoResult ProduceData(base::span<const char>* data, + uint64_t* consumed_buffered_amount); String GetTextMessage(const Vector<base::span<const char>>& chunks, wtf_size_t size); void OnConnectionError(const base::Location& set_from, @@ -246,7 +242,6 @@ class MODULES_EXPORT WebSocketChannelImpl final bool received_text_is_all_ascii_ = true; bool throttle_passed_ = false; bool has_initiated_opening_handshake_ = false; - uint64_t sending_quota_ = 0; size_t sent_size_of_top_message_ = 0; FrameScheduler::SchedulingAffectingFeatureHandle feature_handle_for_scheduler_; @@ -275,6 +270,8 @@ class MODULES_EXPORT WebSocketChannelImpl final WTF::Deque<DataFrame> pending_data_frames_; mojo::ScopedDataPipeProducerHandle writable_; + mojo::SimpleWatcher writable_watcher_; + bool wait_for_writable_ = false; const scoped_refptr<base::SingleThreadTaskRunner> file_reading_task_runner_; }; 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 3d05c4d573d..9282c1f3835 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 @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/modules/websockets/websocket_channel_impl.h" #include <stdint.h> +#include <string.h> #include <memory> #include "base/callback.h" @@ -75,7 +76,7 @@ class MockWebSocketChannelClient MOCK_METHOD3(DidClose, void(ClosingHandshakeCompletionStatus, uint16_t, const String&)); - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { WebSocketChannelClient::Trace(visitor); } }; @@ -98,16 +99,6 @@ class WebSocketChannelImplTest : public PageTestBase { using WebSocketMessageType = network::mojom::WebSocketMessageType; class TestWebSocket final : public network::mojom::blink::WebSocket { public: - struct Frame { - bool fin; - WebSocketMessageType type; - Vector<uint8_t> data; - - bool operator==(const Frame& that) const { - return fin == that.fin && type == that.type && data == that.data; - } - }; - struct DataFrame final { DataFrame(WebSocketMessageType type, uint64_t data_length) : type(type), data_length(data_length) {} @@ -125,13 +116,6 @@ class WebSocketChannelImplTest : public PageTestBase { pending_receiver) : receiver_(this, std::move(pending_receiver)) {} - void SendFrame(bool fin, - WebSocketMessageType type, - 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 SendMessage(WebSocketMessageType type, uint64_t data_length) override { pending_send_data_frames_.push_back(DataFrame(type, data_length)); return; @@ -147,8 +131,6 @@ class WebSocketChannelImplTest : public PageTestBase { closing_reason_ = reason; } - const Vector<Frame>& GetFrames() const { return frames_; } - void ClearFrames() { frames_.clear(); } const Vector<DataFrame>& GetDataFrames() const { return pending_send_data_frames_; } @@ -161,7 +143,6 @@ class WebSocketChannelImplTest : public PageTestBase { const String& GetClosingReason() const { return closing_reason_; } private: - Vector<Frame> frames_; Vector<DataFrame> pending_send_data_frames_; bool is_start_receiving_called_ = false; bool is_start_closing_handshake_called_ = false; @@ -170,7 +151,6 @@ class WebSocketChannelImplTest : public PageTestBase { mojo::Receiver<network::mojom::blink::WebSocket> receiver_; }; - using Frames = Vector<TestWebSocket::Frame>; using DataFrames = Vector<TestWebSocket::DataFrame>; class WebSocketConnector final : public mojom::blink::WebSocketConnector { @@ -315,6 +295,30 @@ class WebSocketChannelImplTest : public PageTestBase { return AsVector(data, strlen(data)); } + Vector<uint8_t> ReadDataFromDataPipe( + mojo::ScopedDataPipeConsumerHandle& readable, + uint32_t bytes_to_read) { + const void* buffer; + uint32_t num_bytes = bytes_to_read; + const MojoResult begin_result = + readable->BeginReadData(&buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE); + + DCHECK_EQ(begin_result, MOJO_RESULT_OK); + if (num_bytes < bytes_to_read) { + ADD_FAILURE() << "ReadDataFromDataPipe expected " << bytes_to_read + << " bytes but only received " << num_bytes << " bytes"; + return Vector<uint8_t>(); + } + + Vector<uint8_t> data_to_pass; + data_to_pass.Append(static_cast<const uint8_t*>(buffer), bytes_to_read); + + const MojoResult end_result = readable->EndReadData(bytes_to_read); + DCHECK_EQ(end_result, MOJO_RESULT_OK); + + return data_to_pass; + } + // Returns nullptr if something bad happens. std::unique_ptr<TestWebSocket> Connect( uint32_t capacity, @@ -388,8 +392,8 @@ class CallTrackingClosure { std::ostream& operator<<( std::ostream& o, - const WebSocketChannelImplTest::TestWebSocket::Frame& f) { - return o << "fin = " << f.fin << ", type = " << f.type << ", data = (...)"; + const WebSocketChannelImplTest::TestWebSocket::DataFrame& f) { + return o << " type = " << f.type << ", data = (...)"; } TEST_F(WebSocketChannelImplTest, ConnectSuccess) { @@ -486,69 +490,10 @@ TEST_F(WebSocketChannelImplTest, SendText) { test::RunPendingTasks(); - EXPECT_TRUE(websocket->GetFrames().IsEmpty()); - - client->AddSendFlowControlQuota(16); - - EXPECT_TRUE(websocket->GetFrames().IsEmpty()); - test::RunPendingTasks(); - - EXPECT_EQ(websocket->GetFrames(), - (Frames{{true, WebSocketMessageType::TEXT, AsVector("foo")}, - {true, WebSocketMessageType::TEXT, AsVector("bar")}, - {true, WebSocketMessageType::TEXT, AsVector("baz")}})); - - EXPECT_EQ(9u, sum_of_consumed_buffered_amount_); -} - -TEST_F(WebSocketChannelImplTest, SendTextContinuation) { - EXPECT_CALL(*ChannelClient(), DidConnect(_, _)); - EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber()); - - mojo::ScopedDataPipeProducerHandle writable; - mojo::ScopedDataPipeConsumerHandle readable; - mojo::Remote<network::mojom::blink::WebSocketClient> client; - auto websocket = Connect(4 * 1024, &writable, &readable, &client); - ASSERT_TRUE(websocket); - - client->AddSendFlowControlQuota(16); - - Channel()->Send("0123456789abcdefg", base::OnceClosure()); - Channel()->Send("hijk", base::OnceClosure()); - Channel()->Send("lmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", - base::OnceClosure()); - test::RunPendingTasks(); - - EXPECT_EQ(websocket->GetFrames(), (Frames{{false, WebSocketMessageType::TEXT, - AsVector("0123456789abcdef")}})); - - websocket->ClearFrames(); - client->AddSendFlowControlQuota(16); - test::RunPendingTasks(); - - EXPECT_EQ( - websocket->GetFrames(), - (Frames{{true, WebSocketMessageType::CONTINUATION, AsVector("g")}, - {true, WebSocketMessageType::TEXT, AsVector("hijk")}, - {false, WebSocketMessageType::TEXT, AsVector("lmnopqrstuv")}})); - - websocket->ClearFrames(); - client->AddSendFlowControlQuota(16); - test::RunPendingTasks(); - - EXPECT_EQ(websocket->GetFrames(), - (Frames{{false, WebSocketMessageType::CONTINUATION, - AsVector("wxyzABCDEFGHIJKL")}})); - - websocket->ClearFrames(); - client->AddSendFlowControlQuota(16); - test::RunPendingTasks(); - - EXPECT_EQ(websocket->GetFrames(), - (Frames{{true, WebSocketMessageType::CONTINUATION, - AsVector("MNOPQRSTUVWXYZ")}})); - - EXPECT_EQ(62u, sum_of_consumed_buffered_amount_); + EXPECT_EQ(websocket->GetDataFrames(), + (DataFrames{{WebSocketMessageType::TEXT, strlen("foo")}, + {WebSocketMessageType::TEXT, strlen("bar")}, + {WebSocketMessageType::TEXT, strlen("baz")}})); } TEST_F(WebSocketChannelImplTest, SendBinaryInVector) { @@ -561,16 +506,14 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInVector) { auto websocket = Connect(4 * 1024, &writable, &readable, &client); ASSERT_TRUE(websocket); - client->AddSendFlowControlQuota(16); - DOMArrayBuffer* foo_buffer = DOMArrayBuffer::Create("foo", 3); Channel()->Send(*foo_buffer, 0, 3, base::OnceClosure()); test::RunPendingTasks(); - EXPECT_EQ(websocket->GetFrames(), - (Frames{{true, WebSocketMessageType::BINARY, AsVector("foo")}})); + EXPECT_EQ(websocket->GetDataFrames(), + (DataFrames{{WebSocketMessageType::BINARY, strlen("foo")}})); - EXPECT_EQ(3u, sum_of_consumed_buffered_amount_); + ASSERT_EQ(AsVector("foo"), ReadDataFromDataPipe(readable, 3u)); } TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferPartial) { @@ -583,8 +526,6 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferPartial) { auto websocket = Connect(4 * 1024, &writable, &readable, &client); ASSERT_TRUE(websocket); - client->AddSendFlowControlQuota(16); - DOMArrayBuffer* foobar_buffer = DOMArrayBuffer::Create("foobar", 6); DOMArrayBuffer* qbazux_buffer = DOMArrayBuffer::Create("qbazux", 6); Channel()->Send(*foobar_buffer, 0, 3, base::OnceClosure()); @@ -594,15 +535,18 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferPartial) { test::RunPendingTasks(); - EXPECT_EQ(websocket->GetFrames(), - (Frames{ - {true, WebSocketMessageType::BINARY, AsVector("foo")}, - {true, WebSocketMessageType::BINARY, AsVector("bar")}, - {true, WebSocketMessageType::BINARY, AsVector("baz")}, - {true, WebSocketMessageType::BINARY, AsVector("a")}, + EXPECT_EQ(websocket->GetDataFrames(), + (DataFrames{ + {WebSocketMessageType::BINARY, strlen("foo")}, + {WebSocketMessageType::BINARY, strlen("bar")}, + {WebSocketMessageType::BINARY, strlen("baz")}, + {WebSocketMessageType::BINARY, strlen("a")}, })); - EXPECT_EQ(10u, sum_of_consumed_buffered_amount_); + ASSERT_EQ(AsVector("foo"), ReadDataFromDataPipe(readable, 3u)); + ASSERT_EQ(AsVector("bar"), ReadDataFromDataPipe(readable, 3u)); + ASSERT_EQ(AsVector("baz"), ReadDataFromDataPipe(readable, 3u)); + ASSERT_EQ(AsVector("a"), ReadDataFromDataPipe(readable, 1u)); } TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferWithNullBytes) { @@ -615,35 +559,42 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferWithNullBytes) { auto websocket = Connect(4 * 1024, &writable, &readable, &client); ASSERT_TRUE(websocket); + constexpr int kLengthOfEachMessage = 3; { - DOMArrayBuffer* b = DOMArrayBuffer::Create("\0ar", 3); + DOMArrayBuffer* b = DOMArrayBuffer::Create("\0ar", kLengthOfEachMessage); Channel()->Send(*b, 0, 3, base::OnceClosure()); } { - DOMArrayBuffer* b = DOMArrayBuffer::Create("b\0z", 3); + DOMArrayBuffer* b = DOMArrayBuffer::Create("b\0z", kLengthOfEachMessage); Channel()->Send(*b, 0, 3, base::OnceClosure()); } { - DOMArrayBuffer* b = DOMArrayBuffer::Create("qu\0", 3); + DOMArrayBuffer* b = DOMArrayBuffer::Create("qu\0", kLengthOfEachMessage); Channel()->Send(*b, 0, 3, base::OnceClosure()); } { - DOMArrayBuffer* b = DOMArrayBuffer::Create("\0\0\0", 3); + DOMArrayBuffer* b = DOMArrayBuffer::Create("\0\0\0", kLengthOfEachMessage); Channel()->Send(*b, 0, 3, base::OnceClosure()); } - client->AddSendFlowControlQuota(16); test::RunPendingTasks(); - EXPECT_EQ(websocket->GetFrames(), - (Frames{ - {true, WebSocketMessageType::BINARY, AsVector("\0ar", 3)}, - {true, WebSocketMessageType::BINARY, AsVector("b\0z", 3)}, - {true, WebSocketMessageType::BINARY, AsVector("qu\0", 3)}, - {true, WebSocketMessageType::BINARY, AsVector("\0\0\0", 3)}, + EXPECT_EQ(websocket->GetDataFrames(), + (DataFrames{ + {WebSocketMessageType::BINARY, kLengthOfEachMessage}, + {WebSocketMessageType::BINARY, kLengthOfEachMessage}, + {WebSocketMessageType::BINARY, kLengthOfEachMessage}, + {WebSocketMessageType::BINARY, kLengthOfEachMessage}, })); - EXPECT_EQ(12u, sum_of_consumed_buffered_amount_); + ASSERT_EQ(AsVector("\0ar", kLengthOfEachMessage), + ReadDataFromDataPipe(readable, 3u)); + ASSERT_EQ(AsVector("b\0z", kLengthOfEachMessage), + ReadDataFromDataPipe(readable, 3u)); + ASSERT_EQ(AsVector("qu\0", kLengthOfEachMessage), + ReadDataFromDataPipe(readable, 3u)); + ASSERT_EQ(AsVector("\0\0\0", kLengthOfEachMessage), + ReadDataFromDataPipe(readable, 3u)); } TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferNonLatin1UTF8) { @@ -659,14 +610,13 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferNonLatin1UTF8) { DOMArrayBuffer* b = DOMArrayBuffer::Create("\xe7\x8b\x90", 3); Channel()->Send(*b, 0, 3, base::OnceClosure()); - client->AddSendFlowControlQuota(16); test::RunPendingTasks(); EXPECT_EQ( - websocket->GetFrames(), - (Frames{{true, WebSocketMessageType::BINARY, AsVector("\xe7\x8b\x90")}})); + websocket->GetDataFrames(), + (DataFrames{{WebSocketMessageType::BINARY, strlen("\xe7\x8b\x90")}})); - EXPECT_EQ(3u, sum_of_consumed_buffered_amount_); + ASSERT_EQ(AsVector("\xe7\x8b\x90"), ReadDataFromDataPipe(readable, 3u)); } TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferNonUTF8) { @@ -682,50 +632,13 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferNonUTF8) { DOMArrayBuffer* b = DOMArrayBuffer::Create("\x80\xff\xe7", 3); Channel()->Send(*b, 0, 3, base::OnceClosure()); - client->AddSendFlowControlQuota(16); test::RunPendingTasks(); EXPECT_EQ( - websocket->GetFrames(), - (Frames{{true, WebSocketMessageType::BINARY, AsVector("\x80\xff\xe7")}})); + websocket->GetDataFrames(), + (DataFrames{{WebSocketMessageType::BINARY, strlen("\x80\xff\xe7")}})); - EXPECT_EQ(3ul, sum_of_consumed_buffered_amount_); -} - -TEST_F(WebSocketChannelImplTest, - SendBinaryInArrayBufferNonLatin1UTF8Continuation) { - EXPECT_CALL(*ChannelClient(), DidConnect(_, _)); - EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber()); - - mojo::ScopedDataPipeProducerHandle writable; - mojo::ScopedDataPipeConsumerHandle readable; - mojo::Remote<network::mojom::blink::WebSocketClient> client; - auto websocket = Connect(4 * 1024, &writable, &readable, &client); - ASSERT_TRUE(websocket); - - DOMArrayBuffer* b = DOMArrayBuffer::Create( - "\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b" - "\x90", - 18); - Channel()->Send(*b, 0, 18, base::OnceClosure()); - - client->AddSendFlowControlQuota(16); - test::RunPendingTasks(); - - EXPECT_EQ(websocket->GetFrames(), - (Frames{{false, WebSocketMessageType::BINARY, - AsVector("\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90\xe7\x8b\x90" - "\xe7\x8b\x90\xe7")}})); - - websocket->ClearFrames(); - client->AddSendFlowControlQuota(16); - test::RunPendingTasks(); - - EXPECT_EQ(websocket->GetFrames(), - (Frames{{true, WebSocketMessageType::CONTINUATION, - AsVector("\x8b\x90")}})); - - EXPECT_EQ(18u, sum_of_consumed_buffered_amount_); + ASSERT_EQ(AsVector("\x80\xff\xe7"), ReadDataFromDataPipe(readable, 3u)); } TEST_F(WebSocketChannelImplTest, SendTextSync) { @@ -738,7 +651,6 @@ TEST_F(WebSocketChannelImplTest, SendTextSync) { auto websocket = Connect(4 * 1024, &writable, &readable, &client); ASSERT_TRUE(websocket); - client->AddSendFlowControlQuota(5); test::RunPendingTasks(); CallTrackingClosure closure; EXPECT_EQ(WebSocketChannel::SendResult::SENT_SYNCHRONOUSLY, @@ -746,7 +658,7 @@ TEST_F(WebSocketChannelImplTest, SendTextSync) { EXPECT_FALSE(closure.WasCalled()); } -TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQuota) { +TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQueueing) { EXPECT_CALL(*ChannelClient(), DidConnect(_, _)); EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber()); @@ -756,21 +668,28 @@ TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQuota) { auto websocket = Connect(4 * 1024, &writable, &readable, &client); ASSERT_TRUE(websocket); - client->AddSendFlowControlQuota(4); - test::RunPendingTasks(); + // The size of message matches the capacity of the datapipe + constexpr int kMessageSize = 4 * 1024; + // Ideally we'd use a Blob to block the queue in this test, but setting up a + // working blob environment in a unit-test is complicated, so just block + // behind a larger string instead. + std::string long_message(kMessageSize, 'a'); + + Channel()->Send(long_message, base::OnceClosure()); CallTrackingClosure closure; EXPECT_EQ(WebSocketChannel::SendResult::CALLBACK_WILL_BE_CALLED, - Channel()->Send("hello", closure.Closure())); - EXPECT_FALSE(closure.WasCalled()); + Channel()->Send(long_message, closure.Closure())); - client->AddSendFlowControlQuota(1); + ReadDataFromDataPipe(readable, kMessageSize); test::RunPendingTasks(); + ReadDataFromDataPipe(readable, kMessageSize); + EXPECT_TRUE(closure.WasCalled()); } -TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQueueing) { +TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToMessageSize) { EXPECT_CALL(*ChannelClient(), DidConnect(_, _)); EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber()); @@ -780,19 +699,15 @@ TEST_F(WebSocketChannelImplTest, SendTextAsyncDueToQueueing) { auto websocket = Connect(4 * 1024, &writable, &readable, &client); ASSERT_TRUE(websocket); - client->AddSendFlowControlQuota(8); - test::RunPendingTasks(); + // The size of message is greater than the capacity of the datapipe + constexpr int kMessageSize = 5 * 1024; + std::string long_message(kMessageSize, 'a'); - // Ideally we'd use a Blob to block the queue in this test, but setting up a - // working blob environment in a unit-test is complicated, so just block - // behind a larger string instead. - Channel()->Send("0123456789", base::OnceClosure()); CallTrackingClosure closure; EXPECT_EQ(WebSocketChannel::SendResult::CALLBACK_WILL_BE_CALLED, - Channel()->Send("hello", closure.Closure())); - EXPECT_FALSE(closure.WasCalled()); + Channel()->Send(long_message, closure.Closure())); - client->AddSendFlowControlQuota(7); + ReadDataFromDataPipe(readable, 4 * 1024); test::RunPendingTasks(); EXPECT_TRUE(closure.WasCalled()); @@ -808,63 +723,66 @@ TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferSync) { auto websocket = Connect(4 * 1024, &writable, &readable, &client); ASSERT_TRUE(websocket); - client->AddSendFlowControlQuota(5); test::RunPendingTasks(); CallTrackingClosure closure; const auto* b = DOMArrayBuffer::Create("hello", 5); EXPECT_EQ(WebSocketChannel::SendResult::SENT_SYNCHRONOUSLY, Channel()->Send(*b, 0, 5, closure.Closure())); + + test::RunPendingTasks(); + EXPECT_FALSE(closure.WasCalled()); } -TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferAsyncDueToQuota) { +TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferAsyncDueToQueueing) { EXPECT_CALL(*ChannelClient(), DidConnect(_, _)); EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber()); mojo::ScopedDataPipeProducerHandle writable; mojo::ScopedDataPipeConsumerHandle readable; mojo::Remote<network::mojom::blink::WebSocketClient> client; - auto websocket = Connect(4 * 1024, &writable, &readable, &client); + auto websocket = Connect(1024, &writable, &readable, &client); ASSERT_TRUE(websocket); - client->AddSendFlowControlQuota(4); - test::RunPendingTasks(); + // The size of message matches the capacity of the datapipe + constexpr int kMessageSize = 1024; + std::string long_message(kMessageSize, 'a'); CallTrackingClosure closure; - const auto* b = DOMArrayBuffer::Create("hello", 5); + const auto* b = DOMArrayBuffer::Create(long_message.data(), kMessageSize); + Channel()->Send(*b, 0, kMessageSize, base::OnceClosure()); EXPECT_EQ(WebSocketChannel::SendResult::CALLBACK_WILL_BE_CALLED, - Channel()->Send(*b, 0, 5, closure.Closure())); - EXPECT_FALSE(closure.WasCalled()); + Channel()->Send(*b, 0, kMessageSize, closure.Closure())); - client->AddSendFlowControlQuota(1); + ReadDataFromDataPipe(readable, kMessageSize); test::RunPendingTasks(); + ReadDataFromDataPipe(readable, kMessageSize); + EXPECT_TRUE(closure.WasCalled()); } -TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferAsyncDueToQueueing) { +TEST_F(WebSocketChannelImplTest, SendBinaryInArrayBufferAsyncDueToMessageSize) { EXPECT_CALL(*ChannelClient(), DidConnect(_, _)); EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)).Times(AnyNumber()); mojo::ScopedDataPipeProducerHandle writable; mojo::ScopedDataPipeConsumerHandle readable; mojo::Remote<network::mojom::blink::WebSocketClient> client; - auto websocket = Connect(4 * 1024, &writable, &readable, &client); + auto websocket = Connect(1024, &writable, &readable, &client); ASSERT_TRUE(websocket); - client->AddSendFlowControlQuota(8); - test::RunPendingTasks(); + // The size of message is greater than the capacity of the datapipe + constexpr int kMessageSize = 2 * 1024; + std::string long_message(kMessageSize, 'a'); - Channel()->Send("0123456789", base::OnceClosure()); CallTrackingClosure closure; - const auto* b = DOMArrayBuffer::Create("hello", 5); + const auto* b = DOMArrayBuffer::Create(long_message.data(), kMessageSize); EXPECT_EQ(WebSocketChannel::SendResult::CALLBACK_WILL_BE_CALLED, - Channel()->Send(*b, 0, 5, closure.Closure())); + Channel()->Send(*b, 0, kMessageSize, closure.Closure())); - EXPECT_FALSE(closure.WasCalled()); - - client->AddSendFlowControlQuota(8); + ReadDataFromDataPipe(readable, 1024); test::RunPendingTasks(); EXPECT_TRUE(closure.WasCalled()); @@ -1598,4 +1516,34 @@ TEST_F(WebSocketChannelImplHandshakeThrottleTest, ConnectFailBeforeThrottle) { test::RunPendingTasks(); } +TEST_F(WebSocketChannelImplTest, RemoteConnectionCloseDuringSend) { + { + InSequence s; + + EXPECT_CALL(*ChannelClient(), DidConnect(_, _)); + EXPECT_CALL(*ChannelClient(), DidConsumeBufferedAmount(_)); + EXPECT_CALL(*ChannelClient(), DidStartClosingHandshake()); + EXPECT_CALL(*ChannelClient(), DidClose(_, _, _)); + } + + mojo::ScopedDataPipeProducerHandle writable; + mojo::ScopedDataPipeConsumerHandle readable; + mojo::Remote<network::mojom::blink::WebSocketClient> client; + auto websocket = Connect(4 * 1024, &writable, &readable, &client); + ASSERT_TRUE(websocket); + + // The message must be larger than the data pipe. + std::string message(16 * 1024, 'a'); + Channel()->Send(message, base::OnceClosure()); + + client->OnClosingHandshake(); + test::RunPendingTasks(); + + client->OnDropChannel(true, WebSocketChannel::kCloseEventCodeNormalClosure, + ""); + + // The test passes if this doesn't crash. + test::RunPendingTasks(); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/websockets/websocket_common.cc b/chromium/third_party/blink/renderer/modules/websockets/websocket_common.cc index a416644e20d..4cd6d80b700 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_common.cc +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_common.cc @@ -88,7 +88,7 @@ WebSocketCommon::ConnectResult WebSocketCommon::Connect( } if (!execution_context->GetContentSecurityPolicyForWorld() - ->AllowConnectToSource(url_)) { + ->AllowConnectToSource(url_, url_, RedirectStatus::kNoRedirect)) { state_ = kClosed; return ConnectResult::kAsyncError; 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 1c9a29ad674..78fb64773dd 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.cc @@ -53,7 +53,7 @@ class WebSocketStream::UnderlyingSource final : public UnderlyingSourceBase { void DidStartClosingHandshake(); void DidClose(bool was_clean, uint16_t code, const String& reason); - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(creator_); UnderlyingSourceBase::Trace(visitor); } @@ -85,7 +85,7 @@ class WebSocketStream::UnderlyingSink final : public UnderlyingSinkBase { void DidClose(bool was_clean, uint16_t code, const String& reason); bool AllDataHasBeenConsumed() { return !is_writing_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(creator_); visitor->Trace(close_resolver_); UnderlyingSinkBase::Trace(visitor); @@ -587,7 +587,7 @@ bool WebSocketStream::HasPendingActivity() const { return channel_; } -void WebSocketStream::Trace(Visitor* visitor) { +void WebSocketStream::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(connection_resolver_); visitor->Trace(closed_resolver_); @@ -611,17 +611,17 @@ void WebSocketStream::Connect(ScriptState* script_state, // 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 (options->hasSignal()) { + auto* signal = options->signal(); + if (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))); } 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 194c862d313..84773de5fc4 100644 --- a/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h +++ b/chromium/third_party/blink/renderer/modules/websockets/websocket_stream.h @@ -83,7 +83,7 @@ class MODULES_EXPORT WebSocketStream final // Implementation of ActiveScriptWrappable. bool HasPendingActivity() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: class UnderlyingSource; diff --git a/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc index 2ab40ec8820..60aaa74f2db 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc +++ b/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.cc @@ -7,7 +7,6 @@ #include <utility> #include "base/check.h" -#include "base/logging.h" #include "third_party/blink/renderer/modules/webtransport/quic_transport.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/persistent.h" @@ -64,11 +63,12 @@ void BidirectionalStream::SendFin() { void BidirectionalStream::OnOutgoingStreamAbort() { DCHECK(!sent_fin_); + quic_transport_->AbortStream(stream_id_); quic_transport_->ForgetStream(stream_id_); incoming_stream_->Reset(); } -void BidirectionalStream::Trace(Visitor* visitor) { +void BidirectionalStream::Trace(Visitor* visitor) const { visitor->Trace(outgoing_stream_); visitor->Trace(incoming_stream_); visitor->Trace(quic_transport_); diff --git a/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.h index a86b9371c09..f7da10abd74 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.h +++ b/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream.h @@ -69,7 +69,7 @@ class MODULES_EXPORT BidirectionalStream final : public ScriptWrappable, void SendFin() override; void OnOutgoingStreamAbort() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void OnIncomingStreamAbort(); diff --git a/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream_test.cc b/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream_test.cc index a02f76640a2..088b21cb1fb 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream_test.cc +++ b/chromium/third_party/blink/renderer/modules/webtransport/bidirectional_stream_test.cc @@ -24,6 +24,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_uint8_array.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_bidirectional_stream.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_quic_transport_options.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_reader.h" @@ -72,6 +73,7 @@ class StubQuicTransport : public network::mojom::blink::QuicTransport { } bool WasSendFinCalled() const { return was_send_fin_called_; } + bool WasAbortStreamCalled() const { return was_abort_stream_called_; } // Responds to an earlier call to AcceptBidirectionalStream with a new stream // as if it was created by the remote server. The remote handles can be @@ -146,6 +148,11 @@ class StubQuicTransport : public network::mojom::blink::QuicTransport { was_send_fin_called_ = true; } + void AbortStream(uint32_t stream_id, uint64_t code) override { + EXPECT_EQ(stream_id, kDefaultStreamId); + was_abort_stream_called_ = true; + } + private: base::OnceCallback<void(uint32_t, mojo::ScopedDataPipeConsumerHandle, @@ -157,6 +164,7 @@ class StubQuicTransport : public network::mojom::blink::QuicTransport { mojo::ScopedDataPipeConsumerHandle output_consumer_; mojo::ScopedDataPipeProducerHandle input_producer_; bool was_send_fin_called_ = false; + bool was_abort_stream_called_ = false; }; // This class sets up a connected blink::QuicTransport object using a @@ -174,9 +182,9 @@ class ScopedQuicTransport : public mojom::blink::QuicTransportConnector { mojom::blink::QuicTransportConnector::Name_, base::BindRepeating(&ScopedQuicTransport::BindConnector, weak_ptr_factory_.GetWeakPtr())); - quic_transport_ = QuicTransport::Create(scope.GetScriptState(), - "quic-transport://example.com/", - ASSERT_NO_EXCEPTION); + quic_transport_ = QuicTransport::Create( + scope.GetScriptState(), "quic-transport://example.com/", + MakeGarbageCollected<QuicTransportOptions>(), ASSERT_NO_EXCEPTION); test::RunPendingTasks(); } @@ -224,6 +232,8 @@ class ScopedQuicTransport : public mojom::blink::QuicTransportConnector { // Implementation of mojom::blink::QuicTransportConnector. void Connect( const KURL&, + Vector<network::mojom::blink::QuicTransportCertificateFingerprintPtr> + fingerprints, mojo::PendingRemote<network::mojom::blink::QuicTransportHandshakeClient> pending_handshake_client) override { mojo::Remote<network::mojom::blink::QuicTransportHandshakeClient> @@ -404,6 +414,10 @@ TEST(BidirectionalStreamTest, OutgoingStreamAbort) { bidirectional_stream->readingAborted()); tester.WaitUntilSettled(); EXPECT_TRUE(tester.IsFulfilled()); + + const auto* const stub = scoped_quic_transport.Stub(); + EXPECT_FALSE(stub->WasSendFinCalled()); + EXPECT_TRUE(stub->WasAbortStreamCalled()); } TEST(BidirectionalStreamTest, OutgoingStreamCleanClose) { @@ -429,6 +443,10 @@ TEST(BidirectionalStreamTest, OutgoingStreamCleanClose) { bidirectional_stream->readingAborted()); tester.WaitUntilSettled(); EXPECT_TRUE(tester.IsFulfilled()); + + const auto* const stub = scoped_quic_transport.Stub(); + EXPECT_TRUE(stub->WasSendFinCalled()); + EXPECT_FALSE(stub->WasAbortStreamCalled()); } TEST(BidirectionalStreamTest, AbortBothOutgoingFirst) { diff --git a/chromium/third_party/blink/renderer/modules/webtransport/idls.gni b/chromium/third_party/blink/renderer/modules/webtransport/idls.gni index b74def74849..3c8d7386e48 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/idls.gni +++ b/chromium/third_party/blink/renderer/modules/webtransport/idls.gni @@ -10,6 +10,7 @@ modules_idl_files = [ ] modules_dictionary_idl_files = [ - "web_transport_close_info.idl", + "quic_transport_options.idl", "stream_abort_info.idl", + "web_transport_close_info.idl", ] diff --git a/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.cc index d162e1d2d32..4bc95913eb5 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.cc +++ b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.cc @@ -57,7 +57,7 @@ class IncomingStream::UnderlyingSource final : public UnderlyingSourceBase { return ScriptPromise::CastUndefined(script_state); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(incoming_stream_); UnderlyingSourceBase::Trace(visitor); } @@ -140,7 +140,7 @@ void IncomingStream::ContextDestroyed() { ResetPipe(); } -void IncomingStream::Trace(Visitor* visitor) { +void IncomingStream::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(readable_); visitor->Trace(controller_); diff --git a/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h index eec9f8b7052..dd529b70e8f 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h +++ b/chromium/third_party/blink/renderer/modules/webtransport/incoming_stream.h @@ -68,7 +68,7 @@ class MODULES_EXPORT IncomingStream final // Does not execute JavaScript. void ContextDestroyed(); - void Trace(Visitor*); + void Trace(Visitor*) const; private: class UnderlyingSource; diff --git a/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc index f8b165dd905..eb5f53ed405 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc +++ b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.cc @@ -87,7 +87,7 @@ class OutgoingStream::UnderlyingSink final : public UnderlyingSinkBase { return close(script_state, exception_state); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(outgoing_stream_); UnderlyingSinkBase::Trace(visitor); } @@ -167,7 +167,7 @@ void OutgoingStream::ContextDestroyed() { ResetPipe(); } -void OutgoingStream::Trace(Visitor* visitor) { +void OutgoingStream::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(client_); visitor->Trace(writable_); diff --git a/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h index c3f1978480b..aa004511ea4 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h +++ b/chromium/third_party/blink/renderer/modules/webtransport/outgoing_stream.h @@ -79,7 +79,7 @@ class MODULES_EXPORT OutgoingStream final // Does not execute JavaScript. void ContextDestroyed(); - void Trace(Visitor*); + void Trace(Visitor*) const; private: class UnderlyingSink; diff --git a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.cc b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.cc index 130586b44e4..4a8645db886 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.cc +++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.cc @@ -17,6 +17,8 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer.h" #include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer_view.h" #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_quic_transport_options.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtls_fingerprint.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/streams/readable_stream.h" @@ -36,6 +38,7 @@ #include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { @@ -122,7 +125,7 @@ class QuicTransport::DatagramUnderlyingSink final : public UnderlyingSinkBase { return ScriptPromise::CastUndefined(script_state); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(quic_transport_); UnderlyingSinkBase::Trace(visitor); } @@ -180,7 +183,7 @@ class QuicTransport::DatagramUnderlyingSource final return ScriptPromise::CastUndefined(script_state); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(quic_transport_); UnderlyingSourceBase::Trace(visitor); } @@ -196,7 +199,7 @@ class QuicTransport::StreamVendingUnderlyingSource final public: using EnqueueCallback = base::OnceCallback<void(ScriptWrappable*)>; virtual void RequestStream(EnqueueCallback) = 0; - virtual void Trace(Visitor*) {} + virtual void Trace(Visitor*) const {} }; template <class VendorType> @@ -244,7 +247,7 @@ class QuicTransport::StreamVendingUnderlyingSource final } } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(script_state_); visitor->Trace(vendor_); UnderlyingSourceBase::Trace(visitor); @@ -271,7 +274,7 @@ class QuicTransport::ReceiveStreamVendor final WrapWeakPersistent(this), std::move(enqueue))); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(script_state_); visitor->Trace(quic_transport_); StreamVendor::Trace(visitor); @@ -310,7 +313,7 @@ class QuicTransport::BidirectionalStreamVendor final WrapWeakPersistent(this), std::move(enqueue))); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(script_state_); visitor->Trace(quic_transport_); StreamVendor::Trace(visitor); @@ -340,11 +343,13 @@ class QuicTransport::BidirectionalStreamVendor final QuicTransport* QuicTransport::Create(ScriptState* script_state, const String& url, + QuicTransportOptions* options, ExceptionState& exception_state) { DVLOG(1) << "QuicTransport::Create() url=" << url; + DCHECK(options); auto* transport = MakeGarbageCollected<QuicTransport>(PassKey(), script_state, url); - transport->Init(url, exception_state); + transport->Init(url, *options, exception_state); return transport; } @@ -566,11 +571,15 @@ void QuicTransport::SendFin(uint32_t stream_id) { quic_transport_->SendFin(stream_id); } +void QuicTransport::AbortStream(uint32_t stream_id) { + quic_transport_->AbortStream(stream_id, /*code=*/0); +} + void QuicTransport::ForgetStream(uint32_t stream_id) { stream_map_.erase(stream_id); } -void QuicTransport::Trace(Visitor* visitor) { +void QuicTransport::Trace(Visitor* visitor) const { visitor->Trace(received_datagrams_); visitor->Trace(received_datagrams_controller_); visitor->Trace(outgoing_datagrams_); @@ -592,7 +601,9 @@ void QuicTransport::Trace(Visitor* visitor) { ScriptWrappable::Trace(visitor); } -void QuicTransport::Init(const String& url, ExceptionState& exception_state) { +void QuicTransport::Init(const String& url, + const QuicTransportOptions& options, + ExceptionState& exception_state) { DVLOG(1) << "QuicTransport::Init() url=" << url << " this=" << this; if (!url_.IsValid()) { exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, @@ -626,7 +637,7 @@ void QuicTransport::Init(const String& url, ExceptionState& exception_state) { auto* execution_context = GetExecutionContext(); if (!execution_context->GetContentSecurityPolicyForWorld() - ->AllowConnectToSource(url_)) { + ->AllowConnectToSource(url_, url_, RedirectStatus::kNoRedirect)) { // TODO(ricea): This error should probably be asynchronous like it is for // WebSockets and fetch. exception_state.ThrowSecurityError( @@ -636,6 +647,16 @@ void QuicTransport::Init(const String& url, ExceptionState& exception_state) { return; } + Vector<network::mojom::blink::QuicTransportCertificateFingerprintPtr> + fingerprints; + if (options.hasServerCertificateFingerprints()) { + for (const auto& fingerprint : options.serverCertificateFingerprints()) { + fingerprints.push_back( + network::mojom::blink::QuicTransportCertificateFingerprint::New( + fingerprint->algorithm(), fingerprint->value())); + } + } + // TODO(ricea): Register SchedulingPolicy so that we don't get throttled and // to disable bfcache. Must be done before shipping. @@ -648,8 +669,9 @@ void QuicTransport::Init(const String& url, ExceptionState& exception_state) { execution_context->GetTaskRunner(TaskType::kNetworking))); connector->Connect( - url_, handshake_client_receiver_.BindNewPipeAndPassRemote( - execution_context->GetTaskRunner(TaskType::kNetworking))); + url_, std::move(fingerprints), + handshake_client_receiver_.BindNewPipeAndPassRemote( + execution_context->GetTaskRunner(TaskType::kNetworking))); handshake_client_receiver_.set_disconnect_handler( WTF::Bind(&QuicTransport::OnConnectionError, WrapWeakPersistent(this))); diff --git a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h index 65d53564c8e..c072e6373cc 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h +++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.h @@ -27,15 +27,16 @@ namespace blink { class ExceptionState; +class QuicTransportOptions; class ReadableStream; class ReadableStreamDefaultControllerWithScriptScope; +class ScriptPromise; +class ScriptPromiseResolver; class ScriptPromiseResolver; class ScriptState; class WebTransportCloseInfo; -class WritableStream; -class ScriptPromise; -class ScriptPromiseResolver; class WebTransportStream; +class WritableStream; // https://wicg.github.io/web-transport/#quic-transport class MODULES_EXPORT QuicTransport final @@ -50,8 +51,9 @@ class MODULES_EXPORT QuicTransport final public: using PassKey = util::PassKey<QuicTransport>; - static QuicTransport* Create(ScriptState* script_state, + static QuicTransport* Create(ScriptState*, const String& url, + QuicTransportOptions*, ExceptionState&); QuicTransport(PassKey, ScriptState*, const String& url); @@ -92,11 +94,14 @@ class MODULES_EXPORT QuicTransport final // Forwards a SendFin() message to the mojo interface. void SendFin(uint32_t stream_id); + // Forwards a AbortStream() message to the mojo interface. + void AbortStream(uint32_t stream_id); + // Removes the reference to a stream. void ForgetStream(uint32_t stream_id); // ScriptWrappable implementation - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: class DatagramUnderlyingSink; @@ -107,7 +112,7 @@ class MODULES_EXPORT QuicTransport final QuicTransport(ScriptState*, const String& url, ExecutionContext* context); - void Init(const String& url, ExceptionState&); + void Init(const String& url, const QuicTransportOptions&, ExceptionState&); // Reset the QuicTransport object and all associated streams. void ResetAll(); diff --git a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.idl b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.idl index e48132858c5..56aca2a3ee5 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.idl +++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport.idl @@ -8,7 +8,7 @@ Exposed=(Window,Worker), RuntimeEnabled=QuicTransport ] interface QuicTransport { - [CallWith=ScriptState, RaisesException, MeasureAs=QuicTransport] constructor(USVString url); + [CallWith=ScriptState, RaisesException, MeasureAs=QuicTransport] constructor(USVString url, optional QuicTransportOptions options = {}); // QuicTransport is the first, and at this moment only, transport which is // implemented. In the (draft) spec there are many mix-in interfaces which // QuicTransport includes, but we define all their methods/attributes here diff --git a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_options.idl b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_options.idl new file mode 100644 index 00000000000..cb20475e391 --- /dev/null +++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_options.idl @@ -0,0 +1,9 @@ +// Copyright 2020 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/web-transport/#quic-transport-configuration + +dictionary QuicTransportOptions { + sequence<RTCDtlsFingerprint> serverCertificateFingerprints; +}; diff --git a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc index 9cade77bd45..54dd6515117 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc +++ b/chromium/third_party/blink/renderer/modules/webtransport/quic_transport_test.cc @@ -27,7 +27,9 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_uint8_array.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_bidirectional_stream.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_quic_transport_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_receive_stream.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_dtls_fingerprint.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_send_stream.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_web_transport_close_info.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" @@ -66,20 +68,29 @@ class QuicTransportConnector final struct ConnectArgs { ConnectArgs( const KURL& url, + Vector<network::mojom::blink::QuicTransportCertificateFingerprintPtr> + fingerprints, mojo::PendingRemote<network::mojom::blink::QuicTransportHandshakeClient> handshake_client) - : url(url), handshake_client(std::move(handshake_client)) {} + : url(url), + fingerprints(std::move(fingerprints)), + handshake_client(std::move(handshake_client)) {} KURL url; + Vector<network::mojom::blink::QuicTransportCertificateFingerprintPtr> + fingerprints; mojo::PendingRemote<network::mojom::blink::QuicTransportHandshakeClient> handshake_client; }; void Connect( const KURL& url, + Vector<network::mojom::blink::QuicTransportCertificateFingerprintPtr> + fingerprints, mojo::PendingRemote<network::mojom::blink::QuicTransportHandshakeClient> handshake_client) override { - connect_args_.push_back(ConnectArgs(url, std::move(handshake_client))); + connect_args_.push_back( + ConnectArgs(url, std::move(fingerprints), std::move(handshake_client))); } Vector<ConnectArgs> TakeConnectArgs() { return std::move(connect_args_); } @@ -120,6 +131,7 @@ class MockQuicTransport : public network::mojom::blink::QuicTransport { void(uint32_t, mojo::ScopedDataPipeConsumerHandle)>)); void SendFin(uint32_t stream_id) override {} + void AbortStream(uint32_t stream_id, uint64_t code) override {} private: mojo::Receiver<network::mojom::blink::QuicTransport> receiver_; @@ -143,10 +155,14 @@ class QuicTransportTest : public ::testing::Test { weak_ptr_factory_.GetWeakPtr())); } + static QuicTransportOptions* EmptyOptions() { + return MakeGarbageCollected<QuicTransportOptions>(); + } + // Creates a QuicTransport object with the given |url|. QuicTransport* Create(const V8TestingScope& scope, const String& url) { AddBinder(scope); - return QuicTransport::Create(scope.GetScriptState(), url, + return QuicTransport::Create(scope.GetScriptState(), url, EmptyOptions(), ASSERT_NO_EXCEPTION); } @@ -283,7 +299,8 @@ class QuicTransportTest : public ::testing::Test { TEST_F(QuicTransportTest, FailWithNullURL) { V8TestingScope scope; auto& exception_state = scope.GetExceptionState(); - QuicTransport::Create(scope.GetScriptState(), String(), exception_state); + QuicTransport::Create(scope.GetScriptState(), String(), EmptyOptions(), + exception_state); EXPECT_TRUE(exception_state.HadException()); EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSyntaxError), exception_state.Code()); @@ -292,7 +309,8 @@ TEST_F(QuicTransportTest, FailWithNullURL) { TEST_F(QuicTransportTest, FailWithEmptyURL) { V8TestingScope scope; auto& exception_state = scope.GetExceptionState(); - QuicTransport::Create(scope.GetScriptState(), String(""), exception_state); + QuicTransport::Create(scope.GetScriptState(), String(""), EmptyOptions(), + exception_state); EXPECT_TRUE(exception_state.HadException()); EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSyntaxError), exception_state.Code()); @@ -303,7 +321,7 @@ TEST_F(QuicTransportTest, FailWithNoScheme) { V8TestingScope scope; auto& exception_state = scope.GetExceptionState(); QuicTransport::Create(scope.GetScriptState(), String("no-scheme"), - exception_state); + EmptyOptions(), exception_state); EXPECT_TRUE(exception_state.HadException()); EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSyntaxError), exception_state.Code()); @@ -314,7 +332,7 @@ TEST_F(QuicTransportTest, FailWithHttpsURL) { V8TestingScope scope; auto& exception_state = scope.GetExceptionState(); QuicTransport::Create(scope.GetScriptState(), String("https://example.com/"), - exception_state); + EmptyOptions(), exception_state); EXPECT_TRUE(exception_state.HadException()); EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSyntaxError), exception_state.Code()); @@ -327,7 +345,7 @@ TEST_F(QuicTransportTest, FailWithNoHost) { V8TestingScope scope; auto& exception_state = scope.GetExceptionState(); QuicTransport::Create(scope.GetScriptState(), String("quic-transport:///"), - exception_state); + EmptyOptions(), exception_state); EXPECT_TRUE(exception_state.HadException()); EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSyntaxError), exception_state.Code()); @@ -340,7 +358,7 @@ TEST_F(QuicTransportTest, FailWithURLFragment) { auto& exception_state = scope.GetExceptionState(); QuicTransport::Create(scope.GetScriptState(), String("quic-transport://example.com/#failing"), - exception_state); + EmptyOptions(), exception_state); EXPECT_TRUE(exception_state.HadException()); EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSyntaxError), exception_state.Code()); @@ -359,7 +377,7 @@ TEST_F(QuicTransportTest, FailByCSP) { network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kHTTP); QuicTransport::Create(scope.GetScriptState(), - String("quic-transport://example.com/"), + String("quic-transport://example.com/"), EmptyOptions(), exception_state); EXPECT_TRUE(exception_state.HadException()); EXPECT_EQ(static_cast<int>(DOMExceptionCode::kSecurityError), @@ -380,7 +398,7 @@ TEST_F(QuicTransportTest, PassCSP) { network::mojom::ContentSecurityPolicyType::kEnforce, network::mojom::ContentSecurityPolicySource::kHTTP); QuicTransport::Create(scope.GetScriptState(), - String("quic-transport://example.com/"), + String("quic-transport://example.com/"), EmptyOptions(), exception_state); EXPECT_FALSE(exception_state.HadException()); } @@ -390,13 +408,14 @@ TEST_F(QuicTransportTest, SendConnect) { AddBinder(scope); auto* quic_transport = QuicTransport::Create( scope.GetScriptState(), String("quic-transport://example.com/"), - ASSERT_NO_EXCEPTION); + EmptyOptions(), ASSERT_NO_EXCEPTION); test::RunPendingTasks(); auto args = connector_.TakeConnectArgs(); ASSERT_EQ(1u, args.size()); EXPECT_EQ(KURL("quic-transport://example.com/"), args[0].url); + EXPECT_TRUE(args[0].fingerprints.IsEmpty()); EXPECT_TRUE(quic_transport->HasPendingActivity()); } @@ -418,7 +437,7 @@ TEST_F(QuicTransportTest, FailedConnect) { AddBinder(scope); auto* quic_transport = QuicTransport::Create( scope.GetScriptState(), String("quic-transport://example.com/"), - ASSERT_NO_EXCEPTION); + EmptyOptions(), ASSERT_NO_EXCEPTION); ScriptPromiseTester ready_tester(scope.GetScriptState(), quic_transport->ready()); ScriptPromiseTester closed_tester(scope.GetScriptState(), @@ -440,12 +459,37 @@ TEST_F(QuicTransportTest, FailedConnect) { EXPECT_TRUE(closed_tester.IsRejected()); } +TEST_F(QuicTransportTest, SendConnectWithFingerprint) { + V8TestingScope scope; + AddBinder(scope); + auto* fingerprints = MakeGarbageCollected<RTCDtlsFingerprint>(); + fingerprints->setAlgorithm("sha-256"); + fingerprints->setValue( + "ED:3D:D7:C3:67:10:94:68:D1:DC:D1:26:5C:B2:74:D7:1C:A2:63:3E:94:94:C0:84:" + "39:D6:64:FA:08:B9:77:37"); + auto* options = MakeGarbageCollected<QuicTransportOptions>(); + options->setServerCertificateFingerprints({fingerprints}); + QuicTransport::Create(scope.GetScriptState(), + String("quic-transport://example.com/"), options, + ASSERT_NO_EXCEPTION); + + test::RunPendingTasks(); + + auto args = connector_.TakeConnectArgs(); + ASSERT_EQ(1u, args.size()); + ASSERT_EQ(1u, args[0].fingerprints.size()); + EXPECT_EQ(args[0].fingerprints[0]->algorithm, "sha-256"); + EXPECT_EQ(args[0].fingerprints[0]->fingerprint, + "ED:3D:D7:C3:67:10:94:68:D1:DC:D1:26:5C:B2:74:D7:1C:A2:63:3E:94:94:" + "C0:84:39:D6:64:FA:08:B9:77:37"); +} + TEST_F(QuicTransportTest, CloseDuringConnect) { V8TestingScope scope; AddBinder(scope); auto* quic_transport = QuicTransport::Create( scope.GetScriptState(), String("quic-transport://example.com/"), - ASSERT_NO_EXCEPTION); + EmptyOptions(), ASSERT_NO_EXCEPTION); ScriptPromiseTester ready_tester(scope.GetScriptState(), quic_transport->ready()); ScriptPromiseTester closed_tester(scope.GetScriptState(), @@ -767,8 +811,9 @@ TEST_F(QuicTransportTest, CreateSendStreamBeforeConnect) { V8TestingScope scope; auto* script_state = scope.GetScriptState(); - auto* quic_transport = QuicTransport::Create( - script_state, "quic-transport://example.com", ASSERT_NO_EXCEPTION); + auto* quic_transport = + QuicTransport::Create(script_state, "quic-transport://example.com", + EmptyOptions(), ASSERT_NO_EXCEPTION); auto& exception_state = scope.GetExceptionState(); ScriptPromise send_stream_promise = quic_transport->createSendStream(script_state, exception_state); diff --git a/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc index 2e0ccb0e69e..c9e673a62e7 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc +++ b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.cc @@ -37,7 +37,7 @@ void ReceiveStream::ContextDestroyed() { incoming_stream_->ContextDestroyed(); } -void ReceiveStream::Trace(Visitor* visitor) { +void ReceiveStream::Trace(Visitor* visitor) const { visitor->Trace(incoming_stream_); visitor->Trace(quic_transport_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.h index fe76f206ddb..d323b266537 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.h +++ b/chromium/third_party/blink/renderer/modules/webtransport/receive_stream.h @@ -54,7 +54,7 @@ class MODULES_EXPORT ReceiveStream final : public ScriptWrappable, void Reset() override; void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void OnAbort(); diff --git a/chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc index 88771198361..c9f73db59eb 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc +++ b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.cc @@ -44,10 +44,11 @@ void SendStream::SendFin() { } void SendStream::OnOutgoingStreamAbort() { + quic_transport_->AbortStream(stream_id_); quic_transport_->ForgetStream(stream_id_); } -void SendStream::Trace(Visitor* visitor) { +void SendStream::Trace(Visitor* visitor) const { visitor->Trace(outgoing_stream_); visitor->Trace(quic_transport_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webtransport/send_stream.h b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.h index 3d9f56b282c..f2ce3dd1545 100644 --- a/chromium/third_party/blink/renderer/modules/webtransport/send_stream.h +++ b/chromium/third_party/blink/renderer/modules/webtransport/send_stream.h @@ -58,7 +58,7 @@ class MODULES_EXPORT SendStream final : public ScriptWrappable, void SendFin() override; void OnOutgoingStreamAbort() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: const Member<OutgoingStream> outgoing_stream_; diff --git a/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.cc b/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.cc index 6d04895c7e6..164ea22a6e9 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.cc +++ b/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.cc @@ -29,7 +29,7 @@ USB* NavigatorUSB::usb() { return usb_; } -void NavigatorUSB::Trace(Visitor* visitor) { +void NavigatorUSB::Trace(Visitor* visitor) const { visitor->Trace(usb_); Supplement<Navigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.h b/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.h index 26629fad5dd..a48f02094c9 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.h +++ b/chromium/third_party/blink/renderer/modules/webusb/navigator_usb.h @@ -30,7 +30,7 @@ class NavigatorUSB final : public GarbageCollected<NavigatorUSB>, explicit NavigatorUSB(Navigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<USB> usb_; diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.cc b/chromium/third_party/blink/renderer/modules/webusb/usb.cc index d9ea236901e..2f94a56f716 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb.cc +++ b/chromium/third_party/blink/renderer/modules/webusb/usb.cc @@ -322,7 +322,7 @@ bool USB::IsFeatureEnabled(ReportOptions report_options) const { mojom::blink::FeaturePolicyFeature::kUsb, report_options); } -void USB::Trace(Visitor* visitor) { +void USB::Trace(Visitor* visitor) const { visitor->Trace(service_); visitor->Trace(get_devices_requests_); visitor->Trace(get_permission_requests_); diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.h b/chromium/third_party/blink/renderer/modules/webusb/usb.h index c9a997f818f..d3042c9a39e 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb.h @@ -69,7 +69,7 @@ class USB final : public EventTargetWithInlineData, void OnServiceConnectionError(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: // EventTarget protected overrides. diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc index 158c07c88f5..04420082b05 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.cc @@ -58,7 +58,7 @@ HeapVector<Member<USBEndpoint>> USBAlternateInterface::endpoints() const { return endpoints; } -void USBAlternateInterface::Trace(Visitor* visitor) { +void USBAlternateInterface::Trace(Visitor* visitor) const { visitor->Trace(interface_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h index 41018f6e5ef..25a3b5d5d98 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_alternate_interface.h @@ -36,7 +36,7 @@ class USBAlternateInterface : public ScriptWrappable { String interfaceName() const { return Info().interface_name; } HeapVector<Member<USBEndpoint>> endpoints() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<const USBInterface> interface_; diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc index 5602c7abe07..348300616ce 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.cc @@ -55,7 +55,7 @@ HeapVector<Member<USBInterface>> USBConfiguration::interfaces() const { return interfaces; } -void USBConfiguration::Trace(Visitor* visitor) { +void USBConfiguration::Trace(Visitor* visitor) const { visitor->Trace(device_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h index 04516b04ba6..233c34fb215 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_configuration.h @@ -35,7 +35,7 @@ class USBConfiguration : public ScriptWrappable { String configurationName() const { return Info().configuration_name; } HeapVector<Member<USBInterface>> interfaces() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<const USBDevice> device_; diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.cc index 54aa4fe097e..9764df97d0a 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.cc +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.cc @@ -29,7 +29,7 @@ USBConnectionEvent::USBConnectionEvent(const AtomicString& type, USBDevice* device) : Event(type, Bubbles::kNo, Cancelable::kNo), device_(device) {} -void USBConnectionEvent::Trace(Visitor* visitor) { +void USBConnectionEvent::Trace(Visitor* visitor) const { visitor->Trace(device_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.h b/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.h index a8dc7bd1b9f..23de8318fb8 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_connection_event.h @@ -26,7 +26,7 @@ class USBConnectionEvent final : public Event { USBDevice* device() const { return device_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<USBDevice> device_; 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 4e04b565149..1ba2a231a0b 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_device.cc @@ -56,8 +56,8 @@ const char kOpenRequired[] = "The device must be opened first."; #if defined(OS_CHROMEOS) const char kExtensionProtocol[] = "chrome-extension"; -// These whitelisted Imprivata extensions can claim the protected HID interface -// class (used as badge readers), see crbug.com/1065112 and crbug.com/995294. +// These Imprivata extensions can claim the protected HID interface class (used +// as badge readers), see crbug.com/1065112 and crbug.com/995294. // This list needs to be alphabetically sorted for quick access via binary // search. const char* kImprivataExtensionIds[] = { @@ -80,7 +80,7 @@ bool IsCStrBefore(const char* first, const char* second) { return strcmp(first, second) < 0; } -bool IsClassWhitelistedForExtension(uint8_t class_code, const KURL& url) { +bool IsClassAllowedForExtension(uint8_t class_code, const KURL& url) { if (url.Protocol() != kExtensionProtocol) return false; @@ -601,7 +601,7 @@ void USBDevice::ContextDestroyed() { device_requests_.clear(); } -void USBDevice::Trace(Visitor* visitor) { +void USBDevice::Trace(Visitor* visitor) const { visitor->Trace(device_); visitor->Trace(device_requests_); ScriptWrappable::Trace(visitor); @@ -670,8 +670,8 @@ bool USBDevice::IsProtectedInterfaceClass(wtf_size_t interface_index) const { std::end(kProtectedClasses), alternate->class_code)) { #if defined(OS_CHROMEOS) - return !IsClassWhitelistedForExtension(alternate->class_code, - GetExecutionContext()->Url()); + return !IsClassAllowedForExtension(alternate->class_code, + GetExecutionContext()->Url()); #else return true; #endif 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 3b8aeb33070..f2c4fcf6d99 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_device.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_device.h @@ -99,7 +99,7 @@ class USBDevice : public ScriptWrappable, // ExecutionContextLifecycleObserver interface. void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: static const size_t kEndpointsBitsNumber = 16; diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc index c60a0b20fe2..a2d05280394 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.cc @@ -90,7 +90,7 @@ String USBEndpoint::type() const { return ConvertTypeToEnum(Info().type); } -void USBEndpoint::Trace(Visitor* visitor) { +void USBEndpoint::Trace(Visitor* visitor) const { visitor->Trace(alternate_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h index 343a31311e1..b37626011cf 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_endpoint.h @@ -34,7 +34,7 @@ class USBEndpoint : public ScriptWrappable { String type() const; unsigned packetSize() const { return Info().packet_size; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<const USBAlternateInterface> alternate_; diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h b/chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h index 426a942e913..e34fe6efe33 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.h @@ -43,7 +43,7 @@ class USBInTransferResult final : public ScriptWrappable { String status() const { return status_; } DOMDataView* data() const { return data_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(data_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc index df7ac329cc6..ee7b79b351e 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.cc @@ -68,7 +68,7 @@ bool USBInterface::claimed() const { return device_->IsInterfaceClaimed(configuration_index_, interface_index_); } -void USBInterface::Trace(Visitor* visitor) { +void USBInterface::Trace(Visitor* visitor) const { visitor->Trace(device_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.h b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.h index 6c6b8c7f0a6..a726f2039e5 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_interface.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_interface.h @@ -37,7 +37,7 @@ class USBInterface : public ScriptWrappable { HeapVector<Member<USBAlternateInterface>> alternates() const; bool claimed() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<const USBDevice> device_; diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.h b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.h index 3afd1a08a5f..ae0695f42dc 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.h @@ -35,7 +35,7 @@ class USBIsochronousInTransferPacket final : public ScriptWrappable { String status() const { return status_; } DOMDataView* data() const { return data_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(data_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h index c9b896e3390..18149c6140f 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.h @@ -52,7 +52,7 @@ class USBIsochronousInTransferResult final : public ScriptWrappable { return packets_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(data_); visitor->Trace(packets_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.h b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.h index 8f1cf5a4151..5980e24978a 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.h +++ b/chromium/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.h @@ -32,7 +32,7 @@ class USBIsochronousOutTransferResult final : public ScriptWrappable { return packets_; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(packets_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.cc b/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.cc index 90d786324a6..fceec63319b 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.cc +++ b/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.cc @@ -51,7 +51,7 @@ USB* WorkerNavigatorUSB::usb(ScriptState* script_state) { return usb_; } -void WorkerNavigatorUSB::Trace(Visitor* visitor) { +void WorkerNavigatorUSB::Trace(Visitor* visitor) const { visitor->Trace(usb_); Supplement<WorkerNavigator>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.h b/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.h index 07a02a6fc15..34543e6b507 100644 --- a/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.h +++ b/chromium/third_party/blink/renderer/modules/webusb/worker_navigator_usb.h @@ -31,7 +31,7 @@ class WorkerNavigatorUSB final : public GarbageCollected<WorkerNavigatorUSB>, explicit WorkerNavigatorUSB(WorkerNavigator&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<USB> usb_; diff --git a/chromium/third_party/blink/renderer/modules/xr/DEPS b/chromium/third_party/blink/renderer/modules/xr/DEPS index 59d1139c4ec..9d573fe4cff 100644 --- a/chromium/third_party/blink/renderer/modules/xr/DEPS +++ b/chromium/third_party/blink/renderer/modules/xr/DEPS @@ -1,5 +1,6 @@ include_rules = [ "+mojo/public/cpp/system/platform_handle.h", + "+device/vr/public/mojom/pose.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", diff --git a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.cc b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.cc index 274cf4078f9..622e37b4c9c 100644 --- a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.cc +++ b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.cc @@ -72,7 +72,7 @@ Document* NavigatorXR::GetDocument() { return GetSupplementable()->GetFrame()->GetDocument(); } -void NavigatorXR::Trace(Visitor* visitor) { +void NavigatorXR::Trace(Visitor* visitor) const { visitor->Trace(xr_); Supplement<Navigator>::Trace(visitor); } 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 78342d32497..0d9a9a95f82 100644 --- a/chromium/third_party/blink/renderer/modules/xr/navigator_xr.h +++ b/chromium/third_party/blink/renderer/modules/xr/navigator_xr.h @@ -30,7 +30,7 @@ class MODULES_EXPORT NavigatorXR final : public GarbageCollected<NavigatorXR>, static XRSystem* xr(Navigator&); XRSystem* xr(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Document* GetDocument(); diff --git a/chromium/third_party/blink/renderer/modules/xr/type_converters.cc b/chromium/third_party/blink/renderer/modules/xr/type_converters.cc index bfea7162f7e..780bebc6a48 100644 --- a/chromium/third_party/blink/renderer/modules/xr/type_converters.cc +++ b/chromium/third_party/blink/renderer/modules/xr/type_converters.cc @@ -22,70 +22,6 @@ TypeConverter<base::Optional<blink::XRPlane::Orientation>, } } -blink::TransformationMatrix -TypeConverter<blink::TransformationMatrix, device::mojom::blink::VRPosePtr>:: - Convert(const device::mojom::blink::VRPosePtr& pose) { - DCHECK(pose); - - blink::TransformationMatrix result; - blink::TransformationMatrix::DecomposedType decomp = {}; - - decomp.perspective_w = 1; - decomp.scale_x = 1; - decomp.scale_y = 1; - decomp.scale_z = 1; - - if (pose->orientation) { - // TODO(https://crbug.com/929841): Remove negation once the bug is fixed. - gfx::Quaternion quat = pose->orientation->inverse(); - decomp.quaternion_x = quat.x(); - decomp.quaternion_y = quat.y(); - decomp.quaternion_z = quat.z(); - decomp.quaternion_w = quat.w(); - } else { - decomp.quaternion_w = 1.0; - } - - if (pose->position) { - decomp.translate_x = pose->position->x(); - decomp.translate_y = pose->position->y(); - decomp.translate_z = pose->position->z(); - } - - result.Recompose(decomp); - - return result; -} - -blink::TransformationMatrix -TypeConverter<blink::TransformationMatrix, device::mojom::blink::PosePtr>:: - Convert(const device::mojom::blink::PosePtr& pose) { - DCHECK(pose); - - blink::TransformationMatrix result; - blink::TransformationMatrix::DecomposedType decomp = {}; - - decomp.perspective_w = 1; - decomp.scale_x = 1; - decomp.scale_y = 1; - decomp.scale_z = 1; - - // TODO(https://crbug.com/929841): Remove negation once the bug is fixed. - gfx::Quaternion quat = pose->orientation.inverse(); - decomp.quaternion_x = quat.x(); - decomp.quaternion_y = quat.y(); - decomp.quaternion_z = quat.z(); - decomp.quaternion_w = quat.w(); - - decomp.translate_x = pose->position.x(); - decomp.translate_y = pose->position.y(); - decomp.translate_z = pose->position.z(); - - result.Recompose(decomp); - - return result; -} - blink::HeapVector<blink::Member<blink::DOMPointReadOnly>> TypeConverter<blink::HeapVector<blink::Member<blink::DOMPointReadOnly>>, Vector<device::mojom::blink::XRPlanePointDataPtr>>:: diff --git a/chromium/third_party/blink/renderer/modules/xr/type_converters.h b/chromium/third_party/blink/renderer/modules/xr/type_converters.h index 075036664d8..0e2590938a7 100644 --- a/chromium/third_party/blink/renderer/modules/xr/type_converters.h +++ b/chromium/third_party/blink/renderer/modules/xr/type_converters.h @@ -20,20 +20,6 @@ struct TypeConverter<base::Optional<blink::XRPlane::Orientation>, }; template <> -struct TypeConverter<blink::TransformationMatrix, - device::mojom::blink::VRPosePtr> { - static blink::TransformationMatrix Convert( - const device::mojom::blink::VRPosePtr& pose); -}; - -template <> -struct TypeConverter<blink::TransformationMatrix, - device::mojom::blink::PosePtr> { - static blink::TransformationMatrix Convert( - const device::mojom::blink::PosePtr& pose); -}; - -template <> struct TypeConverter<blink::HeapVector<blink::Member<blink::DOMPointReadOnly>>, Vector<device::mojom::blink::XRPlanePointDataPtr>> { static blink::HeapVector<blink::Member<blink::DOMPointReadOnly>> Convert( 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 14c2731fc00..9d3857de36f 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "third_party/blink/renderer/modules/xr/xr_anchor.h" -#include "third_party/blink/renderer/modules/xr/type_converters.h" #include "third_party/blink/renderer/modules/xr/xr_object_space.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" #include "third_party/blink/renderer/modules/xr/xr_system.h" @@ -21,28 +20,17 @@ namespace blink { XRAnchor::XRAnchor(uint64_t id, XRSession* session, const device::mojom::blink::XRAnchorData& anchor_data) - : id_(id), is_deleted_(false), session_(session) { - // No need for else - if mojo_from_anchor is not present, the - // default-constructed unique ptr is fine. It would signify that the anchor - // exists and is tracked by the underlying system, but its current location is - // unknown. - if (anchor_data.mojo_from_anchor) { - SetMojoFromAnchor(mojo::ConvertTo<blink::TransformationMatrix>( - anchor_data.mojo_from_anchor)); - } -} + : id_(id), + is_deleted_(false), + session_(session), + mojo_from_anchor_(anchor_data.mojo_from_anchor) {} void XRAnchor::Update(const device::mojom::blink::XRAnchorData& anchor_data) { if (is_deleted_) { return; } - if (anchor_data.mojo_from_anchor) { - SetMojoFromAnchor(mojo::ConvertTo<blink::TransformationMatrix>( - anchor_data.mojo_from_anchor)); - } else { - mojo_from_anchor_ = nullptr; - } + mojo_from_anchor_ = anchor_data.mojo_from_anchor; } uint64_t XRAnchor::id() const { @@ -69,29 +57,20 @@ base::Optional<TransformationMatrix> XRAnchor::MojoFromObject() const { return base::nullopt; } - return *mojo_from_anchor_; + return mojo_from_anchor_->ToTransform().matrix(); } void XRAnchor::Delete() { if (!is_deleted_) { session_->xr()->xrEnvironmentProviderRemote()->DetachAnchor(id_); - mojo_from_anchor_ = nullptr; + mojo_from_anchor_ = base::nullopt; anchor_space_ = nullptr; } is_deleted_ = true; } -void XRAnchor::SetMojoFromAnchor(const TransformationMatrix& mojo_from_anchor) { - if (mojo_from_anchor_) { - *mojo_from_anchor_ = mojo_from_anchor; - } else { - mojo_from_anchor_ = - std::make_unique<TransformationMatrix>(mojo_from_anchor); - } -} - -void XRAnchor::Trace(Visitor* visitor) { +void XRAnchor::Trace(Visitor* visitor) const { visitor->Trace(session_); visitor->Trace(anchor_space_); ScriptWrappable::Trace(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 6b9d05d14f6..92f3dbe87c5 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.h @@ -36,20 +36,18 @@ class XRAnchor : public ScriptWrappable { void Update(const device::mojom::blink::XRAnchorData& anchor_data); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: - void SetMojoFromAnchor(const TransformationMatrix& mojo_from_anchor); - const uint64_t id_; bool is_deleted_; Member<XRSession> session_; - // Anchor's pose in device (mojo) space. Nullptr if the pose of the anchor is + // Anchor's pose in device (mojo) space. Nullopt if the pose of the anchor is // unknown in the current frame. - std::unique_ptr<TransformationMatrix> mojo_from_anchor_; + base::Optional<device::Pose> mojo_from_anchor_; // Cached anchor space - it will be created by `anchorSpace()` if it's not // set. diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.idl b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.idl index 1db10fc71a5..724c6774738 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor.idl @@ -5,7 +5,7 @@ [ SecureContext, Exposed=Window, - RuntimeEnabled=WebXRIncubations + RuntimeEnabled=WebXRAnchors ] interface XRAnchor { [RaisesException] diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.cc b/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.cc index 47588f58545..92a9d189ae6 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.cc @@ -13,7 +13,7 @@ const HeapHashSet<Member<XRAnchor>>& XRAnchorSet::elements() const { return anchors_; } -void XRAnchorSet::Trace(Visitor* visitor) { +void XRAnchorSet::Trace(Visitor* visitor) const { visitor->Trace(anchors_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.h b/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.h index fecd15421b2..2bbde1a0eb4 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.h @@ -18,7 +18,7 @@ class XRAnchorSet : public ScriptWrappable, public XRSetlike<XRAnchor> { public: explicit XRAnchorSet(HeapHashSet<Member<XRAnchor>> anchors); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; protected: const HeapHashSet<Member<XRAnchor>>& elements() const override; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.idl b/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.idl index ddb69dd718c..aee2cb2d1bb 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_anchor_set.idl @@ -5,7 +5,7 @@ [ SecureContext, Exposed=Window, - RuntimeEnabled=WebXRIncubations + RuntimeEnabled=WebXRAnchors ] interface XRAnchorSet { readonly setlike<XRAnchor>; 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 cd8945d55c7..96ebf3d97b0 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 @@ -33,12 +33,17 @@ Member<DOMPointReadOnly> RoundedDOMPoint(const FloatPoint3D& val) { } // anonymous namespace XRBoundedReferenceSpace::XRBoundedReferenceSpace(XRSession* session) - : XRReferenceSpace(session, Type::kTypeBoundedFloor) {} + : XRReferenceSpace( + session, + device::mojom::blink::XRReferenceSpaceType::kBoundedFloor) {} XRBoundedReferenceSpace::XRBoundedReferenceSpace( XRSession* session, XRRigidTransform* origin_offset) - : XRReferenceSpace(session, origin_offset, Type::kTypeBoundedFloor) {} + : XRReferenceSpace( + session, + origin_offset, + device::mojom::blink::XRReferenceSpaceType::kBoundedFloor) {} XRBoundedReferenceSpace::~XRBoundedReferenceSpace() = default; @@ -102,12 +107,7 @@ HeapVector<Member<DOMPointReadOnly>> XRBoundedReferenceSpace::boundsGeometry() { return offset_bounds_geometry_; } -base::Optional<XRNativeOriginInformation> -XRBoundedReferenceSpace::NativeOrigin() const { - return XRNativeOriginInformation::Create(this); -} - -void XRBoundedReferenceSpace::Trace(Visitor* visitor) { +void XRBoundedReferenceSpace::Trace(Visitor* visitor) const { visitor->Trace(offset_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 1261c8267db..09ee79ffd37 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 @@ -24,9 +24,7 @@ class XRBoundedReferenceSpace final : public XRReferenceSpace { HeapVector<Member<DOMPointReadOnly>> boundsGeometry(); - base::Optional<XRNativeOriginInformation> NativeOrigin() const override; - - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void OnReset() override; 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 2b15f65c0cd..431f6e4ae42 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 @@ -40,7 +40,7 @@ class XRCanvasInputEventListener : public NativeEventListener { } } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(input_provider_); EventListener::Trace(visitor); } @@ -128,7 +128,7 @@ void XRCanvasInputProvider::ClearInputSource() { input_source_ = nullptr; } -void XRCanvasInputProvider::Trace(Visitor* visitor) { +void XRCanvasInputProvider::Trace(Visitor* visitor) const { visitor->Trace(session_); visitor->Trace(canvas_); visitor->Trace(listener_); 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 f66c96e099a..4019235b831 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 @@ -38,7 +38,7 @@ class XRCanvasInputProvider : public GarbageCollected<XRCanvasInputProvider>, XRInputSource* GetInputSource(); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "XRCanvasInputProvider"; } diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.cc b/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.cc index 2f096b385e0..a02ca9a84b1 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_cube_map.cc @@ -9,6 +9,7 @@ #include "third_party/blink/renderer/modules/webgl/webgl_texture.h" #include "third_party/blink/renderer/modules/xr/xr_cube_map.h" #include "third_party/blink/renderer/platform/bindings/exception_code.h" +#include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h" namespace { bool IsPowerOfTwo(uint32_t value) { @@ -84,7 +85,9 @@ WebGLTexture* XRCubeMap::updateWebGLEnvironmentCube( } // TODO(https://crbug.com/1079007): Restore the texture binding - gl->BindTexture(GL_TEXTURE_CUBE_MAP, 0); + // gl->BindTexture(GL_TEXTURE_CUBE_MAP, 0); + DrawingBuffer::Client* client = static_cast<DrawingBuffer::Client*>(context); + client->DrawingBufferClientRestoreTextureCubeMapBinding(); // Debug check for success DCHECK(gl->GetError() == GL_NO_ERROR); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.cc b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.cc index 10db7030a66..8d4abd5e26b 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.cc @@ -24,7 +24,7 @@ const String MapOverlayType(XRDOMOverlayState::DOMOverlayType type) { XRDOMOverlayState::XRDOMOverlayState(DOMOverlayType type) : type_string_(MapOverlayType(type)) {} -void XRDOMOverlayState::Trace(Visitor* visitor) { +void XRDOMOverlayState::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h index f39b2705bdb..f286e17fbce 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.h @@ -27,7 +27,7 @@ class XRDOMOverlayState : public ScriptWrappable { const String& type() const { return type_string_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: const String type_string_; 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 8881c4d0c61..b8eec81bd32 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.cc @@ -237,11 +237,10 @@ ScriptPromise XRFrame::createAnchor(ScriptState* script_state, return {}; } - base::Optional<XRNativeOriginInformation> native_origin = - space->NativeOrigin(); - - if (!native_origin) { - DVLOG(2) << __func__ << ": native_origin not set, failing anchor creation"; + base::Optional<device::mojom::blink::XRNativeOriginInformation> + maybe_native_origin = space->NativeOrigin(); + if (!maybe_native_origin) { + DVLOG(2) << __func__ << ": native origin not set, failing anchor creation"; exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, kCannotObtainNativeOrigin); return {}; @@ -264,7 +263,7 @@ ScriptPromise XRFrame::createAnchor(ScriptState* script_state, if (space->IsStationary()) { // Space is considered stationary, no adjustments are needed. return session_->CreateAnchorHelper(script_state, native_origin_from_anchor, - *native_origin, exception_state); + *maybe_native_origin, exception_state); } return CreateAnchorFromNonStationarySpace( @@ -280,26 +279,20 @@ ScriptPromise XRFrame::CreateAnchorFromNonStationarySpace( // Space is not considered stationary - need to adjust the app-provided pose. // Let's ask the session about the appropriate stationary reference space: - auto stationary_reference_space_category = - device::mojom::XRReferenceSpaceCategory::LOCAL; - auto mojo_from_stationary_space = - session_->GetMojoFrom(XRReferenceSpace::Type::kTypeLocal); - if (!mojo_from_stationary_space) { - // Local space is not available, try unbounded. - stationary_reference_space_category = - device::mojom::XRReferenceSpaceCategory::UNBOUNDED; - mojo_from_stationary_space = - session_->GetMojoFrom(XRReferenceSpace::Type::kTypeUnbounded); - } + base::Optional<XRSession::ReferenceSpaceInformation> + reference_space_information = session_->GetStationaryReferenceSpace(); - if (!mojo_from_stationary_space) { + if (!reference_space_information) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, XRSession::kUnableToRetrieveMatrix); return {}; } - DCHECK(mojo_from_stationary_space->IsInvertible()); - auto stationary_space_from_mojo = mojo_from_stationary_space->Inverse(); + const TransformationMatrix& mojo_from_stationary_space = + reference_space_information->mojo_from_space; + + DCHECK(mojo_from_stationary_space.IsInvertible()); + auto stationary_space_from_mojo = mojo_from_stationary_space.Inverse(); // We now have 2 spaces - the dynamic one passed in to create anchor // call, and the stationary one. We also have a rigid transform @@ -318,22 +311,13 @@ ScriptPromise XRFrame::CreateAnchorFromNonStationarySpace( auto stationary_space_from_anchor = stationary_space_from_mojo * mojo_from_anchor; - auto stationary_space_native_origin = - XRNativeOriginInformation::Create(stationary_reference_space_category); - - if (!stationary_space_native_origin) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - kCannotObtainNativeOrigin); - return {}; - } - // Conversion done, make the adjusted call: return session_->CreateAnchorHelper( script_state, stationary_space_from_anchor, - *stationary_space_native_origin, exception_state); + reference_space_information->native_origin, exception_state); } -void XRFrame::Trace(Visitor* visitor) { +void XRFrame::Trace(Visitor* visitor) const { visitor->Trace(session_); visitor->Trace(world_information_); ScriptWrappable::Trace(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 4cbeede766d..5722601ebce 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.h @@ -48,7 +48,7 @@ class XRFrame final : public ScriptWrappable { XRAnchorSet* trackedAnchors() const; XRLightEstimate* getLightEstimate(XRLightProbe*, ExceptionState&) const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void Deactivate(); 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 106f9d58ae0..17bc688c46a 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame.idl @@ -12,7 +12,7 @@ // More details about the real-world understanding APIs can be found here: // https://github.com/immersive-web/real-world-geometry/blob/master/plane-detection-explainer.md - [RuntimeEnabled=WebXRIncubations] readonly attribute XRWorldInformation worldInformation; + [RuntimeEnabled=WebXRPlaneDetection] readonly attribute XRWorldInformation worldInformation; [RuntimeEnabled=WebXRAnchors] readonly attribute XRAnchorSet trackedAnchors; 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 3790a9a0e1e..a1c3b31d674 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 @@ -39,7 +39,7 @@ class XRFrameProviderRequestCallback frame_provider_->OnNonImmersiveVSync(high_res_time_ms); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(frame_provider_); FrameRequestCallbackCollection::FrameCallback::Trace(visitor); @@ -56,6 +56,8 @@ XRFrameProvider::XRFrameProvider(XRSystem* xr) xr->GetExecutionContext(), xr->GetExecutionContext()->GetTaskRunner( TaskType::kMiscPlatformAPI))), + immersive_data_provider_(xr->GetExecutionContext()), + immersive_presentation_provider_(xr->GetExecutionContext()), last_has_focus_(xr->IsFrameFocused()) {} void XRFrameProvider::OnSessionStarted( @@ -71,13 +73,16 @@ void XRFrameProvider::OnSessionStarted( immersive_session_ = session; - immersive_data_provider_.Bind(std::move(session_ptr->data_provider)); + immersive_data_provider_.Bind( + std::move(session_ptr->data_provider), + xr_->GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI)); 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)); + std::move(session_ptr->submit_frame_sink->provider), + xr_->GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI)); immersive_presentation_provider_.set_disconnect_handler( WTF::Bind(&XRFrameProvider::OnProviderConnectionError, WrapWeakPersistent(this), WrapWeakPersistent(session))); @@ -94,13 +99,18 @@ void XRFrameProvider::OnSessionStarted( return; } - mojo::Remote<device::mojom::blink::XRFrameDataProvider> data_provider; - data_provider.Bind(std::move(session_ptr->data_provider)); + HeapMojoRemote<device::mojom::blink::XRFrameDataProvider, + HeapMojoWrapperMode::kWithoutContextObserver> + data_provider(xr_->GetExecutionContext()); + data_provider.Bind( + std::move(session_ptr->data_provider), + xr_->GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI)); data_provider.set_disconnect_handler( WTF::Bind(&XRFrameProvider::OnProviderConnectionError, WrapWeakPersistent(this), WrapWeakPersistent(session))); - non_immersive_data_providers_.insert(session, std::move(data_provider)); + non_immersive_data_providers_.insert( + session, WrapDisallowNew(std::move(data_provider))); } } @@ -139,6 +149,8 @@ void XRFrameProvider::OnSessionEnded(XRSession* session) { immersive_data_provider_.reset(); immersive_frame_pose_ = nullptr; is_immersive_frame_position_emulated_ = false; + first_immersive_frame_time_ = base::nullopt; + first_immersive_frame_time_delta_ = base::nullopt; frame_transport_ = MakeGarbageCollected<XRFrameTransport>( session->GetExecutionContext(), @@ -253,11 +265,22 @@ void XRFrameProvider::OnImmersiveFrameData( if (!doc) return; - base::TimeTicks monotonic_time_now = base::TimeTicks() + data->time_delta; + if (!first_immersive_frame_time_) { + DCHECK(!first_immersive_frame_time_delta_); + + first_immersive_frame_time_ = base::TimeTicks::Now(); + first_immersive_frame_time_delta_ = data->time_delta; + } + + base::TimeDelta current_frame_time_from_first_frame = + data->time_delta - *first_immersive_frame_time_delta_; + base::TimeTicks current_frame_time = + *first_immersive_frame_time_ + current_frame_time_from_first_frame; + double high_res_now_ms = doc->Loader() ->GetTiming() - .MonotonicTimeToZeroBasedDocumentTime(monotonic_time_now) + .MonotonicTimeToZeroBasedDocumentTime(current_frame_time) .InMillisecondsF(); immersive_frame_pose_ = std::move(data->pose); @@ -358,7 +381,7 @@ void XRFrameProvider::RequestNonImmersiveFrameData(XRSession* session) { if (provider == non_immersive_data_providers_.end()) { request->value = nullptr; } else { - auto& data_provider = provider->value; + auto& data_provider = provider->value->Value(); auto options = device::mojom::blink::XRFrameDataRequestOptions::New( session->worldTrackingState()->planeDetectionState()->enabled(), session->LightEstimationEnabled()); @@ -568,7 +591,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(immersive_presentation_provider_); + DCHECK(immersive_presentation_provider_.is_bound()); XRViewport* left = layer->GetViewportForEye(XRView::kEyeLeft); XRViewport* right = layer->GetViewportForEye(XRView::kEyeRight); @@ -607,10 +630,12 @@ void XRFrameProvider::Dispose() { // TODO(bajones): Do something for outstanding frame requests? } -void XRFrameProvider::Trace(Visitor* visitor) { +void XRFrameProvider::Trace(Visitor* visitor) const { visitor->Trace(xr_); visitor->Trace(frame_transport_); visitor->Trace(immersive_session_); + visitor->Trace(immersive_data_provider_); + visitor->Trace(immersive_presentation_provider_); visitor->Trace(non_immersive_data_providers_); visitor->Trace(requesting_sessions_); } 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 6ed8d94dee1..d8b9bb533a1 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,10 +6,13 @@ #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/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/disallow_new_wrapper.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap_allocator.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h" #include "third_party/blink/renderer/platform/wtf/forward.h" namespace blink { @@ -45,7 +48,7 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> { return immersive_data_provider_.get(); } - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; private: void OnImmersiveFrameData(device::mojom::blink::XRFrameDataPtr data); @@ -77,16 +80,26 @@ class XRFrameProvider final : public GarbageCollected<XRFrameProvider> { // Immersive session state Member<XRSession> immersive_session_; Member<XRFrameTransport> frame_transport_; - mojo::Remote<device::mojom::blink::XRFrameDataProvider> + HeapMojoRemote<device::mojom::blink::XRFrameDataProvider, + HeapMojoWrapperMode::kWithoutContextObserver> immersive_data_provider_; - mojo::Remote<device::mojom::blink::XRPresentationProvider> + HeapMojoRemote<device::mojom::blink::XRPresentationProvider, + HeapMojoWrapperMode::kWithoutContextObserver> immersive_presentation_provider_; device::mojom::blink::VRPosePtr immersive_frame_pose_; bool is_immersive_frame_position_emulated_ = false; + // Time the first immersive frame has arrived - used to align the monotonic + // clock the devices use with the base::TimeTicks. + base::Optional<base::TimeTicks> first_immersive_frame_time_; + // The time_delta value of the first immersive frame that has arrived. + base::Optional<base::TimeDelta> first_immersive_frame_time_delta_; + // Non-immersive session state HeapHashMap<Member<XRSession>, - mojo::Remote<device::mojom::blink::XRFrameDataProvider>> + Member<DisallowNewWrapper<HeapMojoRemote< + device::mojom::blink::XRFrameDataProvider, + HeapMojoWrapperMode::kWithoutContextObserver>>>> non_immersive_data_providers_; HeapHashMap<Member<XRSession>, device::mojom::blink::XRFrameDataPtr> requesting_sessions_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc b/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc index 12ebbb526c9..c94be8709ad 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_frame_request_callback_collection.cc @@ -70,7 +70,7 @@ void XRFrameRequestCallbackCollection::ExecuteCallbacks(XRSession* session, current_callbacks_.clear(); } -void XRFrameRequestCallbackCollection::Trace(Visitor* visitor) { +void XRFrameRequestCallbackCollection::Trace(Visitor* visitor) const { visitor->Trace(callbacks_); visitor->Trace(current_callbacks_); visitor->Trace(context_); 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 dfc5344173a..f211fa71ce9 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 @@ -32,7 +32,7 @@ class XRFrameRequestCallbackCollection final bool IsEmpty() const { return !callbacks_.size(); } - void Trace(Visitor*); + void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "XRFrameRequestCallbackCollection"; } 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 e94e661a384..cb937694b0f 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 @@ -21,10 +21,7 @@ base::Optional<TransformationMatrix> XRGripSpace::MojoFromNative() { return base::nullopt; } - if (!input_source_->MojoFromInput()) - return base::nullopt; - - return *(input_source_->MojoFromInput()); + return input_source_->MojoFromInput(); } base::Optional<TransformationMatrix> XRGripSpace::NativeFromMojo() { @@ -35,7 +32,15 @@ bool XRGripSpace::EmulatedPosition() const { return input_source_->emulatedPosition(); } -base::Optional<XRNativeOriginInformation> XRGripSpace::NativeOrigin() const { +base::Optional<device::mojom::blink::XRNativeOriginInformation> +XRGripSpace::NativeOrigin() const { + // Grip space's native origin is equal to input source's native origin, but + // only when using tracked pointer for input. + if (input_source_->TargetRayMode() != + device::mojom::XRTargetRayMode::POINTING) { + return base::nullopt; + } + return input_source_->nativeOrigin(); } @@ -45,7 +50,7 @@ bool XRGripSpace::IsStationary() const { return false; } -void XRGripSpace::Trace(Visitor* visitor) { +void XRGripSpace::Trace(Visitor* visitor) const { 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 bed5becd44a..d88cac429e2 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 @@ -18,11 +18,12 @@ class XRGripSpace : public XRSpace { base::Optional<TransformationMatrix> NativeFromMojo() override; bool EmulatedPosition() const override; - base::Optional<XRNativeOriginInformation> NativeOrigin() const override; + base::Optional<device::mojom::blink::XRNativeOriginInformation> NativeOrigin() + const override; bool IsStationary() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<XRInputSource> input_source_; 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 cdb0a2ada97..f0f031c9790 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 @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/xr/xr_hit_test_result.h" +#include "third_party/blink/renderer/modules/xr/type_converters.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_reference_space.h" @@ -17,8 +18,7 @@ XRHitTestResult::XRHitTestResult( XRSession* session, const device::mojom::blink::XRHitResult& hit_result) : session_(session), - mojo_from_this_(std::make_unique<TransformationMatrix>( - hit_result.hit_matrix.matrix())), + mojo_from_this_(hit_result.mojo_from_result), plane_id_(hit_result.plane_id != 0 ? base::Optional<uint64_t>(hit_result.plane_id) : base::nullopt) {} @@ -27,7 +27,8 @@ XRPose* XRHitTestResult::getPose(XRSpace* other) { auto maybe_other_space_native_from_mojo = other->NativeFromMojo(); DCHECK(maybe_other_space_native_from_mojo); - auto mojo_from_this = *mojo_from_this_; + blink::TransformationMatrix mojo_from_this = + mojo_from_this_.ToTransform().matrix(); auto other_native_from_mojo = *maybe_other_space_native_from_mojo; auto other_offset_from_other_native = other->OffsetFromNativeMatrix(); @@ -41,7 +42,6 @@ XRPose* XRHitTestResult::getPose(XRSpace* other) { } ScriptPromise XRHitTestResult::createAnchor(ScriptState* script_state, - XRRigidTransform* this_from_anchor, ExceptionState& exception_state) { DVLOG(2) << __func__; @@ -51,61 +51,53 @@ ScriptPromise XRHitTestResult::createAnchor(ScriptState* script_state, return {}; } - if (!this_from_anchor) { + // TODO(https://crbug.com/954236): Revisit the approach of plane poses not + // being stable from frame to frame - if we could guarantee that anchor poses + // are not so dynamic, anchor creation could be improved. + // + // Planes are not considered stationary for the purpose of anchor creation + // (their poses may change dramatically on a frame-by-frame basis). Grab an + // information about reference space that is well-suited for anchor creation + // from session: + base::Optional<XRSession::ReferenceSpaceInformation> + reference_space_information = session_->GetStationaryReferenceSpace(); + + if (!reference_space_information) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - XRSession::kNoRigidTransformSpecified); + XRSession::kUnableToRetrieveMatrix); return {}; } + const TransformationMatrix& mojo_from_space = + reference_space_information->mojo_from_space; + + DCHECK(mojo_from_space.IsInvertible()); + + auto space_from_mojo = mojo_from_space.Inverse(); + auto space_from_anchor = + space_from_mojo * (mojo_from_this_.ToTransform().matrix()); + if (plane_id_) { DVLOG(2) << __func__ << ": hit test result's entity is a plane, creating " "plane-attached anchor"; return session_->CreatePlaneAnchorHelper( - script_state, this_from_anchor->TransformMatrix(), *plane_id_, + script_state, space_from_anchor, + reference_space_information->native_origin, *plane_id_, exception_state); } else { DVLOG(2) << __func__ << ": hit test result's entity is unavailable, creating " "free-floating anchor "; - // Let's create free-floating anchor since plane is unavailable. In our - // case, we should first attempt to use the local space as it is supposed to - // be more stable, but if that is unavailable, we can try using unbounded - // space. Otherwise, there's not much we can do so we fail the call. - auto reference_space_category = - device::mojom::XRReferenceSpaceCategory::LOCAL; - auto mojo_from_space = - session_->GetMojoFrom(XRReferenceSpace::Type::kTypeLocal); - if (!mojo_from_space) { - // Local space is not available, try unbounded. - reference_space_category = - device::mojom::XRReferenceSpaceCategory::UNBOUNDED; - mojo_from_space = - session_->GetMojoFrom(XRReferenceSpace::Type::kTypeUnbounded); - } - - if (!mojo_from_space) { - exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - XRSession::kUnableToRetrieveMatrix); - return {}; - } - - DCHECK(mojo_from_space->IsInvertible()); - - auto space_from_mojo = mojo_from_space->Inverse(); - auto space_from_anchor = space_from_mojo * (*mojo_from_this_) * - this_from_anchor->TransformMatrix(); - - auto maybe_native_origin = - XRNativeOriginInformation::Create(reference_space_category); - - return session_->CreateAnchorHelper(script_state, space_from_anchor, - *maybe_native_origin, exception_state); + // Let's create free-floating anchor since plane is unavailable. + return session_->CreateAnchorHelper( + script_state, space_from_anchor, + reference_space_information->native_origin, exception_state); } } -void XRHitTestResult::Trace(Visitor* visitor) { +void XRHitTestResult::Trace(Visitor* visitor) const { visitor->Trace(session_); ScriptWrappable::Trace(visitor); } 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 9d070373885..6b9083dbac1 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 @@ -14,9 +14,7 @@ namespace blink { class ExceptionState; class ScriptState; -class TransformationMatrix; class XRPose; -class XRRigidTransform; class XRSession; class XRSpace; @@ -30,17 +28,16 @@ class XRHitTestResult : public ScriptWrappable { XRPose* getPose(XRSpace* relative_to); ScriptPromise createAnchor(ScriptState* script_state, - XRRigidTransform* initial_pose, ExceptionState& exception_state); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<XRSession> session_; // Hit test results do not have origin-offset so mojo_from_this_ contains // mojo_from_this with origin-offset (identity) already applied. - std::unique_ptr<TransformationMatrix> mojo_from_this_; + device::Pose mojo_from_this_; base::Optional<uint64_t> plane_id_; }; 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 259175bb971..a5c4d2410c1 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 @@ -7,5 +7,5 @@ interface XRHitTestResult { XRPose? getPose(XRSpace relative_to); [RuntimeEnabled=WebXRAnchors, CallWith=ScriptState, RaisesException, MeasureAs=XRHitTestResultCreateAnchor] - Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose); + Promise<XRAnchor> createAnchor(); }; 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 9e539e62dc9..3ec42f13d03 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 @@ -36,7 +36,7 @@ HeapVector<Member<XRHitTestResult>> XRHitTestSource::Results() { for (const auto& result : last_frame_results_) { results.emplace_back( - MakeGarbageCollected<XRHitTestResult>(xr_session_, result)); + MakeGarbageCollected<XRHitTestResult>(xr_session_, *result)); } return results; @@ -47,14 +47,16 @@ void XRHitTestSource::Update( last_frame_results_.clear(); for (auto& result : hit_test_results) { - DVLOG(3) << __func__ << ": processing hit test result, hit matrix: " - << result->hit_matrix.ToString() + DVLOG(3) << __func__ << ": processing hit test result, position=" + << result->mojo_from_result.position().ToString() + << ", orientation=" + << result->mojo_from_result.orientation().ToString() << ", plane_id=" << result->plane_id; - last_frame_results_.push_back(*result); + last_frame_results_.emplace_back(result->Clone()); } } -void XRHitTestSource::Trace(Visitor* visitor) { +void XRHitTestSource::Trace(Visitor* visitor) const { visitor->Trace(xr_session_); ScriptWrappable::Trace(visitor); } 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 672909b3add..79868dce2f8 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 @@ -34,13 +34,13 @@ class XRHitTestSource : public ScriptWrappable { void Update( const Vector<device::mojom::blink::XRHitResultPtr>& hit_test_results); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: const uint64_t id_; Member<XRSession> xr_session_; - Vector<device::mojom::blink::XRHitResult> last_frame_results_; + Vector<device::mojom::blink::XRHitResultPtr> 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 b393c0cb3c6..7b989d02feb 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 @@ -229,7 +229,22 @@ void XRInputSource::UpdateGamepad( } } -base::Optional<XRNativeOriginInformation> XRInputSource::nativeOrigin() const { +base::Optional<TransformationMatrix> XRInputSource::MojoFromInput() const { + if (!mojo_from_input_.get()) { + return base::nullopt; + } + return *(mojo_from_input_.get()); +} + +base::Optional<TransformationMatrix> XRInputSource::InputFromPointer() const { + if (!input_from_pointer_.get()) { + return base::nullopt; + } + return *(input_from_pointer_.get()); +} + +base::Optional<device::mojom::blink::XRNativeOriginInformation> +XRInputSource::nativeOrigin() const { return XRNativeOriginInformation::Create(this); } @@ -589,7 +604,7 @@ XRInputSourceEvent* XRInputSource::CreateInputSourceEvent( return XRInputSourceEvent::Create(type, presentation_frame, this); } -void XRInputSource::Trace(Visitor* visitor) { +void XRInputSource::Trace(Visitor* visitor) const { visitor->Trace(session_); visitor->Trace(target_ray_space_); visitor->Trace(grip_space_); 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 d61df78f3a7..37a2193f2a7 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,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_SOURCE_H_ +#include "base/optional.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" @@ -74,14 +75,13 @@ class XRInputSource : public ScriptWrappable, public Gamepad::Client { device::mojom::XRTargetRayMode TargetRayMode() const { return state_.target_ray_mode; } - const TransformationMatrix* MojoFromInput() const { - return mojo_from_input_.get(); - } - const TransformationMatrix* InputFromPointer() const { - return input_from_pointer_.get(); - } - base::Optional<XRNativeOriginInformation> nativeOrigin() const; + base::Optional<TransformationMatrix> MojoFromInput() const; + + base::Optional<TransformationMatrix> InputFromPointer() const; + + base::Optional<device::mojom::blink::XRNativeOriginInformation> nativeOrigin() + const; void OnSelectStart(); void OnSelectEnd(); @@ -104,7 +104,7 @@ class XRInputSource : public ScriptWrappable, public Gamepad::Client { const device::mojom::blink::XRInputSourceStatePtr& state); bool IsVisible() const { return state_.is_visible; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // In order to ease copying, any new member variables that can be trivially diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.cc b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.cc index bbd561b3cf1..b6bad19e241 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.cc @@ -43,7 +43,7 @@ void XRInputSourceArray::SetWithSourceId(uint32_t source_id, input_sources_.Set(source_id, input_source); } -void XRInputSourceArray::Trace(Visitor* visitor) { +void XRInputSourceArray::Trace(Visitor* visitor) const { visitor->Trace(input_sources_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.h b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.h index 721761149f9..60dbe3edd73 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_array.h @@ -23,7 +23,7 @@ class XRInputSourceArray : public ScriptWrappable { void RemoveWithSourceId(uint32_t source_id); void SetWithSourceId(uint32_t source_id, XRInputSource* input_source); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: HeapHashMap<uint32_t, Member<XRInputSource>> input_sources_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.cc b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.cc index 6e885b9da63..def4a2a6d1f 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.cc @@ -31,7 +31,7 @@ const AtomicString& XRInputSourceEvent::InterfaceName() const { return event_interface_names::kXRInputSourceEvent; } -void XRInputSourceEvent::Trace(Visitor* visitor) { +void XRInputSourceEvent::Trace(Visitor* visitor) const { visitor->Trace(frame_); visitor->Trace(input_source_); Event::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.h b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.h index a9696357013..39560fadd8c 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_source_event.h @@ -40,7 +40,7 @@ class XRInputSourceEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<XRFrame> frame_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.cc b/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.cc index ec5dfc9ea36..82fd3f6ba95 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.cc @@ -34,7 +34,7 @@ const AtomicString& XRInputSourcesChangeEvent::InterfaceName() const { return event_interface_names::kXRInputSourcesChangeEvent; } -void XRInputSourcesChangeEvent::Trace(Visitor* visitor) { +void XRInputSourcesChangeEvent::Trace(Visitor* visitor) const { visitor->Trace(session_); visitor->Trace(added_); visitor->Trace(removed_); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h b/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h index 94786139334..d70833e2516 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.h @@ -45,7 +45,7 @@ class XRInputSourcesChangeEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<XRSession> session_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc b/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc index f4948549d45..eaa8603c735 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc @@ -19,7 +19,7 @@ const AtomicString& XRLayer::InterfaceName() const { return event_target_names::kXRLayer; } -void XRLayer::Trace(Visitor* visitor) { +void XRLayer::Trace(Visitor* visitor) const { visitor->Trace(session_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_layer.h b/chromium/third_party/blink/renderer/modules/xr/xr_layer.h index 7433a6898df..230eb8da255 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_layer.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_layer.h @@ -24,7 +24,7 @@ class XRLayer : public EventTargetWithInlineData { ExecutionContext* GetExecutionContext() const override; const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: const Member<XRSession> session_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.cc b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.cc index f6ce4d435c6..d7b4f50a428 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.cc @@ -31,7 +31,7 @@ XRLightEstimate::XRLightEstimate( light_probe.main_light_intensity.blue(), 1); } -void XRLightEstimate::Trace(Visitor* visitor) { +void XRLightEstimate::Trace(Visitor* visitor) const { visitor->Trace(sh_coefficients_); visitor->Trace(primary_light_direction_); visitor->Trace(primary_light_intensity_); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.h b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.h index bf07417bbe6..7c8fa9265cf 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_estimate.h @@ -31,7 +31,7 @@ class XRLightEstimate : public ScriptWrappable { return primary_light_intensity_.Get(); } - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<DOMFloat32Array> sh_coefficients_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.cc b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.cc index a243287bf96..0481d844a64 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.cc @@ -10,6 +10,7 @@ #include "third_party/blink/renderer/modules/event_target_modules.h" #include "third_party/blink/renderer/modules/xr/xr_cube_map.h" #include "third_party/blink/renderer/modules/xr/xr_light_estimate.h" +#include "third_party/blink/renderer/modules/xr/xr_object_space.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" namespace blink { @@ -23,6 +24,23 @@ const double kReflectionChangeDelta = 1000.0; XRLightProbe::XRLightProbe(XRSession* session) : session_(session) {} +XRSpace* XRLightProbe::probeSpace() const { + if (!probe_space_) { + probe_space_ = + MakeGarbageCollected<XRObjectSpace<XRLightProbe>>(session_, this); + } + + return probe_space_; +} + +base::Optional<TransformationMatrix> XRLightProbe::MojoFromObject() const { + // For the moment we're making an assumption that the lighting estimations + // are always generated from the local space origin. This is the case for + // ARCore, but will need to be made more flexible as other runtimes or methods + // of light estimation are added. + return session_->GetMojoFrom(device::mojom::XRReferenceSpaceType::kLocal); +} + void XRLightProbe::ProcessLightEstimationData( const device::mojom::blink::XRLightEstimationData* data, double timestamp) { @@ -67,8 +85,9 @@ const AtomicString& XRLightProbe::InterfaceName() const { return event_target_names::kXRLightProbe; } -void XRLightProbe::Trace(Visitor* visitor) { +void XRLightProbe::Trace(Visitor* visitor) const { visitor->Trace(session_); + visitor->Trace(probe_space_); visitor->Trace(light_estimate_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.h b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.h index b7544213909..6a208af69da 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.h @@ -17,9 +17,11 @@ namespace blink { +class TransformationMatrix; class XRCubeMap; class XRLightEstimate; class XRSession; +class XRSpace; class XRLightProbe : public EventTargetWithInlineData { DEFINE_WRAPPERTYPEINFO(); @@ -29,8 +31,12 @@ class XRLightProbe : public EventTargetWithInlineData { XRSession* session() const { return session_; } + XRSpace* probeSpace() const; + DEFINE_ATTRIBUTE_EVENT_LISTENER(reflectionchange, kReflectionchange) + base::Optional<TransformationMatrix> MojoFromObject() const; + void ProcessLightEstimationData( const device::mojom::blink::XRLightEstimationData* data, double timestamp); @@ -42,10 +48,11 @@ class XRLightProbe : public EventTargetWithInlineData { ExecutionContext* GetExecutionContext() const override; const AtomicString& InterfaceName() const override; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<XRSession> session_; + mutable Member<XRSpace> probe_space_; Member<XRLightEstimate> light_estimate_; double last_reflection_change_ = 0.0; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.idl b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.idl index 462db1a49c5..4d2ac1867ba 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_light_probe.idl @@ -7,6 +7,8 @@ Exposed=Window, RuntimeEnabled=WebXRLightEstimation ] interface XRLightProbe : EventTarget { + [SameObject] readonly attribute XRSpace probeSpace; + attribute EventHandler onreflectionchange; }; 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 index 82e006057e0..b29f4c0461d 100644 --- 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 @@ -4,102 +4,72 @@ #include "third_party/blink/renderer/modules/xr/xr_native_origin_information.h" -#include "third_party/blink/renderer/modules/xr/type_converters.h" +#include "device/vr/public/mojom/vr_service.mojom-blink.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_light_probe.h" #include "third_party/blink/renderer/modules/xr/xr_plane.h" #include "third_party/blink/renderer/modules/xr/xr_reference_space.h" -namespace { -device::mojom::XRReferenceSpaceCategory ToReferenceSpaceCategory( - blink::XRReferenceSpace::Type reference_space_type) { - switch (reference_space_type) { - case blink::XRReferenceSpace::Type::kTypeBoundedFloor: - return device::mojom::XRReferenceSpaceCategory::BOUNDED_FLOOR; - case blink::XRReferenceSpace::Type::kTypeUnbounded: - return device::mojom::XRReferenceSpaceCategory::UNBOUNDED; - case blink::XRReferenceSpace::Type::kTypeLocalFloor: - return device::mojom::XRReferenceSpaceCategory::LOCAL_FLOOR; - case blink::XRReferenceSpace::Type::kTypeLocal: - return device::mojom::XRReferenceSpaceCategory::LOCAL; - case blink::XRReferenceSpace::Type::kTypeViewer: - return device::mojom::XRReferenceSpaceCategory::VIEWER; - } -} - -} // namespace - namespace blink { -base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create( - const XRAnchor* anchor) { +namespace XRNativeOriginInformation { + +device::mojom::blink::XRNativeOriginInformation Create(const XRAnchor* anchor) { DCHECK(anchor); - return XRNativeOriginInformation(Type::Anchor, anchor->id()); + + device::mojom::blink::XRNativeOriginInformation result; + result.set_anchor_id(anchor->id()); + + return result; } -base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create( +device::mojom::blink::XRNativeOriginInformation Create( const XRInputSource* input_source) { DCHECK(input_source); - return XRNativeOriginInformation(Type::InputSource, - input_source->source_id()); + + device::mojom::blink::XRNativeOriginInformation result; + result.set_input_source_id(input_source->source_id()); + + return result; } -base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create( - const XRPlane* plane) { +device::mojom::blink::XRNativeOriginInformation Create(const XRPlane* plane) { DCHECK(plane); - return XRNativeOriginInformation(Type::Plane, plane->id()); + + device::mojom::blink::XRNativeOriginInformation result; + result.set_plane_id(plane->id()); + + return result; } -base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create( +device::mojom::blink::XRNativeOriginInformation Create( + const XRLightProbe* light_probe) { + DCHECK(light_probe); + + // TODO: We'll want these to correspond to an actual, independent space + // eventually, but at the moment it's sufficient for the ARCore implementation + // to have it be equivalent to the local reference space. + return Create(device::mojom::XRReferenceSpaceType::kLocal); +} + +device::mojom::blink::XRNativeOriginInformation Create( const XRReferenceSpace* reference_space) { DCHECK(reference_space); auto reference_space_type = reference_space->GetType(); - auto reference_space_category = - ToReferenceSpaceCategory(reference_space_type); - return XRNativeOriginInformation(Type::ReferenceSpace, - reference_space_category); + return Create(reference_space_type); } -base::Optional<XRNativeOriginInformation> XRNativeOriginInformation::Create( - device::mojom::XRReferenceSpaceCategory reference_space_type) { - return XRNativeOriginInformation(Type::ReferenceSpace, reference_space_type); -} +device::mojom::blink::XRNativeOriginInformation Create( + device::mojom::XRReferenceSpaceType reference_space_type) { + device::mojom::blink::XRNativeOriginInformation result; + result.set_reference_space_type(reference_space_type); -XRNativeOriginInformation::XRNativeOriginInformation(Type type, - uint32_t input_source_id) - : type_(type), input_source_id_(input_source_id) {} - -XRNativeOriginInformation::XRNativeOriginInformation( - Type type, - uint64_t anchor_or_plane_id) - : type_(type), anchor_or_plane_id_(anchor_or_plane_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( - anchor_or_plane_id_); - - case XRNativeOriginInformation::Type::InputSource: - return device::mojom::blink::XRNativeOriginInformation::NewInputSourceId( - input_source_id_); - - case XRNativeOriginInformation::Type::Plane: - return device::mojom::blink::XRNativeOriginInformation::NewPlaneId( - anchor_or_plane_id_); - - case XRNativeOriginInformation::Type::ReferenceSpace: - return device::mojom::blink::XRNativeOriginInformation:: - NewReferenceSpaceCategory(reference_space_category_); - } + return result; } +} // namespace XRNativeOriginInformation + } // 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 index 9c2f346621a..368b542b94c 100644 --- 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 @@ -5,59 +5,31 @@ #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" +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" namespace blink { class XRAnchor; class XRInputSource; +class XRLightProbe; 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); - - static base::Optional<XRNativeOriginInformation> Create( - device::mojom::XRReferenceSpaceCategory reference_space_category); - - private: - enum class Type : int32_t { ReferenceSpace, InputSource, Anchor, Plane }; - - XRNativeOriginInformation() = delete; - XRNativeOriginInformation(const XRNativeOriginInformation& other) = delete; - void operator=(const XRNativeOriginInformation& other) = delete; +namespace XRNativeOriginInformation { - XRNativeOriginInformation(Type type, uint32_t input_source_id); - XRNativeOriginInformation(Type type, uint64_t anchor_or_plane_id); - XRNativeOriginInformation( - Type type, - device::mojom::XRReferenceSpaceCategory reference_space_type); +device::mojom::blink::XRNativeOriginInformation Create(const XRAnchor* anchor); +device::mojom::blink::XRNativeOriginInformation Create( + const XRInputSource* input_source); +device::mojom::blink::XRNativeOriginInformation Create(const XRPlane* plane); +device::mojom::blink::XRNativeOriginInformation Create( + const XRLightProbe* light_probe); +device::mojom::blink::XRNativeOriginInformation Create( + const XRReferenceSpace* reference_space); - const Type type_; +device::mojom::blink::XRNativeOriginInformation Create( + device::mojom::XRReferenceSpaceType reference_space_type); - const union { - uint32_t input_source_id_; - uint64_t anchor_or_plane_id_; - device::mojom::XRReferenceSpaceCategory reference_space_category_; - }; -}; +} // namespace XRNativeOriginInformation } // namespace blink 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 dffb89709cc..d13f4fc2651 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 @@ -5,6 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_OBJECT_SPACE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_OBJECT_SPACE_H_ +#include "device/vr/public/mojom/vr_service.mojom-blink-forward.h" +#include "third_party/blink/renderer/modules/xr/xr_native_origin_information.h" #include "third_party/blink/renderer/modules/xr/xr_space.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" @@ -35,7 +37,8 @@ class XRObjectSpace : public XRSpace { return XRSpace::TryInvert(MojoFromNative()); } - base::Optional<XRNativeOriginInformation> NativeOrigin() const override { + base::Optional<device::mojom::blink::XRNativeOriginInformation> NativeOrigin() + const override { return XRNativeOriginInformation::Create(object_); } @@ -45,7 +48,7 @@ class XRObjectSpace : public XRSpace { return true; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(object_); XRSpace::Trace(visitor); } 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 f073901e260..83dc1094b8c 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_plane.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane.cc @@ -8,9 +8,14 @@ #include "third_party/blink/renderer/modules/xr/type_converters.h" #include "third_party/blink/renderer/modules/xr/xr_object_space.h" #include "third_party/blink/renderer/modules/xr/xr_reference_space.h" -#include "third_party/blink/renderer/modules/xr/xr_rigid_transform.h" #include "third_party/blink/renderer/modules/xr/xr_session.h" +namespace { + +const char kUnknownPlanePose[] = "Plane pose is unknown."; + +} + namespace blink { XRPlane::XRPlane(uint64_t id, @@ -23,25 +28,19 @@ XRPlane::XRPlane(uint64_t id, plane_data.orientation), mojo::ConvertTo<HeapVector<Member<DOMPointReadOnly>>>( plane_data.polygon), - timestamp) { - // No need for else - if mojo_from_plane is not present, the - // default-constructed unique ptr is fine. It would signify that the plane - // exists and is tracked by the underlying system, but its current location is - // unknown. - if (plane_data.mojo_from_plane) { - SetMojoFromPlane(mojo::ConvertTo<blink::TransformationMatrix>( - plane_data.mojo_from_plane)); - } -} + plane_data.mojo_from_plane, + timestamp) {} XRPlane::XRPlane(uint64_t id, XRSession* session, const base::Optional<Orientation>& orientation, const HeapVector<Member<DOMPointReadOnly>>& polygon, + const base::Optional<device::Pose>& mojo_from_plane, double timestamp) : id_(id), polygon_(polygon), orientation_(orientation), + mojo_from_plane_(mojo_from_plane), session_(session), last_changed_time_(timestamp) { DVLOG(3) << __func__; @@ -64,7 +63,7 @@ base::Optional<TransformationMatrix> XRPlane::MojoFromObject() const { return base::nullopt; } - return *mojo_from_plane_; + return mojo_from_plane_->ToTransform().matrix(); } String XRPlane::orientation() const { @@ -92,7 +91,6 @@ HeapVector<Member<DOMPointReadOnly>> XRPlane::polygon() const { } ScriptPromise XRPlane::createAnchor(ScriptState* script_state, - XRRigidTransform* initial_pose, ExceptionState& exception_state) { DVLOG(2) << __func__; @@ -102,14 +100,38 @@ ScriptPromise XRPlane::createAnchor(ScriptState* script_state, return {}; } - if (!initial_pose) { + if (!mojo_from_plane_) { + exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, + kUnknownPlanePose); + return {}; + } + + // Planes are not considered stationary for the purpose of anchor creation + // (their poses may change dramatically on a frame-by-frame basis). Grab an + // information about reference space that is well-suited for anchor creation + // from session: + base::Optional<XRSession::ReferenceSpaceInformation> + reference_space_information = session_->GetStationaryReferenceSpace(); + + if (!reference_space_information) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, - XRSession::kNoRigidTransformSpecified); + XRSession::kUnableToRetrieveMatrix); return {}; } + const TransformationMatrix& mojo_from_space = + reference_space_information->mojo_from_space; + + DCHECK(mojo_from_space.IsInvertible()); + + auto space_from_mojo = mojo_from_space.Inverse(); + // We'll create an anchor located at the current plane's pose: + auto space_from_anchor = + space_from_mojo * (mojo_from_plane_->ToTransform().matrix()); + return session_->CreatePlaneAnchorHelper( - script_state, initial_pose->TransformMatrix(), id_, exception_state); + script_state, space_from_anchor, + reference_space_information->native_origin, id_, exception_state); } void XRPlane::Update(const device::mojom::blink::XRPlaneData& plane_data, @@ -120,25 +142,14 @@ void XRPlane::Update(const device::mojom::blink::XRPlaneData& plane_data, orientation_ = mojo::ConvertTo<base::Optional<blink::XRPlane::Orientation>>( plane_data.orientation); - if (plane_data.mojo_from_plane) { - SetMojoFromPlane(mojo::ConvertTo<blink::TransformationMatrix>( - plane_data.mojo_from_plane)); - } else { - mojo_from_plane_ = nullptr; - } + + mojo_from_plane_ = plane_data.mojo_from_plane; + polygon_ = mojo::ConvertTo<HeapVector<Member<DOMPointReadOnly>>>(plane_data.polygon); } -void XRPlane::SetMojoFromPlane(const TransformationMatrix& mojo_from_plane) { - if (mojo_from_plane_) { - *mojo_from_plane_ = mojo_from_plane; - } else { - mojo_from_plane_ = std::make_unique<TransformationMatrix>(mojo_from_plane); - } -} - -void XRPlane::Trace(Visitor* visitor) { +void XRPlane::Trace(Visitor* visitor) const { visitor->Trace(polygon_); visitor->Trace(session_); visitor->Trace(plane_space_); 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 8875cf39437..a58b210f052 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_plane.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane.h @@ -17,7 +17,6 @@ namespace blink { class ExceptionState; -class XRRigidTransform; class XRSession; class XRSpace; @@ -43,7 +42,6 @@ class XRPlane : public ScriptWrappable { double lastChangedTime() const; ScriptPromise createAnchor(ScriptState* script_state, - XRRigidTransform* initial_pose, ExceptionState& exception_state); // Updates plane data from passed in |plane_data|. The resulting instance @@ -52,24 +50,23 @@ class XRPlane : public ScriptWrappable { void Update(const device::mojom::blink::XRPlaneData& plane_data, double timestamp); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: XRPlane(uint64_t id, XRSession* session, const base::Optional<Orientation>& orientation, const HeapVector<Member<DOMPointReadOnly>>& polygon, + const base::Optional<device::Pose>& mojo_from_plane, double timestamp); - void SetMojoFromPlane(const TransformationMatrix& mojo_from_plane); - const uint64_t id_; HeapVector<Member<DOMPointReadOnly>> polygon_; base::Optional<Orientation> orientation_; // Plane center's pose in device (mojo) space. Nullptr if the pose of the // anchor is unknown in the current frame. - std::unique_ptr<TransformationMatrix> mojo_from_plane_; + base::Optional<device::Pose> mojo_from_plane_; Member<XRSession> session_; 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 a08445c8c8c..9361d4ed24c 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_plane.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane.idl @@ -12,7 +12,7 @@ enum XRPlaneOrientation { [ SecureContext, Exposed=Window, - RuntimeEnabled=WebXRIncubations + RuntimeEnabled=WebXRPlaneDetection ] interface XRPlane { readonly attribute XRSpace planeSpace; @@ -21,5 +21,5 @@ interface XRPlane { readonly attribute DOMHighResTimeStamp lastChangedTime; [CallWith=ScriptState, RaisesException, RuntimeEnabled=WebXRAnchors] - Promise<XRAnchor> createAnchor(XRRigidTransform initial_pose); + Promise<XRAnchor> createAnchor(); }; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.idl b/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.idl index 8b41426af0f..9457324459d 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane_detection_state.idl @@ -7,7 +7,7 @@ [ SecureContext, Exposed=Window, - RuntimeEnabled=WebXRIncubations + RuntimeEnabled=WebXRPlaneDetection ] interface XRPlaneDetectionState { readonly attribute boolean enabled; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.cc b/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.cc index f941384cf79..158594a2246 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.cc @@ -12,7 +12,7 @@ const HeapHashSet<Member<XRPlane>>& XRPlaneSet::elements() const { return planes_; } -void XRPlaneSet::Trace(Visitor* visitor) { +void XRPlaneSet::Trace(Visitor* visitor) const { visitor->Trace(planes_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.h b/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.h index ba27dbe0238..f3142aa1566 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.h @@ -17,7 +17,7 @@ class XRPlaneSet : public ScriptWrappable, public XRSetlike<XRPlane> { public: explicit XRPlaneSet(HeapHashSet<Member<XRPlane>> planes); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; protected: const HeapHashSet<Member<XRPlane>>& elements() const override; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.idl b/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.idl index f0d3a0d4ce8..8e04e6bd65d 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_plane_set.idl @@ -7,7 +7,7 @@ [ SecureContext, Exposed=Window, - RuntimeEnabled=WebXRIncubations + RuntimeEnabled=WebXRPlaneDetection ] interface XRPlaneSet { readonly setlike<XRPlane>; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_pose.cc b/chromium/third_party/blink/renderer/modules/xr/xr_pose.cc index 4eeb10dfe14..137a5fbe786 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_pose.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_pose.cc @@ -13,7 +13,7 @@ XRPose::XRPose(const TransformationMatrix& pose_model_matrix, : transform_(MakeGarbageCollected<XRRigidTransform>(pose_model_matrix)), emulated_position_(emulated_position) {} -void XRPose::Trace(Visitor* visitor) { +void XRPose::Trace(Visitor* visitor) const { visitor->Trace(transform_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_pose.h b/chromium/third_party/blink/renderer/modules/xr/xr_pose.h index fcc0adde4b6..4d034c83f5b 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_pose.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_pose.h @@ -25,7 +25,7 @@ class XRPose : public ScriptWrappable { XRRigidTransform* transform() const { return transform_; } bool emulatedPosition() const { return emulated_position_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: Member<XRRigidTransform> transform_; 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 f501e4d6e9c..8be9ce9e129 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_ray.cc @@ -194,7 +194,7 @@ TransformationMatrix XRRay::RawMatrix() { return *raw_matrix_; } -void XRRay::Trace(Visitor* visitor) { +void XRRay::Trace(Visitor* visitor) const { visitor->Trace(origin_); visitor->Trace(direction_); visitor->Trace(matrix_); 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 82013f476b9..c5a2aef76b3 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_ray.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_ray.h @@ -46,7 +46,7 @@ class XRRay final : public ScriptWrappable { static XRRay* Create(XRRigidTransform* transform, ExceptionState& exception_state); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void Set(const TransformationMatrix& matrix, ExceptionState& exception_state); 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 31e75624551..184ab7cfac2 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 @@ -13,41 +13,43 @@ namespace blink { +using ReferenceSpaceType = device::mojom::blink::XRReferenceSpaceType; + // Rough estimate of avg human eye height in meters. const double kDefaultEmulationHeightMeters = 1.6; -XRReferenceSpace::Type XRReferenceSpace::StringToReferenceSpaceType( +ReferenceSpaceType XRReferenceSpace::StringToReferenceSpaceType( const String& reference_space_type) { if (reference_space_type == "viewer") { - return XRReferenceSpace::Type::kTypeViewer; + return ReferenceSpaceType::kViewer; } else if (reference_space_type == "local") { - return XRReferenceSpace::Type::kTypeLocal; + return ReferenceSpaceType::kLocal; } else if (reference_space_type == "local-floor") { - return XRReferenceSpace::Type::kTypeLocalFloor; + return ReferenceSpaceType::kLocalFloor; } else if (reference_space_type == "bounded-floor") { - return XRReferenceSpace::Type::kTypeBoundedFloor; + return ReferenceSpaceType::kBoundedFloor; } else if (reference_space_type == "unbounded") { - return XRReferenceSpace::Type::kTypeUnbounded; + return ReferenceSpaceType::kUnbounded; } NOTREACHED(); - return Type::kTypeViewer; + return ReferenceSpaceType::kViewer; } // origin offset starts as identity transform -XRReferenceSpace::XRReferenceSpace(XRSession* session, Type type) +XRReferenceSpace::XRReferenceSpace(XRSession* session, ReferenceSpaceType type) : XRReferenceSpace(session, MakeGarbageCollected<XRRigidTransform>(nullptr, nullptr), type) {} XRReferenceSpace::XRReferenceSpace(XRSession* session, XRRigidTransform* origin_offset, - Type type) + ReferenceSpaceType type) : XRSpace(session), origin_offset_(origin_offset), type_(type) {} XRReferenceSpace::~XRReferenceSpace() = default; XRPose* XRReferenceSpace::getPose(XRSpace* other_space) { - if (type_ == Type::kTypeViewer) { + if (type_ == ReferenceSpaceType::kViewer) { base::Optional<TransformationMatrix> other_offset_from_viewer = other_space->OffsetFromViewer(); if (!other_offset_from_viewer) { @@ -83,18 +85,25 @@ void XRReferenceSpace::SetFloorFromMojo() { base::Optional<TransformationMatrix> XRReferenceSpace::NativeFromMojo() { switch (type_) { - case Type::kTypeLocal: { + case ReferenceSpaceType::kViewer: + case ReferenceSpaceType::kLocal: + case ReferenceSpaceType::kUnbounded: { // The session is the source of truth for latest state of the transform - // between local space and mojo space. - auto mojo_from_local = session()->GetMojoFrom(Type::kTypeLocal); - if (!mojo_from_local) { - return base::nullopt; + // between local & unbounded spaces and mojo space. + auto mojo_from_native = session()->GetMojoFrom(type_); + if (!mojo_from_native) { + // The viewer reference space always has a default pose of identity if + // it's not tracked; but for any other type if it's not locatable, we + // return nullopt. + return type_ == ReferenceSpaceType::kViewer + ? base::Optional<TransformationMatrix>({}) + : base::nullopt; } - DCHECK(mojo_from_local->IsInvertible()); - return mojo_from_local->Inverse(); + DCHECK(mojo_from_native->IsInvertible()); + return mojo_from_native->Inverse(); } - case Type::kTypeLocalFloor: { + case ReferenceSpaceType::kLocalFloor: { // 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()) @@ -106,7 +115,7 @@ base::Optional<TransformationMatrix> XRReferenceSpace::NativeFromMojo() { // If the floor-level transform is unavailable, try to use the default // transform based off of local space: - auto mojo_from_local = session()->GetMojoFrom(Type::kTypeLocal); + auto mojo_from_local = session()->GetMojoFrom(ReferenceSpaceType::kLocal); if (!mojo_from_local) { return base::nullopt; } @@ -120,30 +129,8 @@ base::Optional<TransformationMatrix> XRReferenceSpace::NativeFromMojo() { return floor_from_local * local_from_mojo; } - case Type::kTypeViewer: { - auto mojo_from_viewer = session()->GetMojoFrom(Type::kTypeViewer); - // If we don't have mojo_from_viewer, then it's the default pose, - // which is the identity pose. - if (!mojo_from_viewer) - return TransformationMatrix(); - - // Otherwise we need to return viewer_from_mojo which is the inverse. - DCHECK(mojo_from_viewer->IsInvertible()); - return mojo_from_viewer->Inverse(); - } - case Type::kTypeUnbounded: { - // The session is the source of truth for latest state of the transform - // between unbounded space and mojo space. - auto mojo_from_unbounded = session()->GetMojoFrom(Type::kTypeUnbounded); - if (!mojo_from_unbounded) { - return base::nullopt; - } - - DCHECK(mojo_from_unbounded->IsInvertible()); - return mojo_from_unbounded->Inverse(); - } - case Type::kTypeBoundedFloor: { - NOTREACHED() << "kTypeBoundedFloor should be handled by subclass"; + case ReferenceSpaceType::kBoundedFloor: { + NOTREACHED() << "kBoundedFloor should be handled by subclass"; return base::nullopt; } } @@ -151,7 +138,7 @@ base::Optional<TransformationMatrix> XRReferenceSpace::NativeFromMojo() { base::Optional<TransformationMatrix> XRReferenceSpace::NativeFromViewer( const base::Optional<TransformationMatrix>& mojo_from_viewer) { - if (type_ == Type::kTypeViewer) { + if (type_ == ReferenceSpaceType::kViewer) { // Special case for viewer space, always return an identity matrix // explicitly. In theory the default behavior of multiplying NativeFromMojo // onto MojoFromViewer would be equivalent, but that would likely return an @@ -184,17 +171,17 @@ TransformationMatrix XRReferenceSpace::OffsetFromNativeMatrix() { bool XRReferenceSpace::IsStationary() const { switch (type_) { - case XRReferenceSpace::Type::kTypeLocal: - case XRReferenceSpace::Type::kTypeLocalFloor: - case XRReferenceSpace::Type::kTypeBoundedFloor: - case XRReferenceSpace::Type::kTypeUnbounded: + case ReferenceSpaceType::kLocal: + case ReferenceSpaceType::kLocalFloor: + case ReferenceSpaceType::kBoundedFloor: + case ReferenceSpaceType::kUnbounded: return true; - case XRReferenceSpace::Type::kTypeViewer: + case ReferenceSpaceType::kViewer: return false; } } -XRReferenceSpace::Type XRReferenceSpace::GetType() const { +ReferenceSpaceType XRReferenceSpace::GetType() const { return type_; } @@ -213,18 +200,18 @@ XRReferenceSpace* XRReferenceSpace::cloneWithOriginOffset( type_); } -base::Optional<XRNativeOriginInformation> XRReferenceSpace::NativeOrigin() - const { +base::Optional<device::mojom::blink::XRNativeOriginInformation> +XRReferenceSpace::NativeOrigin() const { return XRNativeOriginInformation::Create(this); } -void XRReferenceSpace::Trace(Visitor* visitor) { +void XRReferenceSpace::Trace(Visitor* visitor) const { visitor->Trace(origin_offset_); XRSpace::Trace(visitor); } void XRReferenceSpace::OnReset() { - if (type_ != Type::kTypeViewer) { + if (type_ != ReferenceSpaceType::kViewer) { DispatchEvent( *XRReferenceSpaceEvent::Create(event_type_names::kReset, this)); } 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 530e5064fb9..081f9758bf9 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 @@ -7,6 +7,7 @@ #include <memory> +#include "device/vr/public/mojom/vr_service.mojom-blink.h" #include "third_party/blink/renderer/modules/xr/xr_space.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" @@ -18,22 +19,14 @@ class XRReferenceSpace : public XRSpace { DEFINE_WRAPPERTYPEINFO(); public: - // Used for metrics, don't remove or change values. - enum class Type : int { - kTypeViewer = 0, - kTypeLocal = 1, - kTypeLocalFloor = 2, - kTypeBoundedFloor = 3, - kTypeUnbounded = 4, - kMaxValue = kTypeUnbounded, - }; - - static Type StringToReferenceSpaceType(const String& reference_space_type); - - XRReferenceSpace(XRSession* session, Type type); + static device::mojom::blink::XRReferenceSpaceType StringToReferenceSpaceType( + const String& reference_space_type); + + XRReferenceSpace(XRSession* session, + device::mojom::blink::XRReferenceSpaceType type); XRReferenceSpace(XRSession* session, XRRigidTransform* origin_offset, - Type type); + device::mojom::blink::XRReferenceSpaceType type); ~XRReferenceSpace() override; base::Optional<TransformationMatrix> NativeFromMojo() override; @@ -54,15 +47,16 @@ class XRReferenceSpace : public XRSpace { // the identity pose instead of the result of multiplying inverse matrices. XRPose* getPose(XRSpace* other_space) override; - Type GetType() const; + device::mojom::blink::XRReferenceSpaceType GetType() const; XRReferenceSpace* getOffsetReferenceSpace(XRRigidTransform* transform); DEFINE_ATTRIBUTE_EVENT_LISTENER(reset, kReset) - base::Optional<XRNativeOriginInformation> NativeOrigin() const override; + base::Optional<device::mojom::blink::XRNativeOriginInformation> NativeOrigin() + const final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; virtual void OnReset(); @@ -79,7 +73,7 @@ class XRReferenceSpace : public XRSpace { // Floor from mojo (aka local-floor_from_mojo) transform. std::unique_ptr<TransformationMatrix> floor_from_mojo_; Member<XRRigidTransform> origin_offset_; - Type type_; + device::mojom::blink::XRReferenceSpaceType type_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.cc b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.cc index 09a4c970517..72da9083ee8 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.cc @@ -32,7 +32,7 @@ const AtomicString& XRReferenceSpaceEvent::InterfaceName() const { return event_interface_names::kXRReferenceSpaceEvent; } -void XRReferenceSpaceEvent::Trace(Visitor* visitor) { +void XRReferenceSpaceEvent::Trace(Visitor* visitor) const { visitor->Trace(reference_space_); visitor->Trace(transform_); Event::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.h b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.h index 291b5f8d0c0..df341e96c90 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_reference_space_event.h @@ -41,7 +41,7 @@ class XRReferenceSpaceEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<XRReferenceSpace> reference_space_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_render_state.cc b/chromium/third_party/blink/renderer/modules/xr/xr_render_state.cc index 83591710b61..0691efd672b 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_render_state.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_render_state.cc @@ -61,7 +61,7 @@ base::Optional<double> XRRenderState::inlineVerticalFieldOfView() const { return inline_vertical_fov_; } -void XRRenderState::Trace(Visitor* visitor) { +void XRRenderState::Trace(Visitor* visitor) const { visitor->Trace(base_layer_); visitor->Trace(inline_vertical_fov_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_render_state.h b/chromium/third_party/blink/renderer/modules/xr/xr_render_state.h index bef3dd87a46..68422584e70 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_render_state.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_render_state.h @@ -36,7 +36,7 @@ class XRRenderState : public ScriptWrappable { // bound to a different session. void removeOutputContext(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: bool immersive_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc b/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc index 1e0b1364104..84652f04aea 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc @@ -155,7 +155,7 @@ void XRRigidTransform::EnsureInverse() { } } -void XRRigidTransform::Trace(Visitor* visitor) { +void XRRigidTransform::Trace(Visitor* visitor) const { visitor->Trace(position_); visitor->Trace(orientation_); visitor->Trace(inverse_); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.h b/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.h index e00e99bcc6d..9a0e47a5c87 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_rigid_transform.h @@ -41,7 +41,7 @@ class MODULES_EXPORT XRRigidTransform : public ScriptWrappable { TransformationMatrix InverseTransformMatrix(); TransformationMatrix TransformMatrix(); // copies matrix_ - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void DecomposeMatrix(); 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 bb1848aa47d..3cce978901a 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_session.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.cc @@ -27,7 +27,6 @@ #include "third_party/blink/renderer/core/resize_observer/resize_observer.h" #include "third_party/blink/renderer/core/resize_observer/resize_observer_entry.h" #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/type_converters.h" #include "third_party/blink/renderer/modules/xr/xr_anchor_set.h" #include "third_party/blink/renderer/modules/xr/xr_bounded_reference_space.h" @@ -46,6 +45,7 @@ #include "third_party/blink/renderer/modules/xr/xr_session_event.h" #include "third_party/blink/renderer/modules/xr/xr_system.h" #include "third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h" +#include "third_party/blink/renderer/modules/xr/xr_utils.h" #include "third_party/blink/renderer/modules/xr/xr_view.h" #include "third_party/blink/renderer/modules/xr/xr_webgl_layer.h" #include "third_party/blink/renderer/modules/xr/xr_world_information.h" @@ -87,6 +87,8 @@ const char kHitTestFeatureNotSupported[] = const char kHitTestSubscriptionFailed[] = "Hit test subscription failed."; +const char kAnchorCreationFailed[] = "Anchor creation failed."; + const char kLightEstimationFeatureNotSupported[] = "Light estimation feature is not supported."; @@ -117,17 +119,17 @@ void UpdateViewFromEyeParameters( // Returns the session feature corresponding to the given reference space type. base::Optional<device::mojom::XRSessionFeature> MapReferenceSpaceTypeToFeature( - XRReferenceSpace::Type type) { + device::mojom::blink::XRReferenceSpaceType type) { switch (type) { - case XRReferenceSpace::Type::kTypeViewer: + case device::mojom::blink::XRReferenceSpaceType::kViewer: return device::mojom::XRSessionFeature::REF_SPACE_VIEWER; - case XRReferenceSpace::Type::kTypeLocal: + case device::mojom::blink::XRReferenceSpaceType::kLocal: return device::mojom::XRSessionFeature::REF_SPACE_LOCAL; - case XRReferenceSpace::Type::kTypeLocalFloor: + case device::mojom::blink::XRReferenceSpaceType::kLocalFloor: return device::mojom::XRSessionFeature::REF_SPACE_LOCAL_FLOOR; - case XRReferenceSpace::Type::kTypeBoundedFloor: + case device::mojom::blink::XRReferenceSpaceType::kBoundedFloor: return device::mojom::XRSessionFeature::REF_SPACE_BOUNDED_FLOOR; - case XRReferenceSpace::Type::kTypeUnbounded: + case device::mojom::blink::XRReferenceSpaceType::kUnbounded: return device::mojom::XRSessionFeature::REF_SPACE_UNBOUNDED; } @@ -140,9 +142,12 @@ std::unique_ptr<TransformationMatrix> getPoseMatrix( if (!pose) return nullptr; + device::Pose device_pose = + device::Pose(pose->position.value_or(gfx::Point3F()), + pose->orientation.value_or(gfx::Quaternion())); + return std::make_unique<TransformationMatrix>( - mojo::TypeConverter<TransformationMatrix, - device::mojom::blink::VRPosePtr>::Convert(pose)); + device_pose.ToTransform().matrix()); } base::Optional<device::mojom::blink::EntityTypeForHitTest> @@ -262,7 +267,7 @@ class XRSession::XRSessionResizeObserverDelegate final session_->UpdateCanvasDimensions(entries[0]->target()); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(session_); ResizeObserver::Delegate::Trace(visitor); } @@ -304,6 +309,7 @@ void XRSession::MetricsReporter::ReportFeatureUsed( case XRSessionFeature::HIT_TEST: case XRSessionFeature::LIGHT_ESTIMATION: case XRSessionFeature::ANCHORS: + case XRSessionFeature::CAMERA_ACCESS: // Not recording metrics for these features currently. break; } @@ -503,14 +509,14 @@ ScriptPromise XRSession::requestReferenceSpace( return ScriptPromise(); } - XRReferenceSpace::Type requested_type = + device::mojom::blink::XRReferenceSpaceType requested_type = XRReferenceSpace::StringToReferenceSpaceType(type); UMA_HISTOGRAM_ENUMERATION("XR.WebXR.ReferenceSpace.Requested", requested_type); if (sensorless_session_ && - requested_type != XRReferenceSpace::Type::kTypeViewer) { + requested_type != device::mojom::blink::XRReferenceSpaceType::kViewer) { exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, kReferenceSpaceNotSupported); return ScriptPromise(); @@ -538,22 +544,22 @@ ScriptPromise XRSession::requestReferenceSpace( XRReferenceSpace* reference_space = nullptr; switch (requested_type) { - case XRReferenceSpace::Type::kTypeViewer: - case XRReferenceSpace::Type::kTypeLocal: - case XRReferenceSpace::Type::kTypeLocalFloor: + case device::mojom::blink::XRReferenceSpaceType::kViewer: + case device::mojom::blink::XRReferenceSpaceType::kLocal: + case device::mojom::blink::XRReferenceSpaceType::kLocalFloor: reference_space = MakeGarbageCollected<XRReferenceSpace>(this, requested_type); break; - case XRReferenceSpace::Type::kTypeBoundedFloor: { + case device::mojom::blink::XRReferenceSpaceType::kBoundedFloor: { if (immersive()) { reference_space = MakeGarbageCollected<XRBoundedReferenceSpace>(this); } break; } - case XRReferenceSpace::Type::kTypeUnbounded: + case device::mojom::blink::XRReferenceSpaceType::kUnbounded: if (immersive()) { - reference_space = MakeGarbageCollected<XRReferenceSpace>( - this, XRReferenceSpace::Type::kTypeUnbounded); + reference_space = + MakeGarbageCollected<XRReferenceSpace>(this, requested_type); } break; } @@ -582,7 +588,8 @@ ScriptPromise XRSession::requestReferenceSpace( ScriptPromise XRSession::CreateAnchorHelper( ScriptState* script_state, const blink::TransformationMatrix& native_origin_from_anchor, - const XRNativeOriginInformation& native_origin_information, + const device::mojom::blink::XRNativeOriginInformation& + native_origin_information, ExceptionState& exception_state) { DVLOG(2) << __func__; @@ -599,34 +606,26 @@ ScriptPromise XRSession::CreateAnchorHelper( return ScriptPromise(); } - TransformationMatrix::DecomposedType decomposed_native_origin_from_anchor; - if (!native_origin_from_anchor.Decompose( - decomposed_native_origin_from_anchor)) { + auto maybe_native_origin_from_anchor_pose = + CreatePose(native_origin_from_anchor); + + if (!maybe_native_origin_from_anchor_pose) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, kUnableToDecomposeMatrix); return ScriptPromise(); } - // TODO(https://crbug.com/929841): Remove negation in quaternion once the bug - // is fixed. - device::mojom::blink::PosePtr pose_ptr = device::mojom::blink::Pose::New( - gfx::Quaternion(-decomposed_native_origin_from_anchor.quaternion_x, - -decomposed_native_origin_from_anchor.quaternion_y, - -decomposed_native_origin_from_anchor.quaternion_z, - decomposed_native_origin_from_anchor.quaternion_w), - blink::FloatPoint3D(decomposed_native_origin_from_anchor.translate_x, - decomposed_native_origin_from_anchor.translate_y, - decomposed_native_origin_from_anchor.translate_z)); - DVLOG(3) << __func__ - << ": pose_ptr->orientation = " << pose_ptr->orientation.ToString() - << ", pose_ptr->position = " << pose_ptr->position.ToString(); + << ": maybe_native_origin_from_anchor_pose->orientation()= " + << maybe_native_origin_from_anchor_pose->orientation().ToString() + << ", maybe_native_origin_from_anchor_pose->position()= " + << maybe_native_origin_from_anchor_pose->position().ToString(); auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); xr_->xrEnvironmentProviderRemote()->CreateAnchor( - native_origin_information.ToMojo(), std::move(pose_ptr), + native_origin_information.Clone(), *maybe_native_origin_from_anchor_pose, WTF::Bind(&XRSession::OnCreateAnchorResult, WrapPersistent(this), WrapPersistent(resolver))); @@ -637,7 +636,9 @@ ScriptPromise XRSession::CreateAnchorHelper( ScriptPromise XRSession::CreatePlaneAnchorHelper( ScriptState* script_state, - const blink::TransformationMatrix& plane_from_anchor, + const blink::TransformationMatrix& native_origin_from_anchor, + const device::mojom::blink::XRNativeOriginInformation& + native_origin_information, uint64_t plane_id, ExceptionState& exception_state) { DVLOG(2) << __func__ << ", plane_id=" << plane_id; @@ -655,33 +656,27 @@ ScriptPromise XRSession::CreatePlaneAnchorHelper( return ScriptPromise(); } - TransformationMatrix::DecomposedType decomposed_plane_from_anchor; - if (!plane_from_anchor.Decompose(decomposed_plane_from_anchor)) { + auto maybe_native_origin_from_anchor_pose = + CreatePose(native_origin_from_anchor); + + if (!maybe_native_origin_from_anchor_pose) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, kUnableToDecomposeMatrix); return ScriptPromise(); } - // TODO(https://crbug.com/929841): Remove negation in quaternion once the bug - // is fixed. - device::mojom::blink::PosePtr pose_ptr = device::mojom::blink::Pose::New( - gfx::Quaternion(-decomposed_plane_from_anchor.quaternion_x, - -decomposed_plane_from_anchor.quaternion_y, - -decomposed_plane_from_anchor.quaternion_z, - decomposed_plane_from_anchor.quaternion_w), - blink::FloatPoint3D(decomposed_plane_from_anchor.translate_x, - decomposed_plane_from_anchor.translate_y, - decomposed_plane_from_anchor.translate_z)); - DVLOG(3) << __func__ - << ": pose_ptr->orientation = " << pose_ptr->orientation.ToString() - << ", pose_ptr->position = " << pose_ptr->position.ToString(); + << ": maybe_native_origin_from_anchor_pose->orientation()= " + << maybe_native_origin_from_anchor_pose->orientation().ToString() + << ", maybe_native_origin_from_anchor_pose->position()= " + << maybe_native_origin_from_anchor_pose->position().ToString(); auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); ScriptPromise promise = resolver->Promise(); xr_->xrEnvironmentProviderRemote()->CreatePlaneAnchor( - std::move(pose_ptr), plane_id, + native_origin_information.Clone(), *maybe_native_origin_from_anchor_pose, + plane_id, WTF::Bind(&XRSession::OnCreateAnchorResult, WrapPersistent(this), WrapPersistent(resolver))); @@ -690,6 +685,35 @@ ScriptPromise XRSession::CreatePlaneAnchorHelper( return promise; } +base::Optional<XRSession::ReferenceSpaceInformation> +XRSession::GetStationaryReferenceSpace() const { + // For anchor creation, we should first attempt to use the local space as it + // is supposed to be more stable, but if that is unavailable, we can try using + // unbounded space. Otherwise, there's not much we can do & we have to return + // nullopt. + + // Try to get mojo_from_local: + auto reference_space_type = device::mojom::XRReferenceSpaceType::kLocal; + auto mojo_from_space = GetMojoFrom(reference_space_type); + + if (!mojo_from_space) { + // Local space is not available, try to get mojo_from_unbounded: + reference_space_type = device::mojom::XRReferenceSpaceType::kUnbounded; + mojo_from_space = GetMojoFrom(reference_space_type); + } + + if (!mojo_from_space) { + // Unbounded is also not available. + return base::nullopt; + } + + ReferenceSpaceInformation result; + result.mojo_from_space = *mojo_from_space; + result.native_origin = + XRNativeOriginInformation::Create(reference_space_type); + return result; +} + int XRSession::requestAnimationFrame(V8XRFrameRequestCallback* callback) { DVLOG(3) << __func__; @@ -711,7 +735,7 @@ XRInputSourceArray* XRSession::inputSources(ScriptState* script_state) const { if (!did_log_getInputSources_ && script_state->ContextIsValid()) { ukm::builders::XR_WebXR(xr_->GetSourceId()) .SetDidGetXRInputSources(1) - .Record(LocalDOMWindow::From(script_state)->document()->UkmRecorder()); + .Record(LocalDOMWindow::From(script_state)->UkmRecorder()); did_log_getInputSources_ = true; } @@ -738,10 +762,10 @@ ScriptPromise XRSession::requestHitTestSource( } // 1. Grab the native origin from the passed in XRSpace. - base::Optional<XRNativeOriginInformation> maybe_native_origin = - options_init && options_init->hasSpace() - ? options_init->space()->NativeOrigin() - : base::nullopt; + base::Optional<device::mojom::blink::XRNativeOriginInformation> + maybe_native_origin = options_init && options_init->hasSpace() + ? options_init->space()->NativeOrigin() + : base::nullopt; if (!maybe_native_origin) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, @@ -799,7 +823,7 @@ ScriptPromise XRSession::requestHitTestSource( ScriptPromise promise = resolver->Promise(); xr_->xrEnvironmentProviderRemote()->SubscribeToHitTest( - maybe_native_origin->ToMojo(), entity_types, std::move(ray_mojo), + maybe_native_origin->Clone(), entity_types, std::move(ray_mojo), WTF::Bind(&XRSession::OnSubscribeToHitTestResult, WrapPersistent(this), WrapPersistent(resolver))); request_hit_test_source_promises_.insert(resolver); @@ -912,6 +936,8 @@ void XRSession::OnSubscribeToHitTestForTransientInputResult( void XRSession::OnCreateAnchorResult(ScriptPromiseResolver* resolver, device::mojom::CreateAnchorResult result, uint64_t id) { + DVLOG(2) << __func__ << ": result=" << result << ", id=" << id; + DCHECK(create_anchor_promises_.Contains(resolver)); create_anchor_promises_.erase(resolver); @@ -920,7 +946,8 @@ void XRSession::OnCreateAnchorResult(ScriptPromiseResolver* resolver, // must contain newly created anchor data. anchor_ids_to_pending_anchor_promises_.insert(id, resolver); } else { - resolver->Reject(); + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kOperationError, kAnchorCreationFailed)); } } @@ -1610,7 +1637,7 @@ void XRSession::LogGetPose() const { ukm::builders::XR_WebXR(xr_->GetSourceId()) .SetDidRequestPose(1) - .Record(window->document()->UkmRecorder()); + .Record(window->UkmRecorder()); } } @@ -1623,12 +1650,12 @@ bool XRSession::CanReportPoses() const { } base::Optional<TransformationMatrix> XRSession::GetMojoFrom( - XRReferenceSpace::Type space_type) { + device::mojom::blink::XRReferenceSpaceType space_type) const { if (!CanReportPoses()) return base::nullopt; switch (space_type) { - case XRReferenceSpace::Type::kTypeViewer: + case device::mojom::blink::XRReferenceSpaceType::kViewer: if (!mojo_from_viewer_) { if (sensorless_session_) { return TransformationMatrix(); @@ -1638,16 +1665,16 @@ base::Optional<TransformationMatrix> XRSession::GetMojoFrom( } return *mojo_from_viewer_; - case XRReferenceSpace::Type::kTypeLocal: + case device::mojom::blink::XRReferenceSpaceType::kLocal: // TODO(https://crbug.com/1070380): This assumes that local space is // equivalent to mojo space! Remove the assumption once the bug is fixed. return TransformationMatrix(); - case XRReferenceSpace::Type::kTypeUnbounded: + case device::mojom::blink::XRReferenceSpaceType::kUnbounded: // TODO(https://crbug.com/1070380): This assumes that unbounded space is // equivalent to mojo space! Remove the assumption once the bug is fixed. return TransformationMatrix(); - case XRReferenceSpace::Type::kTypeLocalFloor: - case XRReferenceSpace::Type::kTypeBoundedFloor: + case device::mojom::blink::XRReferenceSpaceType::kLocalFloor: + case device::mojom::blink::XRReferenceSpaceType::kBoundedFloor: // Information about -floor spaces is currently stored elsewhere (in stage // parameters of display_info_). It probably should eventually move here. return base::nullopt; @@ -1675,16 +1702,6 @@ void XRSession::UpdateCanvasDimensions(Element* element) { update_views_next_frame_ = true; output_width_ = element->OffsetWidth() * devicePixelRatio; output_height_ = element->OffsetHeight() * devicePixelRatio; - int output_angle = 0; - - // TODO(crbug.com/836948): handle square canvases. - // TODO(crbug.com/840346): we should not need to use ScreenOrientation here. - ScreenOrientation* orientation = ScreenOrientation::Create(window); - - if (orientation) { - output_angle = orientation->angle(); - DVLOG(2) << __func__ << ": got angle=" << output_angle; - } if (render_state_->baseLayer()) { render_state_->baseLayer()->OnResize(); @@ -1976,7 +1993,7 @@ bool XRSession::HasPendingActivity() const { return !callback_collection_->IsEmpty() && !ended_; } -void XRSession::Trace(Visitor* visitor) { +void XRSession::Trace(Visitor* visitor) const { visitor->Trace(xr_); visitor->Trace(render_state_); visitor->Trace(world_tracking_state_); 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 3d857fa2e81..1ae0b3bf8a9 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_session.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.h @@ -148,26 +148,46 @@ class XRSession final ExceptionState&); // Helper, not IDL-exposed - // |native_origin_from_anchor| is a matrix describing transform from native - // origin to the initial anchor's position. - // |native_origin_information| describes native origin telative to which the + // |native_origin_from_anchor| is a matrix describing transform between native + // origin and the initial anchor's position. + // |native_origin_information| describes native origin relative to which the // transform is expressed. ScriptPromise CreateAnchorHelper( ScriptState* script_state, const blink::TransformationMatrix& native_origin_from_anchor, - const XRNativeOriginInformation& native_origin_information, + const device::mojom::blink::XRNativeOriginInformation& + native_origin_information, ExceptionState& exception_state); // Helper, not IDL-exposed - // |plane_from_anchor| is a matrix describing transform from plane to the - // initial anchor's position. + // |native_origin_from_anchor| is a matrix describing transform between native + // origin and the initial anchor's position. + // |native_origin_information| describes native origin relative to which the + // transform is expressed. // |plane_id| is the id of the plane to which the anchor should be attached. ScriptPromise CreatePlaneAnchorHelper( ScriptState* script_state, - const blink::TransformationMatrix& plane_from_anchor, + const blink::TransformationMatrix& native_origin_from_anchor, + const device::mojom::blink::XRNativeOriginInformation& + native_origin_information, uint64_t plane_id, ExceptionState& exception_state); + // Helper POD type containing the information needed for anchor creation in + // case the anchor needs to be transformed to be expressed relative to a + // stationary reference space. + struct ReferenceSpaceInformation { + device::mojom::blink::XRNativeOriginInformation native_origin; + blink::TransformationMatrix mojo_from_space; + }; + + // Helper for anchor creation - returns information about the reference space + // type and its transform. The resulting reference space will be well-suited + // for anchor creation (i.e. the native origin set in the struct will be + // describing a stationary space). If a stationary reference space is not + // available, the method returns nullopt. + base::Optional<ReferenceSpaceInformation> GetStationaryReferenceSpace() const; + int requestAnimationFrame(V8XRFrameRequestCallback* callback); void cancelAnimationFrame(int id); @@ -285,7 +305,7 @@ class XRSession final bool UsesInputEventing() { return uses_input_eventing_; } bool LightEstimationEnabled() { return !!world_light_probe_; } - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // ScriptWrappable bool HasPendingActivity() const override; @@ -299,7 +319,7 @@ class XRSession final // stored elsewhere, this method will not work for those reference space // types. base::Optional<TransformationMatrix> GetMojoFrom( - XRReferenceSpace::Type space_type); + device::mojom::blink::XRReferenceSpaceType space_type) const; // Creates presentation frame based on current state of the session. // State currently used in XRFrame creation is mojo_from_viewer_ and 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 3a8f8090c31..5df7c568483 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_session.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_session.idl @@ -58,8 +58,8 @@ enum XRInteractionMode { void cancelAnimationFrame(long handle); // https://github.com/immersive-web/real-world-geometry/blob/master/plane-detection-explainer.md - [RuntimeEnabled=WebXRIncubations] readonly attribute XRWorldTrackingState worldTrackingState; - [RuntimeEnabled=WebXRIncubations, RaisesException] void updateWorldTrackingState(optional XRWorldTrackingStateInit state = {}); + [RuntimeEnabled=WebXRPlaneDetection] readonly attribute XRWorldTrackingState worldTrackingState; + [RuntimeEnabled=WebXRPlaneDetection, RaisesException] void updateWorldTrackingState(optional XRWorldTrackingStateInit state = {}); [CallWith=ScriptState, Measure, RaisesException] Promise<void> end(); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session_event.cc b/chromium/third_party/blink/renderer/modules/xr/xr_session_event.cc index 0fb73b1684b..54ad7d05a77 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_session_event.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_session_event.cc @@ -31,7 +31,7 @@ const AtomicString& XRSessionEvent::InterfaceName() const { return event_interface_names::kXRSessionEvent; } -void XRSessionEvent::Trace(Visitor* visitor) { +void XRSessionEvent::Trace(Visitor* visitor) const { visitor->Trace(session_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_session_event.h b/chromium/third_party/blink/renderer/modules/xr/xr_session_event.h index dd8d1460ef2..6f3bbf8d12f 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_session_event.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_session_event.h @@ -41,7 +41,7 @@ class XRSessionEvent final : public Event { const AtomicString& InterfaceName() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<XRSession> session_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_setlike.h b/chromium/third_party/blink/renderer/modules/xr/xr_setlike.h index 03e89cdde8a..6fd5b116569 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_setlike.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_setlike.h @@ -57,7 +57,7 @@ class XRSetlike : public SetlikeIterable<Member<ElementType>> { return true; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(elements_); SetlikeIterable<Member<ElementType>>::IterationSource::Trace(visitor); } 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 fe3541491e0..375b260b19e 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_space.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_space.cc @@ -98,8 +98,9 @@ XRPose* XRSpace::getPose(XRSpace* other_space) { } base::Optional<TransformationMatrix> XRSpace::OffsetFromViewer() { - base::Optional<TransformationMatrix> native_from_viewer = NativeFromViewer( - session()->GetMojoFrom(XRReferenceSpace::Type::kTypeViewer)); + base::Optional<TransformationMatrix> native_from_viewer = + NativeFromViewer(session()->GetMojoFrom( + device::mojom::blink::XRReferenceSpaceType::kViewer)); if (!native_from_viewer) { return base::nullopt; @@ -116,11 +117,7 @@ const AtomicString& XRSpace::InterfaceName() const { return event_target_names::kXRSpace; } -base::Optional<XRNativeOriginInformation> XRSpace::NativeOrigin() const { - return base::nullopt; -} - -void XRSpace::Trace(Visitor* visitor) { +void XRSpace::Trace(Visitor* visitor) const { visitor->Trace(session_); ScriptWrappable::Trace(visitor); EventTargetWithInlineData::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 e2534bd57e2..90088d8534c 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_space.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_space.h @@ -8,9 +8,9 @@ #include <memory> #include "base/optional.h" +#include "device/vr/public/mojom/vr_service.mojom-blink.h" #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" @@ -94,9 +94,10 @@ class XRSpace : public EventTargetWithInlineData { ExecutionContext* GetExecutionContext() const override; const AtomicString& InterfaceName() const override; - virtual base::Optional<XRNativeOriginInformation> NativeOrigin() const = 0; + virtual base::Optional<device::mojom::blink::XRNativeOriginInformation> + NativeOrigin() const = 0; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; protected: static base::Optional<TransformationMatrix> TryInvert( diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_system.cc b/chromium/third_party/blink/renderer/modules/xr/xr_system.cc index 12ef7ca420d..86a7be1e80c 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_system.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_system.cc @@ -108,7 +108,7 @@ const char* SessionModeToString(device::mojom::blink::XRSessionMode 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 ExecutionContext* context, const String& feature_string) { if (feature_string == "viewer") { return device::mojom::XRSessionFeature::REF_SPACE_VIEWER; @@ -120,17 +120,20 @@ 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::WebXRHitTestEnabled(doc) && + } else if (RuntimeEnabledFeatures::WebXRHitTestEnabled(context) && feature_string == "hit-test") { return device::mojom::XRSessionFeature::HIT_TEST; - } else if (RuntimeEnabledFeatures::WebXRAnchorsEnabled(doc) && + } else if (RuntimeEnabledFeatures::WebXRAnchorsEnabled(context) && feature_string == "anchors") { return device::mojom::XRSessionFeature::ANCHORS; } else if (feature_string == "dom-overlay") { return device::mojom::XRSessionFeature::DOM_OVERLAY; - } else if (RuntimeEnabledFeatures::WebXRLightEstimationEnabled(doc) && + } else if (RuntimeEnabledFeatures::WebXRLightEstimationEnabled(context) && feature_string == "light-estimation") { return device::mojom::XRSessionFeature::LIGHT_ESTIMATION; + } else if (RuntimeEnabledFeatures::WebXRCameraAccessEnabled(context) && + feature_string == "camera-access") { + return device::mojom::XRSessionFeature::CAMERA_ACCESS; } return base::nullopt; @@ -164,13 +167,14 @@ bool IsFeatureValidForMode(device::mojom::XRSessionFeature feature, } return true; case device::mojom::XRSessionFeature::LIGHT_ESTIMATION: + case device::mojom::XRSessionFeature::CAMERA_ACCESS: return mode == device::mojom::blink::XRSessionMode::kImmersiveAr; } } -bool HasRequiredFeaturePolicy(const Document* doc, +bool HasRequiredFeaturePolicy(const ExecutionContext* context, device::mojom::XRSessionFeature feature) { - if (!doc) + if (!context) return false; switch (feature) { @@ -184,8 +188,10 @@ bool HasRequiredFeaturePolicy(const Document* doc, case device::mojom::XRSessionFeature::HIT_TEST: case device::mojom::XRSessionFeature::LIGHT_ESTIMATION: case device::mojom::XRSessionFeature::ANCHORS: - return doc->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kWebXr, - ReportOptions::kReportOnFailure); + case device::mojom::XRSessionFeature::CAMERA_ACCESS: + return context->IsFeatureEnabled( + mojom::blink::FeaturePolicyFeature::kWebXr, + ReportOptions::kReportOnFailure); } } @@ -278,7 +284,7 @@ XRSystem::PendingSupportsSessionQuery::PendingSupportsSessionQuery( mode_(session_mode), throw_on_unsupported_(throw_on_unsupported) {} -void XRSystem::PendingSupportsSessionQuery::Trace(Visitor* visitor) { +void XRSystem::PendingSupportsSessionQuery::Trace(Visitor* visitor) const { visitor->Trace(resolver_); } @@ -549,7 +555,7 @@ void XRSystem::PendingRequestSessionQuery::ParseSensorRequirement() { sensor_requirement_ = kNone; } -void XRSystem::PendingRequestSessionQuery::Trace(Visitor* visitor) { +void XRSystem::PendingRequestSessionQuery::Trace(Visitor* visitor) const { visitor->Trace(resolver_); visitor->Trace(dom_overlay_element_); } @@ -634,7 +640,7 @@ void XRSystem::OverlayFullscreenEventManager::RequestFullscreen() { Fullscreen::RequestType::kUnprefixed); } -void XRSystem::OverlayFullscreenEventManager::Trace(Visitor* visitor) { +void XRSystem::OverlayFullscreenEventManager::Trace(Visitor* visitor) const { visitor->Trace(xr_); visitor->Trace(query_); EventListener::Trace(visitor); @@ -687,7 +693,7 @@ void XRSystem::OverlayFullscreenExitObserver::ExitFullscreen( Fullscreen::FullyExitFullscreen(element_->GetDocument(), kUaOriginated); } -void XRSystem::OverlayFullscreenExitObserver::Trace(Visitor* visitor) { +void XRSystem::OverlayFullscreenExitObserver::Trace(Visitor* visitor) const { visitor->Trace(xr_); visitor->Trace(element_); EventListener::Trace(visitor); @@ -850,10 +856,8 @@ ScriptPromise XRSystem::InternalIsSessionSupported( 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. + if (!GetExecutionContext()) { + // Reject if the context is inaccessible. exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, kNavigatorDetachedError); return ScriptPromise(); // Will be rejected by generated bindings @@ -868,7 +872,7 @@ ScriptPromise XRSystem::InternalIsSessionSupported( throw_on_unsupported); if (session_mode == device::mojom::blink::XRSessionMode::kImmersiveAr && - !RuntimeEnabledFeatures::WebXRARModuleEnabled(doc)) { + !RuntimeEnabledFeatures::WebXRARModuleEnabled(GetExecutionContext())) { DVLOG(2) << __func__ << ": Immersive AR session is only supported if WebXRARModule " "feature is enabled"; @@ -882,8 +886,9 @@ ScriptPromise XRSystem::InternalIsSessionSupported( return promise; } - if (!doc->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kWebXr, - ReportOptions::kReportOnFailure)) { + if (!GetExecutionContext()->IsFeatureEnabled( + mojom::blink::FeaturePolicyFeature::kWebXr, + ReportOptions::kReportOnFailure)) { // Only allow the call to be made if the appropriate feature policy is in // place. query->RejectWithSecurityError(kFeaturePolicyBlocked, &exception_state); @@ -1035,7 +1040,6 @@ void XRSystem::RequestInlineSession(LocalFrame* frame, } XRSystem::RequestedXRSessionFeatureSet XRSystem::ParseRequestedFeatures( - Document* doc, const HeapVector<ScriptValue>& features, const device::mojom::blink::XRSessionMode& session_mode, XRSessionInit* session_init, @@ -1049,7 +1053,8 @@ XRSystem::RequestedXRSessionFeatureSet XRSystem::ParseRequestedFeatures( for (const auto& feature : features) { String feature_string; if (feature.ToString(feature_string)) { - auto feature_enum = StringToXRSessionFeature(doc, feature_string); + auto feature_enum = + StringToXRSessionFeature(GetExecutionContext(), feature_string); if (!feature_enum) { AddConsoleMessage(error_level, @@ -1062,7 +1067,8 @@ XRSystem::RequestedXRSessionFeatureSet XRSystem::ParseRequestedFeatures( "' is not supported for mode: " + SessionModeToString(session_mode)); result.invalid_features = true; - } else if (!HasRequiredFeaturePolicy(doc, feature_enum.value())) { + } else if (!HasRequiredFeaturePolicy(GetExecutionContext(), + feature_enum.value())) { AddConsoleMessage(error_level, "Feature '" + feature_string + "' is not permitted by feature policy"); @@ -1107,7 +1113,7 @@ ScriptPromise XRSystem::requestSession(ScriptState* script_state, // If the request is for immersive-ar, ensure that feature is enabled. if (session_mode == device::mojom::blink::XRSessionMode::kImmersiveAr && - !RuntimeEnabledFeatures::WebXRARModuleEnabled(doc)) { + !RuntimeEnabledFeatures::WebXRARModuleEnabled(GetExecutionContext())) { exception_state.ThrowTypeError( String::Format(kImmersiveArModeNotValid, "requestSession")); @@ -1125,7 +1131,7 @@ ScriptPromise XRSystem::requestSession(ScriptState* script_state, RequestedXRSessionFeatureSet required_features; if (session_init && session_init->hasRequiredFeatures()) { required_features = ParseRequestedFeatures( - doc, session_init->requiredFeatures(), session_mode, session_init, + session_init->requiredFeatures(), session_mode, session_init, mojom::blink::ConsoleMessageLevel::kError); } @@ -1133,7 +1139,7 @@ ScriptPromise XRSystem::requestSession(ScriptState* script_state, RequestedXRSessionFeatureSet optional_features; if (session_init && session_init->hasOptionalFeatures()) { optional_features = ParseRequestedFeatures( - doc, session_init->optionalFeatures(), session_mode, session_init, + session_init->optionalFeatures(), session_mode, session_init, mojom::blink::ConsoleMessageLevel::kWarning); } @@ -1153,7 +1159,7 @@ ScriptPromise XRSystem::requestSession(ScriptState* script_state, } for (const auto& feature : default_features) { - if (HasRequiredFeaturePolicy(doc, feature)) { + if (HasRequiredFeaturePolicy(GetExecutionContext(), feature)) { required_features.valid_features.insert(feature); } else { DVLOG(2) << __func__ @@ -1191,14 +1197,32 @@ ScriptPromise XRSystem::requestSession(ScriptState* script_state, return promise; } +void XRSystem::MakeXrCompatibleAsync( + device::mojom::blink::VRService::MakeXrCompatibleCallback callback) { + TryEnsureService(); + if (service_.is_bound()) { + service_->MakeXrCompatible(std::move(callback)); + } else { + std::move(callback).Run(device::mojom::XrCompatibleResult::kNotCompatible); + } +} + +void XRSystem::MakeXrCompatibleSync( + device::mojom::XrCompatibleResult* xr_compatible_result) { + *xr_compatible_result = device::mojom::XrCompatibleResult::kNotCompatible; + + TryEnsureService(); + if (service_.is_bound()) + service_->MakeXrCompatible(xr_compatible_result); +} + // This will be called when the XR hardware or capabilities have potentially // 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 XRSystem::OnDeviceChanged() { - LocalFrame* frame = GetFrame(); - Document* doc = frame ? frame->GetDocument() : nullptr; - if (doc && - doc->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kWebXr)) { + ExecutionContext* context = GetExecutionContext(); + if (context && + context->IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kWebXr)) { DispatchEvent(*blink::Event::Create(event_type_names::kDevicechange)); } } @@ -1498,7 +1522,7 @@ void XRSystem::TryEnsureService() { DisposeType::kDisconnected)); } -void XRSystem::Trace(Visitor* visitor) { +void XRSystem::Trace(Visitor* visitor) const { visitor->Trace(frame_provider_); visitor->Trace(sessions_); visitor->Trace(service_); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_system.h b/chromium/third_party/blink/renderer/modules/xr/xr_system.h index 98fbbac289d..7117bac5e6a 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_system.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_system.h @@ -97,7 +97,7 @@ class XRSystem final : public EventTargetWithInlineData, // ExecutionContextLifecycleObserver overrides. void ContextDestroyed() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // FocusChangedObserver overrides. void FocusedFrameChanged() override; @@ -119,6 +119,11 @@ class XRSystem final : public EventTargetWithInlineData, bool IsContextDestroyed() const { return is_context_destroyed_; } + void MakeXrCompatibleAsync( + device::mojom::blink::VRService::MakeXrCompatibleCallback callback); + void MakeXrCompatibleSync( + device::mojom::XrCompatibleResult* xr_compatible_result); + private: enum SensorRequirement { kNone, @@ -205,7 +210,7 @@ class XRSystem final : public EventTargetWithInlineData, } Element* DOMOverlayElement() { return dom_overlay_element_; } - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; private: void ParseSensorRequirement(); @@ -273,7 +278,7 @@ class XRSystem final : public EventTargetWithInlineData, device::mojom::blink::XRSessionMode mode() const; - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; private: Member<ScriptPromiseResolver> resolver_; @@ -302,7 +307,7 @@ class XRSystem final : public EventTargetWithInlineData, void RequestFullscreen(); void OnSessionStarting(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<XRSystem> xr_; @@ -323,7 +328,7 @@ class XRSystem final : public EventTargetWithInlineData, void ExitFullscreen(Element* element, base::OnceClosure on_exited); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<XRSystem> xr_; @@ -346,7 +351,6 @@ class XRSystem final : public EventTargetWithInlineData, const PendingRequestSessionQuery& query); RequestedXRSessionFeatureSet ParseRequestedFeatures( - Document* doc, const HeapVector<ScriptValue>& features, const device::mojom::blink::XRSessionMode& session_mode, XRSessionInit* session_init, 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 a86464dd0f9..b7bcc04b4ce 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 @@ -16,8 +16,8 @@ XRTargetRaySpace::XRTargetRaySpace(XRSession* session, XRInputSource* source) : XRSpace(session), input_source_(source) {} base::Optional<TransformationMatrix> XRTargetRaySpace::MojoFromNative() { - auto mojo_from_viewer = - session()->GetMojoFrom(XRReferenceSpace::Type::kTypeViewer); + auto mojo_from_viewer = session()->GetMojoFrom( + device::mojom::blink::XRReferenceSpaceType::kViewer); switch (input_source_->TargetRayMode()) { case device::mojom::XRTargetRayMode::TAPPING: { // If the pointer origin is the screen, we need mojo_from_viewer, as the @@ -54,8 +54,8 @@ bool XRTargetRaySpace::EmulatedPosition() const { return input_source_->emulatedPosition(); } -base::Optional<XRNativeOriginInformation> XRTargetRaySpace::NativeOrigin() - const { +base::Optional<device::mojom::blink::XRNativeOriginInformation> +XRTargetRaySpace::NativeOrigin() const { return input_source_->nativeOrigin(); } @@ -65,7 +65,7 @@ bool XRTargetRaySpace::IsStationary() const { return false; } -void XRTargetRaySpace::Trace(Visitor* visitor) { +void XRTargetRaySpace::Trace(Visitor* visitor) const { 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 f77d3fadbab..f5fbc03b2f6 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 @@ -18,11 +18,12 @@ class XRTargetRaySpace : public XRSpace { base::Optional<TransformationMatrix> NativeFromMojo() override; bool EmulatedPosition() const override; - base::Optional<XRNativeOriginInformation> NativeOrigin() const override; + base::Optional<device::mojom::blink::XRNativeOriginInformation> NativeOrigin() + const override; bool IsStationary() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<XRInputSource> input_source_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.cc b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.cc index 9dd27ba1d84..361ce36663f 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.cc @@ -28,7 +28,7 @@ HeapVector<Member<XRHitTestResult>> XRTransientInputHitTestResult::results() { return results_; } -void XRTransientInputHitTestResult::Trace(Visitor* visitor) { +void XRTransientInputHitTestResult::Trace(Visitor* visitor) const { visitor->Trace(input_source_); visitor->Trace(results_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.h b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.h index a6e82790c22..df60444a319 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.h @@ -26,7 +26,7 @@ class XRTransientInputHitTestResult : public ScriptWrappable { HeapVector<Member<XRHitTestResult>> results(); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<XRInputSource> input_source_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.cc b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.cc index a457b32210b..8decad2453c 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.cc @@ -74,7 +74,7 @@ XRTransientInputHitTestSource::Results() { return current_frame_results_; } -void XRTransientInputHitTestSource::Trace(Visitor* visitor) { +void XRTransientInputHitTestSource::Trace(Visitor* visitor) const { visitor->Trace(current_frame_results_); visitor->Trace(xr_session_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h index e23ea2dca20..d5744653017 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h @@ -35,7 +35,7 @@ class XRTransientInputHitTestSource : public ScriptWrappable { HeapVector<Member<XRTransientInputHitTestResult>> Results(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: HeapVector<Member<XRTransientInputHitTestResult>> current_frame_results_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_utils.cc b/chromium/third_party/blink/renderer/modules/xr/xr_utils.cc index 1faec9eb0a6..cb27d77c6ad 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_utils.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_utils.cc @@ -75,4 +75,10 @@ WebGLRenderingContextBase* webglRenderingContextBaseFromUnion( } } +base::Optional<device::Pose> CreatePose( + const blink::TransformationMatrix& matrix) { + return device::Pose::Create( + gfx::Transform(TransformationMatrix::ToSkMatrix44(matrix))); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_utils.h b/chromium/third_party/blink/renderer/modules/xr/xr_utils.h index 1a496d3729d..c4da10abd20 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_utils.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_utils.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_UTILS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_UTILS_H_ +#include "device/vr/public/mojom/pose.h" #include "third_party/blink/renderer/bindings/modules/v8/webgl_rendering_context_or_webgl2_rendering_context.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -33,6 +34,12 @@ WebGLRenderingContextBase* webglRenderingContextBaseFromUnion( constexpr char kUnableToNormalizeZeroLength[] = "Unable to normalize vector of length 0."; +// Conversion method from transformation matrix to device::Pose. The conversion +// may fail if the matrix cannot be decomposed. In case of failure, the method +// will return base::nullopt. +base::Optional<device::Pose> CreatePose( + const blink::TransformationMatrix& matrix); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_UTILS_H_ diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_view.cc b/chromium/third_party/blink/renderer/modules/xr/xr_view.cc index 6814178a009..10ba86ce7a6 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_view.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_view.cc @@ -141,7 +141,7 @@ XRRigidTransform* XRView::transform() const { return ref_space_from_eye_; } -void XRView::Trace(Visitor* visitor) { +void XRView::Trace(Visitor* visitor) const { visitor->Trace(session_); visitor->Trace(projection_matrix_); visitor->Trace(ref_space_from_eye_); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_view.h b/chromium/third_party/blink/renderer/modules/xr/xr_view.h index 4c20b54ca50..19c9cafb173 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_view.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_view.h @@ -35,7 +35,7 @@ class MODULES_EXPORT XRView final : public ScriptWrappable { DOMFloat32Array* projectionMatrix() const; XRRigidTransform* transform() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: XREye eye_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc b/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc index 52b71f98fb1..732e4ec408c 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc @@ -24,8 +24,9 @@ XRViewerPose::XRViewerPose(XRSession* session, } } -void XRViewerPose::Trace(Visitor* visitor) { +void XRViewerPose::Trace(Visitor* visitor) const { visitor->Trace(views_); + visitor->Trace(camera_views_); XRPose::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.h b/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.h index 04527284430..8aeed3868b2 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.h @@ -22,11 +22,15 @@ class XRViewerPose final : public XRPose { ~XRViewerPose() override = default; const HeapVector<Member<XRView>>& views() const { return views_; } + const HeapVector<Member<XRView>>& cameraViews() const { + return camera_views_; + } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: HeapVector<Member<XRView>> views_; + HeapVector<Member<XRView>> camera_views_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl b/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl index dae4e998ba1..35a2e530f2e 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl @@ -9,4 +9,5 @@ RuntimeEnabled=WebXR ] interface XRViewerPose : XRPose { [SameObject, SaveSameObject] readonly attribute FrozenArray<XRView> views; + [RuntimeEnabled=WebXRCameraAccess, SameObject, SaveSameObject] readonly attribute FrozenArray<XRView> cameraViews; }; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc index aef94e396eb..6b17bb272bb 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.cc @@ -77,7 +77,11 @@ WebGLTexture* XRWebGLBinding::getReflectionCubeMap( return texture; } -void XRWebGLBinding::Trace(Visitor* visitor) { +WebGLTexture* XRWebGLBinding::getCameraImage(XRFrame* frame, XRView* view) { + return nullptr; +} + +void XRWebGLBinding::Trace(Visitor* visitor) const { visitor->Trace(session_); visitor->Trace(webgl_context_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.h b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.h index c44d89c9bd5..5a60724d079 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.h @@ -17,6 +17,8 @@ class WebGLRenderingContextBase; class WebGLTexture; class XRLightProbe; class XRSession; +class XRFrame; +class XRView; class XRWebGLBinding final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); @@ -33,8 +35,9 @@ class XRWebGLBinding final : public ScriptWrappable { XRSession* session() const { return session_; } WebGLTexture* getReflectionCubeMap(XRLightProbe*, ExceptionState&); + WebGLTexture* getCameraImage(XRFrame*, XRView*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: const Member<XRSession> session_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.idl b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.idl index 66b790db9b0..1f6004baff1 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_binding.idl @@ -6,11 +6,13 @@ [ SecureContext, Exposed=Window, - RuntimeEnabled=WebXRLightEstimation + RuntimeEnabled=WebXRReflectionEstimation ] interface XRWebGLBinding { [RaisesException] constructor(XRSession session, XRWebGLRenderingContext context); // Lighting Estimation API - [RaisesException] + [RuntimeEnabled=WebXRReflectionEstimation, RaisesException] WebGLTexture? getReflectionCubeMap(XRLightProbe lightProbe); + + [RuntimeEnabled=WebXRCameraAccess] WebGLTexture? getCameraImage(XRFrame frame, XRView view); };
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc index 1a251ce189c..7fe9555c682 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc @@ -283,8 +283,8 @@ void XRWebGLLayer::OnFrameEnd() { if (!framebuffer_dirty) { // If the session doesn't have a pose then the framebuffer being clean // may be expected, so we won't count those frames. - bool frame_had_pose = - !!session()->GetMojoFrom(XRReferenceSpace::Type::kTypeViewer); + bool frame_had_pose = !!session()->GetMojoFrom( + device::mojom::blink::XRReferenceSpaceType::kViewer); if (frame_had_pose) { clean_frame_count++; if (clean_frame_count == kCleanFrameWarningLimit) { @@ -327,7 +327,7 @@ scoped_refptr<StaticBitmapImage> XRWebGLLayer::TransferToStaticBitmapImage() { return nullptr; } -void XRWebGLLayer::Trace(Visitor* visitor) { +void XRWebGLLayer::Trace(Visitor* visitor) const { visitor->Trace(left_viewport_); visitor->Trace(right_viewport_); visitor->Trace(webgl_context_); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h index 83368290e26..3a771d435c0 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_webgl_layer.h @@ -75,7 +75,7 @@ class XRWebGLLayer final : public XRLayer { scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<XRViewport> left_viewport_; 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 dea1e0fb753..05a13a9e50c 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 @@ -12,7 +12,7 @@ namespace blink { XRWorldInformation::XRWorldInformation(XRSession* session) : session_(session) {} -void XRWorldInformation::Trace(Visitor* visitor) { +void XRWorldInformation::Trace(Visitor* visitor) const { visitor->Trace(plane_ids_to_planes_); visitor->Trace(session_); ScriptWrappable::Trace(visitor); 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 656174defb9..4675e7d98fd 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 @@ -23,7 +23,7 @@ class XRWorldInformation : public ScriptWrappable { // disabled. XRPlaneSet* detectedPlanes() const; - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // Applies changes to the stored plane information based on the contents of // the received frame data. This will update the contents of diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_information.idl b/chromium/third_party/blink/renderer/modules/xr/xr_world_information.idl index b60addc9e85..7aa695098d9 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_world_information.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_information.idl @@ -7,7 +7,7 @@ [ SecureContext, Exposed=Window, - RuntimeEnabled=WebXRIncubations + RuntimeEnabled=WebXRPlaneDetection ] interface XRWorldInformation { readonly attribute XRPlaneSet? detectedPlanes; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc index 90f51738d5a..3eb3e52c487 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.cc @@ -22,7 +22,7 @@ XRWorldTrackingState::XRWorldTrackingState( } } -void XRWorldTrackingState::Trace(Visitor* visitor) { +void XRWorldTrackingState::Trace(Visitor* visitor) const { visitor->Trace(plane_detection_state_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h index 95060f7cca2..3ae8ece7dba 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h +++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.h @@ -25,7 +25,7 @@ class XRWorldTrackingState : public ScriptWrappable { return plane_detection_state_; } - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; private: Member<XRPlaneDetectionState> plane_detection_state_; diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl index ee714c328c3..070ee061f96 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl +++ b/chromium/third_party/blink/renderer/modules/xr/xr_world_tracking_state.idl @@ -7,7 +7,7 @@ [ SecureContext, Exposed=Window, - RuntimeEnabled=WebXRIncubations + RuntimeEnabled=WebXRPlaneDetection ] interface XRWorldTrackingState { readonly attribute XRPlaneDetectionState planeDetectionState; |