summaryrefslogtreecommitdiffstats
path: root/chromium/third_party
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party')
-rw-r--r--chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp4
-rw-r--r--chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h1
-rw-r--r--chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp12
-rw-r--r--chromium/third_party/blink/common/features.cc12
-rw-r--r--chromium/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h19
-rw-r--r--chromium/third_party/blink/public/mojom/page/spatial_navigation.mojom2
-rw-r--r--chromium/third_party/blink/public/platform/web_localized_string.h2
-rw-r--r--chromium/third_party/blink/renderer/bindings/templates/callback_invoke.cc.tmpl5
-rw-r--r--chromium/third_party/blink/renderer/core/dom/element.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/editing/frame_selection.h6
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_frame_test.cc127
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_view_impl.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/exported/web_view_impl.h4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/local_frame.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/frame/remote_frame.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc15
-rw-r--r--chromium/third_party/blink/renderer/core/html/forms/radio_input_type.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_anchor_element.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/html_video_element.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/input/event_handler_test.cc18
-rw-r--r--chromium/third_party/blink/renderer/core/input/keyboard_event_manager.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/input/keyboard_event_manager.h1
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_block.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_box.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/layout/layout_flexible_box.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/loader/form_submission.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_load_request.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_load_request.h13
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_loader.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/loader/frame_loader_types.h1
-rw-r--r--chromium/third_party/blink/renderer/core/loader/resource/script_resource.cc6
-rw-r--r--chromium/third_party/blink/renderer/core/page/focus_controller.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/page/page.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/page/spatial_navigation.cc156
-rw-r--r--chromium/third_party/blink/renderer/core/page/spatial_navigation.h11
-rw-r--r--chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.cc90
-rw-r--r--chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.h14
-rw-r--r--chromium/third_party/blink/renderer/core/page/spatial_navigation_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/xml/xpath_grammar.y15
-rw-r--r--chromium/third_party/blink/renderer/modules/BUILD.gn7
-rw-r--r--chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc7
-rw-r--r--chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h4
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.cc66
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/elements/media_control_panel_element.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc40
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.cc81
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h21
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/resources/legacyMediaControls.css1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc30
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h7
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc16
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc5
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc34
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h5
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc166
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h1
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css8
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc47
-rw-r--r--chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h40
-rw-r--r--chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/permissions/permissions.cc48
-rw-r--r--chromium/third_party/blink/renderer/platform/bindings/script_forbidden_scope.h11
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc19
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h17
-rw-r--r--chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc9
-rw-r--r--chromium/third_party/icu/README.chromium9
-rw-r--r--chromium/third_party/icu/cast/icudtl.datbin5101760 -> 5115168 bytes
-rw-r--r--chromium/third_party/icu/chromeos/icudtl.datbin10380672 -> 10394080 bytes
-rw-r--r--chromium/third_party/icu/common/icudtb.datbin10396864 -> 10410272 bytes
-rw-r--r--chromium/third_party/icu/common/icudtl.datbin10396864 -> 10410272 bytes
-rw-r--r--chromium/third_party/icu/filters/android.json5
-rw-r--r--chromium/third_party/icu/filters/android_small.json5
-rw-r--r--chromium/third_party/icu/filters/cast.json5
-rw-r--r--chromium/third_party/icu/filters/chromeos.json5
-rw-r--r--chromium/third_party/icu/filters/common.json5
-rw-r--r--chromium/third_party/icu/filters/flutter.json5
-rw-r--r--chromium/third_party/icu/flutter/icudtl.datbin894736 -> 908144 bytes
-rw-r--r--chromium/third_party/icu/patches/timezone.patch52
-rwxr-xr-xchromium/third_party/icu/scripts/copy_data.sh7
-rw-r--r--chromium/third_party/icu/source/i18n/timezone.cpp20
-rw-r--r--chromium/third_party/icu/tzres/metaZones.resbin0 -> 41484 bytes
-rw-r--r--chromium/third_party/icu/tzres/timezoneTypes.resbin0 -> 20052 bytes
-rw-r--r--chromium/third_party/icu/tzres/zoneinfo64.resbin0 -> 154224 bytes
-rw-r--r--chromium/third_party/skia/src/core/SkRemoteGlyphCache.cpp40
-rw-r--r--chromium/third_party/skia/src/core/SkStrike.cpp3
-rw-r--r--chromium/third_party/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc130
-rw-r--r--chromium/third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc113
-rw-r--r--chromium/third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h3
-rw-r--r--chromium/third_party/webrtc/pc/jsep_session_description.cc15
-rw-r--r--chromium/third_party/webrtc/pc/peer_connection.cc75
-rw-r--r--chromium/third_party/webrtc/pc/peer_connection.h3
-rw-r--r--chromium/third_party/webrtc/pc/peer_connection_ice_unittest.cc2
-rw-r--r--chromium/third_party/webrtc/video/video_quality_test.cc2
110 files changed, 1505 insertions, 525 deletions
diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp b/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp
index 575b151432d..c4832c66d3a 100644
--- a/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp
+++ b/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp
@@ -115,6 +115,8 @@ const char *Diagnostics::message(ID id)
return "invalid file number";
case PP_INVALID_LINE_DIRECTIVE:
return "invalid line directive";
+ case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1:
+ return "extension directive must occur before any non-preprocessor tokens in ESSL1";
case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3:
return "extension directive must occur before any non-preprocessor tokens in ESSL3";
case PP_UNDEFINED_SHIFT:
@@ -129,7 +131,7 @@ const char *Diagnostics::message(ID id)
return "unexpected token after conditional expression";
case PP_UNRECOGNIZED_PRAGMA:
return "unrecognized pragma";
- case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1:
+ case PP_NON_PP_TOKEN_BEFORE_EXTENSION_WEBGL:
return "extension directive should occur before any non-preprocessor tokens";
case PP_WARNING_MACRO_NAME_RESERVED:
return "macro name with a double underscore is reserved - unintented behavior is "
diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h b/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h
index bb90bf08292..6be5c72ddec 100644
--- a/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h
+++ b/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h
@@ -73,6 +73,7 @@ class Diagnostics
PP_WARNING_BEGIN,
PP_EOF_IN_DIRECTIVE,
PP_UNRECOGNIZED_PRAGMA,
+ PP_NON_PP_TOKEN_BEFORE_EXTENSION_WEBGL,
PP_WARNING_MACRO_NAME_RESERVED,
PP_WARNING_END
};
diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp
index e99d843b2d3..b7f8d91ecf5 100644
--- a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp
+++ b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp
@@ -676,8 +676,16 @@ void DirectiveParser::parseExtension(Token *token)
}
else
{
- mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1,
- token->location, token->text);
+ if (mSettings.shaderSpec == SH_WEBGL_SPEC)
+ {
+ mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_WEBGL,
+ token->location, token->text);
+ }
+ else
+ {
+ mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1,
+ token->location, token->text);
+ }
}
}
if (valid)
diff --git a/chromium/third_party/blink/common/features.cc b/chromium/third_party/blink/common/features.cc
index f5bf253f4a6..6db2247d620 100644
--- a/chromium/third_party/blink/common/features.cc
+++ b/chromium/third_party/blink/common/features.cc
@@ -132,8 +132,16 @@ const base::Feature kPurgeRendererMemoryWhenBackgrounded {
};
// Enable Implicit Root Scroller. https://crbug.com/903260.
-const base::Feature kImplicitRootScroller{"ImplicitRootScroller",
- base::FEATURE_ENABLED_BY_DEFAULT};
+// TODO(bokan): Temporarily disabled on desktop platforms to address issues
+// with non-overlay scrollbars. https://crbug.com/948059.
+const base::Feature kImplicitRootScroller {
+ "ImplicitRootScroller",
+#if defined(OS_ANDROID)
+ base::FEATURE_ENABLED_BY_DEFAULT
+#else
+ base::FEATURE_DISABLED_BY_DEFAULT
+#endif
+};
// Enables usage of getDisplayMedia() that allows capture of web content, see
// https://crbug.com/865060.
diff --git a/chromium/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h b/chromium/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h
index c88a10c9cd0..25858141012 100644
--- a/chromium/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h
+++ b/chromium/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h
@@ -44,7 +44,24 @@ enum class WebSchedulerTrackedFeature {
// Recorded only for the main frame.
kHasScriptableFramesInMultipleTabs = 18,
- kMaxValue = kHasScriptableFramesInMultipleTabs
+ // Whether the page tried to request a permission regardless of the outcome.
+ // TODO(altimin): Track this more accurately depending on the data.
+ // See permission.mojom for more details.
+ kRequestedGeolocationPermission = 19,
+ kRequestedNotificationsPermission = 20,
+ kRequestedMIDIPermission = 21,
+ kRequestedAudioCapturePermission = 22,
+ kRequestedVideoCapturePermission = 23,
+ kRequestedSensorsPermission = 24,
+ // This covers all background-related permissions, including background sync,
+ // background fetch and others.
+ kRequestedBackgroundWorkPermission = 26,
+
+ kBroadcastChannel = 27,
+
+ kIndexedDBConnection = 28,
+
+ kMaxValue = kIndexedDBConnection
};
} // namespace scheduler
diff --git a/chromium/third_party/blink/public/mojom/page/spatial_navigation.mojom b/chromium/third_party/blink/public/mojom/page/spatial_navigation.mojom
index 51538fcc766..8358e7ebc0d 100644
--- a/chromium/third_party/blink/public/mojom/page/spatial_navigation.mojom
+++ b/chromium/third_party/blink/public/mojom/page/spatial_navigation.mojom
@@ -11,6 +11,8 @@ struct SpatialNavigationState {
bool can_exit_focus;
// True if Spatial Navigation has a target that can be selected.
bool can_select_element;
+ // True if the currently focused element is a form element.
+ bool is_form_focused;
// True if the currently focused element is a form element, and there is a
// next form element available to move to.
bool has_next_form_element;
diff --git a/chromium/third_party/blink/public/platform/web_localized_string.h b/chromium/third_party/blink/public/platform/web_localized_string.h
index 7ba33a0c714..51c9a3cdb8b 100644
--- a/chromium/third_party/blink/public/platform/web_localized_string.h
+++ b/chromium/third_party/blink/public/platform/web_localized_string.h
@@ -73,6 +73,8 @@ struct WebLocalizedString {
kAXMediaVolumeSliderHelp,
kAXMediaEnterPictureInPictureButton,
kAXMediaExitPictureInPictureButton,
+ kAXMediaTouchLessSeekAction,
+ kAXMediaTouchLessVolumeAction,
kAXMillisecondFieldText,
kAXMinuteFieldText,
kAXMonthFieldText,
diff --git a/chromium/third_party/blink/renderer/bindings/templates/callback_invoke.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/callback_invoke.cc.tmpl
index a72ca09048d..2598235ff3c 100644
--- a/chromium/third_party/blink/renderer/bindings/templates/callback_invoke.cc.tmpl
+++ b/chromium/third_party/blink/renderer/bindings/templates/callback_invoke.cc.tmpl
@@ -56,6 +56,11 @@
v8::Context::BackupIncumbentScope backup_incumbent_scope(
IncumbentScriptState()->GetContext());
+ if (UNLIKELY(ScriptForbiddenScope::IsScriptForbidden())) {
+ ScriptForbiddenScope::ThrowScriptForbiddenException(GetIsolate());
+ return v8::Nothing<{{return_cpp_type}}>();
+ }
+
{% if invoke_or_construct == 'construct' %}
// step 3. If ! IsConstructor(F) is false, throw a TypeError exception.
//
diff --git a/chromium/third_party/blink/renderer/core/dom/element.cc b/chromium/third_party/blink/renderer/core/dom/element.cc
index d86329b115a..e5df6bbfc6a 100644
--- a/chromium/third_party/blink/renderer/core/dom/element.cc
+++ b/chromium/third_party/blink/renderer/core/dom/element.cc
@@ -3491,11 +3491,26 @@ bool Element::SupportsSpatialNavigationFocus() const {
// events).
if (!IsSpatialNavigationEnabled(GetDocument().GetFrame()))
return false;
+
+ if (!GetLayoutObject())
+ return false;
+
if (HasEventListeners(event_type_names::kClick) ||
HasEventListeners(event_type_names::kKeydown) ||
HasEventListeners(event_type_names::kKeypress) ||
HasEventListeners(event_type_names::kKeyup))
return true;
+
+ // Some web apps use click-handlers to react on clicks within rects that are
+ // styled with {cursor: pointer}. Such rects *look* clickable so they probably
+ // are. Here we make Hand-trees' tip, the first (biggest) node with {cursor:
+ // pointer}, navigable because users shouldn't need to navigate through every
+ // sub element that inherit this CSS.
+ if (GetComputedStyle()->Cursor() == ECursor::kPointer &&
+ ParentComputedStyle()->Cursor() != ECursor::kPointer) {
+ return true;
+ }
+
if (!IsSVGElement())
return false;
return (HasEventListeners(event_type_names::kFocus) ||
diff --git a/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc b/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
index 3b6dab593bd..8f3eaf84d00 100644
--- a/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
+++ b/chromium/third_party/blink/renderer/core/dom/events/event_dispatcher.cc
@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/core/dom/events/event_path.h"
#include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
#include "third_party/blink/renderer/core/dom/events/window_event_context.h"
+#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/events/mouse_event.h"
#include "third_party/blink/renderer/core/frame/ad_tracker.h"
#include "third_party/blink/renderer/core/frame/deprecation.h"
@@ -45,6 +46,8 @@
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/html/html_element.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
+#include "third_party/blink/renderer/core/page/page.h"
+#include "third_party/blink/renderer/core/page/spatial_navigation_controller.h"
#include "third_party/blink/renderer/core/timing/event_timing.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
@@ -370,6 +373,15 @@ inline void EventDispatcher::DispatchEventPostProcess(
}
}
+ if (Page* page = node_->GetDocument().GetPage()) {
+ if (page->GetSettings().GetSpatialNavigationEnabled() &&
+ is_trusted_or_click && event_->IsKeyboardEvent() &&
+ ToKeyboardEvent(*event_).key() == "Enter" &&
+ event_->type() == event_type_names::kKeyup) {
+ page->GetSpatialNavigationController().ResetEnterKeyState();
+ }
+ }
+
// Track the usage of sending a mousedown event to a select element to force
// it to open. This measures a possible breakage of not allowing untrusted
// events to open select boxes.
diff --git a/chromium/third_party/blink/renderer/core/editing/frame_selection.h b/chromium/third_party/blink/renderer/core/editing/frame_selection.h
index 6dc0e1cf974..1da4b7aad96 100644
--- a/chromium/third_party/blink/renderer/core/editing/frame_selection.h
+++ b/chromium/third_party/blink/renderer/core/editing/frame_selection.h
@@ -201,6 +201,10 @@ class CORE_EXPORT FrameSelection final
// Note: this updates styles and layout, use cautiously.
bool ComputeAbsoluteBounds(IntRect& anchor, IntRect& focus) const;
+ // Computes the rect we should use when scrolling/zooming a selection into
+ // view.
+ IntRect ComputeRectToScroll(RevealExtentOption);
+
void DidChangeFocus();
SelectionInDOMTree GetSelectionInDOMTree() const;
@@ -299,8 +303,6 @@ class CORE_EXPORT FrameSelection final
GranularityStrategy* GetGranularityStrategy();
- IntRect ComputeRectToScroll(RevealExtentOption);
-
void MoveRangeSelectionInternal(const SelectionInDOMTree&, TextGranularity);
// Implementation of |SynchronousMutationObserver| member functions.
diff --git a/chromium/third_party/blink/renderer/core/exported/web_frame_test.cc b/chromium/third_party/blink/renderer/core/exported/web_frame_test.cc
index a6969cca501..c45adc0ced8 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -122,6 +122,7 @@
#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
+#include "third_party/blink/renderer/core/html/forms/html_input_element.h"
#include "third_party/blink/renderer/core/html/html_body_element.h"
#include "third_party/blink/renderer/core/html/html_iframe_element.h"
#include "third_party/blink/renderer/core/html/image_document.h"
@@ -3390,6 +3391,46 @@ TEST_F(WebFrameTest, CanOverrideScaleLimits) {
EXPECT_EQ(2.0f, web_view_helper.GetWebView()->MaximumPageScaleFactor());
}
+// Test that setting the "ignore viewport tag scale limits" override remembers
+// the current defaults and restores them when the override is removed.
+TEST_F(WebFrameTest, RestoreOriginalDefaultScaleLimits) {
+ RegisterMockedHttpURLLoad("simple_div.html");
+
+ FixedLayoutTestWebViewClient client;
+ client.screen_info_.device_scale_factor = 1;
+ int viewport_width = 640;
+ int viewport_height = 480;
+
+ frame_test_helpers::WebViewHelper web_view_helper;
+ web_view_helper.InitializeAndLoad(base_url_ + "simple_div.html", nullptr,
+ &client, nullptr, ConfigureAndroid);
+ web_view_helper.Resize(WebSize(viewport_width, viewport_height));
+ web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.25f, 5);
+
+ const float minimum_scale_factor =
+ web_view_helper.GetWebView()->MinimumPageScaleFactor();
+
+ web_view_helper.GetWebView()->SetInitialPageScaleOverride(2.0f);
+
+ // Removing the override when none is set shouldn't change the initial scale.
+ web_view_helper.GetWebView()->SetIgnoreViewportTagScaleLimits(false);
+ UpdateAllLifecyclePhases(web_view_helper.GetWebView());
+ EXPECT_EQ(2.0f, web_view_helper.GetWebView()->PageScaleFactor());
+
+ // Setting the override when will change the initial scale.
+ web_view_helper.GetWebView()->SetIgnoreViewportTagScaleLimits(true);
+ web_view_helper.GetWebView()->ResetScaleStateImmediately();
+ UpdateAllLifecyclePhases(web_view_helper.GetWebView());
+ EXPECT_EQ(minimum_scale_factor,
+ web_view_helper.GetWebView()->PageScaleFactor());
+
+ // Disable the override, we should now use the minimum scale factor
+ web_view_helper.GetWebView()->SetIgnoreViewportTagScaleLimits(false);
+ web_view_helper.GetWebView()->ResetScaleStateImmediately();
+ UpdateAllLifecyclePhases(web_view_helper.GetWebView());
+ EXPECT_EQ(2.0f, web_view_helper.GetWebView()->PageScaleFactor());
+}
+
// Android doesn't have scrollbars on the main LocalFrameView
#if defined(OS_ANDROID)
TEST_F(WebFrameTest, DISABLED_updateOverlayScrollbarLayers)
@@ -11419,6 +11460,40 @@ class WebFrameSimTest : public SimTest {
}
};
+// This test ensures that setting the "Force Ignore Zoom" accessibility setting
+// also causes us to override the initial scale set by the page so that we load
+// fully zoomed out. Since we're overriding the minimum-scale, we're making the
+// layout viewport larger. Since |position: fixed| elements are sized based on
+// the layout viewport size, they may be cut off when the page first loads.
+TEST_F(WebFrameSimTest, ForceIgnoreZoomShouldOverrideInitialScale) {
+ UseAndroidSettings();
+ WebView().MainFrameWidget()->Resize(WebSize(500, 300));
+ WebView().SetIgnoreViewportTagScaleLimits(true);
+
+ SimRequest r("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ r.Complete(R"HTML(
+ <!DOCTYPE html>
+ <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1">
+ <style>
+ body, html {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ }
+ #wide {
+ width: 1000px;
+ height: 10px;
+ }
+ </style>
+ <div id="wide"></div>
+ )HTML");
+
+ Compositor().BeginFrame();
+
+ EXPECT_EQ(0.5f, WebView().PageScaleFactor());
+}
+
TEST_F(WebFrameSimTest, HitTestWithIgnoreClippingAtNegativeOffset) {
WebView().MainFrameWidget()->Resize(WebSize(500, 300));
WebView().GetPage()->GetSettings().SetTextAutosizingEnabled(false);
@@ -11939,6 +12014,58 @@ TEST_F(WebFrameSimTest, ScrollFocusedIntoViewClipped) {
EXPECT_GT(clip->scrollTop(), 0);
}
+// This test ensures that we scroll to the correct scale when the focused
+// element has a selection rather than a carret.
+TEST_F(WebFrameSimTest, ScrollFocusedSelectionIntoView) {
+ UseAndroidSettings();
+ WebView().MainFrameWidget()->Resize(WebSize(400, 600));
+ WebView().EnableFakePageScaleAnimationForTesting(true);
+ WebView().GetPage()->GetSettings().SetTextAutosizingEnabled(false);
+
+ SimRequest request("https://example.com/test.html", "text/html");
+ LoadURL("https://example.com/test.html");
+ request.Complete(R"HTML(
+ <!DOCTYPE html>
+ <style>
+ ::-webkit-scrollbar {
+ width: 0px;
+ height: 0px;
+ }
+ body, html {
+ margin: 0px;
+ width: 100%;
+ height: 100%;
+ }
+ input {
+ padding: 0;
+ width: 100px;
+ height: 20px;
+ }
+ </style>
+ <input type="text" id="target" value="test">
+ )HTML");
+
+ Compositor().BeginFrame();
+ WebView().AdvanceFocus(false);
+
+ HTMLInputElement* input =
+ ToHTMLInputElement(GetDocument().getElementById("target"));
+ input->select();
+
+ // Simulate the keyboard being shown and resizing the widget. Cause a scroll
+ // into view after.
+ ASSERT_EQ(WebView().FakePageScaleAnimationPageScaleForTesting(), 0.f);
+ WebFrameWidget* widget = WebView().MainFrameImpl()->FrameWidgetImpl();
+ widget->ScrollFocusedEditableElementIntoView();
+
+ // Make sure zoomed in but only up to a legible scale. The bounds are
+ // arbitrary and fuzzy since we don't specifically care to constrain the
+ // amount of zooming (that should be tested elsewhere), we just care that it
+ // zooms but not off to infinity.
+ EXPECT_GT(WebView().FakePageScaleAnimationPageScaleForTesting(), .75f);
+ EXPECT_LT(WebView().FakePageScaleAnimationPageScaleForTesting(), 2.f);
+}
+
TEST_F(WebFrameSimTest, DoubleTapZoomWhileScrolled) {
UseAndroidSettings();
WebView().MainFrameWidget()->Resize(WebSize(490, 500));
diff --git a/chromium/third_party/blink/renderer/core/exported/web_view_impl.cc b/chromium/third_party/blink/renderer/core/exported/web_view_impl.cc
index fa2150289b4..41e11e56e95 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/chromium/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -2156,7 +2156,7 @@ bool WebViewImpl::ScrollFocusedEditableElementIntoView() {
element->GetDocument()
.GetFrame()
->Selection()
- .AbsoluteCaretBounds())),
+ .ComputeRectToScroll(kDoNotRevealExtent))),
ShouldZoomToLegibleScale(*element));
return true;
@@ -2514,16 +2514,26 @@ void WebViewImpl::SetMaximumLegibleScale(float maximum_legible_scale) {
}
void WebViewImpl::SetIgnoreViewportTagScaleLimits(bool ignore) {
+ // This method should be idempotent.
+ if (ignore == pre_override_default_constraints_.has_value())
+ return;
+
PageScaleConstraints constraints =
GetPageScaleConstraintsSet().UserAgentConstraints();
if (ignore) {
+ DCHECK(!pre_override_default_constraints_);
+ pre_override_default_constraints_.emplace(constraints);
+
constraints.minimum_scale =
GetPageScaleConstraintsSet().DefaultConstraints().minimum_scale;
constraints.maximum_scale =
GetPageScaleConstraintsSet().DefaultConstraints().maximum_scale;
+ constraints.initial_scale =
+ GetPageScaleConstraintsSet().DefaultConstraints().minimum_scale;
} else {
- constraints.minimum_scale = -1;
- constraints.maximum_scale = -1;
+ DCHECK(pre_override_default_constraints_);
+ constraints = pre_override_default_constraints_.value();
+ pre_override_default_constraints_.reset();
}
GetPage()->SetUserAgentPageScaleConstraints(constraints);
}
diff --git a/chromium/third_party/blink/renderer/core/exported/web_view_impl.h b/chromium/third_party/blink/renderer/core/exported/web_view_impl.h
index aaa17462ee6..64a22db62db 100644
--- a/chromium/third_party/blink/renderer/core/exported/web_view_impl.h
+++ b/chromium/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -691,6 +691,10 @@ class CORE_EXPORT WebViewImpl final : public WebView,
FloatSize elastic_overscroll_;
+ // When overriding the default page scale constraints, store the original so
+ // we can revert to them when the override is removed.
+ base::Optional<PageScaleConstraints> pre_override_default_constraints_;
+
Persistent<EventListener> popup_mouse_wheel_event_listener_;
// The local root whose document has |popup_mouse_wheel_event_listener_|
diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.cc b/chromium/third_party/blink/renderer/core/frame/local_frame.cc
index dd0e2f0df7b..c1f7d53655b 100644
--- a/chromium/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/local_frame.cc
@@ -339,7 +339,7 @@ void LocalFrame::Navigate(const FrameLoadRequest& request,
WebFrameLoadType frame_load_type) {
if (!navigation_rate_limiter().CanProceed())
return;
- if (request.ClientRedirect() == ClientRedirectPolicy::kClientRedirect) {
+ if (request.ClientRedirectReason() != ClientNavigationReason::kNone) {
probe::FrameScheduledNavigation(this, request.GetResourceRequest().Url(),
0.0, request.ClientRedirectReason());
if (NavigationScheduler::MustReplaceCurrentItem(this))
@@ -347,7 +347,7 @@ void LocalFrame::Navigate(const FrameLoadRequest& request,
}
loader_.StartNavigation(request, frame_load_type);
- if (request.ClientRedirect() == ClientRedirectPolicy::kClientRedirect)
+ if (request.ClientRedirectReason() != ClientNavigationReason::kNone)
probe::FrameClearedScheduledNavigation(this);
}
diff --git a/chromium/third_party/blink/renderer/core/frame/remote_frame.cc b/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
index 9de006e1b8e..fce85b75bcd 100644
--- a/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
+++ b/chromium/third_party/blink/renderer/core/frame/remote_frame.cc
@@ -111,8 +111,8 @@ void RemoteFrame::Navigate(const FrameLoadRequest& passed_request,
frame->GetSecurityContext() &&
frame->GetSecurityContext()->IsSandboxed(WebSandboxFlags::kDownloads);
initiator_frame_is_ad = frame->IsAdSubframe();
- if (passed_request.ClientRedirect() ==
- ClientRedirectPolicy::kClientRedirect) {
+ if (passed_request.ClientRedirectReason() !=
+ ClientNavigationReason::kNone) {
probe::FrameRequestedNavigation(frame, this, url,
passed_request.ClientRedirectReason());
}
diff --git a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
index 98176198d5c..334198dff21 100644
--- a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -147,8 +147,6 @@ intptr_t HTMLCanvasElement::global_gpu_memory_usage_ = 0;
unsigned HTMLCanvasElement::global_accelerated_context_count_ = 0;
HTMLCanvasElement::~HTMLCanvasElement() {
- if (surface_layer_bridge_ && surface_layer_bridge_->GetCcLayer())
- GraphicsLayer::UnregisterContentsLayer(surface_layer_bridge_->GetCcLayer());
v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
-externally_allocated_memory_);
}
@@ -177,6 +175,19 @@ void HTMLCanvasElement::Dispose() {
global_accelerated_context_count_--;
}
global_gpu_memory_usage_ -= gpu_memory_usage_;
+
+ if (surface_layer_bridge_) {
+ if (surface_layer_bridge_->GetCcLayer()) {
+ GraphicsLayer::UnregisterContentsLayer(
+ surface_layer_bridge_->GetCcLayer());
+ }
+ // Observer has to be cleared out at this point. Otherwise the
+ // SurfaceLayerBridge may call back into the observer which is undefined
+ // behavior. In the worst case, the dead canvas element re-adds itself into
+ // a data structure which may crash at a later point in time. See
+ // https://crbug.com/976577.
+ surface_layer_bridge_->ClearObserver();
+ }
}
void HTMLCanvasElement::ParseAttribute(
diff --git a/chromium/third_party/blink/renderer/core/html/forms/radio_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/radio_input_type.cc
index 390b142468a..ac8f7326720 100644
--- a/chromium/third_party/blink/renderer/core/html/forms/radio_input_type.cc
+++ b/chromium/third_party/blink/renderer/core/html/forms/radio_input_type.cc
@@ -155,8 +155,6 @@ void RadioInputType::HandleKeyupEvent(KeyboardEvent& event) {
event.key() == "Enter")) {
DispatchSimulatedClickIfActive(event);
}
-
- DispatchSimulatedClickIfActive(event);
}
bool RadioInputType::IsKeyboardFocusable() const {
diff --git a/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc b/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc
index 94733fedf25..786167ccc30 100644
--- a/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc
@@ -429,8 +429,10 @@ void HTMLAnchorElement::HandleClick(Event& event) {
}
request.SetRequestContext(mojom::RequestContextType::HYPERLINK);
- FrameLoadRequest frame_request(&GetDocument(), request,
- getAttribute(kTargetAttr));
+ const AtomicString& target = getAttribute(kTargetAttr);
+ FrameLoadRequest frame_request(
+ &GetDocument(), request,
+ target.IsEmpty() ? GetDocument().BaseTarget() : target);
frame_request.SetNavigationPolicy(NavigationPolicyFromEvent(&event));
if (HasRel(kRelationNoReferrer)) {
frame_request.SetShouldSendReferrer(kNeverSendReferrer);
diff --git a/chromium/third_party/blink/renderer/core/html/html_element.cc b/chromium/third_party/blink/renderer/core/html/html_element.cc
index 8803bea1c77..8a830c69504 100644
--- a/chromium/third_party/blink/renderer/core/html/html_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_element.cc
@@ -1332,6 +1332,8 @@ bool HTMLElement::MatchesReadWritePseudoClass() const {
void HTMLElement::HandleKeypressEvent(KeyboardEvent& event) {
if (!IsSpatialNavigationEnabled(GetDocument().GetFrame()) || !SupportsFocus())
return;
+ if (RuntimeEnabledFeatures::FocuslessSpatialNavigationEnabled())
+ return;
GetDocument().UpdateStyleAndLayoutTree();
// if the element is a text form control (like <input type=text> or
// <textarea>) or has contentEditable attribute on, we should enter a space or
diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc
index bfc6b9530d1..9501d2dd946 100644
--- a/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
+#include "third_party/blink/renderer/core/events/current_input_event.h"
#include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -403,13 +404,12 @@ bool HTMLFrameOwnerElement::LoadOrRedirectSubframe(
KURL url_to_request = url.IsNull() ? BlankURL() : url;
if (ContentFrame()) {
// TODO(sclittle): Support lazily loading frame navigations.
+ FrameLoadRequest request(&GetDocument(), ResourceRequest(url_to_request));
+ request.SetClientRedirectReason(ClientNavigationReason::kFrameNavigation);
WebFrameLoadType frame_load_type = WebFrameLoadType::kStandard;
if (replace_current_item)
frame_load_type = WebFrameLoadType::kReplaceCurrentItem;
-
- ContentFrame()->ScheduleNavigation(GetDocument(), url_to_request,
- frame_load_type,
- UserGestureStatus::kNone);
+ ContentFrame()->Navigate(request, frame_load_type);
return true;
}
diff --git a/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc b/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc
index 07f6c2998fa..723c7faf25b 100644
--- a/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc
@@ -402,6 +402,8 @@ void HTMLVideoElement::OnPlay() {
return;
}
+ std::unique_ptr<UserGestureIndicator> gesture =
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame());
webkitEnterFullscreen();
}
diff --git a/chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc b/chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc
index c1a36918ec0..749e6a68982 100644
--- a/chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc
+++ b/chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc
@@ -157,4 +157,30 @@ TEST_F(VideoAutoFullscreen, ExitFullscreenDoesNotPauseWithPlaysInline) {
EXPECT_FALSE(Video()->paused());
}
+TEST_F(VideoAutoFullscreen, OnPlayTriggersFullscreenWithoutGesture) {
+ Video()->SetSrc("http://example.com/foo.mp4");
+ {
+ std::unique_ptr<UserGestureIndicator> user_gesture_scope =
+ LocalFrame::NotifyUserActivation(GetFrame(),
+ UserGestureToken::kNewGesture);
+ Video()->Play();
+ }
+ MakeGarbageCollected<WaitForEvent>(Video(), event_type_names::kPlay);
+ test::RunPendingTasks();
+
+ EXPECT_TRUE(Video()->IsFullscreen());
+
+ GetWebView()->ExitFullscreen(*GetFrame());
+ test::RunPendingTasks();
+
+ EXPECT_TRUE(Video()->paused());
+ EXPECT_FALSE(Video()->IsFullscreen());
+
+ Video()->Play();
+ test::RunPendingTasks();
+
+ EXPECT_FALSE(Video()->paused());
+ EXPECT_TRUE(Video()->IsFullscreen());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/input/event_handler_test.cc b/chromium/third_party/blink/renderer/core/input/event_handler_test.cc
index 0cff945a90f..33b3969cbc4 100644
--- a/chromium/third_party/blink/renderer/core/input/event_handler_test.cc
+++ b/chromium/third_party/blink/renderer/core/input/event_handler_test.cc
@@ -33,6 +33,8 @@
#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
#include "third_party/blink/renderer/platform/keyboard_codes.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
+#include "ui/events/keycodes/dom/dom_code.h"
+#include "ui/events/keycodes/dom/dom_key.h"
namespace blink {
@@ -592,6 +594,22 @@ TEST_F(EventHandlerTest, EditableAnchorTextCanStartSelection) {
Cursor::Type::kIBeam); // An I-beam signals editability.
}
+TEST_F(EventHandlerTest, implicitSend) {
+ SetHtmlInnerHTML("<button>abc</button>");
+ GetDocument().GetSettings()->SetSpatialNavigationEnabled(true);
+
+ WebKeyboardEvent e{WebInputEvent::kRawKeyDown, WebInputEvent::kNoModifiers,
+ WebInputEvent::GetStaticTimeStampForTests()};
+ e.dom_code = static_cast<int>(ui::DomCode::ARROW_DOWN);
+ e.dom_key = ui::DomKey::ARROW_DOWN;
+ GetDocument().GetFrame()->GetEventHandler().KeyEvent(e);
+
+ // TODO(crbug.com/949766) Should cleanup these magic numbers.
+ e.dom_code = 0;
+ e.dom_key = 0x00200310;
+ GetDocument().GetFrame()->GetEventHandler().KeyEvent(e);
+}
+
// Regression test for http://crbug.com/641403 to verify we use up-to-date
// layout tree for dispatching "contextmenu" event.
TEST_F(EventHandlerTest, sendContextMenuEventWithHover) {
diff --git a/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.cc b/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.cc
index aefdaab5a13..d6b65860898 100644
--- a/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.cc
+++ b/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.cc
@@ -339,6 +339,9 @@ void KeyboardEventManager::DefaultKeyboardEventHandler(
DefaultEscapeEventHandler(event);
} else if (event->key() == "Enter") {
DefaultEnterEventHandler(event);
+ } else if (static_cast<int>(event->KeyEvent()->dom_key) == 0x00200310) {
+ // TODO(bokan): Cleanup magic numbers once https://crbug.com/949766 lands.
+ DefaultImeSubmitHandler(event);
} else {
// TODO(bokan): Seems odd to call the default _arrow_ event handler on
// events that aren't necessarily arrow keys.
@@ -348,16 +351,19 @@ void KeyboardEventManager::DefaultKeyboardEventHandler(
frame_->GetEditor().HandleKeyboardEvent(event);
if (event->DefaultHandled())
return;
- if (event->charCode() == ' ')
+ if (event->key() == "Enter") {
+ DefaultEnterEventHandler(event);
+ } else if (event->charCode() == ' ') {
DefaultSpaceEventHandler(event, possible_focused_node);
+ }
} else if (event->type() == event_type_names::kKeyup) {
+ if (event->DefaultHandled())
+ return;
if (event->key() == "Enter") {
DefaultEnterEventHandler(event);
- return;
- }
-
- if (event->keyCode() == kVKeySpatNavBack)
+ } else if (event->keyCode() == kVKeySpatNavBack) {
DefaultSpatNavBackEventHandler(event);
+ }
}
}
@@ -509,6 +515,17 @@ void KeyboardEventManager::DefaultEnterEventHandler(KeyboardEvent* event) {
}
}
+void KeyboardEventManager::DefaultImeSubmitHandler(KeyboardEvent* event) {
+ Page* page = frame_->GetPage();
+ if (!page)
+ return;
+
+ if (IsSpatialNavigationEnabled(frame_) &&
+ !frame_->GetDocument()->InDesignMode()) {
+ page->GetSpatialNavigationController().HandleImeSubmitKeyboardEvent(event);
+ }
+}
+
static OverrideCapsLockState g_override_caps_lock_state;
void KeyboardEventManager::SetCurrentCapsLockState(
diff --git a/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.h b/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.h
index 3d9afb6f6fe..3f1b4c4de8d 100644
--- a/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.h
+++ b/chromium/third_party/blink/renderer/core/input/keyboard_event_manager.h
@@ -56,6 +56,7 @@ class CORE_EXPORT KeyboardEventManager
void DefaultTabEventHandler(KeyboardEvent*);
void DefaultEscapeEventHandler(KeyboardEvent*);
void DefaultEnterEventHandler(KeyboardEvent*);
+ void DefaultImeSubmitHandler(KeyboardEvent*);
void DefaultArrowEventHandler(KeyboardEvent*, Node*);
bool DefaultSpatNavBackEventHandler(KeyboardEvent*);
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_block.cc b/chromium/third_party/blink/renderer/core/layout/layout_block.cc
index 481a0be7dc1..cbbd9281df3 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_block.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_block.cc
@@ -1128,6 +1128,15 @@ void LayoutBlock::RemovePositionedObjects(
}
void LayoutBlock::AddPercentHeightDescendant(LayoutBox* descendant) {
+ // A replaced object is incapable of properly acting as a containing block for
+ // its children (this is an issue with VIDEO elements, for instance, which
+ // inserts some percentage height flexbox children). Assert that the
+ // descendant hasn't escaped from within a replaced object. Registering the
+ // percentage height descendant further up in the tree is only going to cause
+ // trouble, especially if the replaced object is out-of-flow positioned (and
+ // we failed to notice).
+ DCHECK(!descendant->Container()->IsLayoutReplaced());
+
if (descendant->PercentHeightContainer()) {
if (descendant->PercentHeightContainer() == this) {
DCHECK(HasPercentHeightDescendant(descendant));
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_box.cc b/chromium/third_party/blink/renderer/core/layout/layout_box.cc
index 5313c3963a3..a28f0ae2be2 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_box.cc
@@ -3743,7 +3743,13 @@ LayoutUnit LayoutBox::ComputePercentageLogicalHeight(
&cb, &skipped_auto_height_containing_block);
DCHECK(cb);
- cb->AddPercentHeightDescendant(const_cast<LayoutBox*>(this));
+
+ // If the container of the descendant is a replaced element (a VIDEO, for
+ // instance), |cb| (which uses ContainingBlock()) may actually not be in the
+ // containing block chain for the descendant.
+ const LayoutObject* container = Container();
+ if (!container->IsLayoutReplaced())
+ cb->AddPercentHeightDescendant(const_cast<LayoutBox*>(this));
if (available_height == -1)
return available_height;
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_flexible_box.cc b/chromium/third_party/blink/renderer/core/layout/layout_flexible_box.cc
index 230c3830fbc..4cfaf04e392 100644
--- a/chromium/third_party/blink/renderer/core/layout/layout_flexible_box.cc
+++ b/chromium/third_party/blink/renderer/core/layout/layout_flexible_box.cc
@@ -1393,7 +1393,8 @@ bool LayoutFlexibleBox::ChildHasIntrinsicMainAxisSize(
const FlexLayoutAlgorithm& algorithm,
const LayoutBox& child) const {
bool result = false;
- if (!MainAxisIsInlineAxis(child) && !child.ShouldApplySizeContainment()) {
+ bool main_axis_is_inline = MainAxisIsInlineAxis(child);
+ if (!main_axis_is_inline && !child.ShouldApplySizeContainment()) {
Length child_flex_basis = FlexBasisForChild(child);
const Length& child_min_size = IsHorizontalFlow()
? child.StyleRef().MinWidth()
@@ -1407,6 +1408,11 @@ bool LayoutFlexibleBox::ChildHasIntrinsicMainAxisSize(
} else if (algorithm.ShouldApplyMinSizeAutoForChild(child)) {
result = true;
}
+ } else if (main_axis_is_inline &&
+ child.StyleRef().OverflowInlineDirection() == EOverflow::kAuto) {
+ // Because scrollbars depend on layout, we need to layout before running
+ // the algorithm to get an up-to-date size.
+ result = true;
}
return result;
}
diff --git a/chromium/third_party/blink/renderer/core/loader/form_submission.cc b/chromium/third_party/blink/renderer/core/loader/form_submission.cc
index 020052ff693..1ad45a7cc58 100644
--- a/chromium/third_party/blink/renderer/core/loader/form_submission.cc
+++ b/chromium/third_party/blink/renderer/core/loader/form_submission.cc
@@ -288,6 +288,8 @@ FrameLoadRequest FormSubmission::CreateFrameLoadRequest(
if (!target_.IsEmpty())
frame_request.SetFrameName(target_);
+ else
+ frame_request.SetFrameName(origin_document->BaseTarget());
ClientNavigationReason reason = ClientNavigationReason::kFormSubmissionGet;
if (method_ == FormSubmission::kPostMethod) {
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_load_request.cc b/chromium/third_party/blink/renderer/core/loader/frame_load_request.cc
index 78c15ae6085..1bfa77c670a 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_load_request.cc
+++ b/chromium/third_party/blink/renderer/core/loader/frame_load_request.cc
@@ -8,6 +8,7 @@
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/renderer/core/events/current_input_event.h"
#include "third_party/blink/renderer/core/fileapi/public_url_manager.h"
+#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
@@ -37,7 +38,6 @@ FrameLoadRequest::FrameLoadRequest(
: origin_document_(origin_document),
resource_request_(resource_request),
frame_name_(frame_name),
- client_redirect_(ClientRedirectPolicy::kNotClientRedirect),
should_send_referrer_(kMaybeSendReferrer),
should_check_main_world_content_security_policy_(
should_check_main_world_content_security_policy) {
@@ -63,7 +63,22 @@ FrameLoadRequest::FrameLoadRequest(
origin_document->GetPublicURLManager().Resolve(
resource_request.Url(), MakeRequest(&blob_url_token_->data));
}
+
+ if (ContentSecurityPolicy::ShouldBypassMainWorld(origin_document)) {
+ should_check_main_world_content_security_policy_ =
+ kDoNotCheckContentSecurityPolicy;
+ }
}
}
+ClientRedirectPolicy FrameLoadRequest::ClientRedirect() const {
+ // Form submissions have not historically been reported to the extensions API
+ // as client redirects.
+ if (client_navigation_reason_ == ClientNavigationReason::kNone ||
+ client_navigation_reason_ == ClientNavigationReason::kFormSubmissionGet ||
+ client_navigation_reason_ == ClientNavigationReason::kFormSubmissionPost)
+ return ClientRedirectPolicy::kNotClientRedirect;
+ return ClientRedirectPolicy::kClientRedirect;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_load_request.h b/chromium/third_party/blink/renderer/core/loader/frame_load_request.h
index 3c4e77dec96..a35c92f0ca9 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_load_request.h
+++ b/chromium/third_party/blink/renderer/core/loader/frame_load_request.h
@@ -74,15 +74,15 @@ struct CORE_EXPORT FrameLoadRequest {
frame_name_ = frame_name;
}
- ClientRedirectPolicy ClientRedirect() const { return client_redirect_; }
+ // TODO(japhet): This is only used from frame_loader.cc, and can probably be
+ // an implementation detail there.
+ ClientRedirectPolicy ClientRedirect() const;
void SetClientRedirectReason(ClientNavigationReason reason) {
- client_redirect_ = ClientRedirectPolicy::kClientRedirect;
client_navigation_reason_ = reason;
}
ClientNavigationReason ClientRedirectReason() const {
- DCHECK_EQ(ClientRedirectPolicy::kClientRedirect, client_redirect_);
return client_navigation_reason_;
}
@@ -165,11 +165,8 @@ struct CORE_EXPORT FrameLoadRequest {
ResourceRequest resource_request_;
AtomicString frame_name_;
AtomicString href_translate_;
- // TODO(caseq): merge ClientRedirectPolicy and ClientNavigationReason.
- // Currently, client_navigation_reason_ is set iff ClientRedirectPolicy
- // is set to kClientRedirect.
- ClientRedirectPolicy client_redirect_;
- ClientNavigationReason client_navigation_reason_;
+ ClientNavigationReason client_navigation_reason_ =
+ ClientNavigationReason::kNone;
NavigationPolicy navigation_policy_ = kNavigationPolicyCurrentTab;
WebTriggeringEventInfo triggering_event_info_ =
WebTriggeringEventInfo::kNotFromEvent;
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_loader.cc b/chromium/third_party/blink/renderer/core/loader/frame_loader.cc
index ebc44803f9a..3f2dad0e9a2 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_loader.cc
+++ b/chromium/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -444,7 +444,7 @@ void FrameLoader::DidFinishNavigation() {
// progress.
DCHECK((document_loader_ && document_loader_->SentDidFinishLoad()) ||
!HasProvisionalNavigation());
- if (!document_loader_ || !document_loader_->SentDidFinishLoad() ||
+ if ((document_loader_ && !document_loader_->SentDidFinishLoad()) ||
HasProvisionalNavigation()) {
return;
}
@@ -730,9 +730,6 @@ bool FrameLoader::PrepareRequestForThisFrame(FrameLoadRequest& request) {
"Not allowed to load local resource: " + url.ElidedString()));
return false;
}
-
- if (request.FrameName().IsEmpty())
- request.SetFrameName(frame_->GetDocument()->BaseTarget());
return true;
}
@@ -948,7 +945,7 @@ void FrameLoader::StartNavigation(const FrameLoadRequest& passed_request,
}
}
- if (request.ClientRedirect() == ClientRedirectPolicy::kClientRedirect) {
+ if (request.ClientRedirectReason() != ClientNavigationReason::kNone) {
probe::FrameRequestedNavigation(frame_, frame_, url,
request.ClientRedirectReason());
}
diff --git a/chromium/third_party/blink/renderer/core/loader/frame_loader_types.h b/chromium/third_party/blink/renderer/core/loader/frame_loader_types.h
index 4df8bae808c..fa84bd0dfed 100644
--- a/chromium/third_party/blink/renderer/core/loader/frame_loader_types.h
+++ b/chromium/third_party/blink/renderer/core/loader/frame_loader_types.h
@@ -79,6 +79,7 @@ enum class ClientNavigationReason {
kMetaTagRefresh,
kPageBlock,
kReload,
+ kNone
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/loader/resource/script_resource.cc b/chromium/third_party/blink/renderer/core/loader/resource/script_resource.cc
index e60593d480f..c9db8b3291c 100644
--- a/chromium/third_party/blink/renderer/core/loader/resource/script_resource.cc
+++ b/chromium/third_party/blink/renderer/core/loader/resource/script_resource.cc
@@ -290,6 +290,7 @@ void ScriptResource::OnDataPipeReadable(MojoResult result,
// This means the producer finished and streamed to completion.
watcher_.reset();
response_body_loader_client_->DidFinishLoadingBody();
+ response_body_loader_client_ = nullptr;
return;
case MOJO_RESULT_SHOULD_WAIT:
@@ -300,6 +301,7 @@ void ScriptResource::OnDataPipeReadable(MojoResult result,
// Some other error occurred.
watcher_.reset();
response_body_loader_client_->DidFailLoadingBody();
+ response_body_loader_client_ = nullptr;
return;
}
CHECK(state.readable());
@@ -358,6 +360,7 @@ void ScriptResource::NotifyFinished() {
case StreamingState::kStreamingNotAllowed:
watcher_.reset();
data_pipe_.reset();
+ response_body_loader_client_ = nullptr;
AdvanceStreamingState(StreamingState::kFinishedNotificationSent);
TextResource::NotifyFinished();
break;
@@ -382,6 +385,7 @@ void ScriptResource::StreamingFinished() {
// small) and b) an external error triggered the finished notification.
watcher_.reset();
data_pipe_.reset();
+ response_body_loader_client_ = nullptr;
AdvanceStreamingState(StreamingState::kFinishedNotificationSent);
TextResource::NotifyFinished();
}
@@ -463,6 +467,7 @@ void ScriptResource::SetClientIsWaitingForFinished() {
if (IsLoaded()) {
watcher_.reset();
data_pipe_.reset();
+ response_body_loader_client_ = nullptr;
AdvanceStreamingState(StreamingState::kFinishedNotificationSent);
TextResource::NotifyFinished();
}
@@ -536,6 +541,7 @@ void ScriptResource::CheckStreamingState() const {
CHECK(!streamer_ || streamer_->IsFinished());
CHECK(!watcher_ || !watcher_->IsWatching());
CHECK(!data_pipe_);
+ CHECK(!response_body_loader_client_);
CHECK(IsLoaded());
break;
}
diff --git a/chromium/third_party/blink/renderer/core/page/focus_controller.cc b/chromium/third_party/blink/renderer/core/page/focus_controller.cc
index 8e8348de9a5..041804d5ec7 100644
--- a/chromium/third_party/blink/renderer/core/page/focus_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/focus_controller.cc
@@ -1158,9 +1158,12 @@ Element* FocusController::NextFocusableElementInForm(Element* element,
if (form_element->formOwner() != form_owner ||
form_element->IsDisabledOrReadOnly())
continue;
- // Focusless spatial navigation supports all form types.
+ // Focusless spatial navigation supports all form types. However, submit
+ // buttons are explicitly excluded as moving to them isn't necessary - the
+ // IME should just submit instead.
if (RuntimeEnabledFeatures::FocuslessSpatialNavigationEnabled() &&
- page_->GetSettings().GetSpatialNavigationEnabled()) {
+ page_->GetSettings().GetSpatialNavigationEnabled() &&
+ !form_element->CanBeSuccessfulSubmitButton()) {
return next_element;
}
LayoutObject* layout = next_element->GetLayoutObject();
diff --git a/chromium/third_party/blink/renderer/core/page/page.cc b/chromium/third_party/blink/renderer/core/page/page.cc
index 1c2e3dbbb01..6cc6c5a6f38 100644
--- a/chromium/third_party/blink/renderer/core/page/page.cc
+++ b/chromium/third_party/blink/renderer/core/page/page.cc
@@ -307,8 +307,6 @@ void Page::DocumentDetached(Document* document) {
if (validation_message_client_)
validation_message_client_->DocumentDetached(*document);
hosts_using_features_.DocumentDetached(*document);
- if (spatial_navigation_controller_ && document->GetFrame()->IsMainFrame())
- spatial_navigation_controller_->ResetMojoBindings();
}
bool Page::OpenedByDOM() const {
diff --git a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
index b443a2d9f4a..b95b34b5118 100644
--- a/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
+++ b/chromium/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -827,6 +827,10 @@ bool ScrollsWithRootFrame(LayoutObject* object) {
DCHECK(object);
DCHECK(object->GetFrame());
+ // TODO(bokan): Speculative fix for https://crbug.com/964293.
+ if (!object || !object->GetNode())
+ return true;
+
const LocalFrame& frame = *object->GetFrame();
// If we're in an iframe document, we need to determine if the containing
diff --git a/chromium/third_party/blink/renderer/core/page/spatial_navigation.cc b/chromium/third_party/blink/renderer/core/page/spatial_navigation.cc
index 04c10fd3910..56a992c588c 100644
--- a/chromium/third_party/blink/renderer/core/page/spatial_navigation.cc
+++ b/chromium/third_party/blink/renderer/core/page/spatial_navigation.cc
@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/html/html_image_element.h"
#include "third_party/blink/renderer/core/html_names.h"
+#include "third_party/blink/renderer/core/input/event_handler.h"
#include "third_party/blink/renderer/core/layout/layout_box.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
@@ -47,6 +48,14 @@
namespace blink {
+// A small integer that easily fits into a double with a good margin for
+// arithmetic. In particular, we don't want to use
+// std::numeric_limits<double>::lowest() because, if subtracted, it becomes
+// NaN which will make all following arithmetic NaN too (an unusable number).
+constexpr double kMinDistance = std::numeric_limits<int>::lowest();
+
+constexpr int kFudgeFactor = 2;
+
static void DeflateIfOverlapped(LayoutRect&, LayoutRect&);
FocusCandidate::FocusCandidate(Node* node, SpatialNavigationDirection direction)
@@ -185,6 +194,49 @@ ScrollableArea* ScrollableAreaFor(const Node* node) {
return ToLayoutBox(object)->GetScrollableArea();
}
+bool IsUnobscured(const FocusCandidate& candidate) {
+ DCHECK(candidate.visible_node);
+
+ const LocalFrame* local_main_frame = DynamicTo<LocalFrame>(
+ candidate.visible_node->GetDocument().GetPage()->MainFrame());
+ if (!local_main_frame)
+ return false;
+
+ // TODO(crbug.com/955952): We cannot evaluate visibility for media element
+ // using hit test since attached media controls cover media element.
+ if (candidate.visible_node->IsMediaElement())
+ return true;
+
+ LayoutRect viewport_rect = LayoutRect(
+ local_main_frame->GetPage()->GetVisualViewport().VisibleContentRect());
+ LayoutRect interesting_rect =
+ Intersection(candidate.rect_in_root_frame, viewport_rect);
+
+ if (interesting_rect.IsEmpty())
+ return false;
+
+ HitTestLocation location(interesting_rect);
+ HitTestResult result =
+ local_main_frame->GetEventHandler().HitTestResultAtLocation(
+ location, HitTestRequest::kReadOnly | HitTestRequest::kListBased |
+ HitTestRequest::kIgnoreZeroOpacityObjects |
+ HitTestRequest::kAllowChildFrameContent);
+
+ const HitTestResult::NodeSet& nodes = result.ListBasedTestResult();
+ for (auto hit_node = nodes.rbegin(); hit_node != nodes.rend(); ++hit_node) {
+ if (candidate.visible_node->ContainsIncludingHostElements(**hit_node))
+ return true;
+
+ if (FrameOwnerElement(candidate) &&
+ FrameOwnerElement(candidate)
+ ->contentDocument()
+ ->ContainsIncludingHostElements(**hit_node))
+ return true;
+ }
+
+ return false;
+}
+
bool HasRemoteFrame(const Node* node) {
auto* frame_owner_element = DynamicTo<HTMLFrameOwnerElement>(node);
if (!frame_owner_element)
@@ -237,7 +289,9 @@ bool ScrollInDirection(Node* container, SpatialNavigationDirection direction) {
// CanScrollInDirection(). Regular arrow-key scrolling (without
// --enable-spatial-navigation) already uses smooth scrolling by default.
ScrollableArea* scroller = ScrollableAreaFor(container);
- DCHECK(scroller);
+ if (!scroller)
+ return false;
+
scroller->ScrollBy(ScrollOffset(dx, dy), kUserScroll);
return true;
}
@@ -246,7 +300,7 @@ static void DeflateIfOverlapped(LayoutRect& a, LayoutRect& b) {
if (!a.Intersects(b) || a.Contains(b) || b.Contains(a))
return;
- LayoutUnit deflate_factor = LayoutUnit(-FudgeFactor());
+ LayoutUnit deflate_factor = LayoutUnit(-kFudgeFactor);
// Avoid negative width or height values.
if ((a.Width() + 2 * deflate_factor > 0) &&
@@ -481,55 +535,42 @@ void EntryAndExitPointsForDirection(SpatialNavigationDirection direction,
}
}
-bool AreElementsOnSameLine(const FocusCandidate& first_candidate,
- const FocusCandidate& second_candidate) {
- if (first_candidate.IsNull() || second_candidate.IsNull())
- return false;
-
- if (!first_candidate.visible_node->GetLayoutObject() ||
- !second_candidate.visible_node->GetLayoutObject())
- return false;
-
- if (!first_candidate.rect_in_root_frame.Intersects(
- second_candidate.rect_in_root_frame))
- return false;
-
- if (IsHTMLAreaElement(*first_candidate.focusable_node) ||
- IsHTMLAreaElement(*second_candidate.focusable_node))
- return false;
-
- if (!first_candidate.visible_node->GetLayoutObject()->IsLayoutInline() ||
- !second_candidate.visible_node->GetLayoutObject()->IsLayoutInline())
- return false;
-
- if (first_candidate.visible_node->GetLayoutObject()->ContainingBlock() !=
- second_candidate.visible_node->GetLayoutObject()->ContainingBlock())
- return false;
-
- return true;
-}
-
double ComputeDistanceDataForNode(SpatialNavigationDirection direction,
const FocusCandidate& current_interest,
const FocusCandidate& candidate) {
- if (!IsRectInDirection(direction, current_interest.rect_in_root_frame,
- candidate.rect_in_root_frame))
- return MaxDistance();
-
- if (AreElementsOnSameLine(current_interest, candidate)) {
- if ((direction == SpatialNavigationDirection::kUp &&
- current_interest.rect_in_root_frame.Y() >
- candidate.rect_in_root_frame.Y()) ||
- (direction == SpatialNavigationDirection::kDown &&
- candidate.rect_in_root_frame.Y() >
- current_interest.rect_in_root_frame.Y())) {
- return 0.0;
- }
- }
-
+ double distance = 0.0;
+ double overlap = 0.0;
LayoutRect node_rect = candidate.rect_in_root_frame;
LayoutRect current_rect = current_interest.rect_in_root_frame;
- DeflateIfOverlapped(current_rect, node_rect);
+ if (node_rect.Contains(current_rect)) {
+ // When leaving an "insider", don't focus its underlaying container box.
+ // Go directly to the outside world. This avoids focus from being trapped
+ // inside a container.
+ return kMaxDistance;
+ }
+
+ if (current_rect.Contains(node_rect)) {
+ // We give priority to "insiders", candidates that are completely inside the
+ // current focus rect, by giving them a negative, < 0, distance number.
+ distance = kMinDistance;
+
+ // For insiders we cannot meassure the distance from the outer box. Instead,
+ // we meassure distance _from_ the focused container's rect's "opposite
+ // edge" in the navigated direction, just like we do when we look for
+ // candidates inside a focused scroll container.
+ current_rect = OppositeEdge(direction, current_rect);
+
+ // This candidate fully overlaps the current focus rect so we can omit the
+ // overlap term of the equation. An "insider" will always win against an
+ // "outsider".
+ } else if (!IsRectInDirection(direction, current_rect, node_rect)) {
+ return kMaxDistance;
+ } else {
+ DeflateIfOverlapped(current_rect, node_rect);
+ LayoutRect intersection_rect = Intersection(current_rect, node_rect);
+ overlap =
+ (intersection_rect.Width() * intersection_rect.Height()).ToDouble();
+ }
LayoutPoint exit_point;
LayoutPoint entry_point;
@@ -538,6 +579,9 @@ double ComputeDistanceDataForNode(SpatialNavigationDirection direction,
LayoutUnit x_axis = (exit_point.X() - entry_point.X()).Abs();
LayoutUnit y_axis = (exit_point.Y() - entry_point.Y()).Abs();
+ double euclidian_distance =
+ sqrt((x_axis * x_axis + y_axis * y_axis).ToDouble());
+ distance += euclidian_distance;
LayoutUnit navigation_axis_distance;
LayoutUnit weighted_orthogonal_axis_distance;
@@ -572,21 +616,17 @@ double ComputeDistanceDataForNode(SpatialNavigationDirection direction,
break;
default:
NOTREACHED();
- return MaxDistance();
+ return kMaxDistance;
}
- double euclidian_distance_pow2 =
- (x_axis * x_axis + y_axis * y_axis).ToDouble();
- LayoutRect intersection_rect = Intersection(current_rect, node_rect);
- double overlap =
- (intersection_rect.Width() * intersection_rect.Height()).ToDouble();
-
// Distance calculation is based on http://www.w3.org/TR/WICD/#focus-handling
- return sqrt(euclidian_distance_pow2) + navigation_axis_distance +
+ return distance + navigation_axis_distance +
weighted_orthogonal_axis_distance - sqrt(overlap);
}
-// Returns a thin rectangle that represents one of box's sides.
+// Returns a thin rectangle that represents one of |box|'s edges.
+// To not intersect elements that are positioned inside |box|, we add one
+// LayoutUnit of margin that puts the returned slice "just outside" |box|.
LayoutRect OppositeEdge(SpatialNavigationDirection side,
const LayoutRect& box,
LayoutUnit thickness) {
@@ -595,16 +635,20 @@ LayoutRect OppositeEdge(SpatialNavigationDirection side,
case SpatialNavigationDirection::kLeft:
thin_rect.SetX(thin_rect.MaxX() - thickness);
thin_rect.SetWidth(thickness);
+ thin_rect.Move(1, 0);
break;
case SpatialNavigationDirection::kRight:
thin_rect.SetWidth(thickness);
+ thin_rect.Move(-1, 0);
break;
case SpatialNavigationDirection::kDown:
thin_rect.SetHeight(thickness);
+ thin_rect.Move(0, -1);
break;
case SpatialNavigationDirection::kUp:
thin_rect.SetY(thin_rect.MaxY() - thickness);
thin_rect.SetHeight(thickness);
+ thin_rect.Move(0, 1);
break;
default:
NOTREACHED();
@@ -623,7 +667,7 @@ LayoutRect StartEdgeForAreaElement(const HTMLAreaElement& area,
direction,
area.GetDocument().GetFrame()->View()->ConvertToRootFrame(
area.ComputeAbsoluteRect(area.ImageElement()->GetLayoutObject())),
- LayoutUnit(1) /* snav-imagemap-overlapped-areas.html */);
+ LayoutUnit(kFudgeFactor) /* snav-imagemap-overlapped-areas.html */);
return rect;
}
diff --git a/chromium/third_party/blink/renderer/core/page/spatial_navigation.h b/chromium/third_party/blink/renderer/core/page/spatial_navigation.h
index 5a6e2725239..7112a4d3bed 100644
--- a/chromium/third_party/blink/renderer/core/page/spatial_navigation.h
+++ b/chromium/third_party/blink/renderer/core/page/spatial_navigation.h
@@ -36,13 +36,7 @@ class HTMLFrameOwnerElement;
enum class SpatialNavigationDirection { kNone, kUp, kRight, kDown, kLeft };
-inline double MaxDistance() {
- return std::numeric_limits<double>::max();
-}
-
-inline int FudgeFactor() {
- return 2;
-}
+constexpr double kMaxDistance = std::numeric_limits<double>::max();
CORE_EXPORT bool IsSpatialNavigationEnabled(const LocalFrame*);
@@ -73,14 +67,13 @@ struct FocusCandidate {
CORE_EXPORT bool HasRemoteFrame(const Node*);
CORE_EXPORT FloatRect RectInViewport(const Node&);
CORE_EXPORT bool IsOffscreen(const Node*);
+CORE_EXPORT bool IsUnobscured(const FocusCandidate&);
bool ScrollInDirection(Node* container, SpatialNavigationDirection);
CORE_EXPORT bool IsScrollableNode(const Node* node);
CORE_EXPORT bool IsScrollableAreaOrDocument(const Node*);
CORE_EXPORT Node* ScrollableAreaOrDocumentOf(Node*);
bool CanScrollInDirection(const Node* container, SpatialNavigationDirection);
bool CanScrollInDirection(const LocalFrame*, SpatialNavigationDirection);
-bool AreElementsOnSameLine(const FocusCandidate& first_candidate,
- const FocusCandidate& second_candidate);
double ComputeDistanceDataForNode(SpatialNavigationDirection,
const FocusCandidate& current_interest,
diff --git a/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
index d15a56d90e2..8ba2f2a154f 100644
--- a/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
+++ b/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.cc
@@ -17,6 +17,8 @@
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
+#include "third_party/blink/renderer/core/html/forms/html_form_control_element.h"
+#include "third_party/blink/renderer/core/html/forms/html_form_element.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
@@ -90,47 +92,11 @@ static void ConsiderForBestCandidate(SpatialNavigationDirection direction,
double distance =
ComputeDistanceDataForNode(direction, current_interest, candidate);
- if (distance == MaxDistance())
+ if (distance == kMaxDistance)
return;
- if (best_candidate->IsNull()) {
- *best_candidate = candidate;
- *best_distance = distance;
- return;
- }
- LayoutRect intersection_rect = Intersection(
- candidate.rect_in_root_frame, best_candidate->rect_in_root_frame);
- if (!intersection_rect.IsEmpty() &&
- !AreElementsOnSameLine(*best_candidate, candidate) &&
- intersection_rect == candidate.rect_in_root_frame) {
- // If 2 nodes are intersecting, do hit test to find which node in on top.
- LayoutUnit x = intersection_rect.X() + intersection_rect.Width() / 2;
- LayoutUnit y = intersection_rect.Y() + intersection_rect.Height() / 2;
- if (!IsA<LocalFrame>(
- candidate.visible_node->GetDocument().GetPage()->MainFrame()))
- return;
- HitTestLocation location(IntPoint(x.ToInt(), y.ToInt()));
- HitTestResult result =
- candidate.visible_node->GetDocument()
- .GetPage()
- ->DeprecatedLocalMainFrame()
- ->GetEventHandler()
- .HitTestResultAtLocation(
- location, HitTestRequest::kReadOnly | HitTestRequest::kActive |
- HitTestRequest::kIgnoreClipping);
- if (candidate.visible_node->ContainsIncludingHostElements(
- *result.InnerNode())) {
- *best_candidate = candidate;
- *best_distance = distance;
- return;
- }
- if (best_candidate->visible_node->ContainsIncludingHostElements(
- *result.InnerNode()))
- return;
- }
-
- if (distance < *best_distance) {
+ if (distance < *best_distance && IsUnobscured(candidate)) {
*best_candidate = candidate;
*best_distance = distance;
}
@@ -196,10 +162,18 @@ bool SpatialNavigationController::HandleEnterKeyboardEvent(
return false;
if (event->type() == event_type_names::kKeydown) {
+ enter_key_down_seen_ = true;
interest_element->SetActive(true);
+ } else if (event->type() == event_type_names::kKeypress) {
+ enter_key_press_seen_ = true;
} else if (event->type() == event_type_names::kKeyup) {
interest_element->SetActive(false);
- if (RuntimeEnabledFeatures::FocuslessSpatialNavigationEnabled()) {
+
+ // Ensure that the enter key has not already been handled by something else,
+ // or we can end up clicking elements multiple times. Some elements already
+ // convert the Enter key into click on down and press (and up) events.
+ if (RuntimeEnabledFeatures::FocuslessSpatialNavigationEnabled() &&
+ enter_key_down_seen_ && enter_key_press_seen_) {
interest_element->focus(FocusParams(SelectionBehaviorOnFocus::kReset,
kWebFocusTypeSpatialNavigation,
nullptr));
@@ -212,6 +186,28 @@ bool SpatialNavigationController::HandleEnterKeyboardEvent(
return true;
}
+void SpatialNavigationController::ResetEnterKeyState() {
+ enter_key_down_seen_ = false;
+ enter_key_press_seen_ = false;
+}
+
+bool SpatialNavigationController::HandleImeSubmitKeyboardEvent(
+ KeyboardEvent* event) {
+ DCHECK(page_->GetSettings().GetSpatialNavigationEnabled());
+
+ if (!IsHTMLFormControlElement(GetFocusedElement()))
+ return false;
+
+ HTMLFormControlElement* element =
+ ToHTMLFormControlElement(GetFocusedElement());
+
+ if (!element->formOwner())
+ return false;
+
+ element->formOwner()->SubmitImplicitly(*event, true);
+ return true;
+}
+
bool SpatialNavigationController::HandleEscapeKeyboardEvent(
KeyboardEvent* event) {
DCHECK(page_->GetSettings().GetSpatialNavigationEnabled());
@@ -248,6 +244,8 @@ void SpatialNavigationController::DidDetachFrameView() {
// etc.) then reset navigation.
if (interest_element_ && !interest_element_->GetDocument().View())
interest_element_ = nullptr;
+ // TODO(crbug.com/956209): should be checked via an integration test.
+ ResetMojoBindings();
}
void SpatialNavigationController::Trace(blink::Visitor* visitor) {
@@ -317,7 +315,7 @@ FocusCandidate SpatialNavigationController::FindNextCandidateInContainer(
current_interest.visible_node = interest_child_in_container;
FocusCandidate best_candidate;
- double best_distance = MaxDistance();
+ double best_distance = kMaxDistance;
for (; element;
element =
IsScrollableAreaOrDocument(element)
@@ -550,6 +548,7 @@ void SpatialNavigationController::UpdateSpatialNavigationState(
bool change = false;
change |= UpdateCanExitFocus(element);
change |= UpdateCanSelectInterestedElement(element);
+ change |= UpdateIsFormFocused(element);
change |= UpdateHasNextFormElement(element);
change |= UpdateHasDefaultVideoControls(element);
if (change)
@@ -564,7 +563,7 @@ void SpatialNavigationController::OnSpatialNavigationStateChanged() {
}
bool SpatialNavigationController::UpdateCanExitFocus(Element* element) {
- bool can_exit_focus = IsFocused(element);
+ bool can_exit_focus = IsFocused(element) && !IsHTMLBodyElement(element);
if (can_exit_focus == spatial_navigation_state_->can_exit_focus)
return false;
spatial_navigation_state_->can_exit_focus = can_exit_focus;
@@ -594,6 +593,15 @@ bool SpatialNavigationController::UpdateHasNextFormElement(Element* element) {
return true;
}
+bool SpatialNavigationController::UpdateIsFormFocused(Element* element) {
+ bool is_form_focused = IsFocused(element) && element->IsFormControlElement();
+
+ if (is_form_focused == spatial_navigation_state_->is_form_focused)
+ return false;
+ spatial_navigation_state_->is_form_focused = is_form_focused;
+ return true;
+}
+
bool SpatialNavigationController::UpdateHasDefaultVideoControls(
Element* element) {
bool has_default_video_controls =
diff --git a/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.h b/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.h
index 05ee39d5615..98b709da93c 100644
--- a/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.h
+++ b/chromium/third_party/blink/renderer/core/page/spatial_navigation_controller.h
@@ -30,6 +30,11 @@ class CORE_EXPORT SpatialNavigationController
bool HandleArrowKeyboardEvent(KeyboardEvent* event);
bool HandleEnterKeyboardEvent(KeyboardEvent* event);
bool HandleEscapeKeyboardEvent(KeyboardEvent* event);
+ bool HandleImeSubmitKeyboardEvent(KeyboardEvent* event);
+
+ // Called when the enter key is released to clear local state because we don't
+ // get a consistent event stream when the Enter key is partially handled.
+ void ResetEnterKeyState();
// Returns the element that's currently interested. i.e. the Element that's
// currently indicated to the user.
@@ -40,8 +45,6 @@ class CORE_EXPORT SpatialNavigationController
void OnSpatialNavigationSettingChanged();
void FocusedNodeChanged(Document*);
- void ResetMojoBindings();
-
void Trace(blink::Visitor*);
private:
@@ -97,15 +100,22 @@ class CORE_EXPORT SpatialNavigationController
bool UpdateCanExitFocus(Element* element);
bool UpdateCanSelectInterestedElement(Element* element);
bool UpdateHasNextFormElement(Element* element);
+ bool UpdateIsFormFocused(Element* element);
bool UpdateHasDefaultVideoControls(Element* element);
const mojom::blink::SpatialNavigationHostPtr& GetSpatialNavigationHost();
+ void ResetMojoBindings();
// The currently indicated element or nullptr if no node is indicated by
// spatial navigation.
WeakMember<Element> interest_element_;
Member<Page> page_;
+ // We need to track whether the enter key has been handled in down or press to
+ // know whether to generate a click on the up.
+ bool enter_key_down_seen_ = false;
+ bool enter_key_press_seen_ = false;
+
mojom::blink::SpatialNavigationStatePtr spatial_navigation_state_;
mojom::blink::SpatialNavigationHostPtr spatial_navigation_host_;
};
diff --git a/chromium/third_party/blink/renderer/core/page/spatial_navigation_test.cc b/chromium/third_party/blink/renderer/core/page/spatial_navigation_test.cc
index e0716b124bf..a7416224660 100644
--- a/chromium/third_party/blink/renderer/core/page/spatial_navigation_test.cc
+++ b/chromium/third_party/blink/renderer/core/page/spatial_navigation_test.cc
@@ -26,26 +26,28 @@ class SpatialNavigationTest : public RenderingTest {
LayoutRect TopOfVisualViewport() {
LayoutRect visual_viewport = RootViewport(&GetFrame());
+ visual_viewport.SetY(visual_viewport.Y() - 1);
visual_viewport.SetHeight(LayoutUnit(0));
return visual_viewport;
}
LayoutRect BottomOfVisualViewport() {
LayoutRect visual_viewport = RootViewport(&GetFrame());
- visual_viewport.SetY(visual_viewport.MaxY());
+ visual_viewport.SetY(visual_viewport.MaxY() + 1);
visual_viewport.SetHeight(LayoutUnit(0));
return visual_viewport;
}
LayoutRect LeftSideOfVisualViewport() {
LayoutRect visual_viewport = RootViewport(&GetFrame());
+ visual_viewport.SetX(visual_viewport.X() - 1);
visual_viewport.SetWidth(LayoutUnit(0));
return visual_viewport;
}
LayoutRect RightSideOfVisualViewport() {
LayoutRect visual_viewport = RootViewport(&GetFrame());
- visual_viewport.SetX(visual_viewport.MaxX());
+ visual_viewport.SetX(visual_viewport.MaxX() + 1);
visual_viewport.SetWidth(LayoutUnit(0));
return visual_viewport;
}
@@ -245,7 +247,7 @@ TEST_F(SpatialNavigationTest, StartAtVisibleFocusedIframe) {
}
TEST_F(SpatialNavigationTest, StartAtTopWhenGoingDownwardsWithoutFocus) {
- EXPECT_EQ(LayoutRect(0, 0, 111, 0),
+ EXPECT_EQ(LayoutRect(0, -1, 111, 0),
SearchOrigin({0, 0, 111, 222}, nullptr,
SpatialNavigationDirection::kDown));
@@ -256,7 +258,7 @@ TEST_F(SpatialNavigationTest, StartAtTopWhenGoingDownwardsWithoutFocus) {
TEST_F(SpatialNavigationTest, StartAtBottomWhenGoingUpwardsWithoutFocus) {
EXPECT_EQ(
- LayoutRect(0, 222, 111, 0),
+ LayoutRect(0, 222 + 1, 111, 0),
SearchOrigin({0, 0, 111, 222}, nullptr, SpatialNavigationDirection::kUp));
EXPECT_EQ(SearchOrigin(RootViewport(&GetFrame()), nullptr,
@@ -265,7 +267,7 @@ TEST_F(SpatialNavigationTest, StartAtBottomWhenGoingUpwardsWithoutFocus) {
}
TEST_F(SpatialNavigationTest, StartAtLeftSideWhenGoingEastWithoutFocus) {
- EXPECT_EQ(LayoutRect(0, 0, 0, 222),
+ EXPECT_EQ(LayoutRect(-1, 0, 0, 222),
SearchOrigin({0, 0, 111, 222}, nullptr,
SpatialNavigationDirection::kRight));
@@ -275,7 +277,7 @@ TEST_F(SpatialNavigationTest, StartAtLeftSideWhenGoingEastWithoutFocus) {
}
TEST_F(SpatialNavigationTest, StartAtRightSideWhenGoingWestWithoutFocus) {
- EXPECT_EQ(LayoutRect(111, 0, 0, 222),
+ EXPECT_EQ(LayoutRect(111 + 1, 0, 0, 222),
SearchOrigin({0, 0, 111, 222}, nullptr,
SpatialNavigationDirection::kLeft));
@@ -330,14 +332,15 @@ TEST_F(SpatialNavigationTest, StartAtContainersEdge) {
// Go down.
LayoutRect container_top_edge = container_box;
container_top_edge.SetHeight(LayoutUnit(0));
+ container_top_edge.SetY(container_top_edge.Y() - 1);
EXPECT_EQ(SearchOrigin(RootViewport(&GetFrame()), b,
SpatialNavigationDirection::kDown),
container_top_edge);
// Go up.
LayoutRect container_bottom_edge = container_box;
- container_bottom_edge.SetY(container_bottom_edge.MaxX());
container_bottom_edge.SetHeight(LayoutUnit(0));
+ container_bottom_edge.SetY(container_bottom_edge.MaxX() + 1);
EXPECT_EQ(SearchOrigin(RootViewport(&GetFrame()), b,
SpatialNavigationDirection::kUp),
container_bottom_edge);
@@ -345,13 +348,14 @@ TEST_F(SpatialNavigationTest, StartAtContainersEdge) {
// Go right.
LayoutRect container_leftmost_edge = container_box;
container_leftmost_edge.SetWidth(LayoutUnit(0));
+ container_leftmost_edge.SetX(container_leftmost_edge.X() - 1);
EXPECT_EQ(SearchOrigin(RootViewport(&GetFrame()), b,
SpatialNavigationDirection::kRight),
container_leftmost_edge);
// Go left.
LayoutRect container_rightmost_edge = container_box;
- container_rightmost_edge.SetX(container_bottom_edge.MaxX());
+ container_rightmost_edge.SetX(container_bottom_edge.MaxX() + 1);
container_rightmost_edge.SetWidth(LayoutUnit(0));
EXPECT_EQ(SearchOrigin(RootViewport(&GetFrame()), b,
SpatialNavigationDirection::kLeft),
@@ -596,7 +600,7 @@ TEST_F(SpatialNavigationTest, BottomOfPinchedViewport) {
EXPECT_EQ(origin.Height(), 0);
EXPECT_EQ(origin.Width(), GetFrame().View()->Width());
EXPECT_EQ(origin.X(), 0);
- EXPECT_EQ(origin.Y(), GetFrame().View()->Height());
+ EXPECT_EQ(origin.Y(), GetFrame().View()->Height() + 1);
EXPECT_EQ(origin, BottomOfVisualViewport());
// Now, test SearchOrigin with a pinched viewport.
@@ -608,7 +612,7 @@ TEST_F(SpatialNavigationTest, BottomOfPinchedViewport) {
EXPECT_EQ(origin.Height(), 0);
EXPECT_LT(origin.Width(), GetFrame().View()->Width());
EXPECT_GT(origin.X(), 0);
- EXPECT_LT(origin.Y(), GetFrame().View()->Height());
+ EXPECT_LT(origin.Y(), GetFrame().View()->Height() + 1);
EXPECT_EQ(origin, BottomOfVisualViewport());
}
@@ -618,7 +622,7 @@ TEST_F(SpatialNavigationTest, TopOfPinchedViewport) {
EXPECT_EQ(origin.Height(), 0);
EXPECT_EQ(origin.Width(), GetFrame().View()->Width());
EXPECT_EQ(origin.X(), 0);
- EXPECT_EQ(origin.Y(), 0);
+ EXPECT_EQ(origin.Y(), -1);
EXPECT_EQ(origin, TopOfVisualViewport());
// Now, test SearchOrigin with a pinched viewport.
@@ -630,7 +634,7 @@ TEST_F(SpatialNavigationTest, TopOfPinchedViewport) {
EXPECT_EQ(origin.Height(), 0);
EXPECT_LT(origin.Width(), GetFrame().View()->Width());
EXPECT_GT(origin.X(), 0);
- EXPECT_GT(origin.Y(), 0);
+ EXPECT_GT(origin.Y(), -1);
EXPECT_EQ(origin, TopOfVisualViewport());
}
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
index aff08d420fe..50e185b0966 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
@@ -172,8 +172,16 @@ void CompositingLayerPropertyUpdater::Update(const LayoutObject& object) {
auto* main_graphics_layer = mapping->MainGraphicsLayer();
if (main_graphics_layer->ContentsLayer()) {
- main_graphics_layer->SetContentsPropertyTreeState(
- fragment_data.ContentsProperties());
+ IntPoint offset;
+ // The offset should be zero when the layer has ReplacedContentTransform,
+ // because the offset has been baked into ReplacedContentTransform.
+ if (!fragment_data.PaintProperties() ||
+ !fragment_data.PaintProperties()->ReplacedContentTransform()) {
+ offset = main_graphics_layer->ContentsRect().Location() +
+ main_graphics_layer->GetOffsetFromTransformNode();
+ }
+ main_graphics_layer->SetContentsLayerState(
+ fragment_data.ContentsProperties(), offset);
}
if (auto* squashing_layer = mapping->SquashingLayer()) {
diff --git a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc
index 2e93937014a..5a6dee4b34c 100644
--- a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc
+++ b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc
@@ -69,6 +69,15 @@ namespace blink {
static constexpr float kStartOpacity = 1;
+namespace {
+
+float HighlightTargetOpacity() {
+ // For web tests we don't fade out.
+ return WebTestSupport::IsRunningWebTest() ? kStartOpacity : 0;
+}
+
+} // namespace
+
static CompositorElementId NewElementId() {
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
@@ -103,7 +112,7 @@ LinkHighlightImpl::LinkHighlightImpl(Node* node)
geometry_needs_update_ = true;
EffectPaintPropertyNode::State state;
- state.opacity = kStartOpacity;
+ state.opacity = HighlightTargetOpacity();
state.local_transform_space = &TransformPaintPropertyNode::Root();
state.compositor_element_id = element_id_;
state.direct_compositing_reasons = CompositingReason::kActiveOpacityAnimation;
@@ -354,10 +363,9 @@ void LinkHighlightImpl::StartHighlightAnimationIfNeeded() {
curve->AddKeyframe(CompositorFloatKeyframe(
extra_duration_required.InSecondsF(), kStartOpacity, timing_function));
}
- // For web tests we don't fade out.
curve->AddKeyframe(CompositorFloatKeyframe(
(kFadeDuration + extra_duration_required).InSecondsF(),
- WebTestSupport::IsRunningWebTest() ? kStartOpacity : 0, timing_function));
+ HighlightTargetOpacity(), timing_function));
auto keyframe_model = std::make_unique<CompositorKeyframeModel>(
*curve, compositor_target_property::OPACITY, 0, 0);
diff --git a/chromium/third_party/blink/renderer/core/xml/xpath_grammar.y b/chromium/third_party/blink/renderer/core/xml/xpath_grammar.y
index 17d0b89685d..cf0208370a0 100644
--- a/chromium/third_party/blink/renderer/core/xml/xpath_grammar.y
+++ b/chromium/third_party/blink/renderer/core/xml/xpath_grammar.y
@@ -34,15 +34,14 @@
#include "third_party/blink/renderer/core/xml/xpath_predicate.h"
#include "third_party/blink/renderer/core/xml/xpath_step.h"
#include "third_party/blink/renderer/core/xml/xpath_variable_reference.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
-void* YyFastMalloc(size_t size)
-{
- return WTF::Partitions::FastMalloc(size, nullptr);
-}
-
-#define YYMALLOC YyFastMalloc
-#define YYFREE WTF::Partitions::FastFree
+// The union below must be located on the stack because it contains raw
+// pointers to Oilpan objects. crbug.com/961413
+#define YYSTACK_USE_ALLOCA 1
+// Bison's bug? YYSTACK_ALLOC is not defined if _MSC_VER.
+#if defined(_MSC_VER)
+#define YYSTACK_ALLOC _alloca
+#endif
#define YYENABLE_NLS 0
#define YYLTYPE_IS_TRIVIAL 1
diff --git a/chromium/third_party/blink/renderer/modules/BUILD.gn b/chromium/third_party/blink/renderer/modules/BUILD.gn
index eb6f43aa81f..97a35617a9f 100644
--- a/chromium/third_party/blink/renderer/modules/BUILD.gn
+++ b/chromium/third_party/blink/renderer/modules/BUILD.gn
@@ -393,8 +393,11 @@ jumbo_source_set("unit_tests") {
]
if (is_android && notouch_build) {
- sources +=
- [ "media_controls/touchless/media_controls_touchless_impl_test.cc" ]
+ sources += [
+ "media_controls/touchless/media_controls_touchless_impl_test.cc",
+ "media_controls/touchless/test_media_controls_menu_host.cc",
+ "media_controls/touchless/test_media_controls_menu_host.h",
+ ]
}
configs += [
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 582a091f27b..9d1a1bb6080 100644
--- a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
+++ b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.cc
@@ -75,6 +75,7 @@ void BroadcastChannel::close() {
remote_client_.reset();
if (binding_.is_bound())
binding_.Close();
+ feature_handle_for_scheduler_.reset();
}
const AtomicString& BroadcastChannel::InterfaceName() const {
@@ -119,7 +120,11 @@ BroadcastChannel::BroadcastChannel(ExecutionContext* execution_context,
: ContextLifecycleObserver(execution_context),
origin_(execution_context->GetSecurityOrigin()),
name_(name),
- binding_(this) {
+ binding_(this),
+ feature_handle_for_scheduler_(
+ execution_context->GetScheduler()->RegisterFeature(
+ SchedulingPolicy::Feature::kBroadcastChannel,
+ {SchedulingPolicy::RecordMetricsForBackForwardCache()})) {
mojom::blink::BroadcastChannelProviderPtr& provider =
GetThreadSpecificProvider();
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 62e35c9fc05..6db0dfabbbb 100644
--- a/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h
+++ b/chromium/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.h
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
+#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
namespace blink {
@@ -68,6 +69,10 @@ class BroadcastChannel final : public EventTargetWithInlineData,
mojo::AssociatedBinding<mojom::blink::BroadcastChannelClient> binding_;
mojom::blink::BroadcastChannelClientAssociatedPtr remote_client_;
+ // Notifies the scheduler that a broadcast channel is active.
+ FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle
+ feature_handle_for_scheduler_;
+
DISALLOW_COPY_AND_ASSIGN(BroadcastChannel);
};
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 06fde4ec2da..16156713451 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
@@ -35,7 +35,7 @@ OffscreenCanvasRenderingContext2D::OffscreenCanvasRenderingContext2D(
ExecutionContext* execution_context = canvas->GetTopExecutionContext();
if (auto* document = DynamicTo<Document>(execution_context)) {
Settings* settings = document->GetSettings();
- if (settings->GetDisableReadingFromCanvas())
+ if (settings && settings->GetDisableReadingFromCanvas())
canvas->SetDisableReadingFromCanvasTrue();
return;
}
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 3fad0b87279..4f52673d682 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.cc
@@ -101,7 +101,13 @@ IDBDatabase::IDBDatabase(ExecutionContext* context,
event_queue_(
MakeGarbageCollected<EventQueue>(context, TaskType::kDatabaseAccess)),
database_callbacks_(callbacks),
- isolate_(isolate) {
+ isolate_(isolate),
+ feature_handle_for_scheduler_(
+ context
+ ? context->GetScheduler()->RegisterFeature(
+ SchedulingPolicy::Feature::kIndexedDBConnection,
+ {SchedulingPolicy::RecordMetricsForBackForwardCache()})
+ : FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle()) {
database_callbacks_->Connect(this);
}
@@ -436,6 +442,7 @@ void IDBDatabase::close() {
return;
close_pending_ = true;
+ feature_handle_for_scheduler_.reset();
if (transactions_.IsEmpty())
CloseConnection();
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 202056519af..66bcfa78fe5 100644
--- a/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h
+++ b/chromium/third_party/blink/renderer/modules/indexeddb/idb_database.h
@@ -46,6 +46,7 @@
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h"
namespace blink {
@@ -194,6 +195,9 @@ class MODULES_EXPORT IDBDatabase final
// Maintain the isolate so that all externally allocated memory can be
// registered against it.
v8::Isolate* isolate_;
+
+ FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle
+ feature_handle_for_scheduler_;
};
} // namespace blink
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 1f863f883ec..a6b4645ea31 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
@@ -6,7 +6,6 @@
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h"
@@ -21,61 +20,6 @@ const char kTransparentClassName[] = "transparent";
} // anonymous namespace
-// Listens for the 'transitionend' event.
-class MediaControlPanelElement::TransitionEventListener final
- : public NativeEventListener {
- public:
- using Callback = base::RepeatingCallback<void()>;
-
- // |element| is the element to listen for the 'transitionend' event on.
- // |callback| is the callback to call when the event is handled.
- explicit TransitionEventListener(Element* element, Callback callback)
- : callback_(callback), element_(element) {
- DCHECK(callback_);
- DCHECK(element_);
- }
-
- void Attach() {
- DCHECK(!attached_);
- attached_ = true;
-
- element_->addEventListener(event_type_names::kTransitionend, this, false);
- }
-
- void Detach() {
- DCHECK(attached_);
- attached_ = false;
-
- element_->removeEventListener(event_type_names::kTransitionend, this,
- false);
- }
-
- bool IsAttached() const { return attached_; }
-
- void Invoke(ExecutionContext* context, Event* event) override {
- if (event->target() != element_)
- return;
-
- if (event->type() == event_type_names::kTransitionend) {
- callback_.Run();
- return;
- }
-
- NOTREACHED();
- }
-
- void Trace(blink::Visitor* visitor) override {
- NativeEventListener::Trace(visitor);
- visitor->Trace(element_);
- }
-
- private:
- bool attached_ = false;
-
- Callback callback_;
- Member<Element> element_;
-};
-
MediaControlPanelElement::MediaControlPanelElement(
MediaControlsImpl& media_controls)
: MediaControlDivElement(media_controls), event_listener_(nullptr) {
@@ -148,11 +92,11 @@ bool MediaControlPanelElement::EventListenerIsAttachedForTest() const {
void MediaControlPanelElement::EnsureTransitionEventListener() {
// Create the event listener if it doesn't exist.
if (!event_listener_) {
- event_listener_ =
- MakeGarbageCollected<MediaControlPanelElement::TransitionEventListener>(
- this, WTF::BindRepeating(
- &MediaControlPanelElement::HandleTransitionEndEvent,
- WrapWeakPersistent(this)));
+ event_listener_ = MakeGarbageCollected<
+ MediaControlsSharedHelpers::TransitionEventListener>(
+ this,
+ WTF::BindRepeating(&MediaControlPanelElement::HandleTransitionEndEvent,
+ WrapWeakPersistent(this)));
}
// Attach the event listener if we are not attached.
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 ccb43bbb8fa..a010ba1d627 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
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_ELEMENTS_MEDIA_CONTROL_PANEL_ELEMENT_H_
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_div_element.h"
+#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h"
#include "third_party/blink/renderer/modules/modules_export.h"
namespace blink {
@@ -40,8 +41,6 @@ class MODULES_EXPORT MediaControlPanelElement final
bool EventListenerIsAttachedForTest() const;
private:
- class TransitionEventListener;
-
void EnsureTransitionEventListener();
void DetachTransitionEventListener();
@@ -55,7 +54,7 @@ class MODULES_EXPORT MediaControlPanelElement final
bool opaque_ = true;
bool keep_displayed_for_accessibility_ = false;
- Member<TransitionEventListener> event_listener_;
+ Member<MediaControlsSharedHelpers::TransitionEventListener> event_listener_;
};
} // namespace blink
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 0d3796f252d..00b9f48e9c9 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
@@ -87,6 +87,7 @@
#include "third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_resource_loader.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_rotate_to_fullscreen_delegate.h"
+#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h"
#include "third_party/blink/renderer/modules/remoteplayback/remote_playback.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -154,33 +155,6 @@ constexpr WTF::TimeDelta kTimeToShowVolumeSliderTest =
// The number of seconds to jump when double tapping.
constexpr int kNumberOfSecondsToJump = 10;
-bool ShouldShowFullscreenButton(const HTMLMediaElement& media_element) {
- // Unconditionally allow the user to exit fullscreen if we are in it
- // now. Especially on android, when we might not yet know if
- // fullscreen is supported, we sometimes guess incorrectly and show
- // the button earlier, and we don't want to remove it here if the
- // user chose to enter fullscreen. crbug.com/500732 .
- if (media_element.IsFullscreen())
- return true;
-
- if (!media_element.IsHTMLVideoElement())
- return false;
-
- if (!media_element.HasVideo())
- return false;
-
- if (!Fullscreen::FullscreenEnabled(media_element.GetDocument()))
- return false;
-
- if (media_element.ControlsListInternal()->ShouldHideFullscreen()) {
- UseCounter::Count(media_element.GetDocument(),
- WebFeature::kHTMLMediaElementControlsListNoFullscreen);
- return false;
- }
-
- return true;
-}
-
void MaybeParserAppendChild(Element* parent, Element* child) {
DCHECK(parent);
if (child)
@@ -967,12 +941,14 @@ void MediaControlsImpl::OnControlsListUpdated() {
if (IsModern() && ShouldShowVideoControls()) {
fullscreen_button_->SetIsWanted(true);
- fullscreen_button_->setAttribute(html_names::kDisabledAttr,
- ShouldShowFullscreenButton(MediaElement())
- ? AtomicString()
- : AtomicString(""));
+ fullscreen_button_->setAttribute(
+ html_names::kDisabledAttr,
+ MediaControlsSharedHelpers::ShouldShowFullscreenButton(MediaElement())
+ ? AtomicString()
+ : AtomicString(""));
} else {
- fullscreen_button_->SetIsWanted(ShouldShowFullscreenButton(MediaElement()));
+ fullscreen_button_->SetIsWanted(
+ MediaControlsSharedHelpers::ShouldShowFullscreenButton(MediaElement()));
fullscreen_button_->removeAttribute(html_names::kDisabledAttr);
}
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 33b76717e28..92cc944b9d3 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
@@ -5,7 +5,12 @@
#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h"
#include <cmath>
+#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-shared.h"
+#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/frame/use_counter.h"
+#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
+#include "third_party/blink/renderer/core/html/media/html_media_element_controls_list.h"
#include "third_party/blink/renderer/core/html/time_ranges.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -17,6 +22,54 @@ const double kCurrentTimeBufferedDelta = 1.0;
namespace blink {
+// |element| is the element to listen for the 'transitionend' event on.
+// |callback| is the callback to call when the event is handled.
+MediaControlsSharedHelpers::TransitionEventListener::TransitionEventListener(
+ Element* element,
+ Callback callback)
+ : callback_(callback), element_(element) {
+ DCHECK(callback_);
+ DCHECK(element_);
+}
+
+void MediaControlsSharedHelpers::TransitionEventListener::Attach() {
+ DCHECK(!attached_);
+ attached_ = true;
+
+ element_->addEventListener(event_type_names::kTransitionend, this, false);
+}
+
+void MediaControlsSharedHelpers::TransitionEventListener::Detach() {
+ DCHECK(attached_);
+ attached_ = false;
+
+ element_->removeEventListener(event_type_names::kTransitionend, this, false);
+}
+
+bool MediaControlsSharedHelpers::TransitionEventListener::IsAttached() const {
+ return attached_;
+}
+
+void MediaControlsSharedHelpers::TransitionEventListener::Invoke(
+ ExecutionContext* context,
+ Event* event) {
+ if (event->target() != element_)
+ return;
+
+ if (event->type() == event_type_names::kTransitionend) {
+ callback_.Run();
+ return;
+ }
+
+ NOTREACHED();
+}
+
+void MediaControlsSharedHelpers::TransitionEventListener::Trace(
+ blink::Visitor* visitor) {
+ NativeEventListener::Trace(visitor);
+ visitor->Trace(element_);
+}
+
base::Optional<unsigned>
MediaControlsSharedHelpers::GetCurrentBufferedTimeRange(
HTMLMediaElement& media_element) {
@@ -80,4 +133,32 @@ String MediaControlsSharedHelpers::FormatTime(double time) {
return String::Format("%s%d:%02d", negative_sign, minutes, seconds);
}
+bool MediaControlsSharedHelpers::ShouldShowFullscreenButton(
+ const HTMLMediaElement& media_element) {
+ // Unconditionally allow the user to exit fullscreen if we are in it
+ // now. Especially on android, when we might not yet know if
+ // fullscreen is supported, we sometimes guess incorrectly and show
+ // the button earlier, and we don't want to remove it here if the
+ // user chose to enter fullscreen. crbug.com/500732 .
+ if (media_element.IsFullscreen())
+ return true;
+
+ if (!media_element.IsHTMLVideoElement())
+ return false;
+
+ if (!media_element.HasVideo())
+ return false;
+
+ if (!Fullscreen::FullscreenEnabled(media_element.GetDocument()))
+ return false;
+
+ if (media_element.ControlsListInternal()->ShouldHideFullscreen()) {
+ UseCounter::Count(media_element.GetDocument(),
+ WebFeature::kHTMLMediaElementControlsListNoFullscreen);
+ return false;
+ }
+
+ return true;
+}
+
} // namespace blink
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 daf14b42ec2..4920feffe5c 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
@@ -5,22 +5,43 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_MEDIA_CONTROLS_SHARED_HELPER_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_MEDIA_CONTROLS_SHARED_HELPER_H_
+#include "base/callback.h"
#include "base/optional.h"
+#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
class HTMLMediaElement;
+class Element;
class MediaControlsSharedHelpers final {
STATIC_ONLY(MediaControlsSharedHelpers);
public:
+ class TransitionEventListener final : public NativeEventListener {
+ public:
+ using Callback = base::RepeatingCallback<void()>;
+
+ explicit TransitionEventListener(Element* element, Callback callback);
+ void Attach();
+ void Detach();
+ bool IsAttached() const;
+ void Invoke(ExecutionContext* context, Event* event) override;
+ void Trace(blink::Visitor* visitor) override;
+
+ private:
+ bool attached_ = false;
+ Callback callback_;
+ Member<Element> element_;
+ };
+
static base::Optional<unsigned> GetCurrentBufferedTimeRange(
HTMLMediaElement& media_element);
static String FormatTime(double time);
+ static bool ShouldShowFullscreenButton(const HTMLMediaElement& media_element);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/resources/legacyMediaControls.css b/chromium/third_party/blink/renderer/modules/media_controls/resources/legacyMediaControls.css
index 47780421809..a6ace7d559d 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/resources/legacyMediaControls.css
+++ b/chromium/third_party/blink/renderer/modules/media_controls/resources/legacyMediaControls.css
@@ -638,6 +638,7 @@ video::cue {
display: inline;
background-color: rgba(0, 0, 0, 0.8);
+ padding: 2px 2px;
}
video::-webkit-media-text-track-region {
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css b/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
index 037d667364d..cf64ba3f173 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
+++ b/chromium/third_party/blink/renderer/modules/media_controls/resources/modernMediaControls.css
@@ -1169,6 +1169,7 @@ video::cue {
display: inline;
background-color: rgba(0, 0, 0, 0.8);
+ padding: 2px 2px;
}
video::-webkit-media-text-track-region {
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc
index 4542382a807..d70899258eb 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc
@@ -4,8 +4,10 @@
#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h"
+#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h"
#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
@@ -25,6 +27,14 @@ MediaControlsTouchlessBottomContainerElement::
ParserAppendChild(time_display_element_);
ParserAppendChild(timeline_element_);
+
+ event_listener_ =
+ MakeGarbageCollected<MediaControlsSharedHelpers::TransitionEventListener>(
+ this,
+ WTF::BindRepeating(&MediaControlsTouchlessBottomContainerElement::
+ HandleTransitionEndEvent,
+ WrapWeakPersistent(this)));
+ event_listener_->Attach();
}
LayoutObject*
@@ -37,10 +47,30 @@ MediaControlsTouchlessBottomContainerElement::TimeDisplayLayoutObject() {
return time_display_element_->GetLayoutObject();
}
+void MediaControlsTouchlessBottomContainerElement::MakeOpaque(
+ bool should_hide) {
+ SetDisplayed(true);
+ MediaElement().MediaControlsDidBecomeVisible();
+ MediaControlsTouchlessElement::MakeOpaque(should_hide);
+}
+
+void MediaControlsTouchlessBottomContainerElement::HandleTransitionEndEvent() {
+ SetDisplayed(false);
+}
+
+void MediaControlsTouchlessBottomContainerElement::SetDisplayed(
+ bool displayed) {
+ if (displayed)
+ RemoveInlineStyleProperty(CSSPropertyID::kDisplay);
+ else
+ SetInlineStyleProperty(CSSPropertyID::kDisplay, CSSValueID::kNone);
+}
+
void MediaControlsTouchlessBottomContainerElement::Trace(
blink::Visitor* visitor) {
visitor->Trace(timeline_element_);
visitor->Trace(time_display_element_);
+ visitor->Trace(event_listener_);
MediaControlsTouchlessElement::Trace(visitor);
}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h
index 34d04de3191..e23acc51a24 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h
@@ -5,6 +5,7 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_BOTTOM_CONTAINER_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_BOTTOM_CONTAINER_ELEMENT_H_
+#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h"
#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h"
namespace blink {
@@ -20,11 +21,17 @@ class MediaControlsTouchlessBottomContainerElement
MediaControlsTouchlessBottomContainerElement(MediaControlsTouchlessImpl&);
LayoutObject* TimelineLayoutObject();
LayoutObject* TimeDisplayLayoutObject();
+
+ void MakeOpaque(bool);
void Trace(blink::Visitor*) override;
private:
+ void HandleTransitionEndEvent();
+ void SetDisplayed(bool);
+
Member<MediaControlsTouchlessTimelineElement> timeline_element_;
Member<MediaControlsTouchlessTimeDisplayElement> time_display_element_;
+ Member<MediaControlsSharedHelpers::TransitionEventListener> event_listener_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc
index cbbac960438..4c2c2137a2d 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc
@@ -17,6 +17,7 @@ namespace {
constexpr WTF::TimeDelta kTimeToHideControl = TimeDelta::FromMilliseconds(3000);
const char kTransparentCSSClass[] = "transparent";
+const char kTransparentImmediateCSSClass[] = "transparent-immediate";
} // namespace
@@ -34,7 +35,7 @@ HTMLMediaElement& MediaControlsTouchlessElement::MediaElement() const {
void MediaControlsTouchlessElement::MakeOpaque(bool should_hide) {
EnsureHideControlTimer();
- classList().Remove(kTransparentCSSClass);
+ removeAttribute("class");
if (hide_control_timer_->IsActive())
StopHideControlTimer();
@@ -43,8 +44,9 @@ void MediaControlsTouchlessElement::MakeOpaque(bool should_hide) {
StartHideControlTimer();
}
-void MediaControlsTouchlessElement::MakeTransparent() {
- classList().Add(kTransparentCSSClass);
+void MediaControlsTouchlessElement::MakeTransparent(bool hide_immediate) {
+ classList().Add(hide_immediate ? kTransparentImmediateCSSClass
+ : kTransparentCSSClass);
}
void MediaControlsTouchlessElement::EnsureHideControlTimer() {
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h
index b43c44d21db..f5463bbf466 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h
@@ -27,12 +27,13 @@ class MediaControlsTouchlessElement
void Trace(blink::Visitor* visitor) override;
void MakeOpaque(bool /** True if control should hide after timer fired */);
- void MakeTransparent();
+ void MakeTransparent(bool = false /** True if hide immediately */);
// Non-touch media event listener observer implementation.
void OnFocusIn() override {}
void OnTimeUpdate() override {}
void OnDurationChange() override {}
+ void OnSeeking() override {}
void OnLoadingProgress() override {}
void OnPlay() override {}
void OnPause() override {}
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc
index 5e008b0b004..7ac1f447124 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc
@@ -8,6 +8,8 @@
#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.h"
#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h"
+#include "third_party/blink/renderer/platform/text/platform_locale.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
@@ -39,6 +41,14 @@ MediaControlsTouchlessOverlayElement::MediaControlsTouchlessOverlayElement(
ParserAppendChild(play_button);
ParserAppendChild(seek_forward_button);
ParserAppendChild(volume_down_button);
+
+ StringBuilder aria_label;
+ aria_label.Append(
+ GetLocale().QueryString(WebLocalizedString::kAXMediaTouchLessSeekAction));
+ aria_label.Append(" ");
+ aria_label.Append(GetLocale().QueryString(
+ WebLocalizedString::kAXMediaTouchLessVolumeAction));
+ setAttribute(html_names::kAriaLabelAttr, aria_label.ToAtomicString());
}
void MediaControlsTouchlessOverlayElement::Trace(blink::Visitor* visitor) {
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc
index 261f52bb2d8..5c6db6bfa01 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h"
#include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h"
+#include "third_party/blink/renderer/platform/text/platform_locale.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
namespace blink {
@@ -27,6 +28,11 @@ void MediaControlsTouchlessTimeDisplayElement::OnTimeUpdate() {
UpdateTimeDisplay();
}
+void MediaControlsTouchlessTimeDisplayElement::OnSeeking() {
+ current_time_ = MediaElement().currentTime();
+ UpdateTimeDisplay();
+}
+
void MediaControlsTouchlessTimeDisplayElement::OnDurationChange() {
duration_ = MediaElement().duration();
UpdateTimeDisplay();
@@ -42,6 +48,16 @@ void MediaControlsTouchlessTimeDisplayElement::UpdateTimeDisplay() {
builder.Append(" / ");
builder.Append(MediaControlsSharedHelpers::FormatTime(duration_));
setInnerText(builder.ToAtomicString(), ASSERT_NO_EXCEPTION);
+
+ StringBuilder aria_label;
+ aria_label.Append(GetLocale().QueryString(
+ WebLocalizedString::kAXMediaCurrentTimeDisplay,
+ MediaControlsSharedHelpers::FormatTime(current_time_)));
+ aria_label.Append(" ");
+ aria_label.Append(GetLocale().QueryString(
+ WebLocalizedString::kAXMediaTimeRemainingDisplay,
+ MediaControlsSharedHelpers::FormatTime(duration_)));
+ setAttribute(html_names::kAriaLabelAttr, aria_label.ToAtomicString());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h
index 6a8455a559e..0134b091c4c 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h
@@ -18,6 +18,7 @@ class MediaControlsTouchlessTimeDisplayElement
// MediaControlsTouchlessMediaEventListenerObserver overrides
void OnTimeUpdate() override;
+ void OnSeeking() override;
void OnDurationChange() override;
void Trace(blink::Visitor* visitor) override;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc
index 57bd4a639c8..413ae227057 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc
@@ -34,6 +34,11 @@ void MediaControlsTouchlessTimelineElement::OnTimeUpdate() {
UpdateBars();
}
+void MediaControlsTouchlessTimelineElement::OnSeeking() {
+ current_time_ = MediaElement().currentTime();
+ UpdateBars();
+}
+
void MediaControlsTouchlessTimelineElement::OnDurationChange() {
duration_ = MediaElement().duration();
UpdateBars();
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h
index b1416ce9ae2..c8a17e7ac55 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h
@@ -17,6 +17,7 @@ class MediaControlsTouchlessTimelineElement
// MediaControlsTouchlessMediaEventListenerObserver overrides
void OnTimeUpdate() override;
+ void OnSeeking() override;
void OnDurationChange() override;
void OnLoadingProgress() override;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc
index 7a2c2a8c129..fd6b6b7719a 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc
@@ -23,6 +23,7 @@
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h"
+#include "third_party/blink/renderer/modules/media_controls/media_controls_shared_helper.h"
#include "third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h"
#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h"
#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.h"
@@ -77,24 +78,24 @@ MediaControlsTouchlessImpl* MediaControlsTouchlessImpl::Create(
ShadowRoot& shadow_root) {
MediaControlsTouchlessImpl* controls =
MakeGarbageCollected<MediaControlsTouchlessImpl>(media_element);
- controls->overlay_ =
- MakeGarbageCollected<MediaControlsTouchlessOverlayElement>(*controls);
controls->bottom_container_ =
MakeGarbageCollected<MediaControlsTouchlessBottomContainerElement>(
*controls);
+ controls->overlay_ =
+ MakeGarbageCollected<MediaControlsTouchlessOverlayElement>(*controls);
controls->volume_container_ =
MakeGarbageCollected<MediaControlsTouchlessVolumeContainerElement>(
*controls);
- controls->ParserAppendChild(controls->overlay_);
controls->ParserAppendChild(controls->bottom_container_);
+ controls->ParserAppendChild(controls->overlay_);
controls->ParserAppendChild(controls->volume_container_);
// Controls start hidden.
- controls->overlay_->MakeTransparent();
- controls->volume_container_->MakeTransparent();
if (!media_element.paused())
controls->bottom_container_->MakeTransparent();
+ controls->overlay_->MakeTransparent();
+ controls->volume_container_->MakeTransparent();
if (RuntimeEnabledFeatures::VideoFullscreenOrientationLockEnabled() &&
media_element.IsHTMLVideoElement()) {
@@ -166,8 +167,8 @@ MediaControlsTouchlessImpl::MediaEventListener() const {
void MediaControlsTouchlessImpl::OnFocusIn() {
if (MediaElement().ShouldShowControls()) {
- overlay_->MakeOpaque(true);
bottom_container_->MakeOpaque(!MediaElement().paused());
+ overlay_->MakeOpaque(true);
}
}
@@ -191,7 +192,7 @@ void MediaControlsTouchlessImpl::OnKeyDown(KeyboardEvent* event) {
bool handled = true;
switch (event->keyCode()) {
case VKEY_RETURN:
- volume_container_->MakeTransparent();
+ volume_container_->MakeTransparent(true);
overlay_->MakeOpaque(true);
MediaElement().TogglePlayState();
break;
@@ -270,9 +271,8 @@ void MediaControlsTouchlessImpl::ShowContextMenu() {
WTF::Vector<mojom::blink::MenuItem> menu_items;
- // TODO(jazzhsu, https://crbug.com/942577): Populate fullscreen list entry
- // properly.
- menu_items.push_back(mojom::blink::MenuItem::FULLSCREEN);
+ if (MediaControlsSharedHelpers::ShouldShowFullscreenButton(MediaElement()))
+ menu_items.push_back(mojom::blink::MenuItem::FULLSCREEN);
if (MediaElement().HasAudio())
menu_items.push_back(mojom::blink::MenuItem::MUTE);
@@ -402,14 +402,14 @@ WebScreenOrientationType MediaControlsTouchlessImpl::GetOrientation() {
void MediaControlsTouchlessImpl::HandleTopButtonPress() {
MaybeChangeVolume(kVolumeToChangeForTouchless);
volume_container_->UpdateVolume();
- overlay_->MakeTransparent();
+ overlay_->MakeTransparent(true);
volume_container_->MakeOpaque(true);
}
void MediaControlsTouchlessImpl::HandleBottomButtonPress() {
MaybeChangeVolume(kVolumeToChangeForTouchless * -1);
volume_container_->UpdateVolume();
- overlay_->MakeTransparent();
+ overlay_->MakeTransparent(true);
volume_container_->MakeOpaque(true);
}
@@ -448,9 +448,13 @@ void MediaControlsTouchlessImpl::Trace(blink::Visitor* visitor) {
HTMLDivElement::Trace(visitor);
}
-void MediaControlsTouchlessImpl::OnMediaMenuResultForTest(
- mojom::blink::MenuResponsePtr response) {
- OnMediaMenuResult(std::move(response));
+void MediaControlsTouchlessImpl::SetMediaControlsMenuHostForTesting(
+ mojom::blink::MediaControlsMenuHostPtr menu_host) {
+ media_controls_host_ = std::move(menu_host);
+}
+
+void MediaControlsTouchlessImpl::MenuHostFlushForTesting() {
+ media_controls_host_.FlushForTesting();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h
index 14fc333e7fa..b3d86bd5102 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h
@@ -56,6 +56,7 @@ class MODULES_EXPORT MediaControlsTouchlessImpl final
void OnFocusIn() override;
void OnTimeUpdate() override {}
void OnDurationChange() override {}
+ void OnSeeking() override {}
void OnLoadingProgress() override {}
void OnPlay() override;
void OnPause() override;
@@ -70,7 +71,9 @@ class MODULES_EXPORT MediaControlsTouchlessImpl final
MediaControlsTouchlessMediaEventListener& MediaEventListener() const;
// Test functions
- void OnMediaMenuResultForTest(mojom::blink::MenuResponsePtr);
+ void SetMediaControlsMenuHostForTesting(
+ mojom::blink::MediaControlsMenuHostPtr);
+ void MenuHostFlushForTesting();
void Trace(blink::Visitor*) override;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc
index 9215321dace..01576a0d722 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc
@@ -8,21 +8,26 @@
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/media_controls/touchless/media_controls.mojom-blink.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/dom/dom_token_list.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/element_traversal.h"
#include "third_party/blink/renderer/core/events/keyboard_event.h"
#include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
+#include "third_party/blink/renderer/core/html/media/html_media_element_controls_list.h"
#include "third_party/blink/renderer/core/html/media/html_media_test_helper.h"
#include "third_party/blink/renderer/core/html/media/html_video_element.h"
#include "third_party/blink/renderer/core/html/time_ranges.h"
#include "third_party/blink/renderer/core/html/track/text_track.h"
#include "third_party/blink/renderer/core/html/track/text_track_list.h"
+#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/core/testing/page_test_base.h"
+#include "third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h"
#include "third_party/blink/renderer/platform/keyboard_codes.h"
#include "third_party/blink/renderer/platform/testing/empty_web_media_player.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -31,14 +36,27 @@ namespace blink {
namespace {
+const char kTextTracksOffString[] = "Off";
+
+class LocalePlatformSupport : public TestingPlatformSupport {
+ public:
+ WebString QueryLocalizedString(WebLocalizedString::Name name) override {
+ if (name == WebLocalizedString::kTextTracksOff)
+ return kTextTracksOffString;
+ return TestingPlatformSupport::QueryLocalizedString(name);
+ }
+};
+
class MockWebMediaPlayerForTouchlessImpl : public EmptyWebMediaPlayer {
public:
WebTimeRanges Seekable() const override { return seekable_; }
bool HasVideo() const override { return true; }
+ bool HasAudio() const override { return has_audio_; }
WebTimeRanges Buffered() const override { return buffered_; }
WebTimeRanges buffered_;
WebTimeRanges seekable_;
+ bool has_audio_ = false;
};
class MockChromeClientForTouchlessImpl : public EmptyChromeClient {
@@ -52,6 +70,14 @@ class MockChromeClientForTouchlessImpl : public EmptyChromeClient {
return screen_info;
}
+ void EnterFullscreen(LocalFrame& frame, const FullscreenOptions*) final {
+ Fullscreen::DidEnterFullscreen(*frame.GetDocument());
+ }
+
+ void ExitFullscreen(LocalFrame& frame) final {
+ Fullscreen::DidExitFullscreen(*frame.GetDocument());
+ }
+
void SetOrientation(WebScreenOrientationType orientation_type) {
orientation_ = orientation_type;
}
@@ -66,6 +92,7 @@ class MediaControlsTouchlessImplTest : public PageTestBase {
void InitializePage() {
Page::PageClients clients;
+
FillWithEmptyClients(clients);
chrome_client_ = MakeGarbageCollected<MockChromeClientForTouchlessImpl>();
clients.chrome_client = chrome_client_;
@@ -78,6 +105,11 @@ class MediaControlsTouchlessImplTest : public PageTestBase {
ToHTMLVideoElement(*GetDocument().QuerySelector("video"));
media_controls_ =
static_cast<MediaControlsTouchlessImpl*>(video.GetMediaControls());
+
+ test_media_controls_host_ = std::make_unique<TestMediaControlsMenuHost>();
+
+ media_controls_->SetMediaControlsMenuHostForTesting(
+ test_media_controls_host_->CreateMediaControlsMenuHostPtr());
}
MediaControlsTouchlessImpl& MediaControls() { return *media_controls_; }
@@ -88,6 +120,10 @@ class MediaControlsTouchlessImplTest : public PageTestBase {
MediaElement().GetWebMediaPlayer());
}
+ TestMenuHostArgList& GetMenuHostArgList() {
+ return test_media_controls_host_->GetMenuHostArgList();
+ }
+
void SimulateKeydownEvent(Element& element, int key_code) {
KeyboardEventInit* keyboard_event_init = KeyboardEventInit::Create();
keyboard_event_init->setKeyCode(key_code);
@@ -111,9 +147,20 @@ class MediaControlsTouchlessImplTest : public PageTestBase {
}
bool IsControlsVisible(Element* element) {
- return !element->classList().contains("transparent");
+ return !element->classList().contains("transparent") &&
+ !element->classList().contains("transparent-immediate");
}
+ bool IsElementDisplayed(Element* element) {
+ if (!element->InlineStyle())
+ return true;
+
+ return element->InlineStyle()->GetPropertyValue(CSSPropertyID::kDisplay) !=
+ "none";
+ }
+
+ void SetHasAudio(bool has_audio) { WebMediaPlayer()->has_audio_ = has_audio; }
+
Element* GetControlByShadowPseudoId(const char* shadow_pseudo_id) {
for (Element& element : ElementTraversal::DescendantsOf(MediaControls())) {
if (element.ShadowPseudoId() == shadow_pseudo_id)
@@ -126,12 +173,15 @@ class MediaControlsTouchlessImplTest : public PageTestBase {
chrome_client_->SetOrientation(orientation_type);
}
- void SimulateClickOnMenuItem(mojom::blink::MenuItem menu_item,
- int track_index) {
- mojom::blink::MenuResponsePtr response(mojom::blink::MenuResponse::New());
- response->clicked = menu_item;
- response->track_index = track_index;
- media_controls_->OnMediaMenuResultForTest(std::move(response));
+ void SetMenuResponse(mojom::blink::MenuItem menu_item, int track_index = -1) {
+ test_media_controls_host_->SetMenuResponse(menu_item, track_index);
+ }
+
+ void SetMenuResponseAndShowMenu(mojom::blink::MenuItem menu_item,
+ int track_index = -1) {
+ SetMenuResponse(menu_item, track_index);
+ MediaControls().ShowContextMenu();
+ MediaControls().MenuHostFlushForTesting();
}
void CheckControlKeys(int seek_forward_key,
@@ -161,6 +211,7 @@ class MediaControlsTouchlessImplTest : public PageTestBase {
private:
Persistent<MediaControlsTouchlessImpl> media_controls_;
Persistent<MockChromeClientForTouchlessImpl> chrome_client_;
+ std::unique_ptr<TestMediaControlsMenuHost> test_media_controls_host_;
};
class MediaControlsTouchlessImplTestWithMockScheduler
@@ -283,6 +334,14 @@ TEST_F(MediaControlsTouchlessImplTest, ProgressBar) {
EXPECT_DOUBLE_EQ(buffered / duration, loaded_bar_width / timeline_width);
EXPECT_DOUBLE_EQ(current_time / buffered,
progress_bar_width / loaded_bar_width);
+
+ // Seek event should trigger a UI update as well.
+ SetBufferedRange(0);
+ MediaElement().setCurrentTime(0);
+ MediaElement().DispatchEvent(*Event::Create(event_type_names::kSeeking));
+
+ EXPECT_DOUBLE_EQ(progress_bar->getBoundingClientRect()->width(), 0);
+ EXPECT_DOUBLE_EQ(loaded_bar->getBoundingClientRect()->width(), 0);
}
TEST_F(MediaControlsTouchlessImplTest, TimeDisplay) {
@@ -325,47 +384,70 @@ TEST_F(MediaControlsTouchlessImplTest, VolumeDisplayTest) {
volume_bar_height / volume_bar_background_height, error);
}
-/** (jazzhsu@) TODO: Add mojom binding test and fix the following test.
-TEST_F(MediaControlsTouchlessImplTest, ContextMenuTest) {
- // Fullscreen buttom test.
- EXPECT_FALSE(MediaElement().IsFullscreen());
- SimulateClickOnMenuItem(mojom::blink::MenuItem::FULLSCREEN, -1);
+TEST_F(MediaControlsTouchlessImplTest, ContextMenuMojomTest) {
+ ScopedTestingPlatformSupport<LocalePlatformSupport> support;
+
+ MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4");
+ std::unique_ptr<UserGestureIndicator> user_gesture_scope =
+ LocalFrame::NotifyUserActivation(GetDocument().GetFrame(),
+ UserGestureToken::kNewGesture);
test::RunPendingTasks();
+
+ KeyboardEventInit* keyboard_event_init = KeyboardEventInit::Create();
+ keyboard_event_init->setKey("SoftRight");
+ Event* keyboard_event =
+ MakeGarbageCollected<KeyboardEvent>("keydown", keyboard_event_init);
+
+ // Test fullscreen function.
+ SetMenuResponse(mojom::blink::MenuItem::FULLSCREEN);
+ MediaElement().DispatchEvent(*keyboard_event);
+ MediaControls().MenuHostFlushForTesting();
+ test::RunPendingTasks();
+
+ TestMenuHostArgList& arg_list = GetMenuHostArgList();
+ EXPECT_EQ((int)arg_list.menu_items.size(), 2);
+ EXPECT_EQ(arg_list.menu_items[0], mojom::blink::MenuItem::FULLSCREEN);
+ EXPECT_EQ(arg_list.menu_items[1], mojom::blink::MenuItem::DOWNLOAD);
+ EXPECT_FALSE(arg_list.video_state->is_fullscreen);
EXPECT_TRUE(MediaElement().IsFullscreen());
- SimulateClickOnMenuItem(mojom::blink::MenuItem::FULLSCREEN, -1);
+
+ SetMenuResponseAndShowMenu(mojom::blink::MenuItem::FULLSCREEN);
test::RunPendingTasks();
+
+ EXPECT_TRUE(arg_list.video_state->is_fullscreen);
EXPECT_FALSE(MediaElement().IsFullscreen());
- // Mute buttom test.
- EXPECT_FALSE(MediaElement().muted());
- SimulateClickOnMenuItem(mojom::blink::MenuItem::MUTE, -1);
+ // Disable download and fullscreen, and show mute option.
+ MediaElement().ControlsListInternal()->Add("nofullscreen");
+ MediaElement().GetDocument().GetSettings()->SetHideDownloadUI(true);
+ SetHasAudio(true);
+
+ SetMenuResponseAndShowMenu(mojom::blink::MenuItem::MUTE);
+
+ EXPECT_EQ((int)arg_list.menu_items.size(), 1);
+ EXPECT_EQ(arg_list.menu_items[0], mojom::blink::MenuItem::MUTE);
+ EXPECT_FALSE(arg_list.video_state->is_muted);
EXPECT_TRUE(MediaElement().muted());
- SimulateClickOnMenuItem(mojom::blink::MenuItem::MUTE, -1);
+
+ SetMenuResponseAndShowMenu(mojom::blink::MenuItem::MUTE);
+
+ EXPECT_TRUE(arg_list.video_state->is_muted);
EXPECT_FALSE(MediaElement().muted());
- // Text track test.
- TextTrack* track1 = MediaElement().addTextTrack("subtitle", "english",
- "en", NASSERT_NO_EXCEPTION);
- TextTrack* track2 = MediaElement().addTextTrack("subtitle", "english2",
- "en", ASSERT_NO_EXCEPTION);
- EXPECT_NE(track1->mode(), TextTrack::ShowingKeyword());
- EXPECT_NE(track2->mode(), TextTrack::ShowingKeyword());
-
- // Select first track.
- SimulateClickOnMenuItem(mojom::blink::MenuItem::CAPTIONS, 0);
- EXPECT_EQ(track1->mode(), TextTrack::ShowingKeyword());
-
- // Select second track.
- SimulateClickOnMenuItem(mojom::blink::MenuItem::CAPTIONS, 1);
- EXPECT_NE(track1->mode(), TextTrack::ShowingKeyword());
- EXPECT_EQ(track2->mode(), TextTrack::ShowingKeyword());
-
- // Turn all tracks off.
- SimulateClickOnMenuItem(mojom::blink::MenuItem::CAPTIONS, -1);
- EXPECT_NE(track1->mode(), TextTrack::ShowingKeyword());
- EXPECT_NE(track2->mode(), TextTrack::ShowingKeyword());
+ // Disable mute option and show text track option.
+ SetHasAudio(false);
+ TextTrack* track = MediaElement().addTextTrack("subtitles", "english", "en",
+ ASSERT_NO_EXCEPTION);
+ SetMenuResponseAndShowMenu(mojom::blink::MenuItem::CAPTIONS, 0);
+
+ EXPECT_EQ((int)arg_list.menu_items.size(), 1);
+ EXPECT_EQ(arg_list.menu_items[0], mojom::blink::MenuItem::CAPTIONS);
+ EXPECT_EQ(arg_list.text_tracks[1]->label, "english");
+ EXPECT_EQ(track->mode(), TextTrack::ShowingKeyword());
+
+ SetMenuResponseAndShowMenu(mojom::blink::MenuItem::CAPTIONS, -1);
+ EXPECT_NE(track->mode(), TextTrack::ShowingKeyword());
}
-*/
TEST_F(MediaControlsTouchlessImplTestWithMockScheduler,
MidOverlayHideTimerTest) {
@@ -408,6 +490,7 @@ TEST_F(MediaControlsTouchlessImplTestWithMockScheduler,
// Bottom container starts opaque since video is paused.
EXPECT_TRUE(IsControlsVisible(bottom_container));
+ EXPECT_TRUE(IsElementDisplayed(bottom_container));
MediaElement().Play();
platform()->RunForPeriodSeconds(3);
@@ -434,6 +517,11 @@ TEST_F(MediaControlsTouchlessImplTestWithMockScheduler,
platform()->RunForPeriodSeconds(3);
EXPECT_FALSE(IsControlsVisible(bottom_container));
+ // Display should be none after hide transition ends.
+ bottom_container->DispatchEvent(
+ *Event::Create(event_type_names::kTransitionend));
+ EXPECT_FALSE(IsElementDisplayed(bottom_container));
+
// Bottom container should show after pressing right/left arrow.
SimulateKeydownEvent(MediaElement(), VK_RIGHT);
EXPECT_TRUE(IsControlsVisible(bottom_container));
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.cc
index 315164554be..17fc5f17796 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.cc
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.cc
@@ -35,6 +35,7 @@ void MediaControlsTouchlessMediaEventListener::Attach() {
media_element_->addEventListener(event_type_names::kTimeupdate, this, false);
media_element_->addEventListener(event_type_names::kDurationchange, this,
false);
+ media_element_->addEventListener(event_type_names::kSeeking, this, false);
media_element_->addEventListener(event_type_names::kProgress, this, false);
media_element_->addEventListener(event_type_names::kPlay, this, false);
@@ -76,6 +77,11 @@ void MediaControlsTouchlessMediaEventListener::Invoke(
observer->OnDurationChange();
return;
}
+ if (event->type() == event_type_names::kSeeking) {
+ for (auto& observer : observers_)
+ observer->OnSeeking();
+ return;
+ }
if (event->type() == event_type_names::kProgress) {
for (auto& observer : observers_)
observer->OnLoadingProgress();
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h
index 1c297a9e47c..cf07510f775 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h
@@ -17,6 +17,7 @@ class MediaControlsTouchlessMediaEventListenerObserver
virtual void OnFocusIn() = 0;
virtual void OnTimeUpdate() = 0;
virtual void OnDurationChange() = 0;
+ virtual void OnSeeking() = 0;
virtual void OnLoadingProgress() = 0;
virtual void OnPlay() = 0;
virtual void OnPause() = 0;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css
index 1ef89f2a909..98516f3aa39 100644
--- a/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css
@@ -40,6 +40,10 @@ video::-internal-media-controls-touchless-overlay.transparent {
transition: opacity .5s;
}
+video::-internal-media-controls-touchless-overlay.transparent-immediate {
+ opacity: 0;
+}
+
video::-internal-media-controls-touchless-volume-up-button {
width: 30px;
height: 30px;
@@ -175,6 +179,10 @@ video::-internal-media-controls-touchless-volume-container.transparent {
transition: opacity .5s;
}
+video::-internal-media-controls-touchless-volume-container.transparent-immediate {
+ opacity: 0;
+}
+
video::-internal-media-controls-touchless-volume-bar-background {
width: 4px;
margin-left: 20px;
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc b/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc
new file mode 100644
index 00000000000..d8780771ab3
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.cc
@@ -0,0 +1,47 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h"
+
+namespace blink {
+
+mojom::blink::MediaControlsMenuHostPtr
+TestMediaControlsMenuHost::CreateMediaControlsMenuHostPtr() {
+ mojom::blink::MediaControlsMenuHostPtr ptr;
+ binding_.Bind(mojo::MakeRequest(&ptr));
+ return ptr;
+}
+
+void TestMediaControlsMenuHost::ShowMediaMenu(
+ const WTF::Vector<mojom::MenuItem>& menu_items,
+ mojom::blink::VideoStatePtr video_state,
+ base::Optional<WTF::Vector<mojom::blink::TextTrackMetadataPtr>> text_tracks,
+ ShowMediaMenuCallback callback) {
+ arg_list_.menu_items = WTF::Vector<mojom::MenuItem>(menu_items);
+
+ arg_list_.video_state = mojom::blink::VideoState::New();
+ arg_list_.video_state->is_fullscreen = video_state->is_fullscreen;
+ arg_list_.video_state->is_muted = video_state->is_muted;
+
+ arg_list_.text_tracks = WTF::Vector<mojom::blink::TextTrackMetadataPtr>(
+ std::move(text_tracks.value()));
+
+ std::move(callback).Run(std::move(response_));
+}
+
+TestMenuHostArgList& TestMediaControlsMenuHost::GetMenuHostArgList() {
+ return arg_list_;
+}
+
+void TestMediaControlsMenuHost::SetMenuResponse(
+ mojom::blink::MenuItem menu_item,
+ int track_index) {
+ if (response_.is_null())
+ response_ = mojom::blink::MenuResponse::New();
+
+ response_->clicked = menu_item;
+ response_->track_index = track_index;
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h b/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h
new file mode 100644
index 00000000000..4378945032f
--- /dev/null
+++ b/chromium/third_party/blink/renderer/modules/media_controls/touchless/test_media_controls_menu_host.h
@@ -0,0 +1,40 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_TEST_MEDIA_CONTROLS_MENU_HOST_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_TEST_MEDIA_CONTROLS_MENU_HOST_H_
+
+#include "mojo/public/cpp/bindings/binding.h"
+#include "third_party/blink/public/mojom/media_controls/touchless/media_controls.mojom-blink.h"
+
+namespace blink {
+
+struct TestMenuHostArgList {
+ WTF::Vector<mojom::MenuItem> menu_items;
+ mojom::blink::VideoStatePtr video_state;
+ WTF::Vector<mojom::blink::TextTrackMetadataPtr> text_tracks;
+};
+
+class TestMediaControlsMenuHost : public mojom::blink::MediaControlsMenuHost {
+ public:
+ mojom::blink::MediaControlsMenuHostPtr CreateMediaControlsMenuHostPtr();
+ void ShowMediaMenu(
+ const WTF::Vector<mojom::MenuItem>& menu_items,
+ mojom::blink::VideoStatePtr video_state,
+ base::Optional<WTF::Vector<mojom::blink::TextTrackMetadataPtr>>
+ text_tracks,
+ ShowMediaMenuCallback callback) override;
+
+ TestMenuHostArgList& GetMenuHostArgList();
+ void SetMenuResponse(mojom::blink::MenuItem menu_item, int track_index);
+
+ private:
+ mojo::Binding<mojom::blink::MediaControlsMenuHost> binding_{this};
+ TestMenuHostArgList arg_list_;
+ mojom::blink::MenuResponsePtr response_;
+};
+
+} // namespace blink
+
+#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_TEST_MEDIA_CONTROLS_MENU_HOST_H_
diff --git a/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/chromium/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index a84a1980eaa..9f3885137c6 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
@@ -2883,6 +2883,15 @@ void RTCPeerConnection::DidModifyTransceivers(
transceiver->receiver()->track()->Component()->Source()->SetReadyState(
MediaStreamSource::kReadyStateLive);
}
+
+ // Transceiver modifications can cause changes in the set of ICE
+ // transports, which may affect ICE transport state.
+ // Note - this must be done every time the set of ICE transports happens.
+ // At the moment this only happens in SLD/SRD, and this function is called
+ // whenever these functions complete.
+ if (sdp_semantics_ == webrtc::SdpSemantics::kUnifiedPlan) {
+ UpdateIceConnectionState();
+ }
}
void RTCPeerConnection::SetAssociatedMediaStreams(
diff --git a/chromium/third_party/blink/renderer/modules/permissions/permissions.cc b/chromium/third_party/blink/renderer/modules/permissions/permissions.cc
index 461d120524d..bee801ccead 100644
--- a/chromium/third_party/blink/renderer/modules/permissions/permissions.cc
+++ b/chromium/third_party/blink/renderer/modules/permissions/permissions.cc
@@ -25,6 +25,7 @@
#include "third_party/blink/renderer/modules/permissions/permission_status.h"
#include "third_party/blink/renderer/modules/permissions/permission_utils.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/blink/renderer/platform/wtf/wtf_size_t.h"
@@ -148,6 +149,44 @@ PermissionDescriptorPtr ParsePermission(ScriptState* script_state,
return nullptr;
}
+base::Optional<SchedulingPolicy::Feature> PermissionToSchedulingFeature(
+ PermissionName permission) {
+ switch (permission) {
+ case PermissionName::GEOLOCATION:
+ return SchedulingPolicy::Feature::kRequestedGeolocationPermission;
+ case PermissionName::NOTIFICATIONS:
+ return SchedulingPolicy::Feature::kRequestedNotificationsPermission;
+ case PermissionName::MIDI:
+ return SchedulingPolicy::Feature::kRequestedMIDIPermission;
+ case PermissionName::AUDIO_CAPTURE:
+ return SchedulingPolicy::Feature::kRequestedAudioCapturePermission;
+ case PermissionName::VIDEO_CAPTURE:
+ return SchedulingPolicy::Feature::kRequestedVideoCapturePermission;
+ case PermissionName::SENSORS:
+ return SchedulingPolicy::Feature::kRequestedSensorsPermission;
+ case PermissionName::BACKGROUND_SYNC:
+ case PermissionName::BACKGROUND_FETCH:
+ return SchedulingPolicy::Feature::kRequestedBackgroundWorkPermission;
+ default:
+ return base::nullopt;
+ }
+}
+
+void NotifySchedulerAboutPermissionRequest(ExecutionContext* context,
+ PermissionName permission) {
+ if (!context)
+ return;
+
+ base::Optional<SchedulingPolicy::Feature> feature =
+ PermissionToSchedulingFeature(permission);
+
+ if (!feature)
+ return;
+
+ context->GetScheduler()->RegisterStickyFeature(
+ feature.value(), {SchedulingPolicy::RecordMetricsForBackForwardCache()});
+}
+
} // anonymous namespace
ScriptPromise Permissions::query(ScriptState* script_state,
@@ -184,6 +223,8 @@ ScriptPromise Permissions::request(ScriptState* script_state,
ExecutionContext* context = ExecutionContext::From(script_state);
+ NotifySchedulerAboutPermissionRequest(context, descriptor->name);
+
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
@@ -229,6 +270,9 @@ ScriptPromise Permissions::requestAll(
Vector<PermissionDescriptorPtr> internal_permissions;
Vector<int> caller_index_to_internal_index;
caller_index_to_internal_index.resize(raw_permissions.size());
+
+ ExecutionContext* context = ExecutionContext::From(script_state);
+
for (wtf_size_t i = 0; i < raw_permissions.size(); ++i) {
const ScriptValue& raw_permission = raw_permissions[i];
@@ -237,6 +281,8 @@ ScriptPromise Permissions::requestAll(
if (exception_state.HadException())
return ScriptPromise();
+ NotifySchedulerAboutPermissionRequest(context, descriptor->name);
+
// Only append permissions types that are not already present in the vector.
wtf_size_t internal_index = kNotFound;
for (wtf_size_t j = 0; j < internal_permissions.size(); ++j) {
@@ -252,8 +298,6 @@ ScriptPromise Permissions::requestAll(
caller_index_to_internal_index[i] = internal_index;
}
- ExecutionContext* context = ExecutionContext::From(script_state);
-
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_forbidden_scope.h b/chromium/third_party/blink/renderer/platform/bindings/script_forbidden_scope.h
index 656083c7377..ae44c6d23d8 100644
--- a/chromium/third_party/blink/renderer/platform/bindings/script_forbidden_scope.h
+++ b/chromium/third_party/blink/renderer/platform/bindings/script_forbidden_scope.h
@@ -7,6 +7,7 @@
#include "base/auto_reset.h"
#include "base/macros.h"
+#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/stack_util.h"
@@ -41,7 +42,11 @@ class PLATFORM_EXPORT ScriptForbiddenScope final {
return GetMutableCounter() > 0;
}
- // DO NOT USE THESE FUNCTIONS FROM OUTSIDE OF THIS CLASS.
+ static void ThrowScriptForbiddenException(v8::Isolate* isolate) {
+ V8ThrowException::ThrowError(isolate, "Script execution is forbidden.");
+ }
+
+ private:
static void Enter() {
if (LIKELY(!WTF::MayNotBeMainThread())) {
++g_main_thread_counter_;
@@ -58,9 +63,11 @@ class PLATFORM_EXPORT ScriptForbiddenScope final {
}
}
- private:
static unsigned& GetMutableCounter();
static unsigned g_main_thread_counter_;
+
+ // V8GCController is exceptionally allowed to call Enter/Exit.
+ friend class V8GCController;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
index 48cf52efb0f..e4a7c0c96d1 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc
@@ -1058,16 +1058,23 @@ void GraphicsLayer::SetLayerState(const PropertyTreeState& layer_state,
SetPaintArtifactCompositorNeedsUpdate();
}
-void GraphicsLayer::SetContentsPropertyTreeState(
- const PropertyTreeState& layer_state) {
+void GraphicsLayer::SetContentsLayerState(const PropertyTreeState& layer_state,
+ const IntPoint& layer_offset) {
DCHECK(ContentsLayer());
- if (contents_property_tree_state_) {
- *contents_property_tree_state_ = layer_state;
+ if (contents_layer_state_) {
+ if (contents_layer_state_->state == layer_state &&
+ contents_layer_state_->offset == layer_offset)
+ return;
+ contents_layer_state_->state = layer_state;
+ contents_layer_state_->offset = layer_offset;
} else {
- contents_property_tree_state_ =
- std::make_unique<PropertyTreeState>(layer_state);
+ contents_layer_state_ =
+ std::make_unique<LayerState>(LayerState{layer_state, layer_offset});
}
+
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ SetPaintArtifactCompositorNeedsUpdate();
}
scoped_refptr<cc::DisplayItemList> GraphicsLayer::PaintContentsToDisplayList(
diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
index ced1a78d816..1c7f75af559 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
+++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h
@@ -232,6 +232,8 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
return const_cast<GraphicsLayer*>(this)->ContentsLayerIfRegistered();
}
+ const IntRect& ContentsRect() const { return contents_rect_; }
+
// For hosting this GraphicsLayer in a native layer hierarchy.
cc::PictureLayer* CcLayer() const;
@@ -294,16 +296,15 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
}
IntPoint GetOffsetFromTransformNode() const { return layer_state_->offset; }
- void SetContentsPropertyTreeState(const PropertyTreeState&);
+ void SetContentsLayerState(const PropertyTreeState&,
+ const IntPoint& layer_offset);
const PropertyTreeState& GetContentsPropertyTreeState() const {
- return contents_property_tree_state_ ? *contents_property_tree_state_
- : GetPropertyTreeState();
+ return contents_layer_state_ ? contents_layer_state_->state
+ : GetPropertyTreeState();
}
IntPoint GetContentsOffsetFromTransformNode() const {
- auto offset = contents_rect_.Location();
- if (layer_state_)
- offset = offset + GetOffsetFromTransformNode();
- return offset;
+ return contents_layer_state_ ? contents_layer_state_->offset
+ : GetOffsetFromTransformNode();
}
// Capture the last painted result into a PaintRecord. This GraphicsLayer
@@ -423,7 +424,7 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient,
IntPoint offset;
};
std::unique_ptr<LayerState> layer_state_;
- std::unique_ptr<PropertyTreeState> contents_property_tree_state_;
+ std::unique_ptr<LayerState> contents_layer_state_;
std::unique_ptr<RasterInvalidator> raster_invalidator_;
diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
index 17c24ba6149..c3d0a529526 100644
--- a/chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
+++ b/chromium/third_party/blink/renderer/platform/scheduler/common/scheduling_policy.cc
@@ -16,6 +16,8 @@ bool SchedulingPolicy::IsFeatureSticky(SchedulingPolicy::Feature feature) {
case Feature::kOutstandingNetworkRequest:
case Feature::kOutstandingIndexedDBTransaction:
case Feature::kHasScriptableFramesInMultipleTabs:
+ case Feature::kBroadcastChannel:
+ case Feature::kIndexedDBConnection:
return false;
case Feature::kMainResourceHasCacheControlNoStore:
case Feature::kMainResourceHasCacheControlNoCache:
@@ -30,6 +32,13 @@ bool SchedulingPolicy::IsFeatureSticky(SchedulingPolicy::Feature feature) {
case Feature::kContainsPlugins:
case Feature::kDocumentLoaded:
case Feature::kServiceWorkerControlledPage:
+ case Feature::kRequestedGeolocationPermission:
+ case Feature::kRequestedNotificationsPermission:
+ case Feature::kRequestedMIDIPermission:
+ case Feature::kRequestedAudioCapturePermission:
+ case Feature::kRequestedVideoCapturePermission:
+ case Feature::kRequestedSensorsPermission:
+ case Feature::kRequestedBackgroundWorkPermission:
return true;
}
}
diff --git a/chromium/third_party/icu/README.chromium b/chromium/third_party/icu/README.chromium
index 4c8e9b0fb58..c75f49a1ed5 100644
--- a/chromium/third_party/icu/README.chromium
+++ b/chromium/third_party/icu/README.chromium
@@ -205,7 +205,7 @@ D. Local Modifications
windowsZones.txt
zoneinfo64.txt
- As of Dec 31, 2018, the latest version is 2018i and the above files
+ As of May 7, 2019, the latest version is 2019a and the above files
are available at the ICU github repos.
4. Build-related changes
@@ -258,3 +258,10 @@ D. Local Modifications
https://unicode-org.atlassian.net/browse/ICU-20391
- upstream PR:
https://github.com/unicode-org/icu/pull/628
+
+9. Timezone breakage patch
+ - patches/timezone.patch
+ - upstream bug:
+ https://unicode-org.atlassian.net/browse/ICU-20595
+ - upstream PR:
+ https://github.com/unicode-org/icu/pull/649
diff --git a/chromium/third_party/icu/cast/icudtl.dat b/chromium/third_party/icu/cast/icudtl.dat
index 6b72db42cc1..7d493f69cad 100644
--- a/chromium/third_party/icu/cast/icudtl.dat
+++ b/chromium/third_party/icu/cast/icudtl.dat
Binary files differ
diff --git a/chromium/third_party/icu/chromeos/icudtl.dat b/chromium/third_party/icu/chromeos/icudtl.dat
index 20d9a305662..f0d4aca98c9 100644
--- a/chromium/third_party/icu/chromeos/icudtl.dat
+++ b/chromium/third_party/icu/chromeos/icudtl.dat
Binary files differ
diff --git a/chromium/third_party/icu/common/icudtb.dat b/chromium/third_party/icu/common/icudtb.dat
index 00aab097946..9429366ec85 100644
--- a/chromium/third_party/icu/common/icudtb.dat
+++ b/chromium/third_party/icu/common/icudtb.dat
Binary files differ
diff --git a/chromium/third_party/icu/common/icudtl.dat b/chromium/third_party/icu/common/icudtl.dat
index 195f6f8ed7f..0a6596ae65c 100644
--- a/chromium/third_party/icu/common/icudtl.dat
+++ b/chromium/third_party/icu/common/icudtl.dat
Binary files differ
diff --git a/chromium/third_party/icu/filters/android.json b/chromium/third_party/icu/filters/android.json
index 1ee8f13242f..38be85f6393 100644
--- a/chromium/third_party/icu/filters/android.json
+++ b/chromium/third_party/icu/filters/android.json
@@ -756,11 +756,6 @@
// https://cs.chromium.org/chromium/src/third_party/icu/patches/data.build.patch?rcl=797b7c
"unames": {
"filterType": "exclude"
- },
-// Based on the --disable-layout mentioned in
-// https://cs.chromium.org/chromium/src/third_party/icu/README.chromium?rcl=797b7c
- "ulayout": {
- "filterType": "exclude"
}
},
// Based on the ICU63 version of
diff --git a/chromium/third_party/icu/filters/android_small.json b/chromium/third_party/icu/filters/android_small.json
index 68a19c8df8d..e002a075575 100644
--- a/chromium/third_party/icu/filters/android_small.json
+++ b/chromium/third_party/icu/filters/android_small.json
@@ -739,11 +739,6 @@
// https://cs.chromium.org/chromium/src/third_party/icu/patches/data.build.patch?rcl=797b7c
"unames": {
"filterType": "exclude"
- },
-// Based on the --disable-layout mentioned in
-// https://cs.chromium.org/chromium/src/third_party/icu/README.chromium?rcl=797b7c
- "ulayout": {
- "filterType": "exclude"
}
},
// Based on the ICU63 version of
diff --git a/chromium/third_party/icu/filters/cast.json b/chromium/third_party/icu/filters/cast.json
index a1709eab4d1..7a1e8251811 100644
--- a/chromium/third_party/icu/filters/cast.json
+++ b/chromium/third_party/icu/filters/cast.json
@@ -796,11 +796,6 @@
// https://cs.chromium.org/chromium/src/third_party/icu/patches/data.build.patch?rcl=797b7c
"unames": {
"filterType": "exclude"
- },
-// Based on the --disable-layout mentioned in
-// https://cs.chromium.org/chromium/src/third_party/icu/README.chromium?rcl=797b7c
- "ulayout": {
- "filterType": "exclude"
}
},
// Based on the ICU63 version of
diff --git a/chromium/third_party/icu/filters/chromeos.json b/chromium/third_party/icu/filters/chromeos.json
index 5e28c076f83..d3de23c5bbc 100644
--- a/chromium/third_party/icu/filters/chromeos.json
+++ b/chromium/third_party/icu/filters/chromeos.json
@@ -784,11 +784,6 @@
// https://cs.chromium.org/chromium/src/third_party/icu/patches/data.build.patch?rcl=797b7c
"unames": {
"filterType": "exclude"
- },
-// Based on the --disable-layout mentioned in
-// https://cs.chromium.org/chromium/src/third_party/icu/README.chromium?rcl=797b7c
- "ulayout": {
- "filterType": "exclude"
}
},
// Based on the ICU63 version of
diff --git a/chromium/third_party/icu/filters/common.json b/chromium/third_party/icu/filters/common.json
index 3219e8ad064..9750dcf2be8 100644
--- a/chromium/third_party/icu/filters/common.json
+++ b/chromium/third_party/icu/filters/common.json
@@ -784,11 +784,6 @@
// https://cs.chromium.org/chromium/src/third_party/icu/patches/data.build.patch?rcl=797b7c
"unames": {
"filterType": "exclude"
- },
-// Based on the --disable-layout mentioned in
-// https://cs.chromium.org/chromium/src/third_party/icu/README.chromium?rcl=797b7c
- "ulayout": {
- "filterType": "exclude"
}
},
// Based on the ICU63 version of
diff --git a/chromium/third_party/icu/filters/flutter.json b/chromium/third_party/icu/filters/flutter.json
index bda4b98bbee..91ea4fde4a9 100644
--- a/chromium/third_party/icu/filters/flutter.json
+++ b/chromium/third_party/icu/filters/flutter.json
@@ -722,11 +722,6 @@
// https://cs.chromium.org/chromium/src/third_party/icu/patches/data.build.patch?rcl=797b7c
"unames": {
"filterType": "exclude"
- },
-// Based on the --disable-layout mentioned in
-// https://cs.chromium.org/chromium/src/third_party/icu/README.chromium?rcl=797b7c
- "ulayout": {
- "filterType": "exclude"
}
},
// Based on the ICU63 version of
diff --git a/chromium/third_party/icu/flutter/icudtl.dat b/chromium/third_party/icu/flutter/icudtl.dat
index c501eb4fc86..3606735a793 100644
--- a/chromium/third_party/icu/flutter/icudtl.dat
+++ b/chromium/third_party/icu/flutter/icudtl.dat
Binary files differ
diff --git a/chromium/third_party/icu/patches/timezone.patch b/chromium/third_party/icu/patches/timezone.patch
new file mode 100644
index 00000000000..bf7e1729aef
--- /dev/null
+++ b/chromium/third_party/icu/patches/timezone.patch
@@ -0,0 +1,52 @@
+diff --git a/source/i18n/timezone.cpp b/source/i18n/timezone.cpp
+index f129d8b6..32214d72 100644
+--- a/source/i18n/timezone.cpp
++++ b/source/i18n/timezone.cpp
+@@ -527,6 +527,11 @@ TimeZone::detectHostTimeZone()
+
+ // -------------------------------------
+
++static UMutex *gDefaultZoneMutex() {
++ static UMutex* m = new UMutex();
++ return m;
++}
++
+ /**
+ * Initialize DEFAULT_ZONE from the system default time zone.
+ * Upon return, DEFAULT_ZONE will not be NULL, unless operator new()
+@@ -536,6 +541,7 @@ static void U_CALLCONV initDefault()
+ {
+ ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
+
++ Mutex lock(gDefaultZoneMutex());
+ // If setDefault() has already been called we can skip getting the
+ // default zone information from the system.
+ if (DEFAULT_ZONE != NULL) {
+@@ -571,7 +577,10 @@ TimeZone* U_EXPORT2
+ TimeZone::createDefault()
+ {
+ umtx_initOnce(gDefaultZoneInitOnce, initDefault);
+- return (DEFAULT_ZONE != NULL) ? DEFAULT_ZONE->clone() : NULL;
++ {
++ Mutex lock(gDefaultZoneMutex());
++ return (DEFAULT_ZONE != NULL) ? DEFAULT_ZONE->clone() : NULL;
++ }
+ }
+
+ // -------------------------------------
+@@ -581,9 +590,12 @@ TimeZone::adoptDefault(TimeZone* zone)
+ {
+ if (zone != NULL)
+ {
+- TimeZone *old = DEFAULT_ZONE;
+- DEFAULT_ZONE = zone;
+- delete old;
++ {
++ Mutex lock(gDefaultZoneMutex());
++ TimeZone *old = DEFAULT_ZONE;
++ DEFAULT_ZONE = zone;
++ delete old;
++ }
+ ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
+ }
+ }
diff --git a/chromium/third_party/icu/scripts/copy_data.sh b/chromium/third_party/icu/scripts/copy_data.sh
index edc16771c42..16820e4a7b9 100755
--- a/chromium/third_party/icu/scripts/copy_data.sh
+++ b/chromium/third_party/icu/scripts/copy_data.sh
@@ -19,6 +19,7 @@ source "${TOPSRC}/scripts/data_common.sh"
function copy_common {
DATA_PREFIX="data/out/tmp/icudt${VERSION}"
+ TZRES_PREFIX="data/out/build/icudt${VERSION}l"
echo "Generating the big endian data bundle"
LD_LIBRARY_PATH=lib bin/icupkg -tb "${DATA_PREFIX}l.dat" "${DATA_PREFIX}b.dat"
@@ -29,6 +30,12 @@ function copy_common {
cp "${DATA_PREFIX}${endian}.dat" "${TOPSRC}/common/icudt${endian}.dat"
done
+ echo "Copying metaZones.res, timezoneTypes.res, zoneinfo64.res"
+ for tzfile in metaZones timezoneTypes zoneinfo64
+ do
+ cp "${TZRES_PREFIX}/${tzfile}.res" "${TOPSRC}/tzres/${tzfile}.res"
+ done
+
echo "Done with copying pre-built ICU data files."
}
diff --git a/chromium/third_party/icu/source/i18n/timezone.cpp b/chromium/third_party/icu/source/i18n/timezone.cpp
index f129d8b6076..129e6a5f27d 100644
--- a/chromium/third_party/icu/source/i18n/timezone.cpp
+++ b/chromium/third_party/icu/source/i18n/timezone.cpp
@@ -527,6 +527,11 @@ TimeZone::detectHostTimeZone()
// -------------------------------------
+static UMutex *gDefaultZoneMutex() {
+ static UMutex* m = new UMutex();
+ return m;
+}
+
/**
* Initialize DEFAULT_ZONE from the system default time zone.
* Upon return, DEFAULT_ZONE will not be NULL, unless operator new()
@@ -536,6 +541,7 @@ static void U_CALLCONV initDefault()
{
ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
+ Mutex lock(gDefaultZoneMutex());
// If setDefault() has already been called we can skip getting the
// default zone information from the system.
if (DEFAULT_ZONE != NULL) {
@@ -571,7 +577,10 @@ TimeZone* U_EXPORT2
TimeZone::createDefault()
{
umtx_initOnce(gDefaultZoneInitOnce, initDefault);
- return (DEFAULT_ZONE != NULL) ? DEFAULT_ZONE->clone() : NULL;
+ {
+ Mutex lock(gDefaultZoneMutex());
+ return (DEFAULT_ZONE != NULL) ? DEFAULT_ZONE->clone() : NULL;
+ }
}
// -------------------------------------
@@ -581,9 +590,12 @@ TimeZone::adoptDefault(TimeZone* zone)
{
if (zone != NULL)
{
- TimeZone *old = DEFAULT_ZONE;
- DEFAULT_ZONE = zone;
- delete old;
+ {
+ Mutex lock(gDefaultZoneMutex());
+ TimeZone *old = DEFAULT_ZONE;
+ DEFAULT_ZONE = zone;
+ delete old;
+ }
ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
}
}
diff --git a/chromium/third_party/icu/tzres/metaZones.res b/chromium/third_party/icu/tzres/metaZones.res
new file mode 100644
index 00000000000..a39c3ff8e2f
--- /dev/null
+++ b/chromium/third_party/icu/tzres/metaZones.res
Binary files differ
diff --git a/chromium/third_party/icu/tzres/timezoneTypes.res b/chromium/third_party/icu/tzres/timezoneTypes.res
new file mode 100644
index 00000000000..68cc6204260
--- /dev/null
+++ b/chromium/third_party/icu/tzres/timezoneTypes.res
Binary files differ
diff --git a/chromium/third_party/icu/tzres/zoneinfo64.res b/chromium/third_party/icu/tzres/zoneinfo64.res
new file mode 100644
index 00000000000..7e0afd40558
--- /dev/null
+++ b/chromium/third_party/icu/tzres/zoneinfo64.res
Binary files differ
diff --git a/chromium/third_party/skia/src/core/SkRemoteGlyphCache.cpp b/chromium/third_party/skia/src/core/SkRemoteGlyphCache.cpp
index 7bcb29a35e9..b12e52058a2 100644
--- a/chromium/third_party/skia/src/core/SkRemoteGlyphCache.cpp
+++ b/chromium/third_party/skia/src/core/SkRemoteGlyphCache.cpp
@@ -169,7 +169,10 @@ bool read_path(Deserializer* deserializer, SkGlyph* glyph, SkStrike* cache) {
uint64_t pathSize = 0u;
if (!deserializer->read<uint64_t>(&pathSize)) return false;
- if (pathSize == 0u) return true;
+ if (pathSize == 0u) {
+ cache->initializePath(glyph, nullptr, 0u);
+ return true;
+ }
auto* path = deserializer->read(pathSize, kPathAlignment);
if (!path) return false;
@@ -605,16 +608,14 @@ void SkStrikeServer::SkGlyphCacheState::writeGlyphPath(const SkPackedGlyphID& gl
}
-// This version of glyphMetrics only adds entries to result if their data need to be sent to the
-// GPU process. As a result, empty glyphs will be sent so that the GPU code can lookup the glyph
-// and detect that it is empty.
+// Be sure to read and understand the comment for prepareForDrawing in SkStrikeInterface.h before
+// working on this code.
SkSpan<const SkGlyphPos> SkStrikeServer::SkGlyphCacheState::prepareForDrawing(
const SkGlyphID glyphIDs[],
const SkPoint positions[],
size_t n,
int maxDimension,
SkGlyphPos results[]) {
- size_t glyphsToSendCount = 0;
for (size_t i = 0; i < n; i++) {
SkPoint glyphPos = positions[i];
SkGlyphID glyphID = glyphIDs[i];
@@ -635,10 +636,7 @@ SkSpan<const SkGlyphPos> SkStrikeServer::SkGlyphCacheState::prepareForDrawing(
fContext->getMetrics(glyphPtr);
if (glyphPtr->maxDimension() <= maxDimension) {
-
// The mask/SDF will fit in the cache.
- // TODO: no need to do this once code base converted over to bulk.
- results[glyphsToSendCount++] = {i, glyphPtr, glyphPos};
} else if (glyphPtr->fMaskFormat != SkMask::kARGB32_Format) {
// The glyph is too big for the atlas, but it is not color, so it is handled with a
@@ -646,13 +644,12 @@ SkSpan<const SkGlyphPos> SkStrikeServer::SkGlyphCacheState::prepareForDrawing(
if (glyphPtr->fPathData == nullptr) {
// Never checked for a path before. Add the path now.
- auto path = const_cast<SkGlyph&>(*glyphPtr).addPath(fContext.get(), &fAlloc);
- if (path != nullptr) {
+ const_cast<SkGlyph&>(*glyphPtr).addPath(fContext.get(), &fAlloc);
- // A path was added make sure to send it to the GPU.
- fCachedGlyphPaths.add(glyphPtr->getPackedID());
- fPendingGlyphPaths.push_back(glyphPtr->getPackedID());
- }
+ // Always send the path data, even if its not available, to make sure empty
+ // paths are not incorrectly assumed to be cache misses.
+ fCachedGlyphPaths.add(glyphPtr->getPackedID());
+ fPendingGlyphPaths.push_back(glyphPtr->getPackedID());
}
} else {
@@ -666,8 +663,13 @@ SkSpan<const SkGlyphPos> SkStrikeServer::SkGlyphCacheState::prepareForDrawing(
fPendingGlyphImages.push_back(packedGlyphID);
}
+ // Each glyph needs to be added as per the contract for prepareForDrawing.
+ // TODO(herb): check if the empty glyphs need to be added here. They certainly need to be
+ // sent, but do the need to be processed by the painter?
+ results[i] = {i, glyphPtr, glyphPos};
}
- return SkSpan<const SkGlyphPos>(results, glyphsToSendCount);
+
+ return SkSpan<const SkGlyphPos>{results, n};
}
// SkStrikeClient -----------------------------------------
@@ -694,10 +696,10 @@ SkStrikeClient::SkStrikeClient(sk_sp<DiscardableHandleManager> discardableManage
SkStrikeClient::~SkStrikeClient() = default;
-#define READ_FAILURE \
- { \
- SkDebugf("Bad font data serialization"); \
- return false; \
+#define READ_FAILURE \
+ { \
+ SkDebugf("Bad font data serialization line: %d", __LINE__); \
+ return false; \
}
static bool readGlyph(SkTLazy<SkGlyph>& glyph, Deserializer* deserializer) {
diff --git a/chromium/third_party/skia/src/core/SkStrike.cpp b/chromium/third_party/skia/src/core/SkStrike.cpp
index e248e6f52c7..09ab883dedd 100644
--- a/chromium/third_party/skia/src/core/SkStrike.cpp
+++ b/chromium/third_party/skia/src/core/SkStrike.cpp
@@ -183,6 +183,8 @@ bool SkStrike::initializePath(SkGlyph* glyph, const volatile void* data, size_t
if (glyph->fWidth) {
SkGlyph::PathData* pathData = fAlloc.make<SkGlyph::PathData>();
glyph->fPathData = pathData;
+ if (size == 0u) return true;
+
auto path = skstd::make_unique<SkPath>();
if (!pathData->fPath.readFromMemory(const_cast<const void*>(data), size)) {
return false;
@@ -254,7 +256,6 @@ SkSpan<const SkGlyphPos> SkStrike::prepareForDrawing(const SkGlyphID glyphIDs[],
// The out of atlas glyph is not color so we can draw it using paths.
this->findPath(glyph);
} else {
-
// This will be handled by the fallback strike.
SkASSERT(glyph.maxDimension() > maxDimension
&& glyph.fMaskFormat == SkMask::kARGB32_Format);
diff --git a/chromium/third_party/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/chromium/third_party/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
index 95ba2660a14..5f2f15aa385 100644
--- a/chromium/third_party/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
+++ b/chromium/third_party/webrtc/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
@@ -804,7 +804,7 @@ TEST_F(TestVp9Impl, EnablingNewLayerIsDelayedInScreenshareAndAddsSsInfo) {
codec_settings_.maxFramerate = 30;
ConfigureSvc(num_spatial_layers);
codec_settings_.spatialLayers[0].maxFramerate = 5.0;
- // use 30 for the SL 1 instead of 5, so even if SL 0 frame is dropped due to
+ // use 30 for the SL 1 instead of 10, so even if SL 0 frame is dropped due to
// framerate capping we would still get back at least a middle layer. It
// simplifies the test.
codec_settings_.spatialLayers[1].maxFramerate = 30.0;
@@ -868,6 +868,93 @@ TEST_F(TestVp9Impl, EnablingNewLayerIsDelayedInScreenshareAndAddsSsInfo) {
EXPECT_TRUE(codec_specific_info[0].codecSpecific.VP9.ss_data_available);
}
+TEST_F(TestVp9Impl, ScreenshareFrameDropping) {
+ const int num_spatial_layers = 3;
+ const int num_frames_to_detect_drops = 2;
+
+ codec_settings_.maxFramerate = 30;
+ ConfigureSvc(num_spatial_layers);
+ // use 30 for the SL0 and SL1 because it simplifies the test.
+ codec_settings_.spatialLayers[0].maxFramerate = 30.0;
+ codec_settings_.spatialLayers[1].maxFramerate = 30.0;
+ codec_settings_.spatialLayers[2].maxFramerate = 30.0;
+ codec_settings_.VP9()->frameDroppingOn = true;
+ codec_settings_.mode = VideoCodecMode::kScreensharing;
+ codec_settings_.VP9()->interLayerPred = InterLayerPredMode::kOn;
+ codec_settings_.VP9()->flexibleMode = true;
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
+ 0 /* max payload size (unused) */));
+
+ // Enable all but the last layer.
+ VideoBitrateAllocation bitrate_allocation;
+ // Very low bitrate for the lowest spatial layer to ensure rate-control drops.
+ bitrate_allocation.SetBitrate(0, 0, 1000);
+ bitrate_allocation.SetBitrate(
+ 1, 0, codec_settings_.spatialLayers[1].targetBitrate * 1000);
+ // Disable highest layer.
+ bitrate_allocation.SetBitrate(2, 0, 0);
+
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
+
+ bool frame_dropped = false;
+ // Encode enough frames to force drop due to rate-control.
+ for (size_t frame_num = 0; frame_num < num_frames_to_detect_drops;
+ ++frame_num) {
+ SetWaitForEncodedFramesThreshold(1);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->Encode(*NextInputFrame(), nullptr));
+ std::vector<EncodedImage> encoded_frames;
+ std::vector<CodecSpecificInfo> codec_specific_info;
+ ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific_info));
+ EXPECT_LE(encoded_frames.size(), 2u);
+ EXPECT_GE(encoded_frames.size(), 1u);
+ if (encoded_frames.size() == 1) {
+ frame_dropped = true;
+ // Dropped frame is on the SL0.
+ EXPECT_EQ(encoded_frames[0].SpatialIndex(), 1);
+ }
+ }
+ EXPECT_TRUE(frame_dropped);
+
+ // Enable the last layer.
+ bitrate_allocation.SetBitrate(
+ 2, 0, codec_settings_.spatialLayers[2].targetBitrate * 1000);
+ encoder_->SetRates(VideoEncoder::RateControlParameters(
+ bitrate_allocation, codec_settings_.maxFramerate));
+ SetWaitForEncodedFramesThreshold(1);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->Encode(*NextInputFrame(), nullptr));
+ std::vector<EncodedImage> encoded_frames;
+ std::vector<CodecSpecificInfo> codec_specific_info;
+ ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific_info));
+ // No drop allowed.
+ EXPECT_EQ(encoded_frames.size(), 3u);
+
+ // Verify that frame-dropping is re-enabled back.
+ frame_dropped = false;
+ // Encode enough frames to force drop due to rate-control.
+ for (size_t frame_num = 0; frame_num < num_frames_to_detect_drops;
+ ++frame_num) {
+ SetWaitForEncodedFramesThreshold(1);
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
+ encoder_->Encode(*NextInputFrame(), nullptr));
+ std::vector<EncodedImage> encoded_frames;
+ std::vector<CodecSpecificInfo> codec_specific_info;
+ ASSERT_TRUE(WaitForEncodedFrames(&encoded_frames, &codec_specific_info));
+ EXPECT_LE(encoded_frames.size(), 3u);
+ EXPECT_GE(encoded_frames.size(), 2u);
+ if (encoded_frames.size() == 2) {
+ frame_dropped = true;
+ // Dropped frame is on the SL0.
+ EXPECT_EQ(encoded_frames[0].SpatialIndex(), 1);
+ EXPECT_EQ(encoded_frames[1].SpatialIndex(), 2);
+ }
+ }
+ EXPECT_TRUE(frame_dropped);
+}
+
TEST_F(TestVp9Impl, RemovingLayerIsNotDelayedInScreenshareAndAddsSsInfo) {
const size_t num_spatial_layers = 3;
// Chosen by hand, the 2nd frame is dropped with configured per-layer max
@@ -1341,47 +1428,6 @@ TEST_F(TestVp9ImplFrameDropping, DifferentFrameratePerSpatialLayer) {
}
}
-TEST_F(TestVp9ImplFrameDropping, LayerMaxFramerateIsCappedByCodecMaxFramerate) {
- const float input_framerate_fps = 30.0;
- const float layer_max_framerate_fps = 30.0;
- const uint32_t codec_max_framerate_fps = layer_max_framerate_fps / 3;
- const size_t video_duration_secs = 3;
- const size_t num_input_frames = video_duration_secs * input_framerate_fps;
-
- VideoBitrateAllocation bitrate_allocation;
- codec_settings_.spatialLayers[0].width = codec_settings_.width;
- codec_settings_.spatialLayers[0].height = codec_settings_.height;
- codec_settings_.spatialLayers[0].maxFramerate = layer_max_framerate_fps;
- codec_settings_.spatialLayers[0].minBitrate = codec_settings_.startBitrate;
- codec_settings_.spatialLayers[0].maxBitrate = codec_settings_.startBitrate;
- codec_settings_.spatialLayers[0].targetBitrate = codec_settings_.startBitrate;
- codec_settings_.spatialLayers[0].active = true;
-
- bitrate_allocation.SetBitrate(
- 0, 0, codec_settings_.spatialLayers[0].targetBitrate * 1000);
-
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
- encoder_->InitEncode(&codec_settings_, 1 /* number of cores */,
- 0 /* max payload size (unused) */));
-
- encoder_->SetRates(VideoEncoder::RateControlParameters(
- bitrate_allocation, codec_max_framerate_fps));
-
- VideoFrame* input_frame = NextInputFrame();
- for (size_t frame_num = 0; frame_num < num_input_frames; ++frame_num) {
- EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Encode(*input_frame, nullptr));
- const size_t timestamp = input_frame->timestamp() +
- kVideoPayloadTypeFrequency / input_framerate_fps;
- input_frame->set_timestamp(static_cast<uint32_t>(timestamp));
- }
-
- const size_t num_encoded_frames = GetNumEncodedFrames();
- const float encoded_framerate_fps = num_encoded_frames / video_duration_secs;
- const float max_framerate_error_fps = codec_max_framerate_fps * 0.1f;
- EXPECT_NEAR(encoded_framerate_fps, codec_max_framerate_fps,
- max_framerate_error_fps);
-}
-
class TestVp9ImplProfile2 : public TestVp9Impl {
protected:
void SetUp() override {
diff --git a/chromium/third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc b/chromium/third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
index abb54b6b932..a09a7d944b3 100644
--- a/chromium/third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
+++ b/chromium/third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.cc
@@ -54,7 +54,7 @@ constexpr double kLowRateFactor = 1.0;
constexpr double kHighRateFactor = 2.0;
// These settings correspond to the settings in vpx_codec_enc_cfg.
-struct Vp8RateSettings {
+struct Vp9RateSettings {
uint32_t rc_undershoot_pct;
uint32_t rc_overshoot_pct;
uint32_t rc_buf_sz;
@@ -161,9 +161,9 @@ uint32_t Interpolate(uint32_t low,
return static_cast<uint32_t>(((1.0 - factor) * low) + (factor * high) + 0.5);
}
-Vp8RateSettings GetRateSettings(double bandwidth_headroom_factor) {
- static const Vp8RateSettings low_settings{1000u, 0u, 100u, 30u, 40u};
- static const Vp8RateSettings high_settings{100u, 15u, 1000u, 600u, 5u};
+Vp9RateSettings GetRateSettings(double bandwidth_headroom_factor) {
+ static const Vp9RateSettings low_settings{100u, 0u, 100u, 33u, 40u};
+ static const Vp9RateSettings high_settings{50u, 50u, 1000u, 700u, 5u};
if (bandwidth_headroom_factor <= kLowRateFactor) {
return low_settings;
@@ -171,7 +171,7 @@ Vp8RateSettings GetRateSettings(double bandwidth_headroom_factor) {
return high_settings;
}
- Vp8RateSettings settings;
+ Vp9RateSettings settings;
settings.rc_undershoot_pct =
Interpolate(low_settings.rc_undershoot_pct,
high_settings.rc_undershoot_pct, bandwidth_headroom_factor);
@@ -191,7 +191,7 @@ Vp8RateSettings GetRateSettings(double bandwidth_headroom_factor) {
}
void UpdateRateSettings(vpx_codec_enc_cfg_t* config,
- const Vp8RateSettings& new_settings) {
+ const Vp9RateSettings& new_settings) {
config->rc_undershoot_pct = new_settings.rc_undershoot_pct;
config->rc_overshoot_pct = new_settings.rc_overshoot_pct;
config->rc_buf_sz = new_settings.rc_buf_sz;
@@ -316,8 +316,7 @@ bool VP9EncoderImpl::SetSvcRates(
}
framerate_controller_[sl_idx].SetTargetRate(
- std::min(static_cast<float>(codec_.maxFramerate),
- codec_.spatialLayers[sl_idx].maxFramerate));
+ codec_.spatialLayers[sl_idx].maxFramerate);
}
} else {
float rate_ratio[VPX_MAX_LAYERS] = {0};
@@ -535,24 +534,18 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
inter_layer_pred_ = inst->VP9().interLayerPred;
- different_framerates_used_ = false;
- for (size_t sl_idx = 1; sl_idx < num_spatial_layers_; ++sl_idx) {
- if (std::abs(codec_.spatialLayers[sl_idx].maxFramerate -
- codec_.spatialLayers[0].maxFramerate) > 1e-9) {
- different_framerates_used_ = true;
- }
- }
-
- if (different_framerates_used_ && !is_flexible_mode_) {
- RTC_LOG(LS_ERROR) << "Flexible mode required for different framerates on "
- "different spatial layers";
+ if (num_spatial_layers_ > 1 &&
+ codec_.mode == VideoCodecMode::kScreensharing && !is_flexible_mode_) {
+ RTC_LOG(LS_ERROR) << "Flexible mode is required for screenshare with "
+ "several spatial layers";
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}
// External reference control is required for different frame rate on spatial
// layers because libvpx generates rtp incompatible references in this case.
external_ref_control_ = field_trial::IsEnabled("WebRTC-Vp9ExternalRefCtrl") ||
- different_framerates_used_ ||
+ (num_spatial_layers_ > 1 &&
+ codec_.mode == VideoCodecMode::kScreensharing) ||
inter_layer_pred_ == InterLayerPredMode::kOn;
if (num_temporal_layers_ == 1) {
@@ -589,7 +582,8 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
if (external_ref_control_) {
config_->temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
- if (num_temporal_layers_ > 1 && different_framerates_used_) {
+ if (num_temporal_layers_ > 1 && num_spatial_layers_ > 1 &&
+ codec_.mode == VideoCodecMode::kScreensharing) {
// External reference control for several temporal layers with different
// frame rates on spatial layers is not implemented yet.
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
@@ -717,18 +711,35 @@ int VP9EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) {
RTC_NOTREACHED();
}
- // Configure encoder to drop entire superframe whenever it needs to drop
- // a layer. This mode is prefered over per-layer dropping which causes
- // quality flickering and is not compatible with RTP non-flexible mode.
- vpx_svc_frame_drop_t svc_drop_frame;
- memset(&svc_drop_frame, 0, sizeof(svc_drop_frame));
- svc_drop_frame.framedrop_mode =
- full_superframe_drop_ ? FULL_SUPERFRAME_DROP : CONSTRAINED_LAYER_DROP;
- svc_drop_frame.max_consec_drop = std::numeric_limits<int>::max();
- for (size_t i = 0; i < num_spatial_layers_; ++i) {
- svc_drop_frame.framedrop_thresh[i] = config_->rc_dropframe_thresh;
+ memset(&svc_drop_frame_, 0, sizeof(svc_drop_frame_));
+ dropping_only_base_layer_ = inter_layer_pred_ == InterLayerPredMode::kOn &&
+ codec_.mode == VideoCodecMode::kScreensharing &&
+ num_spatial_layers_ > 1;
+ if (dropping_only_base_layer_) {
+ // Screenshare dropping mode: only the base spatial layer
+ // can be dropped and it doesn't affect other spatial layers.
+ // This mode is preferable because base layer has low bitrate targets
+ // and more likely to drop frames. It shouldn't reduce framerate on other
+ // layers.
+ svc_drop_frame_.framedrop_mode = LAYER_DROP;
+ svc_drop_frame_.max_consec_drop = 5;
+ svc_drop_frame_.framedrop_thresh[0] = config_->rc_dropframe_thresh;
+ for (size_t i = 1; i < num_spatial_layers_; ++i) {
+ svc_drop_frame_.framedrop_thresh[i] = 0;
+ }
+ } else {
+ // Configure encoder to drop entire superframe whenever it needs to drop
+ // a layer. This mode is preferred over per-layer dropping which causes
+ // quality flickering and is not compatible with RTP non-flexible mode.
+ svc_drop_frame_.framedrop_mode =
+ full_superframe_drop_ ? FULL_SUPERFRAME_DROP : CONSTRAINED_LAYER_DROP;
+ svc_drop_frame_.max_consec_drop = std::numeric_limits<int>::max();
+ for (size_t i = 0; i < num_spatial_layers_; ++i) {
+ svc_drop_frame_.framedrop_thresh[i] = config_->rc_dropframe_thresh;
+ }
}
- vpx_codec_control(encoder_, VP9E_SET_SVC_FRAME_DROP_LAYER, &svc_drop_frame);
+ vpx_codec_control(encoder_, VP9E_SET_SVC_FRAME_DROP_LAYER,
+ &svc_drop_frame_);
}
// Register callback for getting each spatial layer.
@@ -894,9 +905,22 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image,
if (less_layers_requested || more_layers_requested) {
ss_info_needed_ = true;
}
+ if (more_layers_requested && !force_key_frame_) {
+ // Prohibit drop of all layers for the next frame, so newly enabled
+ // layer would have a valid spatial reference.
+ for (size_t i = 0; i < num_spatial_layers_; ++i) {
+ svc_drop_frame_.framedrop_thresh[i] = 0;
+ }
+ }
}
}
+ if (num_spatial_layers_ > 1) {
+ // Update frame dropping settings as they may change on per-frame basis.
+ vpx_codec_control(encoder_, VP9E_SET_SVC_FRAME_DROP_LAYER,
+ &svc_drop_frame_);
+ }
+
if (vpx_codec_enc_config_set(encoder_, config_)) {
return WEBRTC_VIDEO_CODEC_ERROR;
}
@@ -964,7 +988,8 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image,
if (VideoCodecMode::kScreensharing == codec_.mode) {
for (uint8_t sl_idx = 0; sl_idx < num_active_spatial_layers_; ++sl_idx) {
ref_config.duration[sl_idx] = static_cast<int64_t>(
- 90000 / framerate_controller_[sl_idx].GetTargetRate());
+ 90000 / (std::min(static_cast<float>(codec_.maxFramerate),
+ framerate_controller_[sl_idx].GetTargetRate())));
}
}
@@ -983,8 +1008,9 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image,
RTC_DCHECK_GE(framerate_controller_.size(), num_active_spatial_layers_);
float target_framerate_fps =
(codec_.mode == VideoCodecMode::kScreensharing)
- ? framerate_controller_[num_active_spatial_layers_ - 1]
- .GetTargetRate()
+ ? std::min(static_cast<float>(codec_.maxFramerate),
+ framerate_controller_[num_active_spatial_layers_ - 1]
+ .GetTargetRate())
: codec_.maxFramerate;
uint32_t duration = static_cast<uint32_t>(90000 / target_framerate_fps);
const vpx_codec_err_t rv = vpx_codec_encode(encoder_, raw_, timestamp_,
@@ -1199,6 +1225,8 @@ void VP9EncoderImpl::FillReferenceIndices(const vpx_codec_cx_pkt& pkt,
// It is safe to ignore this requirement if inter-layer prediction is
// enabled for all frames when all base frames are relayed to receiver.
RTC_DCHECK_EQ(ref_buf.spatial_layer_id, layer_id.spatial_layer_id);
+ } else {
+ RTC_DCHECK_LE(ref_buf.spatial_layer_id, layer_id.spatial_layer_id);
}
RTC_DCHECK_LE(ref_buf.temporal_layer_id, layer_id.temporal_layer_id);
@@ -1318,7 +1346,7 @@ vpx_svc_ref_frame_config_t VP9EncoderImpl::SetReferences(
const bool same_spatial_layer =
ref_buf_[buf_idx].spatial_layer_id == sl_idx;
bool correct_pid = false;
- if (different_framerates_used_) {
+ if (is_flexible_mode_) {
correct_pid = pid_diff < kMaxAllowedPidDIff;
} else {
// Below code assumes single temporal referecence.
@@ -1442,6 +1470,16 @@ int VP9EncoderImpl::GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt) {
void VP9EncoderImpl::DeliverBufferedFrame(bool end_of_picture) {
if (encoded_image_.size() > 0) {
+ if (num_spatial_layers_ > 1) {
+ // Restore frame dropping settings, as dropping may be temporary forbidden
+ // due to dynamically enabled layers.
+ svc_drop_frame_.framedrop_thresh[0] = config_->rc_dropframe_thresh;
+ for (size_t i = 1; i < num_spatial_layers_; ++i) {
+ svc_drop_frame_.framedrop_thresh[i] =
+ dropping_only_base_layer_ ? 0 : config_->rc_dropframe_thresh;
+ }
+ }
+
codec_specific_.codecSpecific.VP9.end_of_picture = end_of_picture;
// No data partitioning in VP9, so 1 partition only.
@@ -1519,7 +1557,8 @@ size_t VP9EncoderImpl::SteadyStateSize(int sid, int tid) {
const size_t bitrate_bps = current_bitrate_allocation_.GetBitrate(
sid, tid == kNoTemporalIdx ? 0 : tid);
const float fps = (codec_.mode == VideoCodecMode::kScreensharing)
- ? framerate_controller_[sid].GetTargetRate()
+ ? std::min(static_cast<float>(codec_.maxFramerate),
+ framerate_controller_[sid].GetTargetRate())
: codec_.maxFramerate;
return static_cast<size_t>(
bitrate_bps / (8 * fps) *
diff --git a/chromium/third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h b/chromium/third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h
index acc03bff5c9..fb195a7c001 100644
--- a/chromium/third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h
+++ b/chromium/third_party/webrtc/modules/video_coding/codecs/vp9/vp9_impl.h
@@ -113,7 +113,6 @@ class VP9EncoderImpl : public VP9Encoder {
GofInfoVP9 gof_; // Contains each frame's temporal information for
// non-flexible mode.
bool force_key_frame_;
- bool different_framerates_used_;
size_t pics_since_key_;
uint8_t num_temporal_layers_;
uint8_t num_spatial_layers_; // Number of configured SLs
@@ -125,6 +124,8 @@ class VP9EncoderImpl : public VP9Encoder {
const bool trusted_rate_controller_;
const bool dynamic_rate_settings_;
const bool full_superframe_drop_;
+ bool dropping_only_base_layer_;
+ vpx_svc_frame_drop_t svc_drop_frame_;
bool first_frame_in_picture_;
VideoBitrateAllocation current_bitrate_allocation_;
absl::optional<RateControlParameters> requested_rate_settings_;
diff --git a/chromium/third_party/webrtc/pc/jsep_session_description.cc b/chromium/third_party/webrtc/pc/jsep_session_description.cc
index 90b12a4125b..d9c1fad94d1 100644
--- a/chromium/third_party/webrtc/pc/jsep_session_description.cc
+++ b/chromium/third_party/webrtc/pc/jsep_session_description.cc
@@ -207,7 +207,7 @@ bool JsepSessionDescription::Initialize(
bool JsepSessionDescription::AddCandidate(
const IceCandidateInterface* candidate) {
- if (!candidate || candidate->sdp_mline_index() < 0)
+ if (!candidate)
return false;
size_t mediasection_index = 0;
if (!GetMediasectionIndex(candidate, &mediasection_index)) {
@@ -291,7 +291,18 @@ bool JsepSessionDescription::GetMediasectionIndex(
if (!candidate || !index) {
return false;
}
- *index = static_cast<size_t>(candidate->sdp_mline_index());
+
+ // If the candidate has no valid mline index or sdp_mid, it is impossible
+ // to find a match.
+ if (candidate->sdp_mid().empty() &&
+ (candidate->sdp_mline_index() < 0 ||
+ static_cast<size_t>(candidate->sdp_mline_index()) >=
+ description_->contents().size())) {
+ return false;
+ }
+
+ if (candidate->sdp_mline_index() >= 0)
+ *index = static_cast<size_t>(candidate->sdp_mline_index());
if (description_ && !candidate->sdp_mid().empty()) {
bool found = false;
// Try to match the sdp_mid with content name.
diff --git a/chromium/third_party/webrtc/pc/peer_connection.cc b/chromium/third_party/webrtc/pc/peer_connection.cc
index 30fbf5c11ca..81034b91fc3 100644
--- a/chromium/third_party/webrtc/pc/peer_connection.cc
+++ b/chromium/third_party/webrtc/pc/peer_connection.cc
@@ -6185,21 +6185,18 @@ bool PeerConnection::UseCandidatesInSessionDescription(
}
bool PeerConnection::UseCandidate(const IceCandidateInterface* candidate) {
- size_t mediacontent_index = static_cast<size_t>(candidate->sdp_mline_index());
- size_t remote_content_size =
- remote_description()->description()->contents().size();
- if (mediacontent_index >= remote_content_size) {
- RTC_LOG(LS_ERROR) << "UseCandidate: Invalid candidate media index.";
+ RTCErrorOr<const cricket::ContentInfo*> result =
+ FindContentInfo(remote_description(), candidate);
+ if (!result.ok()) {
+ RTC_LOG(LS_ERROR) << "UseCandidate: Invalid candidate. "
+ << result.error().message();
return false;
}
-
- cricket::ContentInfo content =
- remote_description()->description()->contents()[mediacontent_index];
std::vector<cricket::Candidate> candidates;
candidates.push_back(candidate->candidate());
// Invoking BaseSession method to handle remote candidates.
- RTCError error =
- transport_controller_->AddRemoteCandidates(content.name, candidates);
+ RTCError error = transport_controller_->AddRemoteCandidates(
+ result.value()->name, candidates);
if (error.ok()) {
// Candidates successfully submitted for checking.
if (ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew ||
@@ -6222,6 +6219,42 @@ bool PeerConnection::UseCandidate(const IceCandidateInterface* candidate) {
return true;
}
+RTCErrorOr<const cricket::ContentInfo*> PeerConnection::FindContentInfo(
+ const SessionDescriptionInterface* description,
+ const IceCandidateInterface* candidate) {
+ if (candidate->sdp_mline_index() >= 0) {
+ size_t mediacontent_index =
+ static_cast<size_t>(candidate->sdp_mline_index());
+ size_t content_size = description->description()->contents().size();
+ if (mediacontent_index < content_size) {
+ return &description->description()->contents()[mediacontent_index];
+ } else {
+ return RTCError(RTCErrorType::INVALID_RANGE,
+ "Media line index (" +
+ rtc::ToString(candidate->sdp_mline_index()) +
+ ") out of range (number of mlines: " +
+ rtc::ToString(content_size) + ").");
+ }
+ } else if (!candidate->sdp_mid().empty()) {
+ auto& contents = description->description()->contents();
+ auto it = absl::c_find_if(
+ contents, [candidate](const cricket::ContentInfo& content_info) {
+ return content_info.mid() == candidate->sdp_mid();
+ });
+ if (it == contents.end()) {
+ return RTCError(
+ RTCErrorType::INVALID_PARAMETER,
+ "Mid " + candidate->sdp_mid() +
+ " specified but no media section with that mid found.");
+ } else {
+ return &*it;
+ }
+ }
+
+ return RTCError(RTCErrorType::INVALID_PARAMETER,
+ "Neither sdp_mline_index nor sdp_mid specified.");
+}
+
void PeerConnection::RemoveUnusedChannels(const SessionDescription* desc) {
// Destroy video channel first since it may have a pointer to the
// voice channel.
@@ -6850,26 +6883,18 @@ bool PeerConnection::ReadyToUseRemoteCandidate(
return false;
}
- size_t mediacontent_index = static_cast<size_t>(candidate->sdp_mline_index());
- size_t remote_content_size =
- current_remote_desc->description()->contents().size();
- if (mediacontent_index >= remote_content_size) {
- RTC_LOG(LS_ERROR)
- << "ReadyToUseRemoteCandidate: Invalid candidate media index "
- << mediacontent_index;
+ RTCErrorOr<const cricket::ContentInfo*> result =
+ FindContentInfo(current_remote_desc, candidate);
+ if (!result.ok()) {
+ RTC_LOG(LS_ERROR) << "ReadyToUseRemoteCandidate: Invalid candidate. "
+ << result.error().message();
*valid = false;
return false;
}
- cricket::ContentInfo content =
- current_remote_desc->description()->contents()[mediacontent_index];
-
- const std::string transport_name = GetTransportName(content.name);
- if (transport_name.empty()) {
- return false;
- }
- return true;
+ std::string transport_name = GetTransportName(result.value()->name);
+ return !transport_name.empty();
}
bool PeerConnection::SrtpRequired() const {
diff --git a/chromium/third_party/webrtc/pc/peer_connection.h b/chromium/third_party/webrtc/pc/peer_connection.h
index 39cb8674061..79408d4c0fd 100644
--- a/chromium/third_party/webrtc/pc/peer_connection.h
+++ b/chromium/third_party/webrtc/pc/peer_connection.h
@@ -911,6 +911,9 @@ class PeerConnection : public PeerConnectionInternal,
// Uses |candidate| in this session.
bool UseCandidate(const IceCandidateInterface* candidate)
RTC_RUN_ON(signaling_thread());
+ RTCErrorOr<const cricket::ContentInfo*> FindContentInfo(
+ const SessionDescriptionInterface* description,
+ const IceCandidateInterface* candidate) RTC_RUN_ON(signaling_thread());
// Deletes the corresponding channel of contents that don't exist in |desc|.
// |desc| can be null. This means that all channels are deleted.
void RemoveUnusedChannels(const cricket::SessionDescription* desc)
diff --git a/chromium/third_party/webrtc/pc/peer_connection_ice_unittest.cc b/chromium/third_party/webrtc/pc/peer_connection_ice_unittest.cc
index 03c11283bbc..afc859434f1 100644
--- a/chromium/third_party/webrtc/pc/peer_connection_ice_unittest.cc
+++ b/chromium/third_party/webrtc/pc/peer_connection_ice_unittest.cc
@@ -58,7 +58,7 @@ class PeerConnectionWrapperForIceTest : public PeerConnectionWrapper {
const auto& first_content = desc->contents()[0];
candidate->set_transport_name(first_content.name);
std::unique_ptr<IceCandidateInterface> jsep_candidate =
- CreateIceCandidate(first_content.name, 0, *candidate);
+ CreateIceCandidate(first_content.name, -1, *candidate);
return pc()->AddIceCandidate(jsep_candidate.get());
}
diff --git a/chromium/third_party/webrtc/video/video_quality_test.cc b/chromium/third_party/webrtc/video/video_quality_test.cc
index 10f96996011..00a1ff3e4cf 100644
--- a/chromium/third_party/webrtc/video/video_quality_test.cc
+++ b/chromium/third_party/webrtc/video/video_quality_test.cc
@@ -822,7 +822,7 @@ void VideoQualityTest::SetupVideo(Transport* send_transport,
params_.ss[video_idx].num_spatial_layers);
vp9_settings.interLayerPred = params_.ss[video_idx].inter_layer_pred;
// High FPS vp9 screenshare requires flexible mode.
- if (params_.video[video_idx].fps > 5) {
+ if (params_.ss[video_idx].num_spatial_layers > 1) {
vp9_settings.flexibleMode = true;
}
video_encoder_configs_[video_idx].encoder_specific_settings =