diff --git a/DEPS b/DEPS index 3024089..df90ad5 100644 --- a/DEPS +++ b/DEPS
@@ -96,11 +96,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'ab7181daad5dae205b8dbd9de318aa3438a1cabf', + 'skia_revision': '6bbd386a0e4bf13cd7abb887900018a56e24091b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'd527ddce3d5f3c0266e56c2b7568c1b837dff0d8', + 'v8_revision': '558cf7d7ae9f4dda0bb1cad06be5275b891c9bb7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -108,7 +108,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '5730c0bf431e2decbddfdb7a3a2ec8338e56be2d', + 'angle_revision': 'a00ef3144f7039b54ea7dbfe255b85b6f4d11224', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -120,7 +120,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '08d96f1cadb14d91b051e7568de0c43804ba7340', + 'pdfium_revision': '473b4ae489e8c6d63b087693589eda03399f60f6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -156,7 +156,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'dd13313c34d34127722d3bab7c2b4f372329c544', + 'catapult_revision': '075ca3000abfdd522bd4faf668cae4b7c820dd64', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -498,7 +498,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '7e9e7b065a98c94ba1435726e1904869724979d5', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c8e4e795ed7527807910153dea581ee6ad9a2698', 'condition': 'checkout_linux', }, @@ -1002,7 +1002,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@eb85cead4784fe9d080343a1332a8e7361235366', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3136ebfa0a629e2906f6f2455f40490e95436baf', 'condition': 'checkout_src_internal', },
diff --git a/ash/system/ime_menu/ime_menu_tray_unittest.cc b/ash/system/ime_menu/ime_menu_tray_unittest.cc index f87010a..3128db3c 100644 --- a/ash/system/ime_menu/ime_menu_tray_unittest.cc +++ b/ash/system/ime_menu/ime_menu_tray_unittest.cc
@@ -106,7 +106,8 @@ void FocusInInputContext(ui::TextInputType input_type) { ui::IMEEngineHandlerInterface::InputContext input_context( input_type, ui::TEXT_INPUT_MODE_DEFAULT, ui::TEXT_INPUT_FLAG_NONE, - ui::TextInputClient::FOCUS_REASON_OTHER); + ui::TextInputClient::FOCUS_REASON_OTHER, + false /* should_do_learning */); ui::IMEBridge::Get()->SetCurrentInputContext(input_context); }
diff --git a/cc/trees/render_frame_metadata.cc b/cc/trees/render_frame_metadata.cc index 2559925..b8a0500b 100644 --- a/cc/trees/render_frame_metadata.cc +++ b/cc/trees/render_frame_metadata.cc
@@ -34,7 +34,7 @@ RenderFrameMetadata& RenderFrameMetadata::operator=( RenderFrameMetadata&& other) = default; -bool RenderFrameMetadata::operator==(const RenderFrameMetadata& other) { +bool RenderFrameMetadata::operator==(const RenderFrameMetadata& other) const { return root_scroll_offset == other.root_scroll_offset && root_background_color == other.root_background_color && is_scroll_offset_at_top == other.is_scroll_offset_at_top && @@ -45,7 +45,7 @@ local_surface_id == other.local_surface_id; } -bool RenderFrameMetadata::operator!=(const RenderFrameMetadata& other) { +bool RenderFrameMetadata::operator!=(const RenderFrameMetadata& other) const { return !operator==(other); }
diff --git a/cc/trees/render_frame_metadata.h b/cc/trees/render_frame_metadata.h index c76d498..94f768c 100644 --- a/cc/trees/render_frame_metadata.h +++ b/cc/trees/render_frame_metadata.h
@@ -31,8 +31,8 @@ RenderFrameMetadata& operator=(const RenderFrameMetadata&); RenderFrameMetadata& operator=(RenderFrameMetadata&& other); - bool operator==(const RenderFrameMetadata& other); - bool operator!=(const RenderFrameMetadata& other); + bool operator==(const RenderFrameMetadata& other) const; + bool operator!=(const RenderFrameMetadata& other) const; // Indicates whether the scroll offset of the root layer is at top, i.e., // whether scroll_offset.y() == 0.
diff --git a/chrome/VERSION b/chrome/VERSION index fa590464..a2ee50e 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=68 MINOR=0 -BUILD=3431 +BUILD=3432 PATCH=0
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index fb24a54..aac3d0f 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-68.0.3430.0_rc-r1.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-68.0.3431.0_rc-r1.afdo.bz2 \ No newline at end of file
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc index 6481b92..3dc8080b 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
@@ -245,23 +245,8 @@ // This bridge must receive OnNotificationStateChanged call for the // notification_key before this receives an accessibility event for it. - // TODO(yawano): change this to DCHECK once we remove backward - // compatibility logic. - if (notification_keys_.find(notification_key) != - notification_keys_.end()) { - tree_source = GetFromNotificationKey(notification_key); - DCHECK(tree_source); - } else { - // Backward compatibility logic. - // TODO(yawano): remove this once this becomes unnecessary. - if (event_data->event_type == - arc::mojom::AccessibilityEventType::WINDOW_STATE_CHANGED) { - tree_source = CreateFromNotificationKey(notification_key); - backward_compat_notification_keys_[notification_key]++; - } else { - tree_source = GetFromNotificationKey(notification_key); - } - } + tree_source = GetFromNotificationKey(notification_key); + DCHECK(tree_source); } else { if (event_data->task_id == kNoTaskId) return; @@ -283,40 +268,21 @@ tree_source->NotifyAccessibilityEvent(event_data.get()); - if (is_notification_event) { - switch (event_data->event_type) { - case arc::mojom::AccessibilityEventType::VIEW_TEXT_SELECTION_CHANGED: { - // If text selection changed event is dispatched from Android, it - // means that user is trying to type a text in Android notification. - // Dispatch text selection changed event to notification content view - // as the view can take necessary actions, e.g. activate itself, etc. - auto* surface_manager = ArcNotificationSurfaceManager::Get(); - if (!surface_manager) - break; - - ArcNotificationSurface* surface = surface_manager->GetArcSurface( - event_data->notification_key.value()); - if (!surface) - break; - + if (is_notification_event && + event_data->event_type == + arc::mojom::AccessibilityEventType::VIEW_TEXT_SELECTION_CHANGED) { + // If text selection changed event is dispatched from Android, it + // means that user is trying to type a text in Android notification. + // Dispatch text selection changed event to notification content view + // as the view can take necessary actions, e.g. activate itself, etc. + auto* surface_manager = ArcNotificationSurfaceManager::Get(); + if (surface_manager) { + ArcNotificationSurface* surface = surface_manager->GetArcSurface( + event_data->notification_key.value()); + if (surface) { surface->GetAttachedHost()->NotifyAccessibilityEvent( ax::mojom::Event::kTextSelectionChanged, true); - break; } - case arc::mojom::AccessibilityEventType::WINDOW_STATE_CHANGED: { - // TODO(yawano): Move this to OnNotificationStateChanged. This can be - // moved there if we don't need to care about backward compat. - ui::AXTreeData tree_data; - if (!tree_source->GetTreeData(&tree_data)) - break; - - DCHECK(event_data->notification_key.has_value()); - UpdateTreeIdOfNotificationSurface( - event_data->notification_key.value(), tree_data.tree_id); - break; - } - default: - break; } } @@ -335,12 +301,19 @@ const std::string& notification_key, arc::mojom::AccessibilityNotificationStateType state) { switch (state) { - case arc::mojom::AccessibilityNotificationStateType::SURFACE_CREATED: - CreateFromNotificationKey(notification_key); - notification_keys_.insert(notification_key); + case arc::mojom::AccessibilityNotificationStateType::SURFACE_CREATED: { + AXTreeSourceArc* tree_source = + CreateFromNotificationKey(notification_key); + + ui::AXTreeData tree_data; + if (!tree_source->GetTreeData(&tree_data)) { + NOTREACHED(); + return; + } + UpdateTreeIdOfNotificationSurface(notification_key, tree_data.tree_id); break; + } case arc::mojom::AccessibilityNotificationStateType::SURFACE_REMOVED: - notification_keys_.erase(notification_key); notification_key_to_tree_.erase(notification_key); UpdateTreeIdOfNotificationSurface(notification_key, kInvalidTreeId); break; @@ -599,22 +572,4 @@ } } -void ArcAccessibilityHelperBridge::OnNotificationSurfaceRemoved( - ArcNotificationSurface* surface) { - const std::string& notification_key = surface->GetNotificationKey(); - - auto it = backward_compat_notification_keys_.find(notification_key); - if (it == backward_compat_notification_keys_.end()) - return; - - it->second--; - - DCHECK(it->second >= 0); - - if (it->second == 0) { - notification_key_to_tree_.erase(notification_key); - backward_compat_notification_keys_.erase(notification_key); - } -} - } // namespace arc
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h index 3de2223..27d4e70 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h
@@ -83,7 +83,7 @@ // ArcNotificationSurfaceManager::Observer overrides. void OnNotificationSurfaceAdded(ArcNotificationSurface* surface) override; - void OnNotificationSurfaceRemoved(ArcNotificationSurface* surface) override; + void OnNotificationSurfaceRemoved(ArcNotificationSurface* surface) override{}; const std::map<int32_t, std::unique_ptr<AXTreeSourceArc>>& task_id_to_tree_for_test() const { @@ -128,16 +128,6 @@ std::unique_ptr<chromeos::AccessibilityStatusSubscription> accessibility_status_subscription_; - // Map for managing notifications in backward compatible way, creating - // notification with WINDOW_STATE_CHANGED event. - // Key: notification key - // Value: retain counter - // TODO(yawano): Remove this after this becomes unnecessary. - std::map<std::string, int32_t> backward_compat_notification_keys_; - - // TODO(yawano): Remove this after this becomes unnecessary. - std::set<std::string> notification_keys_; - DISALLOW_COPY_AND_ASSIGN(ArcAccessibilityHelperBridge); };
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc index 0c75b4a..e40d179 100644 --- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge_unittest.cc
@@ -404,107 +404,6 @@ arc_notification_surface_manager_->RemoveSurface(&test_surface_2); } -// This is the case for testing backward compatibility with creating -// notification by WINDOW_STATE_CHANGED event. -// -// mojo: notification 1 created -// wayland: surface 1 created -// mojo: notification 2 created -// wayland: surface 1 removed -// wayland: surface 2 created -// wayland: surface 2 removed -// -// wayland: surface 3 created -// mojo: notification 3 created -// wayland: surface 3 removed -TEST_F(ArcAccessibilityHelperBridgeTest, NotificationBackwardCompat) { - base::CommandLine::ForCurrentProcess()->AppendSwitch( - chromeos::switches::kEnableChromeVoxArcSupport); - - TestArcAccessibilityHelperBridge* helper_bridge = - accessibility_helper_bridge(); - arc_notification_surface_manager_->AddObserver(helper_bridge); - - const auto& notification_key_to_tree_ = - helper_bridge->notification_key_to_tree_for_test(); - ASSERT_EQ(0U, notification_key_to_tree_.size()); - - // mojo: notification 1 created - auto event1 = arc::mojom::AccessibilityEventData::New(); - event1->event_type = arc::mojom::AccessibilityEventType::WINDOW_STATE_CHANGED; - event1->notification_key = base::make_optional<std::string>(kNotificationKey); - event1->node_data.push_back(arc::mojom::AccessibilityNodeInfoData::New()); - helper_bridge->OnAccessibilityEvent(event1.Clone()); - - EXPECT_EQ(1U, notification_key_to_tree_.size()); - - // wayland: surface 1 added - FakeArcNotificationSurface test_surface1(kNotificationKey); - arc_notification_surface_manager_->AddSurface(&test_surface1); - - auto it = notification_key_to_tree_.find(kNotificationKey); - EXPECT_NE(notification_key_to_tree_.end(), it); - AXTreeSourceArc* tree = it->second.get(); - ui::AXTreeData tree_data; - tree->GetTreeData(&tree_data); - EXPECT_EQ(tree_data.tree_id, test_surface1.GetAXTreeId()); - - // mojo: notification 2 created - auto event2 = arc::mojom::AccessibilityEventData::New(); - event2->event_type = arc::mojom::AccessibilityEventType::WINDOW_STATE_CHANGED; - event2->notification_key = base::make_optional<std::string>(kNotificationKey); - event2->node_data.push_back(arc::mojom::AccessibilityNodeInfoData::New()); - helper_bridge->OnAccessibilityEvent(event2.Clone()); - - auto it2 = notification_key_to_tree_.find(kNotificationKey); - EXPECT_NE(notification_key_to_tree_.end(), it); - AXTreeSourceArc* tree2 = it2->second.get(); - ui::AXTreeData tree_data2; - tree2->GetTreeData(&tree_data2); - EXPECT_EQ(tree_data2.tree_id, test_surface1.GetAXTreeId()); - - // wayland: surface 1 removed - arc_notification_surface_manager_->RemoveSurface(&test_surface1); - - EXPECT_EQ(1U, notification_key_to_tree_.size()); - - // wayland: surface 2 added - FakeArcNotificationSurface test_surface2(kNotificationKey); - arc_notification_surface_manager_->AddSurface(&test_surface2); - - EXPECT_EQ(tree_data2.tree_id, test_surface2.GetAXTreeId()); - - // wayland: surface 2 removed - arc_notification_surface_manager_->RemoveSurface(&test_surface2); - - EXPECT_EQ(0U, notification_key_to_tree_.size()); - - // wayland: surface 3 added - FakeArcNotificationSurface test_surface3(kNotificationKey); - arc_notification_surface_manager_->AddSurface(&test_surface3); - - // mojo: notification 3 created - auto event3 = arc::mojom::AccessibilityEventData::New(); - event3->event_type = arc::mojom::AccessibilityEventType::WINDOW_STATE_CHANGED; - event3->notification_key = base::make_optional<std::string>(kNotificationKey); - event3->node_data.push_back(arc::mojom::AccessibilityNodeInfoData::New()); - helper_bridge->OnAccessibilityEvent(event3.Clone()); - - EXPECT_EQ(1U, notification_key_to_tree_.size()); - - auto it3 = notification_key_to_tree_.find(kNotificationKey); - EXPECT_NE(notification_key_to_tree_.end(), it3); - AXTreeSourceArc* tree3 = it3->second.get(); - ui::AXTreeData tree_data3; - tree3->GetTreeData(&tree_data3); - EXPECT_EQ(tree_data3.tree_id, test_surface3.GetAXTreeId()); - - // wayland: surface 3 removed - arc_notification_surface_manager_->RemoveSurface(&test_surface3); - - EXPECT_EQ(0U, notification_key_to_tree_.size()); -} - // This is the case where surface creation/removal arrive before mojo events. // // wayland: surface 1 added
diff --git a/chrome/browser/chromeos/crostini/crostini_util.cc b/chrome/browser/chromeos/crostini/crostini_util.cc index ef646d96..6d82c04 100644 --- a/chrome/browser/chromeos/crostini/crostini_util.cc +++ b/chrome/browser/chromeos/crostini/crostini_util.cc
@@ -73,9 +73,7 @@ } bool IsCrostiniUIAllowedForProfile(Profile* profile) { - if (!profile || profile->IsOffTheRecord() || - chromeos::ProfileHelper::IsEphemeralUserProfile(profile) || - chromeos::ProfileHelper::IsLockScreenAppProfile(profile)) { + if (!chromeos::ProfileHelper::IsPrimaryProfile(profile)) { return false; }
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc index 2a00be6..e30e41e 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
@@ -67,6 +67,14 @@ void TearDownInProcessBrowserTestFixture() override { extension_ = NULL; } + ui::IMEEngineHandlerInterface::InputContext CreateInputContextWithInputType( + ui::TextInputType type) { + return ui::IMEEngineHandlerInterface::InputContext( + type, ui::TEXT_INPUT_MODE_DEFAULT, ui::TEXT_INPUT_FLAG_NONE, + ui::TextInputClient::FOCUS_REASON_OTHER, + false /* should_do_learning */); + } + protected: void LoadTestInputMethod() { // This will load "chrome/test/data/extensions/input_ime" @@ -179,11 +187,10 @@ ASSERT_TRUE(activated_listener.was_satisfied()); // onFocus event should be fired if FocusIn function is called. - ExtensionTestMessageListener focus_listener("onFocus:text:true:true:true", - false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + ExtensionTestMessageListener focus_listener( + "onFocus:text:true:true:true:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_TEXT); engine_handler->FocusIn(context); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied()); @@ -262,9 +269,8 @@ ASSERT_TRUE(host); engine_handler->Enable("APIArgumentIME"); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_TEXT); engine_handler->FocusIn(context); { @@ -937,61 +943,55 @@ mock_candidate_window->Reset(); { - ExtensionTestMessageListener focus_listener("onFocus:text:true:true:true", - false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + ExtensionTestMessageListener focus_listener( + "onFocus:text:true:true:true:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_TEXT); engine_handler->FocusIn(context); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied()); } { ExtensionTestMessageListener focus_listener( - "onFocus:search:true:true:true", false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_SEARCH, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); - engine_handler->FocusIn(context); - ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); - ASSERT_TRUE(focus_listener.was_satisfied()); - } - { - ExtensionTestMessageListener focus_listener("onFocus:tel:true:true:true", - false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_TELEPHONE, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); - engine_handler->FocusIn(context); - ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); - ASSERT_TRUE(focus_listener.was_satisfied()); - } - { - ExtensionTestMessageListener focus_listener("onFocus:url:true:true:true", - false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_URL, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + "onFocus:search:true:true:true:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_SEARCH); engine_handler->FocusIn(context); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied()); } { ExtensionTestMessageListener focus_listener( - "onFocus:email:true:true:true", false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_EMAIL, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + "onFocus:tel:true:true:true:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_TELEPHONE); engine_handler->FocusIn(context); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied()); } { ExtensionTestMessageListener focus_listener( - "onFocus:number:true:true:true", false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_NUMBER, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + "onFocus:url:true:true:true:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_URL); + engine_handler->FocusIn(context); + ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); + ASSERT_TRUE(focus_listener.was_satisfied()); + } + { + ExtensionTestMessageListener focus_listener( + "onFocus:email:true:true:true:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_EMAIL); + engine_handler->FocusIn(context); + ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); + ASSERT_TRUE(focus_listener.was_satisfied()); + } + { + ExtensionTestMessageListener focus_listener( + "onFocus:number:true:true:true:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_NUMBER); engine_handler->FocusIn(context); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied()); @@ -1090,10 +1090,9 @@ SCOPED_TRACE("Text"); ExtensionTestMessageListener focus_listener( - "onFocus:text:false:false:false", false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + "onFocus:text:false:false:false:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_TEXT); engine_handler->FocusIn(context); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied()); @@ -1102,10 +1101,9 @@ SCOPED_TRACE("Password"); ExtensionTestMessageListener focus_listener( - "onFocus:password:false:false:false", false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_PASSWORD, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + "onFocus:password:false:false:false:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_PASSWORD); engine_handler->FocusIn(context); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied()); @@ -1113,11 +1111,10 @@ { SCOPED_TRACE("URL"); - ExtensionTestMessageListener focus_listener("onFocus:url:false:false:false", - false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_URL, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + ExtensionTestMessageListener focus_listener( + "onFocus:url:false:false:false:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_URL); engine_handler->FocusIn(context); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied()); @@ -1126,10 +1123,9 @@ SCOPED_TRACE("Search"); ExtensionTestMessageListener focus_listener( - "onFocus:search:false:false:false", false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_SEARCH, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + "onFocus:search:false:false:false:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_SEARCH); engine_handler->FocusIn(context); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied()); @@ -1138,10 +1134,9 @@ SCOPED_TRACE("Email"); ExtensionTestMessageListener focus_listener( - "onFocus:email:false:false:false", false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_EMAIL, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + "onFocus:email:false:false:false:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_EMAIL); engine_handler->FocusIn(context); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied()); @@ -1150,10 +1145,9 @@ SCOPED_TRACE("Number"); ExtensionTestMessageListener focus_listener( - "onFocus:number:false:false:false", false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_NUMBER, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + "onFocus:number:false:false:false:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_NUMBER); engine_handler->FocusIn(context); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied()); @@ -1161,17 +1155,45 @@ { SCOPED_TRACE("Telephone"); - ExtensionTestMessageListener focus_listener("onFocus:tel:false:false:false", - false); - ui::IMEEngineHandlerInterface::InputContext context( - ui::TEXT_INPUT_TYPE_TELEPHONE, ui::TEXT_INPUT_MODE_DEFAULT, - ui::TEXT_INPUT_FLAG_NONE, ui::TextInputClient::FOCUS_REASON_OTHER); + ExtensionTestMessageListener focus_listener( + "onFocus:tel:false:false:false:false", false); + const auto context = + CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_TELEPHONE); engine_handler->FocusIn(context); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied()); } } +IN_PROC_BROWSER_TEST_P(InputMethodEngineBrowserTest, ShouldDoLearning) { + LoadTestInputMethod(); + + InputMethodManager::Get()->GetActiveIMEState()->ChangeInputMethod( + kIdentityIMEID, false /* show_message */); + + std::unique_ptr<ui::MockIMEInputContextHandler> mock_input_context( + new ui::MockIMEInputContextHandler()); + std::unique_ptr<MockIMECandidateWindowHandler> mock_candidate_window( + new MockIMECandidateWindowHandler()); + + ui::IMEBridge::Get()->SetInputContextHandler(mock_input_context.get()); + ui::IMEBridge::Get()->SetCandidateWindowHandler(mock_candidate_window.get()); + + ui::IMEEngineHandlerInterface* engine_handler = + ui::IMEBridge::Get()->GetCurrentEngineHandler(); + ASSERT_TRUE(engine_handler); + engine_handler->Enable("IdentityIME"); + + // onFocus event should be fired if FocusIn function is called. + ExtensionTestMessageListener focus_listener( + "onFocus:text:true:true:true:true", false); + auto context = CreateInputContextWithInputType(ui::TEXT_INPUT_TYPE_TEXT); + context.should_do_learning = true; + engine_handler->FocusIn(context); + ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); + ASSERT_TRUE(focus_listener.was_satisfied()); +} + } // namespace } // namespace input_method } // namespace chromeos
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc index bfed21db..f3352ee6 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -167,7 +167,8 @@ void FocusIn(ui::TextInputType input_type) { ui::IMEEngineHandlerInterface::InputContext input_context( input_type, ui::TEXT_INPUT_MODE_DEFAULT, ui::TEXT_INPUT_FLAG_NONE, - ui::TextInputClient::FOCUS_REASON_OTHER); + ui::TextInputClient::FOCUS_REASON_OTHER, + false /* should_do_learning */); engine_->FocusIn(input_context); ui::IMEBridge::Get()->SetCurrentInputContext(input_context); }
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api.cc b/chrome/browser/extensions/api/input_ime/input_ime_api.cc index fdf6dab..34b2a98 100644 --- a/chrome/browser/extensions/api/input_ime/input_ime_api.cc +++ b/chrome/browser/extensions/api/input_ime/input_ime_api.cc
@@ -59,6 +59,7 @@ context_value.auto_correct = ConvertInputContextAutoCorrect(context); context_value.auto_complete = ConvertInputContextAutoComplete(context); context_value.spell_check = ConvertInputContextSpellCheck(context); + context_value.should_do_learning = context.should_do_learning; std::unique_ptr<base::ListValue> args( input_ime::OnFocus::Create(context_value));
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc b/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc index b7dc8c6..85611ab 100644 --- a/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc +++ b/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc
@@ -207,6 +207,7 @@ input_context.auto_correct = ConvertInputContextAutoCorrect(context); input_context.auto_complete = ConvertInputContextAutoComplete(context); input_context.spell_check = ConvertInputContextSpellCheck(context); + input_context.should_do_learning = context.should_do_learning; input_context.focus_reason = input_method_private::ParseFocusReason( ConvertInputContextFocusReason(context));
diff --git a/chrome/browser/extensions/bookmark_app_helper.cc b/chrome/browser/extensions/bookmark_app_helper.cc index 2e4a39a..2f248f45 100644 --- a/chrome/browser/extensions/bookmark_app_helper.cc +++ b/chrome/browser/extensions/bookmark_app_helper.cc
@@ -188,10 +188,9 @@ if (generated_icon_color == SK_ColorTRANSPARENT) generated_icon_color = SK_ColorDKGRAY; - for (std::set<int>::const_iterator it = generate_sizes.begin(); - it != generate_sizes.end(); ++it) { + for (int size : generate_sizes) { extensions::BookmarkAppHelper::GenerateIcon( - bitmap_map, *it, generated_icon_color, icon_letter); + bitmap_map, size, generated_icon_color, icon_letter); } } @@ -385,10 +384,10 @@ const std::set<int>& sizes) { std::map<int, BitmapAndSource> output_bitmaps; std::map<int, BitmapAndSource> ordered_bitmaps; - for (std::vector<BitmapAndSource>::const_iterator it = bitmaps.begin(); - it != bitmaps.end(); ++it) { - DCHECK(it->bitmap.width() == it->bitmap.height()); - ordered_bitmaps[it->bitmap.width()] = *it; + for (const BitmapAndSource& bitmap_and_source : bitmaps) { + const SkBitmap& bitmap = bitmap_and_source.bitmap; + DCHECK(bitmap.width() == bitmap.height()); + ordered_bitmaps[bitmap.width()] = bitmap_and_source; } if (ordered_bitmaps.size() > 0) { @@ -442,14 +441,12 @@ // Iterate through the extensions and extract the LaunchWebUrl (bookmark apps) // or check the web extent (hosted apps). - for (extensions::ExtensionSet::const_iterator iter = extensions.begin(); - iter != extensions.end(); ++iter) { - const Extension* extension = iter->get(); + for (const scoped_refptr<const Extension>& extension : extensions) { if (!extension->is_hosted_app()) continue; if (extension->web_extent().MatchesURL(url) || - AppLaunchInfo::GetLaunchWebURL(extension) == url) { + AppLaunchInfo::GetLaunchWebURL(extension.get()) == url) { return true; } } @@ -673,28 +670,20 @@ } std::vector<BitmapAndSource> downloaded_icons; - for (FaviconDownloader::FaviconMap::const_iterator map_it = bitmaps.begin(); - map_it != bitmaps.end(); - ++map_it) { - for (std::vector<SkBitmap>::const_iterator bitmap_it = - map_it->second.begin(); - bitmap_it != map_it->second.end(); - ++bitmap_it) { - if (bitmap_it->empty() || bitmap_it->width() != bitmap_it->height()) + for (const std::pair<GURL, std::vector<SkBitmap>>& url_bitmap : bitmaps) { + for (const SkBitmap& bitmap : url_bitmap.second) { + if (bitmap.empty() || bitmap.width() != bitmap.height()) continue; - downloaded_icons.push_back(BitmapAndSource(map_it->first, *bitmap_it)); + downloaded_icons.push_back(BitmapAndSource(url_bitmap.first, bitmap)); } } // Add all existing icons from WebApplicationInfo. - for (std::vector<WebApplicationInfo::IconInfo>::const_iterator it = - web_app_info_.icons.begin(); - it != web_app_info_.icons.end(); - ++it) { - const SkBitmap& icon = it->data; + for (const WebApplicationInfo::IconInfo& icon_info : web_app_info_.icons) { + const SkBitmap& icon = icon_info.data; if (!icon.drawsNothing() && icon.width() == icon.height()) { - downloaded_icons.push_back(BitmapAndSource(it->url, icon)); + downloaded_icons.push_back(BitmapAndSource(icon_info.url, icon)); } }
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.cc b/chrome/browser/media/router/mojo/media_router_desktop.cc index dca903dc..02f46c8 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/media/router/mojo/media_route_controller.h" #include "chrome/browser/media/router/mojo/media_router_mojo_metrics.h" #include "chrome/browser/media/router/providers/cast/cast_media_route_provider.h" +#include "chrome/browser/media/router/providers/cast/chrome_cast_message_handler.h" #include "chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_features.h" @@ -243,7 +244,9 @@ new CastMediaRouteProvider( mojo::MakeRequest(&cast_provider_ptr), media_router_ptr.PassInterface(), - media_sink_service_->cast_app_discovery_service(), task_runner), + media_sink_service_->GetCastMediaSinkServiceImpl(), + media_sink_service_->cast_app_discovery_service(), + GetCastMessageHandler(), task_runner), base::OnTaskRunnerDeleter(task_runner)); RegisterMediaRouteProvider(MediaRouteProviderId::CAST, std::move(cast_provider_ptr), base::DoNothing());
diff --git a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc index 291ef691..adad5fa 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc +++ b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.cc
@@ -37,7 +37,7 @@ } // namespace -CastAppDiscoveryService::CastAppDiscoveryService( +CastAppDiscoveryServiceImpl::CastAppDiscoveryServiceImpl( cast_channel::CastMessageHandler* message_handler, cast_channel::CastSocketService* socket_service, MediaSinkServiceBase* media_sink_service, @@ -52,17 +52,17 @@ DCHECK(socket_service_); DCHECK(clock_); socket_service_->task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&CastAppDiscoveryService::Init, base::Unretained(this))); + FROM_HERE, base::BindOnce(&CastAppDiscoveryServiceImpl::Init, + base::Unretained(this))); } -CastAppDiscoveryService::~CastAppDiscoveryService() { +CastAppDiscoveryServiceImpl::~CastAppDiscoveryServiceImpl() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); media_sink_service_->RemoveObserver(this); } CastAppDiscoveryService::Subscription -CastAppDiscoveryService::StartObservingMediaSinks( +CastAppDiscoveryServiceImpl::StartObservingMediaSinks( const CastMediaSource& source, const SinkQueryCallback& callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -77,9 +77,9 @@ auto& callback_list = sink_queries_[source_id]; if (!callback_list) { callback_list = std::make_unique<SinkQueryCallbackList>(); - callback_list->set_removal_callback( - base::BindRepeating(&CastAppDiscoveryService::MaybeRemoveSinkQueryEntry, - base::Unretained(this), source)); + callback_list->set_removal_callback(base::BindRepeating( + &CastAppDiscoveryServiceImpl::MaybeRemoveSinkQueryEntry, + base::Unretained(this), source)); // Note: even though we retain availability results for an app unregistered // from the tracker, we will send app availability requests again when it @@ -108,7 +108,7 @@ return callback_list->Add(callback); } -void CastAppDiscoveryService::Refresh() { +void CastAppDiscoveryServiceImpl::Refresh() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); const auto app_ids = availability_tracker_.GetRegisteredApps(); base::TimeTicks now = clock_->NowTicks(); @@ -133,7 +133,7 @@ } } -void CastAppDiscoveryService::MaybeRemoveSinkQueryEntry( +void CastAppDiscoveryServiceImpl::MaybeRemoveSinkQueryEntry( const CastMediaSource& source) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); auto it = sink_queries_.find(source.source_id()); @@ -145,12 +145,12 @@ } } -void CastAppDiscoveryService::Init() { +void CastAppDiscoveryServiceImpl::Init() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); media_sink_service_->AddObserver(this); } -void CastAppDiscoveryService::OnSinkAddedOrUpdated( +void CastAppDiscoveryServiceImpl::OnSinkAddedOrUpdated( const MediaSinkInternal& sink) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -169,24 +169,24 @@ } } -void CastAppDiscoveryService::OnSinkRemoved(const MediaSinkInternal& sink) { +void CastAppDiscoveryServiceImpl::OnSinkRemoved(const MediaSinkInternal& sink) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); const MediaSink::Id& sink_id = sink.sink().id(); UpdateSinkQueries(availability_tracker_.RemoveResultsForSink(sink_id)); } -void CastAppDiscoveryService::RequestAppAvailability( +void CastAppDiscoveryServiceImpl::RequestAppAvailability( cast_channel::CastSocket* socket, const std::string& app_id, const MediaSink::Id& sink_id) { message_handler_->RequestAppAvailability( socket, app_id, - base::BindOnce(&CastAppDiscoveryService::UpdateAppAvailability, + base::BindOnce(&CastAppDiscoveryServiceImpl::UpdateAppAvailability, weak_ptr_factory_.GetWeakPtr(), clock_->NowTicks(), sink_id)); } -void CastAppDiscoveryService::UpdateAppAvailability( +void CastAppDiscoveryServiceImpl::UpdateAppAvailability( base::TimeTicks start_time, const MediaSink::Id& sink_id, const std::string& app_id, @@ -203,7 +203,7 @@ sink_id, app_id, {availability, clock_->NowTicks()})); } -void CastAppDiscoveryService::UpdateSinkQueries( +void CastAppDiscoveryServiceImpl::UpdateSinkQueries( const std::vector<CastMediaSource>& sources) { for (const auto& source : sources) { const MediaSource::Id& source_id = source.source_id(); @@ -216,7 +216,7 @@ } } -std::vector<MediaSinkInternal> CastAppDiscoveryService::GetSinksByIds( +std::vector<MediaSinkInternal> CastAppDiscoveryServiceImpl::GetSinksByIds( const base::flat_set<MediaSink::Id>& sink_ids) const { std::vector<MediaSinkInternal> sinks; for (const auto& sink_id : sink_ids) {
diff --git a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.h b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.h index 4748f6b..def76dc 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_discovery_service.h +++ b/chrome/browser/media/router/providers/cast/cast_app_discovery_service.h
@@ -35,11 +35,8 @@ namespace media_router { -// Keeps track of sink queries and listens to CastMediaSinkServiceImpl for sink -// updates, and issues app availability requests based on these signals. This -// class may be created on any sequence. All other methods must be called on the -// CastSocketService sequence. -class CastAppDiscoveryService : public MediaSinkServiceBase::Observer { +// Interface for app discovery for Cast MediaSinks. +class CastAppDiscoveryService { public: using SinkQueryFunc = void(const MediaSource::Id& source_id, const std::vector<MediaSinkInternal>& sinks); @@ -47,27 +44,46 @@ using SinkQueryCallbackList = base::CallbackList<SinkQueryFunc>; using Subscription = std::unique_ptr<SinkQueryCallbackList::Subscription>; - CastAppDiscoveryService(cast_channel::CastMessageHandler* message_handler, - cast_channel::CastSocketService* socket_service, - MediaSinkServiceBase* media_sink_service, - const base::TickClock* clock); - ~CastAppDiscoveryService() override; + virtual ~CastAppDiscoveryService() = default; // Adds a sink query for |source|. Results will be continuously returned via // |callback| until the returned Subscription is destroyed by the caller. // If there are cached results available, |callback| will be invoked before // this method returns. - Subscription StartObservingMediaSinks(const CastMediaSource& source, - const SinkQueryCallback& callback); + virtual Subscription StartObservingMediaSinks( + const CastMediaSource& source, + const SinkQueryCallback& callback) = 0; - // Reissues app availability requests for currently registered (sink, app_id) - // pairs whose status is kUnavailable or kUnknown. It is suitable to call + // Refreshes the state of app discovery in the service. It is suitable to call // this method when the user initiates a user gesture (such as opening the // Media Router dialog). - void Refresh(); + virtual void Refresh() = 0; +}; + +// Keeps track of sink queries and listens to CastMediaSinkServiceImpl for sink +// updates, and issues app availability requests based on these signals. This +// class may be created on any sequence. All other methods must be called on the +// CastSocketService sequence. +class CastAppDiscoveryServiceImpl : public CastAppDiscoveryService, + public MediaSinkServiceBase::Observer { + public: + CastAppDiscoveryServiceImpl(cast_channel::CastMessageHandler* message_handler, + cast_channel::CastSocketService* socket_service, + MediaSinkServiceBase* media_sink_service, + const base::TickClock* clock); + ~CastAppDiscoveryServiceImpl() override; + + // CastAppDiscoveryService implementation. + Subscription StartObservingMediaSinks( + const CastMediaSource& source, + const SinkQueryCallback& callback) override; + + // Reissues app availability requests for currently registered (sink, app_id) + // pairs whose status is kUnavailable or kUnknown. + void Refresh() override; private: - friend class CastAppDiscoveryServiceTest; + friend class CastAppDiscoveryServiceImplTest; // Called on construction. Registers an observer with |media_sink_service_|. void Init(); @@ -115,8 +131,8 @@ const base::TickClock* const clock_; SEQUENCE_CHECKER(sequence_checker_); - base::WeakPtrFactory<CastAppDiscoveryService> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(CastAppDiscoveryService); + base::WeakPtrFactory<CastAppDiscoveryServiceImpl> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(CastAppDiscoveryServiceImpl); }; } // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc b/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc index 32e2f18..de86665 100644 --- a/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc
@@ -28,10 +28,10 @@ socket_service_(task_runner_), message_handler_(&socket_service_), app_discovery_service_( - std::make_unique<CastAppDiscoveryService>(&message_handler_, - &socket_service_, - &media_sink_service_, - &clock_)), + std::make_unique<CastAppDiscoveryServiceImpl>(&message_handler_, + &socket_service_, + &media_sink_service_, + &clock_)), source_a_1_(*CastMediaSource::From("cast:AAAAAAAA?clientId=1")), source_a_2_(*CastMediaSource::From("cast:AAAAAAAA?clientId=2")), source_b_1_(*CastMediaSource::From("cast:BBBBBBBB?clientId=1")) {
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc index 26c400d..3cdfa5c 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc
@@ -6,6 +6,7 @@ #include "base/stl_util.h" #include "chrome/common/media_router/providers/cast/cast_media_source.h" +#include "components/cast_channel/cast_message_handler.h" #include "url/origin.h" namespace media_router { @@ -34,11 +35,18 @@ CastMediaRouteProvider::CastMediaRouteProvider( mojom::MediaRouteProviderRequest request, mojom::MediaRouterPtrInfo media_router, + MediaSinkServiceBase* media_sink_service, CastAppDiscoveryService* app_discovery_service, - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) - : binding_(this), app_discovery_service_(app_discovery_service) { + cast_channel::CastMessageHandler* message_handler, + const scoped_refptr<base::SequencedTaskRunner>& task_runner) + : binding_(this), + media_sink_service_(media_sink_service), + app_discovery_service_(app_discovery_service), + message_handler_(message_handler) { DETACH_FROM_SEQUENCE(sequence_checker_); + DCHECK(media_sink_service_); DCHECK(app_discovery_service_); + DCHECK(message_handler_); task_runner->PostTask( FROM_HERE, @@ -145,8 +153,9 @@ // A broadcast request is not an actual sink query; it is used to send a // app precache message to receivers. if (cast_source->broadcast_request()) { - // TODO(crbug.com/809249): Implement broadcast, or figure out a re-design - // that does not use sink queries. + // TODO(imcheng): Add metric to record broadcast usage. + BroadcastMessageToSinks(cast_source->GetAppIds(), + *cast_source->broadcast_request()); return; } @@ -227,4 +236,14 @@ GetOrigins(source_id)); } +void CastMediaRouteProvider::BroadcastMessageToSinks( + const std::vector<std::string>& app_ids, + const cast_channel::BroadcastRequest& request) { + for (const auto& id_and_sink : media_sink_service_->GetSinks()) { + const MediaSinkInternal& sink = id_and_sink.second; + message_handler_->SendBroadcastMessage(sink.cast_data().cast_channel_id, + app_ids, request); + } +} + } // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider.h b/chrome/browser/media/router/providers/cast/cast_media_route_provider.h index 5dd7b23..b23da2d 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider.h +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider.h
@@ -12,6 +12,10 @@ #include "chrome/common/media_router/mojo/media_router.mojom.h" #include "mojo/public/cpp/bindings/binding.h" +namespace cast_channel { +class CastMessageHandler; +} + namespace url { class Origin; } @@ -26,8 +30,10 @@ CastMediaRouteProvider( mojom::MediaRouteProviderRequest request, mojom::MediaRouterPtrInfo media_router, + MediaSinkServiceBase* media_sink_service, CastAppDiscoveryService* app_discovery_service, - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); + cast_channel::CastMessageHandler* message_handler, + const scoped_refptr<base::SequencedTaskRunner>& task_runner); ~CastMediaRouteProvider() override; // mojom::MediaRouteProvider: @@ -92,15 +98,25 @@ void OnSinkQueryUpdated(const MediaSource::Id& source_id, const std::vector<MediaSinkInternal>& sinks); + // Broadcasts a message with |app_ids| and |requests| to all sinks. + void BroadcastMessageToSinks(const std::vector<std::string>& app_ids, + const cast_channel::BroadcastRequest& request); + // Binds |this| to the Mojo request passed into the ctor. mojo::Binding<mojom::MediaRouteProvider> binding_; // Mojo pointer to the Media Router. mojom::MediaRouterPtr media_router_; + // Non-owned pointer to the Cast MediaSinkServiceBase. + MediaSinkServiceBase* const media_sink_service_; + // Non-owned pointer to the CastAppDiscoveryService instance. CastAppDiscoveryService* const app_discovery_service_; + // Non-owned pointer to the CastMessageHandler instance. + cast_channel::CastMessageHandler* const message_handler_; + // Registered sink queries. base::flat_map<MediaSource::Id, CastAppDiscoveryService::Subscription> sink_queries_;
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc new file mode 100644 index 0000000..b32a575 --- /dev/null +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc
@@ -0,0 +1,93 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/media/router/providers/cast/cast_media_route_provider.h" + +#include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" +#include "base/test/test_simple_task_runner.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "chrome/browser/media/router/test/mock_mojo_media_router.h" +#include "chrome/browser/media/router/test/test_helper.h" +#include "chrome/common/media_router/test/test_helper.h" +#include "components/cast_channel/cast_test_util.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; + +namespace media_router { + +class CastMediaRouteProviderTest : public testing::Test { + public: + CastMediaRouteProviderTest() + : socket_service_(new base::TestSimpleTaskRunner()), + message_handler_(&socket_service_) {} + ~CastMediaRouteProviderTest() override = default; + + void SetUp() override { + mojom::MediaRouterPtr router_ptr; + router_binding_ = std::make_unique<mojo::Binding<mojom::MediaRouter>>( + &mock_router_, mojo::MakeRequest(&router_ptr)); + + EXPECT_CALL(mock_router_, OnSinkAvailabilityUpdated(_, _)); + provider_ = std::make_unique<CastMediaRouteProvider>( + mojo::MakeRequest(&provider_ptr_), router_ptr.PassInterface(), + &media_sink_service_, &app_discovery_service_, &message_handler_, + base::SequencedTaskRunnerHandle::Get()); + + base::RunLoop().RunUntilIdle(); + } + + void TearDown() override { provider_.reset(); } + + protected: + base::test::ScopedTaskEnvironment environment_; + mojom::MediaRouteProviderPtr provider_ptr_; + MockMojoMediaRouter mock_router_; + std::unique_ptr<mojo::Binding<mojom::MediaRouter>> router_binding_; + + cast_channel::MockCastSocketService socket_service_; + cast_channel::MockCastMessageHandler message_handler_; + + TestMediaSinkService media_sink_service_; + MockCastAppDiscoveryService app_discovery_service_; + std::unique_ptr<CastMediaRouteProvider> provider_; + + private: + DISALLOW_COPY_AND_ASSIGN(CastMediaRouteProviderTest); +}; + +TEST_F(CastMediaRouteProviderTest, StartObservingMediaSinks) { + MediaSource::Id non_cast_source("not-a-cast-source:foo"); + EXPECT_CALL(app_discovery_service_, DoStartObservingMediaSinks(_)).Times(0); + provider_->StartObservingMediaSinks(non_cast_source); + + MediaSource::Id cast_source("cast:ABCDEFGH"); + EXPECT_CALL(app_discovery_service_, DoStartObservingMediaSinks(_)); + provider_->StartObservingMediaSinks(cast_source); + EXPECT_FALSE(app_discovery_service_.callbacks().empty()); + + provider_->StopObservingMediaSinks(cast_source); + EXPECT_TRUE(app_discovery_service_.callbacks().empty()); +} + +TEST_F(CastMediaRouteProviderTest, BroadcastRequest) { + media_sink_service_.AddOrUpdateSink(CreateCastSink(1)); + media_sink_service_.AddOrUpdateSink(CreateCastSink(2)); + MediaSource::Id source_id( + "cast:ABCDEFAB?capabilities=video_out,audio_out" + "&broadcastNamespace=namespace" + "&broadcastMessage=message"); + + std::vector<std::string> app_ids = {"ABCDEFAB"}; + cast_channel::BroadcastRequest request("namespace", "message"); + EXPECT_CALL(message_handler_, SendBroadcastMessage(1, app_ids, request)); + EXPECT_CALL(message_handler_, SendBroadcastMessage(2, app_ids, request)); + EXPECT_CALL(app_discovery_service_, DoStartObservingMediaSinks(_)).Times(0); + provider_->StartObservingMediaSinks(source_id); + EXPECT_TRUE(app_discovery_service_.callbacks().empty()); +} + +} // namespace media_router
diff --git a/chrome/browser/media/router/providers/cast/dual_media_sink_service.cc b/chrome/browser/media/router/providers/cast/dual_media_sink_service.cc index 706f3994..c558ef7 100644 --- a/chrome/browser/media/router/providers/cast/dual_media_sink_service.cc +++ b/chrome/browser/media/router/providers/cast/dual_media_sink_service.cc
@@ -38,6 +38,10 @@ return dial_media_sink_service_->impl(); } +MediaSinkServiceBase* DualMediaSinkService::GetCastMediaSinkServiceImpl() { + return cast_media_sink_service_->impl(); +} + DualMediaSinkService::Subscription DualMediaSinkService::AddSinksDiscoveredCallback( const OnSinksDiscoveredProviderCallback& callback) { @@ -75,10 +79,11 @@ if (CastMediaRouteProviderEnabled()) { cast_channel::CastSocketService* cast_socket_service = cast_channel::CastSocketService::GetInstance(); - cast_app_discovery_service_ = std::make_unique<CastAppDiscoveryService>( - GetCastMessageHandler(), cast_socket_service, - cast_media_sink_service_->impl(), - base::DefaultTickClock::GetInstance()); + cast_app_discovery_service_ = + std::make_unique<CastAppDiscoveryServiceImpl>( + GetCastMessageHandler(), cast_socket_service, + cast_media_sink_service_->impl(), + base::DefaultTickClock::GetInstance()); } } }
diff --git a/chrome/browser/media/router/providers/cast/dual_media_sink_service.h b/chrome/browser/media/router/providers/cast/dual_media_sink_service.h index 21a801d..b5ea6ca 100644 --- a/chrome/browser/media/router/providers/cast/dual_media_sink_service.h +++ b/chrome/browser/media/router/providers/cast/dual_media_sink_service.h
@@ -59,6 +59,9 @@ // Used by DialMediaRouteProvider only. DialMediaSinkServiceImpl* GetDialMediaSinkServiceImpl(); + // Used by CastMediaRouteProvider only. + MediaSinkServiceBase* GetCastMediaSinkServiceImpl(); + CastAppDiscoveryService* cast_app_discovery_service() { return cast_app_discovery_service_.get(); }
diff --git a/chrome/browser/media/router/test/test_helper.cc b/chrome/browser/media/router/test/test_helper.cc index 7556e85..609ef90 100644 --- a/chrome/browser/media/router/test/test_helper.cc +++ b/chrome/browser/media/router/test/test_helper.cc
@@ -61,6 +61,17 @@ MockCastMediaSinkService::MockCastMediaSinkService() : CastMediaSinkService() {} MockCastMediaSinkService::~MockCastMediaSinkService() = default; +MockCastAppDiscoveryService::MockCastAppDiscoveryService() {} +MockCastAppDiscoveryService::~MockCastAppDiscoveryService() = default; + +CastAppDiscoveryService::Subscription +MockCastAppDiscoveryService::StartObservingMediaSinks( + const CastMediaSource& source, + const CastAppDiscoveryService::SinkQueryCallback& callback) { + DoStartObservingMediaSinks(source); + return callbacks_.Add(callback); +} + MockDialAppDiscoveryService::MockDialAppDiscoveryService() : DialAppDiscoveryService(/*connector=*/nullptr) {} MockDialAppDiscoveryService::~MockDialAppDiscoveryService() = default;
diff --git a/chrome/browser/media/router/test/test_helper.h b/chrome/browser/media/router/test/test_helper.h index bf6b9315..30b37ee 100644 --- a/chrome/browser/media/router/test/test_helper.h +++ b/chrome/browser/media/router/test/test_helper.h
@@ -26,6 +26,7 @@ #include "chrome/browser/media/router/discovery/dial/dial_url_fetcher.h" #include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h" #include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.h" +#include "chrome/browser/media/router/providers/cast/cast_app_discovery_service.h" #include "chrome/browser/media/router/providers/dial/dial_activity_manager.h" #include "chrome/common/media_router/discovery/media_sink_internal.h" #include "net/base/ip_endpoint.h" @@ -138,6 +139,23 @@ MOCK_METHOD0(StartMdnsDiscovery, void()); }; +class MockCastAppDiscoveryService : public CastAppDiscoveryService { + public: + MockCastAppDiscoveryService(); + ~MockCastAppDiscoveryService() override; + + Subscription StartObservingMediaSinks( + const CastMediaSource& source, + const SinkQueryCallback& callback) override; + MOCK_METHOD1(DoStartObservingMediaSinks, void(const CastMediaSource&)); + MOCK_METHOD0(Refresh, void()); + + SinkQueryCallbackList& callbacks() { return callbacks_; } + + private: + SinkQueryCallbackList callbacks_; +}; + class MockDialAppDiscoveryService : public DialAppDiscoveryService { public: MockDialAppDiscoveryService();
diff --git a/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html b/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html index 32ef3ea..b2daa381 100644 --- a/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html +++ b/chrome/browser/resources/settings/about_page/channel_switcher_dialog.html
@@ -1,9 +1,9 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-selector/iron-selector.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html"> <link rel="import" href="about_page_browser_proxy.html"> <link rel="import" href="../settings_shared_css.html"> @@ -21,17 +21,17 @@ <!-- TODO(dbeam): this can be policy-controlled. Show this in the UI. https://www.chromium.org/administrators/policy-list-3#ChromeOsReleaseChannel --> - <paper-radio-group + <paper-radio-group selectable="cr-radio-button" on-paper-radio-group-changed="onChannelSelectionChanged_"> - <paper-radio-button name="[[browserChannelEnum_.STABLE]]"> + <cr-radio-button name="[[browserChannelEnum_.STABLE]]"> $i18n{aboutChannelDialogStable} - </paper-radio-button> - <paper-radio-button name="[[browserChannelEnum_.BETA]]"> + </cr-radio-button> + <cr-radio-button name="[[browserChannelEnum_.BETA]]"> $i18n{aboutChannelDialogBeta} - </paper-radio-button> - <paper-radio-button name="[[browserChannelEnum_.DEV]]"> + </cr-radio-button> + <cr-radio-button name="[[browserChannelEnum_.DEV]]"> $i18n{aboutChannelDialogDev} - </paper-radio-button> + </cr-radio-button> </paper-radio-group> <iron-selector id="warningSelector"> <div>
diff --git a/chrome/browser/resources/settings/controls/BUILD.gn b/chrome/browser/resources/settings/controls/BUILD.gn index c624702..21618639 100644 --- a/chrome/browser/resources/settings/controls/BUILD.gn +++ b/chrome/browser/resources/settings/controls/BUILD.gn
@@ -33,6 +33,7 @@ ":pref_control_behavior", "../prefs:pref_util", "//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted", + "//ui/webui/resources/cr_elements/cr_radio_button:cr_radio_button_behavior", "//ui/webui/resources/js:assert", ] externs_list = [ "$externs_path/settings_private.js" ]
diff --git a/chrome/browser/resources/settings/controls/controlled_radio_button.html b/chrome/browser/resources/settings/controls/controlled_radio_button.html index 018f8dd..a8260c2 100644 --- a/chrome/browser/resources/settings/controls/controlled_radio_button.html +++ b/chrome/browser/resources/settings/controls/controlled_radio_button.html
@@ -1,5 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button_behavior.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button_style_css.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> <link rel="import" href="pref_control_behavior.html"> @@ -8,109 +10,15 @@ <dom-module id="controlled-radio-button"> <template> - <style include="settings-shared"> - :host { - --ink-to-circle: calc((var(--paper-radio-button-ink-size) - - var(--paper-radio-button-size)) / 2); - @apply --settings-actionable; - align-items: center; - display: flex; - outline: none; - } - - #labelWrapper { - -webkit-margin-start: var(--paper-radio-button-label-spacing, 10px); - flex: 1; - } - - #label { - color: var(--paper-radio-button-label-color, var(--primary-text-color)); - } - - .circle, - .disc, - .disc-wrapper, - paper-ripple { - border-radius: 50%; - } - - .disc-wrapper { - height: var(--paper-radio-button-ink-size); - margin: 0 calc(-1 * var(--ink-to-circle)); - position: relative; - width: var(--paper-radio-button-ink-size); - } - - .circle, - .disc { - box-sizing: border-box; - height: var(--paper-radio-button-size); - left: var(--ink-to-circle); - position: absolute; - top: var(--ink-to-circle); - width: var(--paper-radio-button-size); - } - - .circle { - border: 2px solid var(--paper-radio-button-unchecked-color, - var(--primary-text-color)); - } - - :host([checked]) .circle { - border-color: var(--paper-radio-button-checked-color, - var(--primary-color)); - } - - .disc { - background-color: var(--paper-radio-button-unchecked-background-color, - transparent); - transform: scale(0); - transition: border-color 200ms, transform 200ms; - } - - :host([checked]) .disc { - background-color: var(--paper-radio-button-checked-color, - var(--primary-color)); - transform: scale(0.5); - } - - paper-ripple { - color: var(--paper-radio-button-unchecked-ink-color, - var(--primary-text-color)); - opacity: .6; - } - - :host([checked]) paper-ripple { - color: var(--paper-radio-button-checked-ink-color, - var(--primary-text-color)); - } - - :host(:not([disabled])) { - @apply --settings-actionable; - } - + <style include="settings-shared cr-radio-button-style"> :host([disabled]) { - /* Disable pointer events for this whole element, as outer on-tap gets - * triggered when clicking/tapping anywhere in :host. */ - pointer-events: none; + opacity: 1; } - :host([disabled]) :-webkit-any(.circle, .disc) { - opacity: .5; - } - - :host([disabled]) .circle { - border-color: var(--paper-radio-button-unchecked-color, - var(--primary-text-color)); - } - - :host([disabled][checked]) .disc { - background-color: var(--paper-radio-button-unchecked-color, - var(--primary-text-color)); - } - + /* Disc and label should be transluscent, but not the policy indicator. */ + :host([disabled]) .disc-wrapper, :host([disabled]) #labelWrapper { - opacity: .65; + opacity: var(--cr-disabled-opacity); } cr-policy-pref-indicator { @@ -122,9 +30,8 @@ </style> <div class="disc-wrapper"> - <div class="circle"></div> + <div class="disc-border"></div> <div class="disc"></div> - <paper-ripple center hold-down="[[pressed_]]"></paper-ripple> </div> <div id="labelWrapper">
diff --git a/chrome/browser/resources/settings/controls/controlled_radio_button.js b/chrome/browser/resources/settings/controls/controlled_radio_button.js index 66af565..19bbcef 100644 --- a/chrome/browser/resources/settings/controls/controlled_radio_button.js +++ b/chrome/browser/resources/settings/controls/controlled_radio_button.js
@@ -7,17 +7,10 @@ behaviors: [ PrefControlBehavior, - Polymer.IronA11yKeysBehavior, + CrRadioButtonBehavior, ], properties: { - checked: { - type: Boolean, - value: false, - reflectToAttribute: true, - observer: 'checkedChanged_', - }, - disabled: { type: Boolean, computed: 'computeDisabled_(pref.*)', @@ -25,44 +18,10 @@ observer: 'disabledChanged_', }, - label: { - type: String, - value: '', // Allows the hidden$= binding to run without being set. - }, - name: { type: String, notify: true, }, - - /** @private */ - pressed_: Boolean, - }, - - hostAttributes: { - 'aria-disabled': 'false', - 'aria-checked': 'false', - role: 'radio', - tabindex: 0, - }, - - listeners: { - 'blur': 'updatePressed_', - 'down': 'updatePressed_', - 'focus': 'updatePressed_', - 'up': 'updatePressed_', - }, - - keyBindings: { - // This is mainly for screenreaders, which can perform actions on things - // that aren't focused (only focused things get synthetic click/tap events). - 'enter:keyup': 'click', - 'space:keyup': 'click', - }, - - /** @private */ - checkedChanged_: function() { - this.setAttribute('aria-checked', this.checked ? 'true' : 'false'); }, /** @@ -104,15 +63,4 @@ e.preventDefault(); e.stopPropagation(); }, - - /** - * @param {!Event} e - * @private - */ - updatePressed_: function(e) { - if (this.disabled) - return; - - this.pressed_ = ['down', 'focus'].includes(e.type); - }, });
diff --git a/chrome/browser/resources/settings/controls/settings_radio_group.html b/chrome/browser/resources/settings/controls/settings_radio_group.html index 19c4b1bb..8bc90c2 100644 --- a/chrome/browser/resources/settings/controls/settings_radio_group.html +++ b/chrome/browser/resources/settings/controls/settings_radio_group.html
@@ -1,7 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html"> <link rel="import" href="pref_control_behavior.html"> <link rel="import" href="../prefs/pref_util.html"> <link rel="import" href="../settings_shared_css.html"> @@ -11,7 +11,7 @@ <style include="settings-shared"></style> <div>[[label]]</div> <paper-radio-group selected="{{selected}}" - selectable="paper-radio-button, controlled-radio-button"> + selectable="cr-radio-button, controlled-radio-button"> <slot></slot> </paper-radio-group> </template>
diff --git a/chrome/browser/resources/settings/device_page/pointers.html b/chrome/browser/resources/settings/device_page/pointers.html index 0fb133e..221a442 100644 --- a/chrome/browser/resources/settings/device_page/pointers.html +++ b/chrome/browser/resources/settings/device_page/pointers.html
@@ -1,11 +1,11 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> <link rel="import" href="../controls/settings_radio_group.html"> <link rel="import" href="../controls/settings_slider.html"> <link rel="import" href="../controls/settings_toggle_button.html"> -<link rel="import" href="device_page_browser_proxy.html"> <link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="device_page_browser_proxy.html"> <dom-module id="settings-pointers"> <template> @@ -79,17 +79,17 @@ <div class="list-frame"> <settings-radio-group pref="{{prefs.settings.touchpad.natural_scroll}}"> - <paper-radio-button name="false"> + <cr-radio-button name="false"> $i18n{traditionalScrollLabel} - </paper-radio-button> - <paper-radio-button name="true"> + </cr-radio-button> + <cr-radio-button name="true"> $i18n{naturalScrollLabel} <a href="$i18n{naturalScrollLearnMoreLink}" target="_blank" on-click="onLearnMoreLinkActivated_" on-keydown="onLearnMoreLinkActivated_"> $i18n{naturalScrollLearnMore} </a> - </paper-radio-button> + </cr-radio-button> </settings-radio-group> </div> </div>
diff --git a/chrome/browser/resources/settings/people_page/lock_screen.html b/chrome/browser/resources/settings/people_page/lock_screen.html index a68afd0..590edea 100644 --- a/chrome/browser/resources/settings/people_page/lock_screen.html +++ b/chrome/browser/resources/settings/people_page/lock_screen.html
@@ -1,5 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html"> <link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html"> @@ -43,8 +44,8 @@ display: block; } - paper-radio-button { - --paper-radio-button-label: { + cr-radio-button { + --cr-radio-button-label: { display: flex; line-height: 154%; /* Apply 20px line-height to paper radio button text to match rest of settings line-heights. */ @@ -94,14 +95,13 @@ <div class="list-frame" > <paper-radio-group id="unlockType" disabled$="[[quickUnlockDisabledByPolicy_]]" - selected="{{selectedUnlockType}}"> - <paper-radio-button name="password" class="list-item underbar"> + selected="{{selectedUnlockType}}" selectable="cr-radio-button"> + <cr-radio-button name="password" class="list-item underbar"> <div class="start"> $i18n{lockScreenPasswordOnly} </div> - </paper-radio-button> - <paper-radio-button name="pin+password" - class="list-item"> + </cr-radio-button> + <cr-radio-button name="pin+password" class="list-item"> <div id="pinPasswordDiv" class="start"> $i18n{lockScreenPinOrPassword} </div> @@ -116,7 +116,7 @@ </paper-button> </div> </template> - </paper-radio-button> + </cr-radio-button> </paper-radio-group> </div> </div>
diff --git a/chrome/browser/resources/settings/people_page/sync_page.html b/chrome/browser/resources/settings/people_page/sync_page.html index e3a196f..f1dd27a3 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.html +++ b/chrome/browser/resources/settings/people_page/sync_page.html
@@ -5,12 +5,12 @@ <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-button/paper-radio-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html"> <link rel="import" href="sync_browser_proxy.html"> <link rel="import" href="../privacy_page/personalization_options.html"> @@ -373,13 +373,14 @@ <paper-radio-group disabled$="[[syncPrefs.encryptAllData]]" selected="[[selectedEncryptionRadio_( syncPrefs.passphraseTypeIsCustom)]]" + selectable="cr-radio-button" on-paper-radio-group-changed= "onEncryptionRadioSelectionChanged_"> - <paper-radio-button name="encrypt-with-google" + <cr-radio-button name="encrypt-with-google" class="list-item" disabled="[[syncPrefs.encryptAllData]]"> $i18n{encryptWithGoogleCredentialsLabel} - </paper-radio-button> - <paper-radio-button name="encrypt-with-passphrase" + </cr-radio-button> + <cr-radio-button name="encrypt-with-passphrase" class="list-item" disabled="[[syncPrefs.encryptAllData]]"> <template is="dom-if" if="[[syncPrefs.fullEncryptionBody]]"> <span>[[syncPrefs.fullEncryptionBody]]</span> @@ -389,7 +390,7 @@ $i18nRaw{encryptWithSyncPassphraseLabel} </span> </template> - </paper-radio-button> + </cr-radio-button> </paper-radio-group> <div id="reset-sync-message-box" class="list-item" hidden="[[!syncPrefs.encryptAllData]]">
diff --git a/chrome/browser/resources/settings/settings_shared_css.html b/chrome/browser/resources/settings/settings_shared_css.html index 06bf219..a47b3fa 100644 --- a/chrome/browser/resources/settings/settings_shared_css.html +++ b/chrome/browser/resources/settings/settings_shared_css.html
@@ -105,24 +105,15 @@ color: var(--google-blue-500); } - controlled-radio-button, - paper-radio-button { - --paper-radio-button-checked-color: var(--google-blue-500); - --paper-radio-button-label-spacing: 22px; - --paper-radio-button-radio-container: { - flex-shrink: 0; - }; - --paper-radio-button-unchecked-color: var(--paper-grey-600); - -webkit-margin-start: 2px; - align-items: center; - display: flex; - min-height: var(--settings-row-min-height); - } - paper-radio-group { width: 100%; } + paper-radio-group:focus { + background-color: var(--google-grey-300); + outline: none; + } + /* See also: .no-min-width below. */ .text-elide { @apply --cr-text-elide;
diff --git a/chrome/browser/resources/settings/settings_vars_css.html b/chrome/browser/resources/settings/settings_vars_css.html index 5e9062e..e914c74 100644 --- a/chrome/browser/resources/settings/settings_vars_css.html +++ b/chrome/browser/resources/settings/settings_vars_css.html
@@ -53,9 +53,6 @@ --iron-icon-height: var(--cr-icon-size); --iron-icon-width: var(--cr-icon-size); - --paper-radio-button-ink-size: 40px; - --paper-radio-button-label-color: inherit; - --paper-radio-button-size: 16px; --paper-radio-group-item-padding: 0; --paper-tabs-selection-bar-color: var(--paper-blue-500);
diff --git a/chrome/browser/site_per_process_interactive_browsertest.cc b/chrome/browser/site_per_process_interactive_browsertest.cc index 2e2de26a..0c3dcd5 100644 --- a/chrome/browser/site_per_process_interactive_browsertest.cc +++ b/chrome/browser/site_per_process_interactive_browsertest.cc
@@ -224,7 +224,7 @@ // take time to propagate to the renderer's main thread. content::DOMMessageQueue msg_queue; std::string reply; - SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('f'), + SimulateKeyPress(web_contents, ui::DomKey::FromCharacter('F'), ui::DomCode::US_F, ui::VKEY_F, false, false, false, false); EXPECT_TRUE(msg_queue.WaitForMessage(&reply)); EXPECT_EQ("\"F\"", reply);
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index c7df2e0..30f87332 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -103,6 +103,7 @@ #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" +#include "content/public/browser/network_service_instance.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_frame_host.h" @@ -785,36 +786,6 @@ EXPECT_TRUE(pref_service->IsManagedPreference(pref_name)); } - // Sets the policy identified by |policy_name| to the value specified by - // |list_values|, ensuring that the corresponding list pref |pref_name| is - // updated to match. |policy_name| must specify a policy that is a list of - // string values. - void ConfigureStringListPolicy(PrefService* pref_service, - const char* policy_name, - const char* pref_name, - const std::vector<std::string>& list_values) { - std::unique_ptr<base::ListValue> policy_value = - std::make_unique<base::ListValue>(); - for (const auto& value : list_values) { - policy_value->GetList().emplace_back(value); - } - policy::PolicyMap policy_map; - policy_map.Set(policy_name, policy::POLICY_LEVEL_MANDATORY, - policy::POLICY_SCOPE_MACHINE, policy::POLICY_SOURCE_CLOUD, - std::move(policy_value), nullptr); - - EXPECT_NO_FATAL_FAILURE(UpdateChromePolicy(policy_map)); - - const base::ListValue* pref_value = pref_service->GetList(pref_name); - ASSERT_TRUE(pref_value); - std::vector<std::string> pref_values; - for (const auto& value : pref_value->GetList()) { - ASSERT_TRUE(value.is_string()); - pref_values.push_back(value.GetString()); - } - EXPECT_THAT(pref_values, testing::UnorderedElementsAreArray(list_values)); - } - // Checks that the SSLConfig associated with the net::URLRequestContext // of the |context_getter| has the SSLConfig member identified by |member| // set to |expected|. This is sequenced such that any changes to prefs @@ -949,8 +920,10 @@ policy_provider_.UpdateChromePolicy(policies); ASSERT_TRUE(base::MessageLoopCurrent::Get()); - base::RunLoop loop; - loop.RunUntilIdle(); + base::RunLoop().RunUntilIdle(); + + if (base::FeatureList::IsEnabled(network::features::kNetworkService)) + content::FlushNetworkServiceInstanceForTesting(); } void RunOnIOThreadBlocking(base::OnceClosure task) { @@ -1983,38 +1956,137 @@ CheckSSLConfig(browser()->profile()->GetRequestContext(), member, true)); } -IN_PROC_BROWSER_TEST_P(SSLUITest, - CertificateTransparencyEnforcementDisabledForUrls) { - bool require = true; - net::TransportSecurityState::SetShouldRequireCTForTesting(&require); +class CertificateTransparencySSLUITest : public CertVerifierBrowserTest { + public: + CertificateTransparencySSLUITest() + : CertVerifierBrowserTest(), + https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} + ~CertificateTransparencySSLUITest() override {} - scoped_refptr<net::X509Certificate> cert = https_server_.GetCertificate(); - net::HashValueVector hashes; - hashes.push_back(GetSPKIHash(cert->cert_buffer())); - std::vector<std::string> disabled_urls{"www.google.com"}; + void SetUpOnMainThread() override { + CertVerifierBrowserTest::SetUpOnMainThread(); + host_resolver()->AddRule("*", "127.0.0.1"); + https_server_.AddDefaultHandlers(base::FilePath(kDocRoot)); + } - // Make sure that CT is required without the policy set. - ASSERT_NO_FATAL_FAILURE(CheckCTStatus( - browser()->profile()->GetRequestContext(), disabled_urls.front(), cert, - true, hashes, net::ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS, - net::TransportSecurityState::CTRequirementsStatus:: - CT_REQUIREMENTS_NOT_MET)); - ASSERT_NO_FATAL_FAILURE(CheckCTStatus( - browser()->profile()->GetRequestContext(), disabled_urls.front(), cert, - true, hashes, net::ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS, - net::TransportSecurityState::CTRequirementsStatus::CT_REQUIREMENTS_MET)); + void SetUp() override { + EXPECT_CALL(policy_provider_, IsInitializationComplete(testing::_)) + .WillRepeatedly(testing::Return(true)); + policy::BrowserPolicyConnector::SetPolicyProviderForTesting( + &policy_provider_); - // Configure the policy. + CertVerifierBrowserTest::SetUp(); + } + + // Sets the policy identified by |policy_name| to the value specified by + // |list_values|, ensuring that the corresponding list pref |pref_name| is + // updated to match. |policy_name| must specify a policy that is a list of + // string values. + void ConfigureStringListPolicy(PrefService* pref_service, + const char* policy_name, + const char* pref_name, + const std::vector<std::string>& list_values) { + std::unique_ptr<base::ListValue> policy_value = + std::make_unique<base::ListValue>(); + for (const auto& value : list_values) { + policy_value->GetList().emplace_back(value); + } + policy::PolicyMap policy_map; + policy_map.Set(policy_name, policy::POLICY_LEVEL_MANDATORY, + policy::POLICY_SCOPE_MACHINE, policy::POLICY_SOURCE_CLOUD, + std::move(policy_value), nullptr); + + EXPECT_NO_FATAL_FAILURE(UpdateChromePolicy(policy_map)); + + const base::ListValue* pref_value = pref_service->GetList(pref_name); + ASSERT_TRUE(pref_value); + std::vector<std::string> pref_values; + for (const auto& value : pref_value->GetList()) { + ASSERT_TRUE(value.is_string()); + pref_values.push_back(value.GetString()); + } + EXPECT_THAT(pref_values, testing::UnorderedElementsAreArray(list_values)); + } + + net::EmbeddedTestServer* https_server() { return &https_server_; } + + private: + void UpdateChromePolicy(const policy::PolicyMap& policies) { + policy_provider_.UpdateChromePolicy(policies); + ASSERT_TRUE(base::MessageLoopCurrent::Get()); + + base::RunLoop().RunUntilIdle(); + + if (base::FeatureList::IsEnabled(network::features::kNetworkService)) + content::FlushNetworkServiceInstanceForTesting(); + } + + net::EmbeddedTestServer https_server_; + + policy::MockConfigurationPolicyProvider policy_provider_; + + DISALLOW_COPY_AND_ASSIGN(CertificateTransparencySSLUITest); +}; + +// Visit an HTTPS page that has a publicly trusted certificate issued after +// the Certificate Transparency requirement date of April 2018. The connection +// should be blocked, as the server will not be providing CT details, and the +// Chrome CT Policy should be being enforced. +IN_PROC_BROWSER_TEST_F(CertificateTransparencySSLUITest, + EnforcedAfterApril2018) { + ASSERT_TRUE(https_server()->Start()); + + net::CertVerifyResult verify_result; + verify_result.verified_cert = + net::ImportCertFromFile(net::GetTestCertsDirectory(), "may_2018.pem"); + ASSERT_TRUE(verify_result.verified_cert); + verify_result.is_issued_by_known_root = true; + verify_result.public_key_hashes.push_back( + GetSPKIHash(verify_result.verified_cert->cert_buffer())); + + mock_cert_verifier()->AddResultForCert(https_server()->GetCertificate().get(), + verify_result, net::OK); + + ui_test_utils::NavigateToURL(browser(), + https_server()->GetURL("/ssl/google.html")); + + CheckSecurityState(browser()->tab_strip_model()->GetActiveWebContents(), + net::CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED, + security_state::DANGEROUS, + AuthState::SHOWING_INTERSTITIAL); +} + +// Visit an HTTPS page that has a publicly trusted certificate issued after +// the Certificate Transparency requirement date of April 2018. The connection +// would normally be blocked, as the server will not be providing CT details, +// and the Chrome CT Policy should be being enforced; however, because a policy +// configuration exists that disables CT enforcement for that cert, the +// connection should succeed. +IN_PROC_BROWSER_TEST_F(CertificateTransparencySSLUITest, + EnforcedAfterApril2018UnlessPoliciesSet) { + ASSERT_TRUE(https_server()->Start()); + + net::CertVerifyResult verify_result; + verify_result.verified_cert = + net::ImportCertFromFile(net::GetTestCertsDirectory(), "may_2018.pem"); + ASSERT_TRUE(verify_result.verified_cert); + verify_result.is_issued_by_known_root = true; + verify_result.public_key_hashes.push_back( + GetSPKIHash(verify_result.verified_cert->cert_buffer())); + + mock_cert_verifier()->AddResultForCert(https_server()->GetCertificate().get(), + verify_result, net::OK); + ASSERT_NO_FATAL_FAILURE(ConfigureStringListPolicy( browser()->profile()->GetPrefs(), - policy::key::kCertificateTransparencyEnforcementDisabledForUrls, - certificate_transparency::prefs::kCTExcludedHosts, disabled_urls)); + policy::key::kCertificateTransparencyEnforcementDisabledForCas, + certificate_transparency::prefs::kCTExcludedSPKIs, + {verify_result.public_key_hashes.back().ToString()})); - // Make sure CT is now explicitly disabled. - ASSERT_NO_FATAL_FAILURE(CheckCTStatus( - browser()->profile()->GetRequestContext(), disabled_urls.front(), cert, - true, hashes, net::ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS, - net::TransportSecurityState::CTRequirementsStatus::CT_NOT_REQUIRED)); + ui_test_utils::NavigateToURL(browser(), + https_server()->GetURL("/ssl/google.html")); + CheckSecurityState(browser()->tab_strip_model()->GetActiveWebContents(), + CertError::NONE, security_state::SECURE, AuthState::NONE); } // Visit a HTTP page which request WSS connection to a server providing invalid
diff --git a/chrome/browser/sync/sync_ui_util.cc b/chrome/browser/sync/sync_ui_util.cc index ea91650..3bfaa5ad 100644 --- a/chrome/browser/sync/sync_ui_util.cc +++ b/chrome/browser/sync/sync_ui_util.cc
@@ -120,7 +120,7 @@ // Unrecoverable error is sometimes accompanied by actionable error. // If status message is set display that message, otherwise show generic // unrecoverable error message. - ProfileSyncService::Status status; + syncer::SyncStatus status; service->QueryDetailedSyncStatus(&status); GetStatusForActionableError(status.sync_protocol_error, status_label, link_label, action_type); @@ -238,7 +238,7 @@ } // We don't have an auth error. Check for an actionable error. - ProfileSyncService::Status status; + syncer::SyncStatus status; service->QueryDetailedSyncStatus(&status); if (status_label && link_label) { GetStatusForActionableError(status.sync_protocol_error, status_label, @@ -284,7 +284,7 @@ // or provide a link to continue with setup. if (service->IsFirstSetupInProgress()) { result_type = PRE_SYNCED; - ProfileSyncService::Status status; + syncer::SyncStatus status; service->QueryDetailedSyncStatus(&status); AuthError auth_error = SigninErrorControllerFactory::GetForProfile(profile)->auth_error(); @@ -364,7 +364,7 @@ // An unrecoverable error is sometimes accompanied by an actionable error. // If an actionable error is not set to be UPGRADE_CLIENT, then show a // generic unrecoverable error message. - ProfileSyncService::Status status; + syncer::SyncStatus status; service->QueryDetailedSyncStatus(&status); if (status.sync_protocol_error.action != syncer::UPGRADE_CLIENT) { // Display different messages and buttons for managed accounts. @@ -404,7 +404,7 @@ // Check for sync errors if the sync service is enabled. if (service) { // Check for an actionable UPGRADE_CLIENT error. - ProfileSyncService::Status status; + syncer::SyncStatus status; service->QueryDetailedSyncStatus(&status); if (status.sync_protocol_error.action == syncer::UPGRADE_CLIENT) { *content_string_id = IDS_SYNC_ERROR_USER_MENU_UPGRADE_MESSAGE;
diff --git a/chrome/browser/sync/test/integration/profile_sync_service_harness.cc b/chrome/browser/sync/test/integration/profile_sync_service_harness.cc index bafe409..4260443 100644 --- a/chrome/browser/sync/test/integration/profile_sync_service_harness.cc +++ b/chrome/browser/sync/test/integration/profile_sync_service_harness.cc
@@ -524,7 +524,7 @@ os << profile_debug_name_ << ": " << message << ": "; if (service()) { const SyncCycleSnapshot& snap = GetLastCycleSnapshot(); - ProfileSyncService::Status status; + syncer::SyncStatus status; service()->QueryDetailedSyncStatus(&status); // Capture select info from the sync session snapshot and syncer status. os << ", has_unsynced_items: " << snap.has_remaining_local_changes()
diff --git a/chrome/browser/sync/test/integration/sync_errors_test.cc b/chrome/browser/sync/test/integration/sync_errors_test.cc index fa7ae5d1..fabd3d4 100644 --- a/chrome/browser/sync/test/integration/sync_errors_test.cc +++ b/chrome/browser/sync/test/integration/sync_errors_test.cc
@@ -86,7 +86,7 @@ // Checks if an actionable error has been hit. Called repeatedly each time PSS // notifies observers of a state change. bool IsExitConditionSatisfied() override { - ProfileSyncService::Status status; + syncer::SyncStatus status; service()->QueryDetailedSyncStatus(&status); return (status.sync_protocol_error.action != syncer::UNKNOWN_ACTION && service()->HasUnrecoverableError()); @@ -137,7 +137,7 @@ // Wait until an actionable error is encountered. ASSERT_TRUE(ActionableErrorChecker(GetSyncService(0)).Wait()); - ProfileSyncService::Status status; + syncer::SyncStatus status; GetSyncService(0)->QueryDetailedSyncStatus(&status); ASSERT_EQ(status.sync_protocol_error.error_type, syncer::TRANSIENT_ERROR); ASSERT_EQ(status.sync_protocol_error.action, syncer::UPGRADE_CLIENT); @@ -198,7 +198,7 @@ const BookmarkNode* node2 = AddFolder(0, 0, "title2"); SetTitle(0, node2, "new_title2"); ASSERT_TRUE(SyncDisabledChecker(GetSyncService(0)).Wait()); - ProfileSyncService::Status status; + syncer::SyncStatus status; GetSyncService(0)->QueryDetailedSyncStatus(&status); ASSERT_EQ(status.sync_protocol_error.error_type, syncer::NOT_MY_BIRTHDAY); ASSERT_EQ(status.sync_protocol_error.action, syncer::DISABLE_SYNC_ON_CLIENT); @@ -219,7 +219,7 @@ std::string url = "www.google.com"; // Remember cache_guid before actionable error. - ProfileSyncService::Status status; + syncer::SyncStatus status; GetSyncService(0)->QueryDetailedSyncStatus(&status); std::string old_cache_guid = status.sync_id;
diff --git a/chrome/browser/ui/app_list/crostini/crostini_installer_view.cc b/chrome/browser/ui/app_list/crostini/crostini_installer_view.cc index 01d4d72..39ff5f80 100644 --- a/chrome/browser/ui/app_list/crostini/crostini_installer_view.cc +++ b/chrome/browser/ui/app_list/crostini/crostini_installer_view.cc
@@ -134,94 +134,6 @@ return gfx::Size(kDialogWidth, height); } -// static -CrostiniInstallerView* CrostiniInstallerView::GetActiveViewForTesting() { - return g_crostini_installer_view; -} - -CrostiniInstallerView::CrostiniInstallerView(Profile* profile) - : app_name_(base::ASCIIToUTF16(kCrostiniTerminalAppName)), - profile_(profile), - weak_ptr_factory_(this) { - - views::LayoutProvider* provider = views::LayoutProvider::Get(); - SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, - provider->GetInsetsMetric(views::InsetsMetric::INSETS_DIALOG), - provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); - set_margins(provider->GetDialogInsetsForContentType( - views::DialogContentType::TEXT, views::DialogContentType::TEXT)); - - // TODO(timloh): Descenders in the message appear to be clipped, re-visit once - // the UI has been fleshed out more. - const base::string16 device_type = ui::GetChromeOSDeviceName(); - const base::string16 message = l10n_util::GetStringFUTF16( - IDS_CROSTINI_INSTALLER_BODY, device_type, app_name_, - ui::FormatBytesWithUnits(kDownloadSizeInBytes, ui::DATA_UNITS_MEBIBYTE, - /*show_units=*/true)); - message_label_ = new views::Label(message); - message_label_->SetMultiLine(true); - message_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); - AddChildView(message_label_); - - chrome::RecordDialogCreation(chrome::DialogIdentifier::CROSTINI_INSTALLER); -} - -CrostiniInstallerView::~CrostiniInstallerView() { - g_crostini_installer_view = nullptr; -} - -void CrostiniInstallerView::StepProgress() { - if (State::INSTALL_START <= state_ && state_ < State::INSTALL_END) { - // Setting value to -1 makes the progress bar play the - // "indeterminate animation". - progress_bar_->SetValue(-1); - } - SetMessageLabel(); - DialogModelChanged(); - GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); -} - -void CrostiniInstallerView::HandleError(const base::string16& error_message, - SetupResult result) { - // Only ever set the error once. This check is necessary as the - // CrostiniManager can give multiple error callbacks. Only the first should be - // shown to the user. - if (state_ == State::ERROR) - return; - - RecordSetupResultHistogram(result); - state_ = State::ERROR; - message_label_->SetVisible(true); - message_label_->SetText(error_message); - progress_bar_->SetVisible(false); - GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); - GetWidget()->UpdateWindowTitle(); -} - -void CrostiniInstallerView::SetMessageLabel() { - int message_id = 0; - // The States below refer to stages that have completed. - // The messages selected refer to the next stage, now underway. - if (state_ == State::INSTALL_START) { - message_id = IDS_CROSTINI_INSTALLER_LOAD_TERMINA_MESSAGE; - } else if (state_ == State::INSTALL_IMAGE_LOADER) { - message_id = IDS_CROSTINI_INSTALLER_START_CONCIERGE_MESSAGE; - } else if (state_ == State::START_CONCIERGE) { - message_id = IDS_CROSTINI_INSTALLER_CREATE_DISK_IMAGE_MESSAGE; - } else if (state_ == State::CREATE_DISK_IMAGE) { - message_id = IDS_CROSTINI_INSTALLER_START_TERMINA_VM_MESSAGE; - } else if (state_ == State::START_TERMINA_VM) { - message_id = IDS_CROSTINI_INSTALLER_START_CONTAINER_MESSAGE; - } - if (message_id != 0) { - message_label_->SetText(l10n_util::GetStringUTF16(message_id)); - message_label_->SetVisible(true); - } else { - message_label_->SetVisible(false); - } -} - void CrostiniInstallerView::OnComponentLoaded(ConciergeClientResult result) { DCHECK_EQ(state_, State::INSTALL_START); state_ = State::INSTALL_IMAGE_LOADER; @@ -281,6 +193,59 @@ StepProgress(); } +// static +CrostiniInstallerView* CrostiniInstallerView::GetActiveViewForTesting() { + return g_crostini_installer_view; +} + +CrostiniInstallerView::CrostiniInstallerView(Profile* profile) + : app_name_(base::ASCIIToUTF16(kCrostiniTerminalAppName)), + profile_(profile), + weak_ptr_factory_(this) { + views::LayoutProvider* provider = views::LayoutProvider::Get(); + SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::kVertical, + provider->GetInsetsMetric(views::InsetsMetric::INSETS_DIALOG), + provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL))); + set_margins(provider->GetDialogInsetsForContentType( + views::DialogContentType::TEXT, views::DialogContentType::TEXT)); + + // TODO(timloh): Descenders in the message appear to be clipped, re-visit once + // the UI has been fleshed out more. + const base::string16 device_type = ui::GetChromeOSDeviceName(); + const base::string16 message = l10n_util::GetStringFUTF16( + IDS_CROSTINI_INSTALLER_BODY, device_type, app_name_, + ui::FormatBytesWithUnits(kDownloadSizeInBytes, ui::DATA_UNITS_MEBIBYTE, + /*show_units=*/true)); + message_label_ = new views::Label(message); + message_label_->SetMultiLine(true); + message_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); + AddChildView(message_label_); + + chrome::RecordDialogCreation(chrome::DialogIdentifier::CROSTINI_INSTALLER); +} + +CrostiniInstallerView::~CrostiniInstallerView() { + g_crostini_installer_view = nullptr; +} + +void CrostiniInstallerView::HandleError(const base::string16& error_message, + SetupResult result) { + // Only ever set the error once. This check is necessary as the + // CrostiniManager can give multiple error callbacks. Only the first should be + // shown to the user. + if (state_ == State::ERROR) + return; + + RecordSetupResultHistogram(result); + state_ = State::ERROR; + message_label_->SetVisible(true); + message_label_->SetText(error_message); + progress_bar_->SetVisible(false); + GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); + GetWidget()->UpdateWindowTitle(); +} + void CrostiniInstallerView::StartContainerFinished( ConciergeClientResult result) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -309,6 +274,40 @@ GetWidget()->Close(); } +void CrostiniInstallerView::StepProgress() { + if (State::INSTALL_START <= state_ && state_ < State::INSTALL_END) { + // Setting value to -1 makes the progress bar play the + // "indeterminate animation". + progress_bar_->SetValue(-1); + } + SetMessageLabel(); + DialogModelChanged(); + GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); +} + +void CrostiniInstallerView::SetMessageLabel() { + int message_id = 0; + // The States below refer to stages that have completed. + // The messages selected refer to the next stage, now underway. + if (state_ == State::INSTALL_START) { + message_id = IDS_CROSTINI_INSTALLER_LOAD_TERMINA_MESSAGE; + } else if (state_ == State::INSTALL_IMAGE_LOADER) { + message_id = IDS_CROSTINI_INSTALLER_START_CONCIERGE_MESSAGE; + } else if (state_ == State::START_CONCIERGE) { + message_id = IDS_CROSTINI_INSTALLER_CREATE_DISK_IMAGE_MESSAGE; + } else if (state_ == State::CREATE_DISK_IMAGE) { + message_id = IDS_CROSTINI_INSTALLER_START_TERMINA_VM_MESSAGE; + } else if (state_ == State::START_TERMINA_VM) { + message_id = IDS_CROSTINI_INSTALLER_START_CONTAINER_MESSAGE; + } + if (message_id != 0) { + message_label_->SetText(l10n_util::GetStringUTF16(message_id)); + message_label_->SetVisible(true); + } else { + message_label_->SetVisible(false); + } +} + void CrostiniInstallerView::RecordSetupResultHistogram(SetupResult result) { // Prevent multiple results being logged for a given setup flow. This can // happen due to multiple error callbacks happening in some cases, as well as
diff --git a/chrome/browser/ui/avatar_button_error_controller.cc b/chrome/browser/ui/avatar_button_error_controller.cc index 59697f91..ae7d034a 100644 --- a/chrome/browser/ui/avatar_button_error_controller.cc +++ b/chrome/browser/ui/avatar_button_error_controller.cc
@@ -90,7 +90,7 @@ if (sync_service) { SyncErrorController* sync_error_controller = sync_service->sync_error_controller(); - browser_sync::ProfileSyncService::Status status; + syncer::SyncStatus status; sync_service->QueryDetailedSyncStatus(&status); return sync_service->HasUnrecoverableError() || status.sync_protocol_error.action == syncer::UPGRADE_CLIENT ||
diff --git a/chrome/browser/ui/input_method/input_method_engine_base.cc b/chrome/browser/ui/input_method/input_method_engine_base.cc index abd3f75a..91de5a4 100644 --- a/chrome/browser/ui/input_method/input_method_engine_base.cc +++ b/chrome/browser/ui/input_method/input_method_engine_base.cc
@@ -308,7 +308,7 @@ observer_->OnFocus(ui::IMEEngineHandlerInterface::InputContext( context_id_, input_context.type, input_context.mode, input_context.flags, - input_context.focus_reason)); + input_context.focus_reason, input_context.should_do_learning)); } void InputMethodEngineBase::FocusOut() {
diff --git a/chrome/browser/ui/input_method/input_method_engine_unittest.cc b/chrome/browser/ui/input_method/input_method_engine_unittest.cc index 42d0bbe..7e37d9d 100644 --- a/chrome/browser/ui/input_method/input_method_engine_unittest.cc +++ b/chrome/browser/ui/input_method/input_method_engine_unittest.cc
@@ -172,7 +172,8 @@ void FocusIn(ui::TextInputType input_type) { ui::IMEEngineHandlerInterface::InputContext input_context( input_type, ui::TEXT_INPUT_MODE_DEFAULT, ui::TEXT_INPUT_FLAG_NONE, - ui::TextInputClient::FOCUS_REASON_OTHER); + ui::TextInputClient::FOCUS_REASON_OTHER, + false /* should_do_learning */); engine_->FocusIn(input_context); ui::IMEBridge::Get()->SetCurrentInputContext(input_context); }
diff --git a/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc b/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc index 1c04fa2..eaed822 100644 --- a/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc +++ b/chrome/browser/ui/views/ime_driver/remote_text_input_client.cc
@@ -176,6 +176,12 @@ return base::EmptyString(); } +bool RemoteTextInputClient::ShouldDoLearning() { + // TODO(https://crbug.com/311180): Implement this method. + NOTIMPLEMENTED_LOG_ONCE(); + return false; +} + ui::EventDispatchDetails RemoteTextInputClient::DispatchKeyEventPostIME( ui::KeyEvent* event) { remote_client_->DispatchKeyEventPostIME(ui::Event::Clone(*event),
diff --git a/chrome/browser/ui/views/ime_driver/remote_text_input_client.h b/chrome/browser/ui/views/ime_driver/remote_text_input_client.h index 63b1b9cf..704c17ee 100644 --- a/chrome/browser/ui/views/ime_driver/remote_text_input_client.h +++ b/chrome/browser/ui/views/ime_driver/remote_text_input_client.h
@@ -58,6 +58,7 @@ bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override; void SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) override; const std::string& GetClientSourceInfo() const override; + bool ShouldDoLearning() override; // ui::internal::InputMethodDelegate: ui::EventDispatchDetails DispatchKeyEventPostIME(
diff --git a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc index 52eaba4..51d2a74 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_match_cell_view.cc
@@ -139,16 +139,32 @@ kRichImageCornerRadius, flags); } -} // namespace - //////////////////////////////////////////////////////////////////////////////// // OmniboxImageView: class OmniboxImageView : public views::ImageView { public: + OmniboxImageView() = default; + bool CanProcessEventsWithinSubtree() const override { return false; } + + private: + // views::ImageView: + void OnPaint(gfx::Canvas* canvas) override; + + DISALLOW_COPY_AND_ASSIGN(OmniboxImageView); }; +void OmniboxImageView::OnPaint(gfx::Canvas* canvas) { + gfx::Path mask; + mask.addRoundRect(gfx::RectToSkRect(GetImageBounds()), kRichImageCornerRadius, + kRichImageCornerRadius); + canvas->ClipPath(mask, true); + ImageView::OnPaint(canvas); +} + +} // namespace + //////////////////////////////////////////////////////////////////////////////// // OmniboxMatchCellView:
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index 7461c8a..2f51073 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -387,6 +387,10 @@ scoped_observer_.RemoveAll(); } +bool OmniboxViewViews::ShouldDoLearning() { + return location_bar_view_ && !location_bar_view_->profile()->IsOffTheRecord(); +} + void OmniboxViewViews::SetTextAndSelectedRange(const base::string16& text, const gfx::Range& range) { SetText(text);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.h b/chrome/browser/ui/views/omnibox/omnibox_view_views.h index ff49173..2270f53 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.h +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
@@ -107,6 +107,7 @@ ui::TextInputType GetTextInputType() const override; void AddedToWidget() override; void RemovedFromWidget() override; + bool ShouldDoLearning() override; protected: // For testing only.
diff --git a/chrome/browser/ui/views/tabs/tab_renderer_data.cc b/chrome/browser/ui/views/tabs/tab_renderer_data.cc index a6059d2c..2f71a9b 100644 --- a/chrome/browser/ui/views/tabs/tab_renderer_data.cc +++ b/chrome/browser/ui/views/tabs/tab_renderer_data.cc
@@ -17,7 +17,7 @@ TabRendererData::~TabRendererData() = default; -bool TabRendererData::operator==(const TabRendererData& other) { +bool TabRendererData::operator==(const TabRendererData& other) const { return favicon.BackedBySameObjectAs(other.favicon) && network_state == other.network_state && title == other.title && url == other.url && crashed_status == other.crashed_status &&
diff --git a/chrome/browser/ui/views/tabs/tab_renderer_data.h b/chrome/browser/ui/views/tabs/tab_renderer_data.h index 8edd33c..605dc26 100644 --- a/chrome/browser/ui/views/tabs/tab_renderer_data.h +++ b/chrome/browser/ui/views/tabs/tab_renderer_data.h
@@ -22,7 +22,7 @@ TabRendererData& operator=(const TabRendererData& other); TabRendererData& operator=(TabRendererData&& other); - bool operator==(const TabRendererData& other); + bool operator==(const TabRendererData& other) const; // This interprets the crashed status to decide whether or not this // render data represents a tab that is "crashed" (i.e. the render
diff --git a/chrome/common/extensions/api/input_ime.json b/chrome/common/extensions/api/input_ime.json index 5a9ced36..0aab48d 100644 --- a/chrome/common/extensions/api/input_ime.json +++ b/chrome/common/extensions/api/input_ime.json
@@ -44,7 +44,8 @@ "type": {"$ref": "InputContextType", "description": "Type of value this text field edits, (Text, Number, URL, etc)"}, "autoCorrect": {"type": "boolean", "description": "Whether the text field wants auto-correct."}, "autoComplete": {"type": "boolean", "description": "Whether the text field wants auto-complete."}, - "spellCheck": {"type": "boolean", "description": "Whether the text field wants spell-check."} + "spellCheck": {"type": "boolean", "description": "Whether the text field wants spell-check."}, + "shouldDoLearning": {"type": "boolean", "description": "Whether text entered into the text field should be used to improve typing suggestions for the user."} } }, {
diff --git a/chrome/common/extensions/api/input_method_private.json b/chrome/common/extensions/api/input_method_private.json index 79ce1ff..a123ab6 100644 --- a/chrome/common/extensions/api/input_method_private.json +++ b/chrome/common/extensions/api/input_method_private.json
@@ -55,6 +55,7 @@ "autoCorrect": {"type": "boolean", "description": "Whether the text field wants auto-correct."}, "autoComplete": {"type": "boolean", "description": "Whether the text field wants auto-complete."}, "spellCheck": {"type": "boolean", "description": "Whether the text field wants spell-check."}, + "shouldDoLearning": {"type": "boolean", "description": "Whether text entered into the text field should be used to improve typing suggestions for the user."}, "focusReason": {"$ref": "FocusReason", "description": "How the text field was focused"} } }
diff --git a/chrome/common/media_router/providers/cast/cast_media_source.cc b/chrome/common/media_router/providers/cast/cast_media_source.cc index aeb49d5..06f0047 100644 --- a/chrome/common/media_router/providers/cast/cast_media_source.cc +++ b/chrome/common/media_router/providers/cast/cast_media_source.cc
@@ -12,6 +12,8 @@ #include "url/gurl.h" #include "url/url_util.h" +using cast_channel::BroadcastRequest; + namespace media_router { namespace { @@ -76,6 +78,23 @@ #endif } +std::unique_ptr<CastMediaSource> CreateFromURLParams( + const MediaSource::Id& source_id, + const std::vector<CastAppInfo>& app_infos, + const std::string& broadcast_namespace, + const std::string& broadcast_message) { + if (app_infos.empty()) + return nullptr; + + auto cast_source = std::make_unique<CastMediaSource>(source_id, app_infos); + if (!broadcast_namespace.empty() && !broadcast_message.empty()) { + cast_source->set_broadcast_request( + BroadcastRequest(broadcast_namespace, broadcast_message)); + } + + return cast_source; +} + std::unique_ptr<CastMediaSource> ParseCastUrl(const MediaSource::Id& source_id, const GURL& url) { std::string app_id = url.path(); @@ -110,13 +129,8 @@ } } - auto parsed = std::make_unique<CastMediaSource>(source_id, app_info); - if (!broadcast_namespace.empty() && !broadcast_message.empty()) { - parsed->set_broadcast_request( - BroadcastRequest(broadcast_namespace, broadcast_message)); - } - - return parsed; + return CreateFromURLParams(source_id, {app_info}, broadcast_namespace, + broadcast_message); } std::unique_ptr<CastMediaSource> ParseLegacyCastUrl( @@ -173,9 +187,8 @@ if (app_infos.empty()) return nullptr; - auto parsed = - std::make_unique<CastMediaSource>(source_id, std::move(app_infos)); - return parsed; + return CreateFromURLParams(source_id, app_infos, broadcast_namespace, + broadcast_message); } } // namespace @@ -185,11 +198,6 @@ CastAppInfo::CastAppInfo(const CastAppInfo& other) = default; -BroadcastRequest::BroadcastRequest(const std::string& broadcast_namespace, - const std::string& message) - : broadcast_namespace(broadcast_namespace), message(message) {} -BroadcastRequest::~BroadcastRequest() = default; - // static std::unique_ptr<CastMediaSource> CastMediaSource::From( const MediaSource::Id& source_id) { @@ -240,4 +248,13 @@ app_ids.begin(), app_ids.end(), [this](const std::string& app_id) { return ContainsApp(app_id); }); } + +std::vector<std::string> CastMediaSource::GetAppIds() const { + std::vector<std::string> app_ids; + for (const auto& info : app_infos_) + app_ids.push_back(info.app_id); + + return app_ids; +} + } // namespace media_router
diff --git a/chrome/common/media_router/providers/cast/cast_media_source.h b/chrome/common/media_router/providers/cast/cast_media_source.h index 5f52338..ae090b5e2 100644 --- a/chrome/common/media_router/providers/cast/cast_media_source.h +++ b/chrome/common/media_router/providers/cast/cast_media_source.h
@@ -11,6 +11,7 @@ #include "base/optional.h" #include "chrome/common/media_router/media_source.h" +#include "components/cast_channel/cast_message_util.h" #include "components/cast_channel/cast_socket.h" namespace media_router { @@ -28,17 +29,6 @@ int required_capabilities = cast_channel::CastDeviceCapability::NONE; }; -// Represents a broadcast request. Currently it is used for precaching data -// on a receiver. -struct BroadcastRequest { - BroadcastRequest(const std::string& broadcast_namespace, - const std::string& message); - ~BroadcastRequest(); - - std::string broadcast_namespace; - std::string message; -}; - // Represents a MediaSource parsed into structured, Cast specific data. The // following MediaSources can be parsed into CastMediaSource: // - Cast Presentation URLs @@ -60,13 +50,17 @@ bool ContainsApp(const std::string& app_id) const; bool ContainsAnyAppFrom(const std::vector<std::string>& app_ids) const; + // Returns a list of App IDs in this CastMediaSource. + std::vector<std::string> GetAppIds() const; + const MediaSource::Id& source_id() const { return source_id_; } const std::vector<CastAppInfo>& app_infos() const { return app_infos_; } - const base::Optional<BroadcastRequest>& broadcast_request() const { + const base::Optional<cast_channel::BroadcastRequest>& broadcast_request() + const { return broadcast_request_; } - void set_broadcast_request(const BroadcastRequest& request) { + void set_broadcast_request(const cast_channel::BroadcastRequest& request) { broadcast_request_ = request; } @@ -74,7 +68,7 @@ // TODO(imcheng): Fill in other parameters. MediaSource::Id source_id_; std::vector<CastAppInfo> app_infos_; - base::Optional<BroadcastRequest> broadcast_request_; + base::Optional<cast_channel::BroadcastRequest> broadcast_request_; }; } // namespace media_router
diff --git a/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc b/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc index df72aab..94a9204 100644 --- a/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc +++ b/chrome/common/media_router/providers/cast/cast_media_source_unittest.cc
@@ -10,7 +10,10 @@ namespace media_router { TEST(CastMediaSourceTest, FromCastURL) { - MediaSource::Id source_id("cast:ABCDEFAB?capabilities=video_out,audio_out"); + MediaSource::Id source_id( + "cast:ABCDEFAB?capabilities=video_out,audio_out" + "&broadcastNamespace=namespace" + "&broadcastMessage=message"); std::unique_ptr<CastMediaSource> source = CastMediaSource::From(source_id); ASSERT_TRUE(source); EXPECT_EQ(source_id, source->source_id()); @@ -20,11 +23,17 @@ EXPECT_EQ(cast_channel::CastDeviceCapability::VIDEO_OUT | cast_channel::CastDeviceCapability::AUDIO_OUT, app_info.required_capabilities); + const auto& broadcast_request = source->broadcast_request(); + ASSERT_TRUE(broadcast_request); + EXPECT_EQ("namespace", broadcast_request->broadcast_namespace); + EXPECT_EQ("message", broadcast_request->message); } TEST(CastMediaSourceTest, FromLegacyCastURL) { MediaSource::Id source_id( - "https://google.com/cast#__castAppId__=ABCDEFAB(video_out,audio_out)"); + "https://google.com/cast#__castAppId__=ABCDEFAB(video_out,audio_out)" + "/__castBroadcastNamespace__=namespace" + "/__castBroadcastMessage__=message"); std::unique_ptr<CastMediaSource> source = CastMediaSource::From(source_id); ASSERT_TRUE(source); EXPECT_EQ(source_id, source->source_id()); @@ -34,6 +43,10 @@ EXPECT_EQ(cast_channel::CastDeviceCapability::VIDEO_OUT | cast_channel::CastDeviceCapability::AUDIO_OUT, app_info.required_capabilities); + const auto& broadcast_request = source->broadcast_request(); + ASSERT_TRUE(broadcast_request); + EXPECT_EQ("namespace", broadcast_request->broadcast_namespace); + EXPECT_EQ("message", broadcast_request->message); } TEST(CastMediaSourceTest, FromPresentationURL) {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 38af6168..9774f08f 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3118,6 +3118,7 @@ "../browser/media/router/providers/cast/cast_app_availability_tracker_unittest.cc", "../browser/media/router/providers/cast/cast_app_discovery_service_unittest.cc", "../browser/media/router/providers/cast/cast_media_route_provider_metrics_unittest.cc", + "../browser/media/router/providers/cast/cast_media_route_provider_unittest.cc", "../browser/media/router/providers/cast/dual_media_sink_service_unittest.cc", "../browser/media/router/providers/dial/dial_activity_manager_unittest.cc", "../browser/media/router/providers/dial/dial_internal_message_util_unittest.cc",
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index 30a2e9e6..cf86cf9f 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -110,34 +110,12 @@ _OS_NEGATIVE_FILTER = {} _OS_NEGATIVE_FILTER['win'] = [ - # Flaky: https://bugs.chromium.org/p/chromedriver/issues/detail?id=373 - 'RenderedWebElementTest.testHoverPersists', - 'RenderedWebElementTest.canClickOnASuckerFishStyleMenu', - # Flaky: https://bugs.chromium.org/p/chromedriver/issues/detail?id=416 - 'TakesScreenshotTest.testShouldCaptureScreenshotAtFramePageAfterSwitching', - 'TakesScreenshotTest.testShouldCaptureScreenshotAtFramePage', ] _OS_NEGATIVE_FILTER['linux'] = [ - # Flaky: https://bugs.chromium.org/p/chromedriver/issues/detail?id=416 - 'TakesScreenshotTest.testShouldCaptureScreenshotAtFramePage', - # Flaky: https://bugs.chromium.org/p/chromedriver/issues/detail?id=1148 - 'CombinedInputActionsTest.testCombiningShiftAndClickResultsInANewWindow', - # Flaky: https://bugs.chromium.org/p/chromedriver/issues/detail?id=1150 - 'BasicKeyboardInterfaceTest.testBasicKeyboardInputOnActiveElement', ] _OS_NEGATIVE_FILTER['mac'] = [ - # https://bugs.chromium.org/p/chromedriver/issues/detail?id=26 - 'AlertsTest.testAlertShouldNotAllowAdditionalCommandsIfDismissed', - 'AlertsTest.testShouldAllowUsersToDismissAnAlertManually', - 'FormHandlingTest.handleFormWithJavascriptAction', - # Flaky: https://bugs.chromium.org/p/chromedriver/issues/detail?id=354 - 'AlertsTest.testShouldAllowUsersToAcceptAnAlertInAFrame', - # Flaky: https://bugs.chromium.org/p/chromedriver/issues/detail?id=375 - 'PageLoadingTest.testShouldBeAbleToNavigateBackInTheBrowserHistoryInPresenceOfIframes', # Flaky: https://bugs.chromium.org/p/chromedriver/issues/detail?id=416 'TakesScreenshotTest.testShouldCaptureScreenshotAtFramePage', - # Flaky: https://bugs.chromium.org/p/chromedriver/issues/detail?id=1149 - 'ChromeDriverTests.testShouldAllowTheUserToSwitchToAnIFrameAndRemainFocusedOnIt', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1857 'TakesScreenshotTest.testShouldCaptureScreenshot', 'TakesScreenshotTest.testShouldCaptureScreenshotAtFramePageAfterSwitching',
diff --git a/chrome/test/data/extensions/input_ime/main.js b/chrome/test/data/extensions/input_ime/main.js index 7162f4c..f639d5f8 100644 --- a/chrome/test/data/extensions/input_ime/main.js +++ b/chrome/test/data/extensions/input_ime/main.js
@@ -143,7 +143,8 @@ context.type + ':' + context.autoComplete + ':' + context.autoCorrect + ':' + - context.spellCheck); + context.spellCheck + ':' + + context.shouldDoLearning); }, /**
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js index 9fc8334..b530845 100644 --- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js +++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
@@ -350,3 +350,27 @@ TEST_F('CrElementsCheckboxTest', 'All', function() { mocha.run(); }); + +/** + * @constructor + * @extends {CrElementsBrowserTest} + */ +function CrElementsRadioButtonTest() {} + +CrElementsRadioButtonTest.prototype = { + __proto__: CrElementsBrowserTest.prototype, + + /** @override */ + browsePreload: + 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html', + + /** @override */ + extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([ + '../settings/test_util.js', + 'cr_radio_button_test.js', + ]), +}; + +TEST_F('CrElementsRadioButtonTest', 'All', function() { + mocha.run(); +});
diff --git a/chrome/test/data/webui/cr_elements/cr_radio_button_test.js b/chrome/test/data/webui/cr_elements/cr_radio_button_test.js new file mode 100644 index 0000000..ca1290a --- /dev/null +++ b/chrome/test/data/webui/cr_elements/cr_radio_button_test.js
@@ -0,0 +1,75 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +suite('cr-radio-button', function() { + let radioButton; + + setup(function() { + PolymerTest.clearBody(); + document.body.innerHTML = ` + <cr-radio-button>label</cr-radio-button> + `; + + radioButton = document.querySelector('cr-radio-button'); + }); + + function assertChecked() { + assertTrue(radioButton.hasAttribute('checked')); + assertEquals('true', radioButton.getAttribute('aria-checked')); + assertTrue( + getComputedStyle(radioButton.$$('.disc')).backgroundColor != + 'rgba(0, 0, 0, 0)'); + } + + function assertNotChecked() { + assertFalse(radioButton.hasAttribute('checked')); + assertEquals('false', radioButton.getAttribute('aria-checked')); + assertEquals( + 'rgba(0, 0, 0, 0)', + getComputedStyle(radioButton.$$('.disc')).backgroundColor); + } + + function assertDisabled() { + assertEquals('-1', radioButton.getAttribute('tabindex')); + assertTrue(radioButton.hasAttribute('disabled')); + assertEquals('true', radioButton.getAttribute('aria-disabled')); + assertEquals('none', getComputedStyle(radioButton).pointerEvents); + assertTrue('1' != getComputedStyle(radioButton).opacity); + } + + function assertNotDisabled() { + assertEquals('0', radioButton.getAttribute('tabindex')); + assertFalse(radioButton.hasAttribute('disabled')); + assertEquals('false', radioButton.getAttribute('aria-disabled')); + assertEquals('1', getComputedStyle(radioButton).opacity); + } + + // Setting selection by mouse/keyboard is paper-radio-group's job, so + // these tests simply set states programatically and make sure the element + // is visually correct. + test('Checked', function() { + assertNotChecked(); + radioButton.checked = true; + assertChecked(); + radioButton.checked = false; + assertNotChecked(); + }); + + test('Disabled', function() { + assertNotDisabled(); + radioButton.disabled = true; + assertDisabled(); + radioButton.disabled = false; + assertNotChecked(); + }); + + test('Ripple', function() { + assertFalse(!!radioButton.$$('paper-ripple')); + radioButton.fire('focus'); + assertTrue(!!radioButton.$$('paper-ripple')); + assertTrue(radioButton.$$('paper-ripple').holdDown); + radioButton.fire('pointerup'); + assertFalse(radioButton.$$('paper-ripple').holdDown); + }); +});
diff --git a/chrome/test/data/webui/settings/about_page_tests.js b/chrome/test/data/webui/settings/about_page_tests.js index 317cdfcb..c9e007d7 100644 --- a/chrome/test/data/webui/settings/about_page_tests.js +++ b/chrome/test/data/webui/settings/about_page_tests.js
@@ -912,8 +912,7 @@ dialog = document.createElement('settings-channel-switcher-dialog'); document.body.appendChild(dialog); - radioButtons = - dialog.shadowRoot.querySelectorAll('paper-radio-button'); + radioButtons = dialog.shadowRoot.querySelectorAll('cr-radio-button'); assertEquals(3, radioButtons.length); return browserProxy.whenCalled('getChannelInfo'); });
diff --git a/chrome/test/data/webui/settings/device_page_tests.js b/chrome/test/data/webui/settings/device_page_tests.js index 53fbc73d..0ec0f9f 100644 --- a/chrome/test/data/webui/settings/device_page_tests.js +++ b/chrome/test/data/webui/settings/device_page_tests.js
@@ -450,10 +450,8 @@ * @param {boolean} expected */ function expectNaturalScrollValue(pointersPage, expected) { - const naturalScrollOff = - pointersPage.$$('paper-radio-button[name="false"]'); - const naturalScrollOn = - pointersPage.$$('paper-radio-button[name="true"]'); + const naturalScrollOff = pointersPage.$$('cr-radio-button[name="false"]'); + const naturalScrollOn = pointersPage.$$('cr-radio-button[name="true"]'); assertTrue(!!naturalScrollOff); assertTrue(!!naturalScrollOn); @@ -567,8 +565,7 @@ expectNaturalScrollValue(pointersPage, false); // Tapping the link shouldn't enable the radio button. - const naturalScrollOn = - pointersPage.$$('paper-radio-button[name="true"]'); + const naturalScrollOn = pointersPage.$$('cr-radio-button[name="true"]'); const a = naturalScrollOn.querySelector('a'); MockInteractions.tap(a);
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_test.js b/chrome/test/data/webui/settings/people_page_sync_page_test.js index 1a3f842c7..f09722a 100644 --- a/chrome/test/data/webui/settings/people_page_sync_page_test.js +++ b/chrome/test/data/webui/settings/people_page_sync_page_test.js
@@ -78,9 +78,9 @@ Polymer.dom.flush(); encryptWithGoogle = - syncPage.$$('paper-radio-button[name="encrypt-with-google"]'); + syncPage.$$('cr-radio-button[name="encrypt-with-google"]'); encryptWithPassphrase = - syncPage.$$('paper-radio-button[name="encrypt-with-passphrase"]'); + syncPage.$$('cr-radio-button[name="encrypt-with-passphrase"]'); assertTrue(!!encryptWithGoogle); assertTrue(!!encryptWithPassphrase); });
diff --git a/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js b/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js index b35fa28..bf5a265d 100644 --- a/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js +++ b/chrome/test/data/webui/settings/quick_unlock_authenticate_browsertest_chromeos.js
@@ -177,16 +177,17 @@ const noneRadioButton = null; /** - * Asserts that only the given radio button is active and all of the - * others are inactive. + * Asserts that only the given radio button is checked and all of the + * others are unchecked. * @param {Element} radioButton */ - function assertRadioButtonActive(radioButton) { + function assertRadioButtonChecked(radioButton) { function doAssert(element, name) { if (radioButton == element) - assertTrue(element.active, 'Expected ' + name + ' to be active'); + assertTrue(element.checked, 'Expected ' + name + ' to be checked'); else - assertFalse(element.active, 'Expected ' + name + ' to be inactive'); + assertFalse( + element.checked, 'Expected ' + name + ' to be unchecked'); } doAssert(passwordRadioButton, 'passwordButton'); @@ -263,9 +264,9 @@ }); passwordRadioButton = - getFromElement('paper-radio-button[name="password"]'); + getFromElement('cr-radio-button[name="password"]'); pinPasswordRadioButton = - getFromElement('paper-radio-button[name="pin+password"]'); + getFromElement('cr-radio-button[name="pin+password"]'); done(); }); @@ -275,7 +276,7 @@ // quickUnlockPrivate calls. test('ShowingScreenDoesNotModifyPrefs', function() { assertTrue(getLockScreenPref()); - assertRadioButtonActive(passwordRadioButton); + assertRadioButtonChecked(passwordRadioButton); assertDeepEquals([], quickUnlockPrivateApi.activeModes); }); @@ -301,11 +302,11 @@ // prefs. test('TappingButtonsChangesUnderlyingState', function() { function togglePin() { - assertRadioButtonActive(passwordRadioButton); + assertRadioButtonChecked(passwordRadioButton); // Tap pin+password button. MockInteractions.tap(pinPasswordRadioButton); - assertRadioButtonActive(pinPasswordRadioButton); + assertRadioButtonChecked(pinPasswordRadioButton); assertTrue(isSetupPinButtonVisible()); assertDeepEquals([], quickUnlockPrivateApi.activeModes); @@ -314,7 +315,7 @@ // Tap password button and verify quick unlock is disabled. MockInteractions.tap(passwordRadioButton); - assertRadioButtonActive(passwordRadioButton); + assertRadioButtonChecked(passwordRadioButton); assertFalse(isSetupPinButtonVisible()); assertDeepEquals([], quickUnlockPrivateApi.activeModes); } @@ -334,11 +335,11 @@ // will update to show quick unlock is active. test('EnablingQuickUnlockChangesButtonState', function() { setActiveModes([QuickUnlockMode.PIN]); - assertRadioButtonActive(pinPasswordRadioButton); + assertRadioButtonChecked(pinPasswordRadioButton); assertTrue(isSetupPinButtonVisible()); setActiveModes([]); - assertRadioButtonActive(passwordRadioButton); + assertRadioButtonChecked(passwordRadioButton); assertDeepEquals([], quickUnlockPrivateApi.activeModes); }); @@ -349,11 +350,11 @@ 0, fakeUma.getHistogramValue( LockScreenProgress.CHOOSE_PIN_OR_PASSWORD)); - assertRadioButtonActive(passwordRadioButton); + assertRadioButtonChecked(passwordRadioButton); MockInteractions.tap(pinPasswordRadioButton); assertTrue(isSetupPinButtonVisible()); - assertRadioButtonActive(pinPasswordRadioButton); + assertRadioButtonChecked(pinPasswordRadioButton); Polymer.dom.flush(); MockInteractions.tap(getFromElement('#setupPinButton'));
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index dcdc442..12ba117 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -10677.0.0 \ No newline at end of file +10680.0.0 \ No newline at end of file
diff --git a/components/arc/ime/arc_ime_service.cc b/components/arc/ime/arc_ime_service.cc index b530e6ac..f6fffe7 100644 --- a/components/arc/ime/arc_ime_service.cc +++ b/components/arc/ime/arc_ime_service.cc
@@ -518,6 +518,12 @@ return base::EmptyString(); } +bool ArcImeService::ShouldDoLearning() { + // TODO(https://crbug.com/311180): Implement this method. + NOTIMPLEMENTED_LOG_ONCE(); + return true; +} + // static void ArcImeService::SetOverrideDefaultDeviceScaleFactorForTesting( base::Optional<double> scale_factor) {
diff --git a/components/arc/ime/arc_ime_service.h b/components/arc/ime/arc_ime_service.h index feee49e..a1beae6 100644 --- a/components/arc/ime/arc_ime_service.h +++ b/components/arc/ime/arc_ime_service.h
@@ -138,6 +138,7 @@ void SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) override { } const std::string& GetClientSourceInfo() const override; + bool ShouldDoLearning() override; // Normally, the default device scale factor is used to convert from DPI to // physical pixels. This method provides a way to override it for testing.
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h index c36e255..f36ce9d 100644 --- a/components/browser_sync/profile_sync_service.h +++ b/components/browser_sync/profile_sync_service.h
@@ -177,7 +177,6 @@ public identity::IdentityManager::Observer, public GaiaCookieManagerService::Observer { public: - using Status = syncer::SyncStatus; using PlatformSyncAllowedProvider = base::RepeatingCallback<bool()>; using SigninScopedDeviceIdCallback = base::RepeatingCallback<std::string()>;
diff --git a/components/cast_channel/cast_message_handler.cc b/components/cast_channel/cast_message_handler.cc index b12c1b49..d9734f4 100644 --- a/components/cast_channel/cast_message_handler.cc +++ b/components/cast_channel/cast_message_handler.cc
@@ -133,6 +133,29 @@ SendCastMessage(socket, message); } +void CastMessageHandler::SendBroadcastMessage( + int socket_id, + const std::vector<std::string>& app_ids, + const BroadcastRequest& request) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + CastSocket* socket = socket_service_->GetSocket(socket_id); + if (!socket) { + DVLOG(2) << __func__ << ": socket not found: " << socket_id; + return; + } + + int request_id = NextRequestId(); + DVLOG(2) << __func__ << ", socket_id: " << socket->id() + << ", request_id: " << request_id; + + // Note: Even though the message is formatted like a request, we don't care + // about the response, as broadcasts are fire-and-forget. + CastMessage message = + CreateBroadcastRequest(sender_id_, request_id, app_ids, request); + SendCastMessage(socket, message); +} + void CastMessageHandler::AppAvailabilityTimedOut(int request_id) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DVLOG(1) << __func__ << ", request_id: " << request_id;
diff --git a/components/cast_channel/cast_message_handler.h b/components/cast_channel/cast_message_handler.h index ad775ed7..2617790c 100644 --- a/components/cast_channel/cast_message_handler.h +++ b/components/cast_channel/cast_message_handler.h
@@ -91,6 +91,12 @@ const std::string& app_id, GetAppAvailabilityCallback callback); + // Sends a broadcast message containing |app_ids| and |request| to the socket + // given by |socket_id|. + virtual void SendBroadcastMessage(int socket_id, + const std::vector<std::string>& app_ids, + const BroadcastRequest& request); + const std::string& sender_id() const { return sender_id_; } private:
diff --git a/components/cast_channel/cast_message_util.cc b/components/cast_channel/cast_message_util.cc index 0b3dc78..77a32ac6 100644 --- a/components/cast_channel/cast_message_util.cc +++ b/components/cast_channel/cast_message_util.cc
@@ -26,6 +26,7 @@ constexpr char kConnectionNamespace[] = "urn:x-cast:com.google.cast.tp.connection"; constexpr char kReceiverNamespace[] = "urn:x-cast:com.google.cast.receiver"; +constexpr char kBroadcastNamespace[] = "urn:x-cast:com.google.cast.broadcast"; // Text payload keys. constexpr char kTypeNodeId[] = "type"; @@ -36,6 +37,7 @@ constexpr char kKeepAlivePongType[] = "PONG"; constexpr char kGetAppAvailabilityRequestType[] = "GET_APP_AVAILABILITY"; constexpr char kConnectionRequestType[] = "CONNECT"; +constexpr char kBroadcastRequestType[] = "APPLICATION_BROADCAST"; // The value used for "sdkType" in a virtual connect request. Historically, this // value is used in the Media Router extension, but here it is reused in Chrome. @@ -55,16 +57,20 @@ message->set_namespace_(message_namespace); } +void SetJSONStringPayload(CastMessage* message, const Value& payload) { + message->set_payload_type( + CastMessage::PayloadType::CastMessage_PayloadType_STRING); + CHECK(base::JSONWriter::Write(payload, message->mutable_payload_utf8())); +} + CastMessage CreateKeepAliveMessage(const char* keep_alive_type) { CastMessage output; FillCommonCastMessageFields(&output, kPlatformSenderId, kPlatformReceiverId, kHeartbeatNamespace); - output.set_payload_type( - CastMessage::PayloadType::CastMessage_PayloadType_STRING); base::DictionaryValue type_dict; type_dict.SetString(kTypeNodeId, keep_alive_type); - CHECK(base::JSONWriter::Write(type_dict, output.mutable_payload_utf8())); + SetJSONStringPayload(&output, type_dict); return output; } @@ -223,8 +229,6 @@ CastMessage output; FillCommonCastMessageFields(&output, source_id, destination_id, kConnectionNamespace); - output.set_payload_type( - CastMessage::PayloadType::CastMessage_PayloadType_STRING); // Parse system_version from user agent string. It contains platform, OS and // CPU info and is contained in the first set of parentheses of the user @@ -254,7 +258,8 @@ sender_info.SetKey("systemVersion", Value(system_version)); dict.SetKey("senderInfo", std::move(sender_info)); - CHECK(base::JSONWriter::Write(dict, output.mutable_payload_utf8())); + + SetJSONStringPayload(&output, dict); return output; } @@ -264,8 +269,6 @@ CastMessage output; FillCommonCastMessageFields(&output, source_id, kPlatformReceiverId, kReceiverNamespace); - output.set_payload_type( - CastMessage::PayloadType::CastMessage_PayloadType_STRING); Value dict(Value::Type::DICTIONARY); dict.SetKey(kTypeNodeId, Value(kGetAppAvailabilityRequestType)); @@ -273,7 +276,40 @@ app_id_value.GetList().push_back(Value(app_id)); dict.SetKey("appId", std::move(app_id_value)); dict.SetKey(kRequestIdNodeId, Value(request_id)); - CHECK(base::JSONWriter::Write(dict, output.mutable_payload_utf8())); + + SetJSONStringPayload(&output, dict); + return output; +} + +BroadcastRequest::BroadcastRequest(const std::string& broadcast_namespace, + const std::string& message) + : broadcast_namespace(broadcast_namespace), message(message) {} +BroadcastRequest::~BroadcastRequest() = default; + +bool BroadcastRequest::operator==(const BroadcastRequest& other) const { + return broadcast_namespace == other.broadcast_namespace && + message == other.message; +} + +CastMessage CreateBroadcastRequest(const std::string& source_id, + int request_id, + const std::vector<std::string>& app_ids, + const BroadcastRequest& request) { + CastMessage output; + FillCommonCastMessageFields(&output, source_id, kPlatformReceiverId, + kBroadcastNamespace); + + Value dict(Value::Type::DICTIONARY); + dict.SetKey(kTypeNodeId, Value(kBroadcastRequestType)); + std::vector<Value> app_ids_value; + for (const std::string& app_id : app_ids) + app_ids_value.push_back(Value(app_id)); + + dict.SetKey("appIds", Value(std::move(app_ids_value))); + dict.SetKey("namespace", Value(request.broadcast_namespace)); + dict.SetKey("message", Value(request.message)); + + SetJSONStringPayload(&output, dict); return output; }
diff --git a/components/cast_channel/cast_message_util.h b/components/cast_channel/cast_message_util.h index 4a64c59..8ec880b 100644 --- a/components/cast_channel/cast_message_util.h +++ b/components/cast_channel/cast_message_util.h
@@ -87,6 +87,24 @@ int request_id, const std::string& app_id); +// Represents a broadcast request. Currently it is used for precaching data +// on a receiver. +struct BroadcastRequest { + BroadcastRequest(const std::string& broadcast_namespace, + const std::string& message); + ~BroadcastRequest(); + bool operator==(const BroadcastRequest& other) const; + + std::string broadcast_namespace; + std::string message; +}; + +// Creates a broadcast request with the given parameters. +CastMessage CreateBroadcastRequest(const std::string& source_id, + int request_id, + const std::vector<std::string>& app_ids, + const BroadcastRequest& request); + // Possible results of a GET_APP_AVAILABILITY request. enum class GetAppAvailabilityResult { kAvailable,
diff --git a/components/cast_channel/cast_test_util.h b/components/cast_channel/cast_test_util.h index 8781325..5448486 100644 --- a/components/cast_channel/cast_test_util.h +++ b/components/cast_channel/cast_test_util.h
@@ -160,6 +160,11 @@ const std::string&, GetAppAvailabilityCallback&)); + MOCK_METHOD3(SendBroadcastMessage, + void(int, + const std::vector<std::string>&, + const BroadcastRequest&)); + private: DISALLOW_COPY_AND_ASSIGN(MockCastMessageHandler); };
diff --git a/components/cast_channel/cast_transport.cc b/components/cast_channel/cast_transport.cc index 8036767..4040f2f 100644 --- a/components/cast_channel/cast_transport.cc +++ b/components/cast_channel/cast_transport.cc
@@ -88,6 +88,7 @@ const net::CompletionCallback& callback, const net::NetworkTrafficAnnotationTag& traffic_annotation) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsCastMessageValid(message)); std::string serialized_message; if (!MessageFramer::Serialize(message, &serialized_message)) { base::ThreadTaskRunnerHandle::Get()->PostTask(
diff --git a/components/certificate_transparency/BUILD.gn b/components/certificate_transparency/BUILD.gn index 1c702a0..604177a7 100644 --- a/components/certificate_transparency/BUILD.gn +++ b/components/certificate_transparency/BUILD.gn
@@ -6,10 +6,10 @@ sources = [ "chrome_ct_policy_enforcer.cc", "chrome_ct_policy_enforcer.h", + "chrome_require_ct_delegate.cc", + "chrome_require_ct_delegate.h", "ct_known_logs.cc", "ct_known_logs.h", - "ct_policy_manager.cc", - "ct_policy_manager.h", "features.cc", "features.h", "log_dns_client.cc", @@ -42,8 +42,8 @@ testonly = true sources = [ "chrome_ct_policy_enforcer_unittest.cc", + "chrome_require_ct_delegate_unittest.cc", "ct_known_logs_unittest.cc", - "ct_policy_manager_unittest.cc", "log_dns_client_unittest.cc", "mock_log_dns_traffic.cc", "mock_log_dns_traffic.h",
diff --git a/components/certificate_transparency/ct_policy_manager.cc b/components/certificate_transparency/chrome_require_ct_delegate.cc similarity index 72% rename from components/certificate_transparency/ct_policy_manager.cc rename to components/certificate_transparency/chrome_require_ct_delegate.cc index d896d33..c75aec7 100644 --- a/components/certificate_transparency/ct_policy_manager.cc +++ b/components/certificate_transparency/chrome_require_ct_delegate.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/certificate_transparency/ct_policy_manager.h" +#include "components/certificate_transparency/chrome_require_ct_delegate.h" #include <algorithm> #include <iterator> @@ -161,111 +161,67 @@ } // namespace -class CTPolicyManager::CTDelegate - : public net::TransportSecurityState::RequireCTDelegate { - public: - explicit CTDelegate(); - ~CTDelegate() override = default; +ChromeRequireCTDelegate::ChromeRequireCTDelegate() + : url_matcher_(std::make_unique<url_matcher::URLMatcher>()), next_id_(0) {} - // Updates the CTDelegate to require CT - // for |required_hosts|, and exclude |excluded_hosts| from CT policies. - void UpdateCTPolicies(const std::vector<std::string>& required_hosts, - const std::vector<std::string>& excluded_hosts, - const std::vector<std::string>& excluded_spkis, - const std::vector<std::string>& excluded_legacy_spkis); - - // RequireCTDelegate implementation - // Called on the network task runner. - CTRequirementLevel IsCTRequiredForHost( - const std::string& hostname, - const net::X509Certificate* chain, - const net::HashValueVector& hashes) override; - - private: - struct Filter { - bool ct_required = false; - bool match_subdomains = false; - size_t host_length = 0; - }; - - // Returns true if a policy for |hostname| is found, setting - // |*ct_required| to indicate whether or not Certificate Transparency is - // required for the host. - bool MatchHostname(const std::string& hostname, bool* ct_required) const; - - // Returns true if a policy for |chain|, which contains the SPKI hashes - // |hashes|, is found, setting |*ct_required| to indicate whether or not - // Certificate Transparency is required for the certificate. - bool MatchSPKI(const net::X509Certificate* chain, - const net::HashValueVector& hashes, - bool* ct_required) const; - - // Updates the |url_matcher_| to - // require CT for |required_hosts| and exclude |excluded_hosts|, both - // of which are Lists of Strings which are URLBlacklist filters, and - // updates |excluded_spkis| and |excluded_legacy_spkis| to exclude CT for - // those SPKIs, which are encoded as strings using net::HashValue::ToString. - void Update(const std::vector<std::string>& required_hosts, - const std::vector<std::string>& excluded_hosts, - const std::vector<std::string>& excluded_spkis, - const std::vector<std::string>& excluded_legacy_spkis); - - // Parses the filters from |host_patterns|, adding them as filters to - // |filters_| (with |ct_required| indicating whether or not CT is required - // for that host), and updating |*conditions| with the corresponding - // URLMatcher::Conditions to match the host. - void AddFilters(bool ct_required, - const std::vector<std::string>& host_patterns, - url_matcher::URLMatcherConditionSet::Vector* conditions); - - // Parses the SPKIs from |list|, setting |*hashes| to the sorted set of all - // valid SPKIs. - void ParseSpkiHashes(const std::vector<std::string> list, - net::HashValueVector* hashes) const; - - // Returns true if |lhs| has greater precedence than |rhs|. - bool FilterTakesPrecedence(const Filter& lhs, const Filter& rhs) const; - - std::unique_ptr<url_matcher::URLMatcher> url_matcher_; - url_matcher::URLMatcherConditionSet::ID next_id_; - std::map<url_matcher::URLMatcherConditionSet::ID, Filter> filters_; - - // Both SPKI lists are sorted. - net::HashValueVector spkis_; - net::HashValueVector legacy_spkis_; - - DISALLOW_COPY_AND_ASSIGN(CTDelegate); -}; - -CTPolicyManager::CTDelegate::CTDelegate() - : url_matcher_(new url_matcher::URLMatcher), next_id_(0) {} - -void CTPolicyManager::CTDelegate::UpdateCTPolicies( - const std::vector<std::string>& required_hosts, - const std::vector<std::string>& excluded_hosts, - const std::vector<std::string>& excluded_spkis, - const std::vector<std::string>& excluded_legacy_spkis) { - Update(required_hosts, excluded_hosts, excluded_spkis, excluded_legacy_spkis); -} +ChromeRequireCTDelegate::~ChromeRequireCTDelegate() {} net::TransportSecurityState::RequireCTDelegate::CTRequirementLevel -CTPolicyManager::CTDelegate::IsCTRequiredForHost( +ChromeRequireCTDelegate::IsCTRequiredForHost( const std::string& hostname, const net::X509Certificate* chain, - const net::HashValueVector& hashes) { - + const net::HashValueVector& spki_hashes) { bool ct_required = false; if (MatchHostname(hostname, &ct_required) || - MatchSPKI(chain, hashes, &ct_required)) { + MatchSPKI(chain, spki_hashes, &ct_required)) { return ct_required ? CTRequirementLevel::REQUIRED : CTRequirementLevel::NOT_REQUIRED; } + // Compute >= 2018-05-01, rather than deal with possible fractional + // seconds. + const base::Time kMay_1_2018 = + base::Time::UnixEpoch() + base::TimeDelta::FromSeconds(1525132800); + if (chain->valid_start() >= kMay_1_2018) + return CTRequirementLevel::REQUIRED; + return CTRequirementLevel::DEFAULT; } -bool CTPolicyManager::CTDelegate::MatchHostname(const std::string& hostname, - bool* ct_required) const { +void ChromeRequireCTDelegate::UpdateCTPolicies( + const std::vector<std::string>& required_hosts, + const std::vector<std::string>& excluded_hosts, + const std::vector<std::string>& excluded_spkis, + const std::vector<std::string>& excluded_legacy_spkis) { + url_matcher_ = std::make_unique<url_matcher::URLMatcher>(); + filters_.clear(); + next_id_ = 0; + + url_matcher::URLMatcherConditionSet::Vector all_conditions; + AddFilters(true, required_hosts, &all_conditions); + AddFilters(false, excluded_hosts, &all_conditions); + + url_matcher_->AddConditionSets(all_conditions); + + ParseSpkiHashes(excluded_spkis, &spkis_); + ParseSpkiHashes(excluded_legacy_spkis, &legacy_spkis_); + + // Filter out SPKIs that aren't for legacy CAs. + legacy_spkis_.erase( + std::remove_if(legacy_spkis_.begin(), legacy_spkis_.end(), + [](const net::HashValue& hash) { + if (!net::IsLegacyPubliclyTrustedCA(hash)) { + LOG(ERROR) << "Non-legacy SPKI configured " + << hash.ToString(); + return true; + } + return false; + }), + legacy_spkis_.end()); +} + +bool ChromeRequireCTDelegate::MatchHostname(const std::string& hostname, + bool* ct_required) const { if (url_matcher_->IsEmpty()) return false; @@ -301,9 +257,9 @@ return true; } -bool CTPolicyManager::CTDelegate::MatchSPKI(const net::X509Certificate* chain, - const net::HashValueVector& hashes, - bool* ct_required) const { +bool ChromeRequireCTDelegate::MatchSPKI(const net::X509Certificate* chain, + const net::HashValueVector& hashes, + bool* ct_required) const { // Try to scan legacy SPKIs first, if any, since they will only require // comparing hash values. if (!legacy_spkis_.empty()) { @@ -379,39 +335,7 @@ return false; } -void CTPolicyManager::CTDelegate::Update( - const std::vector<std::string>& required_hosts, - const std::vector<std::string>& excluded_hosts, - const std::vector<std::string>& excluded_spkis, - const std::vector<std::string>& excluded_legacy_spkis) { - url_matcher_.reset(new url_matcher::URLMatcher); - filters_.clear(); - next_id_ = 0; - - url_matcher::URLMatcherConditionSet::Vector all_conditions; - AddFilters(true, required_hosts, &all_conditions); - AddFilters(false, excluded_hosts, &all_conditions); - - url_matcher_->AddConditionSets(all_conditions); - - ParseSpkiHashes(excluded_spkis, &spkis_); - ParseSpkiHashes(excluded_legacy_spkis, &legacy_spkis_); - - // Filter out SPKIs that aren't for legacy CAs. - legacy_spkis_.erase( - std::remove_if(legacy_spkis_.begin(), legacy_spkis_.end(), - [](const net::HashValue& hash) { - if (!net::IsLegacyPubliclyTrustedCA(hash)) { - LOG(ERROR) << "Non-legacy SPKI configured " - << hash.ToString(); - return true; - } - return false; - }), - legacy_spkis_.end()); -} - -void CTPolicyManager::CTDelegate::AddFilters( +void ChromeRequireCTDelegate::AddFilters( bool ct_required, const std::vector<std::string>& hosts, url_matcher::URLMatcherConditionSet::Vector* conditions) { @@ -472,11 +396,11 @@ } } -void CTPolicyManager::CTDelegate::ParseSpkiHashes( - const std::vector<std::string> list, +void ChromeRequireCTDelegate::ParseSpkiHashes( + const std::vector<std::string> spki_list, net::HashValueVector* hashes) const { hashes->clear(); - for (const auto& value : list) { + for (const auto& value : spki_list) { net::HashValue hash; if (!hash.FromString(value)) { continue; @@ -486,9 +410,8 @@ std::sort(hashes->begin(), hashes->end()); } -bool CTPolicyManager::CTDelegate::FilterTakesPrecedence( - const Filter& lhs, - const Filter& rhs) const { +bool ChromeRequireCTDelegate::FilterTakesPrecedence(const Filter& lhs, + const Filter& rhs) const { if (lhs.match_subdomains != rhs.match_subdomains) return !lhs.match_subdomains; // Prefer the more explicit policy. @@ -501,21 +424,4 @@ return false; } -CTPolicyManager::CTPolicyManager() : delegate_(new CTDelegate()) {} - -CTPolicyManager::~CTPolicyManager() {} - -void CTPolicyManager::UpdateCTPolicies( - const std::vector<std::string>& required_hosts, - const std::vector<std::string>& excluded_hosts, - const std::vector<std::string>& excluded_spkis, - const std::vector<std::string>& excluded_legacy_spkis) { - delegate_->UpdateCTPolicies(required_hosts, excluded_hosts, excluded_spkis, - excluded_legacy_spkis); -} - -net::TransportSecurityState::RequireCTDelegate* CTPolicyManager::GetDelegate() { - return delegate_.get(); -} - } // namespace certificate_transparency
diff --git a/components/certificate_transparency/chrome_require_ct_delegate.h b/components/certificate_transparency/chrome_require_ct_delegate.h new file mode 100644 index 0000000..3b947f5 --- /dev/null +++ b/components/certificate_transparency/chrome_require_ct_delegate.h
@@ -0,0 +1,107 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_CERTIFICATE_TRANSPARENCY_CHROME_REQUIRE_CT_DELEGATE_H_ +#define COMPONENTS_CERTIFICATE_TRANSPARENCY_CHROME_REQUIRE_CT_DELEGATE_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "components/url_matcher/url_matcher.h" +#include "net/base/hash_value.h" +#include "net/http/transport_security_state.h" + +namespace net { +class X509Certificate; +} // namespace net + +namespace certificate_transparency { + +// ChromeRequireCTDelegate implements the policies used by Chrome to determine +// when to require Certificate Transparency for a host or certificate. Combined +// with ChromeCTPolicyEnforcer, these two classes implement the +// "Certificate Transparency in Chrome" policy from +// https://goo.gl/chrome/ct-policy - PolicyEnforcer imposing the policies on +// the SCTs to determine whether or not a certificate complies, and +// RequireCTDelegate to determine whether or not compliance is required for the +// connection to succeed. +// +// To support Enterprise configuration, additional requirements or exceptions +// can be provided via |UpdateCTPolicies()|, which uses the configuration +// syntax documented in pref_names.h for each of the options. +class ChromeRequireCTDelegate + : public net::TransportSecurityState::RequireCTDelegate { + public: + explicit ChromeRequireCTDelegate(); + ~ChromeRequireCTDelegate() override; + + // RequireCTDelegate implementation + CTRequirementLevel IsCTRequiredForHost( + const std::string& hostname, + const net::X509Certificate* chain, + const net::HashValueVector& spki_hashes) override; + + // Updates the CTDelegate to require CT for |required_hosts|, and exclude + // |excluded_hosts| from CT policies. In addtion, this method updates + // |excluded_spkis| and |excluded_legacy_spkis| intended for use within an + // Enterprise (see https://crbug.com/824184). + void UpdateCTPolicies(const std::vector<std::string>& required_hosts, + const std::vector<std::string>& excluded_hosts, + const std::vector<std::string>& excluded_spkis, + const std::vector<std::string>& excluded_legacy_spkis); + + private: + struct Filter { + bool ct_required = false; + bool match_subdomains = false; + size_t host_length = 0; + }; + + // Returns true if a policy for |hostname| is found, setting + // |*ct_required| to indicate whether or not Certificate Transparency is + // required for the host. + bool MatchHostname(const std::string& hostname, bool* ct_required) const; + + // Returns true if a policy for |chain|, which contains the SPKI hashes + // |hashes|, is found, setting |*ct_required| to indicate whether or not + // Certificate Transparency is required for the certificate. + bool MatchSPKI(const net::X509Certificate* chain, + const net::HashValueVector& hashes, + bool* ct_required) const; + + // Parses the filters from |host_patterns|, adding them as filters to + // |filters_| (with |ct_required| indicating whether or not CT is required + // for that host), and updating |*conditions| with the corresponding + // URLMatcher::Conditions to match the host. + void AddFilters(bool ct_required, + const std::vector<std::string>& host_patterns, + url_matcher::URLMatcherConditionSet::Vector* conditions); + + // Parses the SPKIs from |spki_list|, setting |*hashes| to the sorted set of + // all valid SPKIs. + void ParseSpkiHashes(const std::vector<std::string> spki_list, + net::HashValueVector* hashes) const; + + // Returns true if |lhs| has greater precedence than |rhs|. Filters of + // higher precedence are consulted first when determining if a given filter + // matches. + bool FilterTakesPrecedence(const Filter& lhs, const Filter& rhs) const; + + std::unique_ptr<url_matcher::URLMatcher> url_matcher_; + url_matcher::URLMatcherConditionSet::ID next_id_; + std::map<url_matcher::URLMatcherConditionSet::ID, Filter> filters_; + + // Both SPKI lists are sorted. + net::HashValueVector spkis_; + net::HashValueVector legacy_spkis_; + + DISALLOW_COPY_AND_ASSIGN(ChromeRequireCTDelegate); +}; + +} // namespace certificate_transparency + +#endif // COMPONENTS_CERTIFICATE_TRANSPARENCY_CHROME_REQUIRE_CT_DELEGATE_H_
diff --git a/components/certificate_transparency/ct_policy_manager_unittest.cc b/components/certificate_transparency/chrome_require_ct_delegate_unittest.cc similarity index 61% rename from components/certificate_transparency/ct_policy_manager_unittest.cc rename to components/certificate_transparency/chrome_require_ct_delegate_unittest.cc index 0cd328e..a9e1628 100644 --- a/components/certificate_transparency/ct_policy_manager_unittest.cc +++ b/components/certificate_transparency/chrome_require_ct_delegate_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/certificate_transparency/ct_policy_manager.h" +#include "components/certificate_transparency/chrome_require_ct_delegate.h" #include <iterator> @@ -27,9 +27,9 @@ namespace { -class CTPolicyManagerTest : public ::testing::Test { +class ChromeRequireCTDelegateTest : public ::testing::Test { public: - CTPolicyManagerTest() : message_loop_(base::MessageLoop::TYPE_IO) {} + ChromeRequireCTDelegateTest() : message_loop_(base::MessageLoop::TYPE_IO) {} void SetUp() override { cert_ = net::CreateCertificateChainFromFile( @@ -48,7 +48,7 @@ // Treat the preferences as a black box as far as naming, but ensure that // preferences get registered. -TEST_F(CTPolicyManagerTest, RegistersPrefs) { +TEST_F(ChromeRequireCTDelegateTest, RegistersPrefs) { TestingPrefServiceSimple pref_service; auto registered_prefs = std::distance(pref_service.registry()->begin(), pref_service.registry()->end()); @@ -58,172 +58,144 @@ EXPECT_NE(registered_prefs, newly_registered_prefs); } -TEST_F(CTPolicyManagerTest, DelegateChecksRequired) { +TEST_F(ChromeRequireCTDelegateTest, DelegateChecksRequired) { using CTRequirementLevel = net::TransportSecurityState::RequireCTDelegate::CTRequirementLevel; - CTPolicyManager manager; - - net::TransportSecurityState::RequireCTDelegate* delegate = - manager.GetDelegate(); - ASSERT_TRUE(delegate); + ChromeRequireCTDelegate delegate; // No required host set yet. EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("google.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("google.com", cert_.get(), hashes_)); // Add a required host - manager.UpdateCTPolicies( - std::vector<std::string>{"google.com"}, std::vector<std::string>(), - std::vector<std::string>(), std::vector<std::string>()); + delegate.UpdateCTPolicies({"google.com"}, {}, {}, {}); // The new setting should take effect. EXPECT_EQ(CTRequirementLevel::REQUIRED, - delegate->IsCTRequiredForHost("google.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("google.com", cert_.get(), hashes_)); } -TEST_F(CTPolicyManagerTest, DelegateChecksExcluded) { +TEST_F(ChromeRequireCTDelegateTest, DelegateChecksExcluded) { using CTRequirementLevel = net::TransportSecurityState::RequireCTDelegate::CTRequirementLevel; - CTPolicyManager manager; - - net::TransportSecurityState::RequireCTDelegate* delegate = - manager.GetDelegate(); - ASSERT_TRUE(delegate); + ChromeRequireCTDelegate delegate; // No setting should yield the default results. EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("google.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("google.com", cert_.get(), hashes_)); // Add a excluded host - manager.UpdateCTPolicies( - std::vector<std::string>(), std::vector<std::string>{"google.com"}, - std::vector<std::string>(), std::vector<std::string>()); + delegate.UpdateCTPolicies({}, {"google.com"}, {}, {}); // The new setting should take effect. EXPECT_EQ(CTRequirementLevel::NOT_REQUIRED, - delegate->IsCTRequiredForHost("google.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("google.com", cert_.get(), hashes_)); } -TEST_F(CTPolicyManagerTest, IgnoresInvalidEntries) { +TEST_F(ChromeRequireCTDelegateTest, IgnoresInvalidEntries) { using CTRequirementLevel = net::TransportSecurityState::RequireCTDelegate::CTRequirementLevel; - CTPolicyManager manager; - - net::TransportSecurityState::RequireCTDelegate* delegate = - manager.GetDelegate(); - ASSERT_TRUE(delegate); + ChromeRequireCTDelegate delegate; // No setting should yield the default results. EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("google.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("google.com", cert_.get(), hashes_)); // Now setup invalid state (that is, that fail to be parsable as // URLs). - manager.UpdateCTPolicies( - std::vector<std::string>{ - "file:///etc/fstab", "file://withahost/etc/fstab", - "file:///c|/Windows", "*", "https://*", "example.com", - "https://example.test:invalid_port"}, - std::vector<std::string>(), std::vector<std::string>(), - std::vector<std::string>()); + delegate.UpdateCTPolicies( + {"file:///etc/fstab", "file://withahost/etc/fstab", "file:///c|/Windows", + "*", "https://*", "example.com", "https://example.test:invalid_port"}, + {}, {}, {}); // Wildcards are ignored (both * and https://*). EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("google.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("google.com", cert_.get(), hashes_)); + // File URL hosts are ignored. // TODO(rsleevi): https://crbug.com/841407 - Ensure that file URLs have their // hosts ignored for policy. // EXPECT_EQ(CTRequirementLevel::DEFAULT, - // delegate->IsCTRequiredForHost("withahost", cert_.get(), hashes_)); + // delegate.IsCTRequiredForHost("withahost", cert_.get(), hashes_)); // While the partially parsed hosts should take effect. - EXPECT_EQ( - CTRequirementLevel::REQUIRED, - delegate->IsCTRequiredForHost("example.test", cert_.get(), hashes_)); EXPECT_EQ(CTRequirementLevel::REQUIRED, - delegate->IsCTRequiredForHost("example.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("example.test", cert_.get(), hashes_)); + EXPECT_EQ(CTRequirementLevel::REQUIRED, + delegate.IsCTRequiredForHost("example.com", cert_.get(), hashes_)); } // Make sure the various 'undocumented' priorities apply: // - non-wildcards beat wildcards // - more specific hosts beat less specific hosts // - requiring beats excluding -TEST_F(CTPolicyManagerTest, AppliesPriority) { +TEST_F(ChromeRequireCTDelegateTest, AppliesPriority) { using CTRequirementLevel = net::TransportSecurityState::RequireCTDelegate::CTRequirementLevel; - CTPolicyManager manager; - - net::TransportSecurityState::RequireCTDelegate* delegate = - manager.GetDelegate(); - ASSERT_TRUE(delegate); + ChromeRequireCTDelegate delegate; // No setting should yield the default results. EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("example.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("example.com", cert_.get(), hashes_)); EXPECT_EQ( CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("sub.example.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("sub.example.com", cert_.get(), hashes_)); EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("accounts.example.com", cert_.get(), - hashes_)); + delegate.IsCTRequiredForHost("accounts.example.com", cert_.get(), + hashes_)); EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("login.accounts.example.com", - cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("login.accounts.example.com", + cert_.get(), hashes_)); EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("sub.accounts.example.com", - cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("sub.accounts.example.com", + cert_.get(), hashes_)); EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("login.sub.accounts.example.com", - cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("login.sub.accounts.example.com", + cert_.get(), hashes_)); EXPECT_EQ( CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("test.example.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("test.example.com", cert_.get(), hashes_)); // Set up policies that exclude it for a domain and all of its subdomains, // but then require it for a specific host. - manager.UpdateCTPolicies( - std::vector<std::string>{"sub.example.com", "accounts.example.com", - "test.example.com"}, - std::vector<std::string>{"example.com", ".sub.example.com", - ".sub.accounts.example.com", "test.example.com"}, - std::vector<std::string>(), std::vector<std::string>()); + delegate.UpdateCTPolicies( + {"sub.example.com", "accounts.example.com", "test.example.com"}, + {"example.com", ".sub.example.com", ".sub.accounts.example.com", + "test.example.com"}, + {}, {}); EXPECT_EQ(CTRequirementLevel::NOT_REQUIRED, - delegate->IsCTRequiredForHost("example.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("example.com", cert_.get(), hashes_)); // Non-wildcarding (.sub.example.com) beats wildcarding (sub.example.com). EXPECT_EQ( CTRequirementLevel::NOT_REQUIRED, - delegate->IsCTRequiredForHost("sub.example.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("sub.example.com", cert_.get(), hashes_)); // More specific hosts (accounts.example.com) beat less specific hosts // (example.com + wildcard). EXPECT_EQ(CTRequirementLevel::REQUIRED, - delegate->IsCTRequiredForHost("accounts.example.com", cert_.get(), - hashes_)); + delegate.IsCTRequiredForHost("accounts.example.com", cert_.get(), + hashes_)); // More specific hosts (accounts.example.com) beat less specific hosts // (example.com). EXPECT_EQ(CTRequirementLevel::REQUIRED, - delegate->IsCTRequiredForHost("login.accounts.example.com", - cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("login.accounts.example.com", + cert_.get(), hashes_)); EXPECT_EQ(CTRequirementLevel::NOT_REQUIRED, - delegate->IsCTRequiredForHost("sub.accounts.example.com", - cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("sub.accounts.example.com", + cert_.get(), hashes_)); EXPECT_EQ(CTRequirementLevel::REQUIRED, - delegate->IsCTRequiredForHost("login.sub.accounts.example.com", - cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("login.sub.accounts.example.com", + cert_.get(), hashes_)); // Requiring beats excluding. EXPECT_EQ( CTRequirementLevel::REQUIRED, - delegate->IsCTRequiredForHost("test.example.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("test.example.com", cert_.get(), hashes_)); } -TEST_F(CTPolicyManagerTest, SupportsOrgRestrictions) { +TEST_F(ChromeRequireCTDelegateTest, SupportsOrgRestrictions) { using CTRequirementLevel = net::TransportSecurityState::RequireCTDelegate::CTRequirementLevel; - CTPolicyManager manager; - - net::TransportSecurityState::RequireCTDelegate* delegate = - manager.GetDelegate(); - ASSERT_TRUE(delegate); + ChromeRequireCTDelegate delegate; base::FilePath test_directory = net::GetTestNetDataDirectory().Append( FILE_PATH_LITERAL("ov_name_constraints")); @@ -340,33 +312,24 @@ net::x509_util::DupCryptoBuffer(leaf->cert_buffer()), std::move(intermediates)); } - manager.UpdateCTPolicies( - std::vector<std::string>(), std::vector<std::string>(), - std::vector<std::string>(), std::vector<std::string>()); + delegate.UpdateCTPolicies({}, {}, {}, {}); // There should be no existing settings. EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("google.com", leaf.get(), hashes)); + delegate.IsCTRequiredForHost("google.com", leaf.get(), hashes)); - manager.UpdateCTPolicies(std::vector<std::string>(), - std::vector<std::string>(), - std::vector<std::string>{test.spki.ToString()}, - std::vector<std::string>()); + delegate.UpdateCTPolicies({}, {}, {test.spki.ToString()}, {}); // The new setting should take effect. EXPECT_EQ(test.expected, - delegate->IsCTRequiredForHost("google.com", leaf.get(), hashes)); + delegate.IsCTRequiredForHost("google.com", leaf.get(), hashes)); } } -TEST_F(CTPolicyManagerTest, SupportsLegacyCaRestrictions) { +TEST_F(ChromeRequireCTDelegateTest, SupportsLegacyCaRestrictions) { using CTRequirementLevel = net::TransportSecurityState::RequireCTDelegate::CTRequirementLevel; - CTPolicyManager manager; - - net::TransportSecurityState::RequireCTDelegate* delegate = - manager.GetDelegate(); - ASSERT_TRUE(delegate); + ChromeRequireCTDelegate delegate; // The hash of a known legacy CA. See // //net/cert/root_cert_list_generated.h @@ -375,35 +338,99 @@ 0x38, 0x3E, 0x37, 0x3F, 0x0F, 0x22, 0x9E, 0x7D, 0xFE, 0x34, 0x44, 0x81, 0x0A, 0x8D, 0x6E, 0x50, 0x90, 0x5D, 0x20, 0xD6, 0x61, }}; - hashes_.push_back(net::HashValue(legacy_spki)); // No setting should yield the default results. EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("google.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("google.com", cert_.get(), hashes_)); // Setting to a non-legacy CA should not work. std::string leaf_hash_string = hashes_.front().ToString(); - manager.UpdateCTPolicies( - std::vector<std::string>(), std::vector<std::string>(), - std::vector<std::string>(), std::vector<std::string>{leaf_hash_string}); + delegate.UpdateCTPolicies({}, {}, {}, {leaf_hash_string}); // This setting should have no effect, because the hash for |cert_| // is not a legacy CA hash. EXPECT_EQ(CTRequirementLevel::DEFAULT, - delegate->IsCTRequiredForHost("google.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("google.com", cert_.get(), hashes_)); // Now set to a truly legacy CA, and create a chain that // contains that legacy CA hash. - std::string legacy_ca_hash_string = hashes_.back().ToString(); - - manager.UpdateCTPolicies(std::vector<std::string>(), - std::vector<std::string>(), - std::vector<std::string>(), - std::vector<std::string>{legacy_ca_hash_string}); - + delegate.UpdateCTPolicies({}, {}, {}, {hashes_.back().ToString()}); EXPECT_EQ(CTRequirementLevel::NOT_REQUIRED, - delegate->IsCTRequiredForHost("google.com", cert_.get(), hashes_)); + delegate.IsCTRequiredForHost("google.com", cert_.get(), hashes_)); +} + +TEST_F(ChromeRequireCTDelegateTest, RequiresCTAfterApril2018) { + using CTRequirementLevel = + net::TransportSecurityState::RequireCTDelegate::CTRequirementLevel; + ChromeRequireCTDelegate delegate; + + EXPECT_EQ(CTRequirementLevel::DEFAULT, + delegate.IsCTRequiredForHost("example.com", cert_.get(), hashes_)); + + scoped_refptr<net::X509Certificate> may_2018 = + net::CreateCertificateChainFromFile( + net::GetTestCertsDirectory(), "may_2018.pem", + net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE); + ASSERT_TRUE(may_2018); + + net::HashValueVector new_hashes; + new_hashes.push_back(net::HashValue( + net::X509Certificate::CalculateFingerprint256(may_2018->cert_buffer()))); + + EXPECT_EQ( + CTRequirementLevel::REQUIRED, + delegate.IsCTRequiredForHost("example.com", may_2018.get(), new_hashes)); +} + +TEST_F(ChromeRequireCTDelegateTest, + PoliciesCheckedBeforeRequiringCTAfterApril2018) { + using CTRequirementLevel = + net::TransportSecurityState::RequireCTDelegate::CTRequirementLevel; + ChromeRequireCTDelegate delegate; + + scoped_refptr<net::X509Certificate> may_2018 = + net::CreateCertificateChainFromFile( + net::GetTestCertsDirectory(), "may_2018.pem", + net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE); + ASSERT_TRUE(may_2018); + + net::HashValueVector new_hashes; + net::HashValue leaf_hash; + ASSERT_TRUE(net::x509_util::CalculateSha256SpkiHash(may_2018->cert_buffer(), + &leaf_hash)); + new_hashes.push_back(std::move(leaf_hash)); + + EXPECT_EQ( + CTRequirementLevel::REQUIRED, + delegate.IsCTRequiredForHost("example.com", may_2018.get(), new_hashes)); + + // Check excluding by hostname. + delegate.UpdateCTPolicies({}, {"example.com"}, {}, {}); + EXPECT_EQ( + CTRequirementLevel::NOT_REQUIRED, + delegate.IsCTRequiredForHost("example.com", may_2018.get(), new_hashes)); + + // Check excluding by leaf hash. + delegate.UpdateCTPolicies({}, {}, {new_hashes.front().ToString()}, {}); + EXPECT_EQ( + CTRequirementLevel::NOT_REQUIRED, + delegate.IsCTRequiredForHost("example.com", may_2018.get(), new_hashes)); + + // Check excluding by legacy CA hash. + + // The hash of a known legacy CA. See + // //net/cert/root_cert_list_generated.h + net::SHA256HashValue legacy_spki = {{ + 0x00, 0x6C, 0xB2, 0x26, 0xA7, 0x72, 0xC7, 0x18, 0x2D, 0x77, 0x72, + 0x38, 0x3E, 0x37, 0x3F, 0x0F, 0x22, 0x9E, 0x7D, 0xFE, 0x34, 0x44, + 0x81, 0x0A, 0x8D, 0x6E, 0x50, 0x90, 0x5D, 0x20, 0xD6, 0x61, + }}; + new_hashes.push_back(net::HashValue(legacy_spki)); + delegate.UpdateCTPolicies({}, {}, {}, {new_hashes.back().ToString()}); + EXPECT_EQ( + CTRequirementLevel::NOT_REQUIRED, + delegate.IsCTRequiredForHost("example.com", may_2018.get(), new_hashes)); } } // namespace
diff --git a/components/certificate_transparency/ct_policy_manager.h b/components/certificate_transparency/ct_policy_manager.h deleted file mode 100644 index 88f3b97..0000000 --- a/components/certificate_transparency/ct_policy_manager.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_CERTIFICATE_TRANSPARENCY_CT_POLICY_MANAGER_H_ -#define COMPONENTS_CERTIFICATE_TRANSPARENCY_CT_POLICY_MANAGER_H_ - -#include <memory> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "net/http/transport_security_state.h" - -namespace certificate_transparency { - -// CTPolicyManager serves as the bridge between the Certificate Transparency -// preferences (see pref_names.h) and the actual implementation, by exposing -// a TransportSecurityState::RequireCTDelegate that can be used to query for -// CT-related policies. -class CTPolicyManager { - public: - // Creates a CTPolicyManager that will provide a RequireCTDelegate delegate. - CTPolicyManager(); - ~CTPolicyManager(); - - // Returns a RequireCTDelegate that responds based on the policies set via - // preferences. - // - // The order of priority of the preferences is that: - // - Specific hosts are preferred over those that match subdomains. - // - The most specific host is preferred. - // - Requiring CT is preferred over excluding CT - // - net::TransportSecurityState::RequireCTDelegate* GetDelegate(); - - // Updates the CTDelegate to require CT for |required_hosts|, and exclude - // |excluded_hosts| from CT policies. In addtion, this method updates - // |excluded_spkis| and |excluded_legacy_spkis| intended for use within an - // Enterprise (see https://crbug.com/824184). - void UpdateCTPolicies(const std::vector<std::string>& required_hosts, - const std::vector<std::string>& excluded_hosts, - const std::vector<std::string>& excluded_spkis, - const std::vector<std::string>& excluded_legacy_spkis); - - private: - class CTDelegate; - std::unique_ptr<CTDelegate> delegate_; - - DISALLOW_COPY_AND_ASSIGN(CTPolicyManager); -}; - -} // namespace certificate_transparency - -#endif // COMPONENTS_CERTIFICATE_TRANSPARENCY_CT_POLICY_MANAGER_H_
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index 560c716..abf40af 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -576,8 +576,9 @@ if (state_.input_region) { hit_test_region_ = *state_.input_region; hit_test_region_.Intersect(surface_hierarchy_content_bounds_); - } else + } else { hit_test_region_ = surface_hierarchy_content_bounds_; + } int outset = state_.input_outset; if (outset > 0) { @@ -727,7 +728,7 @@ Surface::State::~State() = default; -bool Surface::State::operator==(const State& other) { +bool Surface::State::operator==(const State& other) const { return other.opaque_region == opaque_region && other.input_region == input_region && other.buffer_scale == buffer_scale &&
diff --git a/components/exo/surface.h b/components/exo/surface.h index d0874a9..4f070a9 100644 --- a/components/exo/surface.h +++ b/components/exo/surface.h
@@ -248,8 +248,8 @@ State(); ~State(); - bool operator==(const State& other); - bool operator!=(const State& other) { return !(*this == other); } + bool operator==(const State& other) const; + bool operator!=(const State& other) const { return !(*this == other); } cc::Region opaque_region; base::Optional<cc::Region> input_region;
diff --git a/components/viz/service/display/dc_layer_overlay.cc b/components/viz/service/display/dc_layer_overlay.cc index 592eb099..1b0bd24 100644 --- a/components/viz/service/display/dc_layer_overlay.cc +++ b/components/viz/service/display/dc_layer_overlay.cc
@@ -21,16 +21,16 @@ DCLayerOverlayProcessor::DCLayerResult FromYUVQuad( cc::DisplayResourceProvider* resource_provider, const YUVVideoDrawQuad* quad, - DCLayerOverlay* ca_layer_overlay) { + DCLayerOverlay* dc_layer_overlay) { for (const auto& resource : quad->resources) { if (!resource_provider->IsOverlayCandidate(resource)) return DCLayerOverlayProcessor::DC_LAYER_FAILED_TEXTURE_NOT_CANDIDATE; } - ca_layer_overlay->resources = quad->resources; - ca_layer_overlay->contents_rect = quad->ya_tex_coord_rect; - ca_layer_overlay->filter = GL_LINEAR; - ca_layer_overlay->color_space = quad->video_color_space; - ca_layer_overlay->require_overlay = quad->require_overlay; + dc_layer_overlay->resources = quad->resources; + dc_layer_overlay->contents_rect = quad->ya_tex_coord_rect; + dc_layer_overlay->filter = GL_LINEAR; + dc_layer_overlay->color_space = quad->video_color_space; + dc_layer_overlay->require_overlay = quad->require_overlay; return DCLayerOverlayProcessor::DC_LAYER_SUCCESS; } @@ -94,7 +94,7 @@ const gfx::RectF& display_rect, QuadList::ConstIterator quad_list_begin, QuadList::ConstIterator quad, - DCLayerOverlay* ca_layer_overlay) { + DCLayerOverlay* dc_layer_overlay) { if (quad->shared_quad_state->blend_mode != SkBlendMode::kSrcOver) return DC_LAYER_FAILED_QUAD_BLEND_MODE; @@ -103,7 +103,7 @@ case DrawQuad::YUV_VIDEO_CONTENT: result = FromYUVQuad(resource_provider, YUVVideoDrawQuad::MaterialCast(*quad), - ca_layer_overlay); + dc_layer_overlay); break; default: return DC_LAYER_FAILED_UNSUPPORTED_QUAD; @@ -123,8 +123,8 @@ overlay_shared_state->transform = quad->shared_quad_state->quad_to_target_transform.matrix(); - ca_layer_overlay->shared_state = overlay_shared_state; - ca_layer_overlay->bounds_rect = gfx::RectF(quad->rect); + dc_layer_overlay->shared_state = overlay_shared_state; + dc_layer_overlay->bounds_rect = gfx::RectF(quad->rect); return result; } @@ -135,7 +135,7 @@ RenderPassList* render_passes, gfx::Rect* overlay_damage_rect, gfx::Rect* damage_rect, - DCLayerOverlayList* ca_layer_overlays) { + DCLayerOverlayList* dc_layer_overlays) { DCHECK(pass_info_.empty()); processed_overlay_in_frame_ = false; if (base::FeatureList::IsEnabled( @@ -145,12 +145,12 @@ ProcessRenderPass(resource_provider, display_rect, pass.get(), is_root, overlay_damage_rect, is_root ? damage_rect : &pass->damage_rect, - ca_layer_overlays); + dc_layer_overlays); } } else { ProcessRenderPass(resource_provider, display_rect, render_passes->back().get(), true, overlay_damage_rect, - damage_rect, ca_layer_overlays); + damage_rect, dc_layer_overlays); } pass_info_.clear(); } @@ -224,7 +224,7 @@ bool is_root, gfx::Rect* overlay_damage_rect, gfx::Rect* damage_rect, - DCLayerOverlayList* ca_layer_overlays) { + DCLayerOverlayList* dc_layer_overlays) { gfx::Rect this_frame_underlay_rect; QuadList* quad_list = &render_pass->quad_list; @@ -286,7 +286,7 @@ overlay_damage_rect->Union(rect_in_root); RecordDCLayerResult(DC_LAYER_SUCCESS); - ca_layer_overlays->push_back(dc_layer); + dc_layer_overlays->push_back(dc_layer); if (!base::FeatureList::IsEnabled( features::kDirectCompositionNonrootOverlays)) { // Only allow one overlay for now.
diff --git a/components/viz/service/surfaces/surface_dependency_deadline.cc b/components/viz/service/surfaces/surface_dependency_deadline.cc index f60a39b..4e86b83 100644 --- a/components/viz/service/surfaces/surface_dependency_deadline.cc +++ b/components/viz/service/surfaces/surface_dependency_deadline.cc
@@ -59,7 +59,7 @@ } bool SurfaceDependencyDeadline::operator==( - const SurfaceDependencyDeadline& other) { + const SurfaceDependencyDeadline& other) const { return begin_frame_source_ == other.begin_frame_source_ && deadline_ == other.deadline_; }
diff --git a/components/viz/service/surfaces/surface_dependency_deadline.h b/components/viz/service/surfaces/surface_dependency_deadline.h index bc5913b..9c0349df 100644 --- a/components/viz/service/surfaces/surface_dependency_deadline.h +++ b/components/viz/service/surfaces/surface_dependency_deadline.h
@@ -45,8 +45,8 @@ // Takes on the same BeginFrameSource and deadline as |other|. void InheritFrom(const SurfaceDependencyDeadline& other); - bool operator==(const SurfaceDependencyDeadline& other); - bool operator!=(const SurfaceDependencyDeadline& other) { + bool operator==(const SurfaceDependencyDeadline& other) const; + bool operator!=(const SurfaceDependencyDeadline& other) const { return !(*this == other); }
diff --git a/content/browser/loader/resource_message_filter.cc b/content/browser/loader/resource_message_filter.cc index 7118227d..4a82566 100644 --- a/content/browser/loader/resource_message_filter.cc +++ b/content/browser/loader/resource_message_filter.cc
@@ -179,7 +179,10 @@ if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCORS)) { url_loader_factory_ = std::make_unique<network::cors::CORSURLLoaderFactory>( - std::move(url_loader_factory_)); + std::move(url_loader_factory_), + base::BindRepeating(&ResourceDispatcherHostImpl::CancelRequest, + base::Unretained(ResourceDispatcherHostImpl::Get()), + requester_info_->child_id())); } }
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index f0f1018..95f60d73d 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -1459,6 +1459,10 @@ return base::EmptyString(); } +bool RenderWidgetHostViewAura::ShouldDoLearning() { + return GetTextInputManager() && GetTextInputManager()->should_do_learning(); +} + //////////////////////////////////////////////////////////////////////////////// // RenderWidgetHostViewAura, display::DisplayObserver implementation:
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index a711134..775967b8 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -240,6 +240,7 @@ bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override; void SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) override; const std::string& GetClientSourceInfo() const override; + bool ShouldDoLearning() override; // Overridden from display::DisplayObserver: void OnDisplayAdded(const display::Display& new_display) override;
diff --git a/content/browser/renderer_host/text_input_manager.cc b/content/browser/renderer_host/text_input_manager.cc index 8ab2992..24f32e72 100644 --- a/content/browser/renderer_host/text_input_manager.cc +++ b/content/browser/renderer_host/text_input_manager.cc
@@ -35,7 +35,8 @@ } // namespace -TextInputManager::TextInputManager() : active_view_(nullptr) {} +TextInputManager::TextInputManager(bool should_do_learning) + : active_view_(nullptr), should_do_learning_(should_do_learning) {} TextInputManager::~TextInputManager() { // If there is an active view, we should unregister it first so that the
diff --git a/content/browser/renderer_host/text_input_manager.h b/content/browser/renderer_host/text_input_manager.h index b4cbcae..8e4ecfe 100644 --- a/content/browser/renderer_host/text_input_manager.h +++ b/content/browser/renderer_host/text_input_manager.h
@@ -131,7 +131,7 @@ base::string16 text_; }; - TextInputManager(); + explicit TextInputManager(bool should_do_learning); ~TextInputManager(); // Returns the currently active widget, i.e., the RWH which is associated with @@ -226,6 +226,8 @@ RenderWidgetHostViewBase* view); const gfx::Range* GetCompositionRangeForTesting() const; + bool should_do_learning() const { return should_do_learning_; } + private: // This class is used to create maps which hold specific IME state for a // view. @@ -249,6 +251,10 @@ ViewMap<CompositionRangeInfo> composition_range_info_map_; ViewMap<TextSelection> text_selection_map_; + // Whether the text input should be used to improve typing suggestions for the + // user. + bool should_do_learning_; + base::ObserverList<Observer> observer_list_; DISALLOW_COPY_AND_ASSIGN(TextInputManager);
diff --git a/content/browser/service_worker/service_worker_context_request_handler_unittest.cc b/content/browser/service_worker/service_worker_context_request_handler_unittest.cc index 2868fc41..9c653a1e 100644 --- a/content/browser/service_worker/service_worker_context_request_handler_unittest.cc +++ b/content/browser/service_worker/service_worker_context_request_handler_unittest.cc
@@ -137,11 +137,6 @@ void TestBypassCache(const GURL& url, ResourceType resource_type, bool expect_bypass) { - // TODO(https://crbug.com/675540): Remove the following command line switch - // when updateViaCache is shipped to stable. - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kEnableExperimentalWebPlatformFeatures); - std::unique_ptr<net::URLRequest> request(CreateRequest(url)); std::unique_ptr<ServiceWorkerContextRequestHandler> handler( CreateHandler(resource_type)); @@ -190,34 +185,6 @@ TestBypassCacheForImportedScript(false); } -// TODO(https://crbug.com/675540): Remove the -// UpdateBefore24HoursWithoutUpdateViaCache test when the update_via_cache flag -// is shipped to stable as this is to test the legacy behavior. -TEST_F(ServiceWorkerContextRequestHandlerTest, - UpdateBefore24HoursWithoutUpdateViaCache) { - registration_->set_last_update_check(base::Time::Now()); - version_->SetStatus(ServiceWorkerVersion::NEW); - - // Conduct a resource fetch for the main script. - base::HistogramTester histograms; - std::unique_ptr<net::URLRequest> request(CreateRequest(script_url_)); - std::unique_ptr<ServiceWorkerContextRequestHandler> handler( - CreateHandler(RESOURCE_TYPE_SERVICE_WORKER)); - std::unique_ptr<net::URLRequestJob> job( - handler->MaybeCreateJob(request.get(), nullptr, nullptr)); - ASSERT_TRUE(job.get()); - ServiceWorkerWriteToCacheJob* sw_job = - static_cast<ServiceWorkerWriteToCacheJob*>(job.get()); - histograms.ExpectUniqueSample( - "ServiceWorker.ContextRequestHandlerStatus.NewWorker.MainScript", - static_cast<int>( - ServiceWorkerContextRequestHandler::CreateJobStatus::WRITE_JOB), - 1); - - // Verify the net request is not initialized to bypass the browser cache. - EXPECT_FALSE(sw_job->net_request_->load_flags() & net::LOAD_BYPASS_CACHE); -} - TEST_F(ServiceWorkerContextRequestHandlerTest, UpdateBefore24HoursWithUpdateViaCacheAll) { registration_->SetUpdateViaCache(
diff --git a/content/browser/service_worker/service_worker_database.cc b/content/browser/service_worker/service_worker_database.cc index 5ff951c..c34711b2 100644 --- a/content/browser/service_worker/service_worker_database.cc +++ b/content/browser/service_worker/service_worker_database.cc
@@ -1466,15 +1466,10 @@ for (uint32_t feature : registration.used_features) data.add_used_features(feature); - // TODO(https://crbug.com/675540): Remove the the command line check and - // always set to data when shipping the updateViaCache flag to stable. - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableExperimentalWebPlatformFeatures)) { - data.set_update_via_cache( - static_cast< - ServiceWorkerRegistrationData_ServiceWorkerUpdateViaCacheType>( - registration.update_via_cache)); - } + data.set_update_via_cache( + static_cast< + ServiceWorkerRegistrationData_ServiceWorkerUpdateViaCacheType>( + registration.update_via_cache)); std::string value; bool success = data.SerializeToString(&value);
diff --git a/content/browser/service_worker/service_worker_write_to_cache_job.h b/content/browser/service_worker/service_worker_write_to_cache_job.h index 53b4536..1a3a3f2a 100644 --- a/content/browser/service_worker/service_worker_write_to_cache_job.h +++ b/content/browser/service_worker/service_worker_write_to_cache_job.h
@@ -62,11 +62,6 @@ private: friend class ServiceWorkerContextRequestHandlerTest; - // TODO(https://crbug.com/675540): Remove the following - // FRIEND_TEST_ALL_PREFIXES directive when the update_via_cache flag is - // shipped to stable. - FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextRequestHandlerTest, - UpdateBefore24HoursWithoutUpdateViaCache); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerContextRequestHandlerTest, ServiceWorkerDataRequestAnnotation);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 03ec3aa..2d1375e 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2845,8 +2845,11 @@ if (GetOuterWebContents()) return GetOuterWebContents()->GetTextInputManager(); - if (!text_input_manager_) - text_input_manager_.reset(new TextInputManager()); + if (!text_input_manager_) { + text_input_manager_.reset(new TextInputManager( + GetBrowserContext() && + !GetBrowserContext()->IsOffTheRecord()) /* should_do_learning */); + } return text_input_manager_.get(); }
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher.cc b/content/browser/web_package/signed_exchange_cert_fetcher.cc index a91bdf9b..083d6c6 100644 --- a/content/browser/web_package/signed_exchange_cert_fetcher.cc +++ b/content/browser/web_package/signed_exchange_cert_fetcher.cc
@@ -70,15 +70,16 @@ const GURL& cert_url, url::Origin request_initiator, bool force_fetch, + SignedExchangeVersion version, CertificateCallback callback, SignedExchangeDevToolsProxy* devtools_proxy) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("loading"), "SignedExchangeCertFetcher::CreateAndStart"); std::unique_ptr<SignedExchangeCertFetcher> cert_fetcher( - new SignedExchangeCertFetcher(std::move(shared_url_loader_factory), - std::move(throttles), cert_url, - std::move(request_initiator), force_fetch, - std::move(callback), devtools_proxy)); + new SignedExchangeCertFetcher( + std::move(shared_url_loader_factory), std::move(throttles), cert_url, + std::move(request_initiator), force_fetch, version, + std::move(callback), devtools_proxy)); cert_fetcher->Start(); return cert_fetcher; } @@ -89,11 +90,13 @@ const GURL& cert_url, url::Origin request_initiator, bool force_fetch, + SignedExchangeVersion version, CertificateCallback callback, SignedExchangeDevToolsProxy* devtools_proxy) : shared_url_loader_factory_(std::move(shared_url_loader_factory)), throttles_(std::move(throttles)), resource_request_(std::make_unique<network::ResourceRequest>()), + version_(version), callback_(std::move(callback)), devtools_proxy_(devtools_proxy) { // TODO(https://crbug.com/803774): Revisit more ResourceRequest flags. @@ -179,12 +182,10 @@ body_.reset(); handle_watcher_ = nullptr; - // TODO(https://crbug.com/803774): Take SignedExchangeVersion as a - // parameter of CreateAndStart() and use it here. std::unique_ptr<SignedExchangeCertificateChain> cert_chain = SignedExchangeCertificateChain::Parse( - SignedExchangeVersion::kB0, - base::as_bytes(base::make_span(body_string_)), devtools_proxy_); + version_, base::as_bytes(base::make_span(body_string_)), + devtools_proxy_); body_string_.clear(); if (!cert_chain) { signed_exchange_utils::ReportErrorAndEndTraceEvent(
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher.h b/content/browser/web_package/signed_exchange_cert_fetcher.h index 3e860f2c..23de061 100644 --- a/content/browser/web_package/signed_exchange_cert_fetcher.h +++ b/content/browser/web_package/signed_exchange_cert_fetcher.h
@@ -52,6 +52,7 @@ const GURL& cert_url, url::Origin request_initiator, bool force_fetch, + SignedExchangeVersion version, CertificateCallback callback, SignedExchangeDevToolsProxy* devtools_proxy); @@ -73,6 +74,7 @@ const GURL& cert_url, url::Origin request_initiator, bool force_fetch, + SignedExchangeVersion version, CertificateCallback callback, SignedExchangeDevToolsProxy* devtools_proxy); void Start(); @@ -99,6 +101,7 @@ scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_; std::vector<std::unique_ptr<URLLoaderThrottle>> throttles_; std::unique_ptr<network::ResourceRequest> resource_request_; + const SignedExchangeVersion version_; CertificateCallback callback_; std::unique_ptr<ThrottlingURLLoader> url_loader_;
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc b/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc index a853b33..2023480 100644 --- a/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc +++ b/content/browser/web_package/signed_exchange_cert_fetcher_factory.cc
@@ -25,6 +25,7 @@ std::unique_ptr<SignedExchangeCertFetcher> CreateFetcherAndStart( const GURL& cert_url, bool force_fetch, + SignedExchangeVersion version, SignedExchangeCertFetcher::CertificateCallback callback, SignedExchangeDevToolsProxy* devtools_proxy) override; @@ -38,6 +39,7 @@ SignedExchangeCertFetcherFactoryImpl::CreateFetcherAndStart( const GURL& cert_url, bool force_fetch, + SignedExchangeVersion version, SignedExchangeCertFetcher::CertificateCallback callback, SignedExchangeDevToolsProxy* devtools_proxy) { DCHECK(url_loader_factory_); @@ -46,7 +48,7 @@ std::move(url_loader_throttles_getter_).Run(); return SignedExchangeCertFetcher::CreateAndStart( std::move(url_loader_factory_), std::move(throttles), cert_url, - std::move(request_initiator_), force_fetch, std::move(callback), + std::move(request_initiator_), force_fetch, version, std::move(callback), devtools_proxy); }
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher_factory.h b/content/browser/web_package/signed_exchange_cert_fetcher_factory.h index 808fc572..dc01c1c 100644 --- a/content/browser/web_package/signed_exchange_cert_fetcher_factory.h +++ b/content/browser/web_package/signed_exchange_cert_fetcher_factory.h
@@ -32,6 +32,7 @@ virtual std::unique_ptr<SignedExchangeCertFetcher> CreateFetcherAndStart( const GURL& cert_url, bool force_fetch, + SignedExchangeVersion version, SignedExchangeCertFetcher::CertificateCallback callback, SignedExchangeDevToolsProxy* devtools_proxy) = 0;
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc b/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc index 771e601..4d84e0e 100644 --- a/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc +++ b/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
@@ -210,7 +210,8 @@ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &mock_loader_factory_), std::move(throttles_), url_, request_initiator_, force_fetch, - std::move(callback), nullptr /* devtools_proxy */); + SignedExchangeVersion::kB0, std::move(callback), + nullptr /* devtools_proxy */); } void CallOnReceiveResponse() {
diff --git a/content/browser/web_package/signed_exchange_handler.cc b/content/browser/web_package/signed_exchange_handler.cc index 9b60011..3d0e9c1 100644 --- a/content/browser/web_package/signed_exchange_handler.cc +++ b/content/browser/web_package/signed_exchange_handler.cc
@@ -10,7 +10,6 @@ #include "content/browser/loader/merkle_integrity_source_stream.h" #include "content/browser/web_package/signed_exchange_cert_fetcher_factory.h" #include "content/browser/web_package/signed_exchange_certificate_chain.h" -#include "content/browser/web_package/signed_exchange_consts.h" #include "content/browser/web_package/signed_exchange_devtools_proxy.h" #include "content/browser/web_package/signed_exchange_header.h" #include "content/browser/web_package/signed_exchange_signature_verifier.h" @@ -89,10 +88,10 @@ TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"), "SignedExchangeHandler::SignedExchangeHandler"); - base::Optional<std::string> content_type_version_param; - if (!SignedExchangeHeaderParser::GetVersionParamFromContentType( - content_type, &content_type_version_param) || - !content_type_version_param || *content_type_version_param != "b0") { + // Currently, only 'v=b0' is supported. + if (!SignedExchangeHeaderParser::GetVersionParamFromContentType(content_type, + &version_) || + version_ != SignedExchangeVersion::kB0) { base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&SignedExchangeHandler::RunErrorCallback, weak_factory_.GetWeakPtr(), net::ERR_FAILED)); @@ -237,11 +236,12 @@ // TODO(https://crbug.com/819467): When we will support ed25519Key, |cert_url| // may be empty. DCHECK(cert_url.is_valid()); + DCHECK(version_.has_value()); DCHECK(cert_fetcher_factory_); cert_fetcher_ = std::move(cert_fetcher_factory_) ->CreateFetcherAndStart( - cert_url, false, + cert_url, false, *version_, base::BindOnce(&SignedExchangeHandler::OnCertReceived, base::Unretained(this)), devtools_proxy_.get());
diff --git a/content/browser/web_package/signed_exchange_handler.h b/content/browser/web_package/signed_exchange_handler.h index 83c7615..52386898 100644 --- a/content/browser/web_package/signed_exchange_handler.h +++ b/content/browser/web_package/signed_exchange_handler.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/optional.h" #include "base/time/time.h" +#include "content/browser/web_package/signed_exchange_consts.h" #include "content/browser/web_package/signed_exchange_header.h" #include "content/common/content_export.h" #include "mojo/public/cpp/system/data_pipe.h" @@ -96,6 +97,7 @@ void OnCertVerifyComplete(int result); ExchangeHeadersCallback headers_callback_; + base::Optional<SignedExchangeVersion> version_; std::unique_ptr<net::SourceStream> source_; State state_ = State::kReadingHeadersLength;
diff --git a/content/browser/web_package/signed_exchange_handler_unittest.cc b/content/browser/web_package/signed_exchange_handler_unittest.cc index 9610a99..cf72a86 100644 --- a/content/browser/web_package/signed_exchange_handler_unittest.cc +++ b/content/browser/web_package/signed_exchange_handler_unittest.cc
@@ -60,13 +60,13 @@ std::unique_ptr<SignedExchangeCertFetcher> CreateFetcherAndStart( const GURL& cert_url, bool force_fetch, + SignedExchangeVersion version, SignedExchangeCertFetcher::CertificateCallback callback, SignedExchangeDevToolsProxy* devtools_proxy) override { EXPECT_EQ(cert_url, expected_cert_url_); auto cert_chain = SignedExchangeCertificateChain::Parse( - SignedExchangeVersion::kB0, base::as_bytes(base::make_span(cert_str_)), - devtools_proxy); + version, base::as_bytes(base::make_span(cert_str_)), devtools_proxy); EXPECT_TRUE(cert_chain); base::SequencedTaskRunnerHandle::Get()->PostTask(
diff --git a/content/browser/web_package/signed_exchange_header_parser.cc b/content/browser/web_package/signed_exchange_header_parser.cc index 5a9c66a..96e26d3 100644 --- a/content/browser/web_package/signed_exchange_header_parser.cc +++ b/content/browser/web_package/signed_exchange_header_parser.cc
@@ -286,7 +286,7 @@ // static bool SignedExchangeHeaderParser::GetVersionParamFromContentType( base::StringPiece content_type, - base::Optional<std::string>* version_param) { + base::Optional<SignedExchangeVersion>* version_param) { DCHECK(version_param); StructuredHeaderParser parser(content_type); ParameterisedLabel parameterised_label; @@ -297,7 +297,12 @@ if (it == parameterised_label.params.end()) { *version_param = base::nullopt; } else { - *version_param = it->second; + if (it->second == "b0") + *version_param = SignedExchangeVersion::kB0; + else if (it->second == "b1") + *version_param = SignedExchangeVersion::kB1; + else + return false; } return true; }
diff --git a/content/browser/web_package/signed_exchange_header_parser.h b/content/browser/web_package/signed_exchange_header_parser.h index 7eb7660..01697eb5 100644 --- a/content/browser/web_package/signed_exchange_header_parser.h +++ b/content/browser/web_package/signed_exchange_header_parser.h
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/optional.h" #include "base/strings/string_piece.h" +#include "content/browser/web_package/signed_exchange_consts.h" #include "content/common/content_export.h" #include "net/base/hash_value.h" #include "url/gurl.h" @@ -49,11 +50,11 @@ SignedExchangeDevToolsProxy* devtools_proxy); // Parses |content_type| to get the value of "v=" parameter of the signed - // exchange. Example: "b0" for "application/signed-exchange;v=b0". Returns - // false if failed to parse. + // exchange, and converts to SignedExchangeVersion. Returns false if failed to + // parse. static bool GetVersionParamFromContentType( base::StringPiece content_type, - base::Optional<std::string>* version_param); + base::Optional<SignedExchangeVersion>* version_param); }; } // namespace content
diff --git a/content/browser/web_package/signed_exchange_header_parser_unittest.cc b/content/browser/web_package/signed_exchange_header_parser_unittest.cc index 096617d..32f912e 100644 --- a/content/browser/web_package/signed_exchange_header_parser_unittest.cc +++ b/content/browser/web_package/signed_exchange_header_parser_unittest.cc
@@ -231,7 +231,7 @@ TEST_F(SignedExchangeHeaderParserTest, VersionParam_None) { const char content_type[] = "application/signed-exchange"; - base::Optional<std::string> version; + base::Optional<SignedExchangeVersion> version; EXPECT_TRUE(SignedExchangeHeaderParser::GetVersionParamFromContentType( content_type, &version)); EXPECT_FALSE(version); @@ -239,43 +239,43 @@ TEST_F(SignedExchangeHeaderParserTest, VersionParam_NoneWithSemicolon) { const char content_type[] = "application/signed-exchange;"; - base::Optional<std::string> version; + base::Optional<SignedExchangeVersion> version; EXPECT_FALSE(SignedExchangeHeaderParser::GetVersionParamFromContentType( content_type, &version)); } TEST_F(SignedExchangeHeaderParserTest, VersionParam_EmptyString) { const char content_type[] = "application/signed-exchange;v="; - base::Optional<std::string> version; + base::Optional<SignedExchangeVersion> version; EXPECT_FALSE(SignedExchangeHeaderParser::GetVersionParamFromContentType( content_type, &version)); } TEST_F(SignedExchangeHeaderParserTest, VersionParam_Simple) { const char content_type[] = "application/signed-exchange;v=b0"; - base::Optional<std::string> version; + base::Optional<SignedExchangeVersion> version; EXPECT_TRUE(SignedExchangeHeaderParser::GetVersionParamFromContentType( content_type, &version)); ASSERT_TRUE(version); - EXPECT_EQ(*version, "b0"); + EXPECT_EQ(*version, SignedExchangeVersion::kB0); } TEST_F(SignedExchangeHeaderParserTest, VersionParam_SimpleWithSpace) { - const char content_type[] = "application/signed-exchange; v=b0"; - base::Optional<std::string> version; + const char content_type[] = "application/signed-exchange; v=b1"; + base::Optional<SignedExchangeVersion> version; EXPECT_TRUE(SignedExchangeHeaderParser::GetVersionParamFromContentType( content_type, &version)); ASSERT_TRUE(version); - EXPECT_EQ(*version, "b0"); + EXPECT_EQ(*version, SignedExchangeVersion::kB1); } TEST_F(SignedExchangeHeaderParserTest, VersionParam_SimpleWithDoublequotes) { const char content_type[] = "application/signed-exchange;v=\"b0\""; - base::Optional<std::string> version; + base::Optional<SignedExchangeVersion> version; EXPECT_TRUE(SignedExchangeHeaderParser::GetVersionParamFromContentType( content_type, &version)); ASSERT_TRUE(version); - EXPECT_EQ(*version, "b0"); + EXPECT_EQ(*version, SignedExchangeVersion::kB0); } } // namespace content
diff --git a/content/common/service_worker/service_worker_utils.cc b/content/common/service_worker/service_worker_utils.cc index 5584d42a..0820aad 100644 --- a/content/common/service_worker/service_worker_utils.cc +++ b/content/common/service_worker/service_worker_utils.cc
@@ -215,12 +215,6 @@ bool ServiceWorkerUtils::ShouldBypassCacheDueToUpdateViaCache( bool is_main_script, blink::mojom::ServiceWorkerUpdateViaCache cache_mode) { - // TODO(https://crbug.com/675540): Remove the command line check and always - // respect cache_mode when shipping updateViaCache flag to stable. - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableExperimentalWebPlatformFeatures)) { - return false; - } switch (cache_mode) { case blink::mojom::ServiceWorkerUpdateViaCache::kImports: return is_main_script;
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index a238465..8911ec660 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -277,8 +277,15 @@ if (type == blink::WebInputEvent::kChar || type == blink::WebInputEvent::kRawKeyDown) { - event->text[0] = key_code; - event->unmodified_text[0] = key_code; + // |key| is the only parameter that contains information about the case of + // the character. Use it to be able to generate lower case input. + if (key.IsCharacter()) { + event->text[0] = key.ToCharacter(); + event->unmodified_text[0] = key.ToCharacter(); + } else { + event->text[0] = key_code; + event->unmodified_text[0] = key_code; + } } }
diff --git a/content/test/mock_render_widget_host_delegate.cc b/content/test/mock_render_widget_host_delegate.cc index 9d2404e..bb23893 100644 --- a/content/test/mock_render_widget_host_delegate.cc +++ b/content/test/mock_render_widget_host_delegate.cc
@@ -11,7 +11,9 @@ namespace content { -MockRenderWidgetHostDelegate::MockRenderWidgetHostDelegate() = default; +MockRenderWidgetHostDelegate::MockRenderWidgetHostDelegate() + : text_input_manager_(false /* should_do_learning */) {} + MockRenderWidgetHostDelegate::~MockRenderWidgetHostDelegate() = default; void MockRenderWidgetHostDelegate::ResizeDueToAutoResize(
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index f15a48a..02ada53 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -108,24 +108,6 @@ ] } -mojom("tab_socket") { - sources = [ - "lib/tab_socket.mojom", - ] - public_deps = [ - "//mojo/public/mojom/base", - ] -} - -mojom("headless_render_frame_controller") { - sources = [ - "lib/headless_render_frame_controller.mojom", - ] - public_deps = [ - "//mojo/public/mojom/base", - ] -} - service_manifest("headless_browser_manifest_overlay") { source = "lib/browser/headless_browser_manifest_overlay.json" } @@ -150,8 +132,6 @@ deps = [ ":headless_browser_manifest_overlay", ":headless_packaged_services_manifest_overlay", - ":headless_render_frame_controller_js", - ":tab_socket_js", ] } @@ -338,8 +318,6 @@ "lib/browser/headless_resource_dispatcher_host_delegate.h", "lib/browser/headless_shell_application_mac.h", "lib/browser/headless_shell_application_mac.mm", - "lib/browser/headless_tab_socket_impl.cc", - "lib/browser/headless_tab_socket_impl.h", "lib/browser/headless_url_request_context_getter.cc", "lib/browser/headless_url_request_context_getter.h", "lib/browser/headless_window_tree_host.h", @@ -453,9 +431,7 @@ deps = [ ":gen_devtools_client_api", - ":headless_render_frame_controller", ":protocol_sources", - ":tab_socket", ":version_header", "//components/cookie_config", "//components/security_state/core", @@ -483,10 +459,6 @@ "lib/headless_content_main_delegate.h", "lib/renderer/headless_content_renderer_client.cc", "lib/renderer/headless_content_renderer_client.h", - "lib/renderer/headless_render_frame_controller_impl.cc", - "lib/renderer/headless_render_frame_controller_impl.h", - "lib/renderer/headless_tab_socket_bindings.cc", - "lib/renderer/headless_tab_socket_bindings.h", "lib/utility/headless_content_utility_client.cc", "lib/utility/headless_content_utility_client.h", ] @@ -569,10 +541,6 @@ "lib/headless_content_main_delegate.h", "lib/renderer/headless_content_renderer_client.cc", "lib/renderer/headless_content_renderer_client.h", - "lib/renderer/headless_render_frame_controller_impl.cc", - "lib/renderer/headless_render_frame_controller_impl.h", - "lib/renderer/headless_tab_socket_bindings.cc", - "lib/renderer/headless_tab_socket_bindings.h", ] deps = [ @@ -792,8 +760,6 @@ "test/headless_browser_test.cc", "test/headless_browser_test.h", "test/headless_test_launcher.cc", - "test/tab_socket_test.cc", - "test/tab_socket_test.h", "test/test_protocol_handler.cc", "test/test_protocol_handler.h", "test/test_url_request_job.cc",
diff --git a/headless/lib/browser/devtools_api/devtools_connection.js b/headless/lib/browser/devtools_api/devtools_connection.js index 461bd76..bcd64b1b 100644 --- a/headless/lib/browser/devtools_api/devtools_connection.js +++ b/headless/lib/browser/devtools_api/devtools_connection.js
@@ -4,8 +4,7 @@ /** * @fileoverview Contains a class which marshals DevTools protocol messages over - * a provided low level message transport. This transport might be a headless - * TabSocket, or a WebSocket or a mock for testing. + * a provided low level message transport. */ 'use strict';
diff --git a/headless/lib/browser/headless_browser_context_impl.cc b/headless/lib/browser/headless_browser_context_impl.cc index 2fff1c5d..cb38ee1 100644 --- a/headless/lib/browser/headless_browser_context_impl.cc +++ b/headless/lib/browser/headless_browser_context_impl.cc
@@ -507,16 +507,6 @@ } HeadlessBrowserContext::Builder& -HeadlessBrowserContext::Builder::AddTabSocketMojoBindings() { - std::string js_bindings = - ui::ResourceBundle::GetSharedInstance() - .GetRawDataResource(IDR_HEADLESS_TAB_SOCKET_MOJOM_JS) - .as_string(); - mojo_bindings_.emplace_back("headless/lib/tab_socket.mojom", js_bindings); - return *this; -} - -HeadlessBrowserContext::Builder& HeadlessBrowserContext::Builder::EnableUnsafeNetworkAccessWithMojoBindings( bool enable_http_and_https_if_mojo_used) { enable_http_and_https_if_mojo_used_ = enable_http_and_https_if_mojo_used;
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc index c2f5615..14d0d72 100644 --- a/headless/lib/browser/headless_content_browser_client.cc +++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -53,8 +53,6 @@ namespace headless { namespace { -const char kCapabilityPath[] = - "interface_provider_specs.navigation:frame.provides.renderer"; #if defined(HEADLESS_USE_BREAKPAD) breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost( @@ -174,21 +172,7 @@ base::StringPiece manifest_template = ui::ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_HEADLESS_BROWSER_MANIFEST_OVERLAY); - std::unique_ptr<base::Value> manifest = - base::JSONReader::Read(manifest_template); - - // Add mojo_service_names to renderer capability specified in options. - base::DictionaryValue* manifest_dictionary = nullptr; - CHECK(manifest->GetAsDictionary(&manifest_dictionary)); - - base::ListValue* capability_list = nullptr; - CHECK(manifest_dictionary->GetList(kCapabilityPath, &capability_list)); - - for (std::string service_name : browser_->options()->mojo_service_names) { - capability_list->AppendString(service_name); - } - - return manifest; + return base::JSONReader::Read(manifest_template); } std::unique_ptr<base::Value>
diff --git a/headless/lib/browser/headless_tab_socket_impl.cc b/headless/lib/browser/headless_tab_socket_impl.cc deleted file mode 100644 index 4ea3c8c1..0000000 --- a/headless/lib/browser/headless_tab_socket_impl.cc +++ /dev/null
@@ -1,215 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "headless/lib/browser/headless_tab_socket_impl.h" - -#include "base/stl_util.h" -#include "content/public/browser/devtools_agent_host.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/web_contents.h" -#include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/interface_provider.h" - -namespace headless { - -HeadlessTabSocketImpl::HeadlessTabSocketImpl(content::WebContents* web_contents) - : web_contents_(web_contents), - listener_(nullptr), - weak_ptr_factory_(this) {} - -HeadlessTabSocketImpl::~HeadlessTabSocketImpl() = default; - -// Wrangles the async responses to -// HeadlessRenderFrameControllerImpl::InstallTabSocket for which at most one -// should succeed. -class TabSocketInstallationController - : public base::RefCounted<TabSocketInstallationController> { - public: - TabSocketInstallationController( - int v8_execution_context_id, - size_t render_frame_count, - base::WeakPtr<HeadlessTabSocketImpl> headless_tab_socket_impl, - base::OnceCallback<void(bool)> callback) - : v8_execution_context_id_(v8_execution_context_id), - render_frame_count_(render_frame_count), - headless_tab_socket_impl_(headless_tab_socket_impl), - callback_(std::move(callback)), - success_(false) {} - - void InstallTabSocketCallback(content::RenderFrameHost* render_frame_host, - bool success) { - render_frame_count_--; - - // It's possible the HeadlessTabSocketImpl went away, if that happened we - // don't want to pretend TabSocket installation succeeded. - if (!headless_tab_socket_impl_) - success = false; - - if (success) { - CHECK(!success_) << "At most one InstallTabSocket call should succeed!"; - success_ = true; - headless_tab_socket_impl_->v8_execution_context_id_to_render_frame_host_ - .insert(std::make_pair(v8_execution_context_id_, render_frame_host)); - - std::move(callback_).Run(true); - } else if (render_frame_count_ == 0 && !success_) { - std::move(callback_).Run(false); - } - } - - private: - int v8_execution_context_id_; - size_t render_frame_count_; - - base::WeakPtr<HeadlessTabSocketImpl> headless_tab_socket_impl_; - base::OnceCallback<void(bool)> callback_; - bool success_; - - friend class base::RefCounted<TabSocketInstallationController>; - ~TabSocketInstallationController() = default; -}; - -void HeadlessTabSocketImpl::InstallHeadlessTabSocketBindings( - int v8_execution_context_id, - base::OnceCallback<void(bool)> callback) { - // We need to find the right RenderFrameHost to install the bindings on but - // the browser doesn't know which RenderFrameHost |v8_execution_context_id| - // corresponds to if any. So we try all of them. - scoped_refptr<TabSocketInstallationController> - tab_socket_installation_controller = new TabSocketInstallationController( - v8_execution_context_id, render_frame_hosts_.size(), - weak_ptr_factory_.GetWeakPtr(), std::move(callback)); - for (content::RenderFrameHost* render_frame_host : render_frame_hosts_) { - HeadlessRenderFrameControllerPtr& headless_render_frame_controller = - render_frame_controllers_[render_frame_host]; - if (!headless_render_frame_controller.is_bound()) { - render_frame_host->GetRemoteInterfaces()->GetInterface( - &headless_render_frame_controller); - } - - // This will only succeed if the |render_frame_host_controller| contains - // |v8_execution_context_id|. The TabSocketInstallationController keeps - // track of how many callbacks have been received and if all of them have - // been unsuccessful it runs |callback| with false. If one of them succeeds - // it runs |callback| with true. - headless_render_frame_controller->InstallTabSocket( - v8_execution_context_id, - base::BindOnce( - &TabSocketInstallationController::InstallTabSocketCallback, - tab_socket_installation_controller, render_frame_host)); - } -} - -void HeadlessTabSocketImpl::InstallMainFrameMainWorldHeadlessTabSocketBindings( - base::OnceCallback<void(base::Optional<int>)> callback) { - content::RenderFrameHost* main_frame = web_contents_->GetMainFrame(); - HeadlessRenderFrameControllerPtr& headless_render_frame_controller = - render_frame_controllers_[main_frame]; - if (!headless_render_frame_controller.is_bound()) { - main_frame->GetRemoteInterfaces()->GetInterface( - &headless_render_frame_controller); - } - headless_render_frame_controller->InstallMainWorldTabSocket( - base::BindOnce(&HeadlessTabSocketImpl::OnInstallMainWorldTabSocket, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); -} - -void HeadlessTabSocketImpl::OnInstallMainWorldTabSocket( - base::OnceCallback<void(base::Optional<int>)> callback, - int v8_execution_context_id) { - if (v8_execution_context_id == -1) { - std::move(callback).Run(base::nullopt); - } else { - v8_execution_context_id_to_render_frame_host_.insert( - std::make_pair(v8_execution_context_id, web_contents_->GetMainFrame())); - std::move(callback).Run(v8_execution_context_id); - } -} - -void HeadlessTabSocketImpl::SendMessageToContext( - const std::string& message, - int32_t v8_execution_context_id) { - auto render_frame_host = v8_execution_context_id_to_render_frame_host_.find( - v8_execution_context_id); - if (render_frame_host == - v8_execution_context_id_to_render_frame_host_.end()) { - LOG(WARNING) << "Unknown v8_execution_context_id " - << v8_execution_context_id; - return; - } - - auto render_frame_controller = - render_frame_controllers_.find(render_frame_host->second); - if (render_frame_controller == render_frame_controllers_.end()) { - LOG(WARNING) << "Unknown RenderFrameHist " << render_frame_host->second; - return; - } - render_frame_controller->second->SendMessageToTabSocket( - message, v8_execution_context_id); -} - -void HeadlessTabSocketImpl::SetListener(Listener* listener) { - MessageQueue messages; - - { - base::AutoLock lock(lock_); - listener_ = listener; - if (!listener) - return; - - std::swap(messages, from_tab_message_queue_); - } - - for (const Message& message : messages) { - listener_->OnMessageFromContext(message.first, message.second); - } -} - -void HeadlessTabSocketImpl::SendMessageToEmbedder( - const std::string& message, - int32_t v8_execution_context_id) { - Listener* listener = nullptr; - { - base::AutoLock lock(lock_); - CHECK(v8_execution_context_id_to_render_frame_host_.find( - v8_execution_context_id) != - v8_execution_context_id_to_render_frame_host_.end()) - << "Unknown v8_execution_context_id " << v8_execution_context_id; - if (listener_) { - listener = listener_; - } else { - from_tab_message_queue_.emplace_back(message, v8_execution_context_id); - return; - } - } - - listener->OnMessageFromContext(message, v8_execution_context_id); -} - -void HeadlessTabSocketImpl::CreateMojoService( - mojo::InterfaceRequest<TabSocket> request) { - mojo_bindings_.AddBinding(this, std::move(request)); -} - -void HeadlessTabSocketImpl::RenderFrameCreated( - content::RenderFrameHost* render_frame_host) { - render_frame_hosts_.insert(render_frame_host); -} - -void HeadlessTabSocketImpl::RenderFrameDeleted( - content::RenderFrameHost* render_frame_host) { - // Remove all entries from |v8_execution_context_id_to_render_frame_host_| - // where the mapped value is |render_frame_host|. - base::EraseIf(v8_execution_context_id_to_render_frame_host_, - [render_frame_host]( - const std::pair<int, content::RenderFrameHost*>& pair) { - return render_frame_host == pair.second; - }); - - render_frame_controllers_.erase(render_frame_host); - render_frame_hosts_.erase(render_frame_host); -} - -} // namespace headless
diff --git a/headless/lib/browser/headless_tab_socket_impl.h b/headless/lib/browser/headless_tab_socket_impl.h deleted file mode 100644 index 13e4c42..0000000 --- a/headless/lib/browser/headless_tab_socket_impl.h +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef HEADLESS_LIB_BROWSER_HEADLESS_TAB_SOCKET_IMPL_H_ -#define HEADLESS_LIB_BROWSER_HEADLESS_TAB_SOCKET_IMPL_H_ - -#include <list> - -#include "base/synchronization/lock.h" -#include "headless/lib/headless_render_frame_controller.mojom.h" -#include "headless/lib/tab_socket.mojom.h" -#include "headless/public/headless_tab_socket.h" -#include "mojo/public/cpp/bindings/binding_set.h" - -namespace content { -class RenderFrameHost; -class WebContents; -} // namespace content - -namespace headless { - -class HeadlessTabSocketImpl : public HeadlessTabSocket, public TabSocket { - public: - explicit HeadlessTabSocketImpl(content::WebContents* web_contents); - ~HeadlessTabSocketImpl() override; - - // HeadlessTabSocket implementation: - void InstallHeadlessTabSocketBindings( - int v8_execution_context_id, - base::OnceCallback<void(bool)> callback) override; - void InstallMainFrameMainWorldHeadlessTabSocketBindings( - base::OnceCallback<void(base::Optional<int>)> callback) override; - void SendMessageToContext(const std::string& message, - int v8_execution_context_id) override; - void SetListener(Listener* listener) override; - - // TabSocket implementation: - void SendMessageToEmbedder(const std::string& message, - int32_t v8_execution_context_id) override; - - void CreateMojoService(mojo::InterfaceRequest<TabSocket> request); - - void RenderFrameCreated(content::RenderFrameHost* render_frame_host); - void RenderFrameDeleted(content::RenderFrameHost* render_frame_host); - - private: - friend class TabSocketInstallationController; - - void OnInstallMainWorldTabSocket( - base::OnceCallback<void(base::Optional<int>)> callback, - int world_id); - - base::Lock lock_; // Protects everything below. - using Message = std::pair<std::string, int>; - using MessageQueue = std::list<Message>; - - MessageQueue from_tab_message_queue_; - content::WebContents* web_contents_; // NOT OWNED - Listener* listener_; // NOT OWNED - - mojo::BindingSet<TabSocket> mojo_bindings_; - - std::set<content::RenderFrameHost*> render_frame_hosts_; - std::map<int, content::RenderFrameHost*> - v8_execution_context_id_to_render_frame_host_; - std::map<content::RenderFrameHost*, HeadlessRenderFrameControllerPtr> - render_frame_controllers_; - base::WeakPtrFactory<HeadlessTabSocketImpl> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(HeadlessTabSocketImpl); -}; - -} // namespace headless - -#endif // HEADLESS_LIB_BROWSER_HEADLESS_TAB_SOCKET_IMPL_H_
diff --git a/headless/lib/browser/headless_web_contents_impl.cc b/headless/lib/browser/headless_web_contents_impl.cc index c447659..51d5010e 100644 --- a/headless/lib/browser/headless_web_contents_impl.cc +++ b/headless/lib/browser/headless_web_contents_impl.cc
@@ -34,7 +34,6 @@ #include "headless/lib/browser/headless_browser_context_impl.h" #include "headless/lib/browser/headless_browser_impl.h" #include "headless/lib/browser/headless_browser_main_parts.h" -#include "headless/lib/browser/headless_tab_socket_impl.h" #include "headless/lib/browser/protocol/headless_handler.h" #include "headless/public/internal/headless_devtools_client_impl.h" #include "printing/buildflags/buildflags.h" @@ -139,8 +138,6 @@ HeadlessWebContentsImpl* child_contents = HeadlessWebContentsImpl::From( headless_web_contents_->browser_context() ->CreateWebContentsBuilder() - .SetAllowTabSockets( - !!headless_web_contents_->GetHeadlessTabSocket()) .SetWindowSize(source->GetContainerBounds().size()) .Build()); headless_web_contents_->browser_context()->NotifyChildContentsCreated( @@ -204,17 +201,6 @@ DISALLOW_COPY_AND_ASSIGN(Delegate); }; -namespace { - -void CreateTabSocketMojoServiceForContents( - HeadlessWebContents* web_contents, - mojo::ScopedMessagePipeHandle handle) { - HeadlessWebContentsImpl::From(web_contents) - ->CreateTabSocketMojoService(std::move(handle)); -} - -} // namespace - struct HeadlessWebContentsImpl::PendingFrame { public: PendingFrame() = default; @@ -250,17 +236,6 @@ content::WebContents::Create(create_params), builder->browser_context_)); - if (builder->tab_sockets_allowed_) { - headless_web_contents->headless_tab_socket_ = - std::make_unique<HeadlessTabSocketImpl>( - headless_web_contents->web_contents_.get()); - headless_web_contents->inject_mojo_services_into_isolated_world_ = true; - - builder->mojo_services_.emplace_back( - TabSocket::Name_, base::Bind(&CreateTabSocketMojoServiceForContents)); - } - - headless_web_contents->mojo_services_ = std::move(builder->mojo_services_); headless_web_contents->begin_frame_control_enabled_ = builder->enable_begin_frame_control_ || headless_web_contents->browser()->options()->enable_begin_frame_control; @@ -283,15 +258,6 @@ child->begin_frame_control_enabled_ = parent->begin_frame_control_enabled_; child->InitializeWindow(child->web_contents_->GetContainerBounds()); - // Copy mojo services and tab socket settings from parent. - child->mojo_services_ = parent->mojo_services_; - if (parent->headless_tab_socket_) { - child->headless_tab_socket_ = - std::make_unique<HeadlessTabSocketImpl>(child->web_contents_.get()); - child->inject_mojo_services_into_isolated_world_ = - parent->inject_mojo_services_into_isolated_world_; - } - // There may already be frames, so make sure they also have our services. for (content::RenderFrameHost* frame_host : child->web_contents_->GetAllFrames()) @@ -328,7 +294,6 @@ web_contents_(std::move(web_contents)), agent_host_( content::DevToolsAgentHost::GetOrCreateFor(web_contents_.get())), - inject_mojo_services_into_isolated_world_(false), browser_context_(browser_context), render_process_host_(web_contents_->GetMainFrame()->GetProcess()), weak_ptr_factory_(this) { @@ -356,48 +321,17 @@ } } -void HeadlessWebContentsImpl::CreateTabSocketMojoService( - mojo::ScopedMessagePipeHandle handle) { - headless_tab_socket_->CreateMojoService(TabSocketRequest(std::move(handle))); -} - -void HeadlessWebContentsImpl::CreateMojoService( - const MojoService::ServiceFactoryCallback& service_factory, - mojo::ScopedMessagePipeHandle handle) { - service_factory.Run(this, std::move(handle)); -} - void HeadlessWebContentsImpl::RenderFrameCreated( content::RenderFrameHost* render_frame_host) { - for (const MojoService& service : mojo_services_) { - registry_.AddInterface( - service.service_name, - base::Bind(&HeadlessWebContentsImpl::CreateMojoService, - base::Unretained(this), service.service_factory), - browser()->BrowserMainThread()); - } - browser_context_->SetDevToolsFrameToken( render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID(), render_frame_host->GetDevToolsFrameToken(), render_frame_host->GetFrameTreeNodeId()); - - if (headless_tab_socket_) - headless_tab_socket_->RenderFrameCreated(render_frame_host); -} - -void HeadlessWebContentsImpl::OnInterfaceRequestFromFrame( - content::RenderFrameHost* render_frame_host, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle* interface_pipe) { - registry_.TryBindInterface(interface_name, interface_pipe); } void HeadlessWebContentsImpl::RenderFrameDeleted( content::RenderFrameHost* render_frame_host) { - if (headless_tab_socket_) - headless_tab_socket_->RenderFrameDeleted(render_frame_host); browser_context_->RemoveDevToolsFrameToken( render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID(), @@ -540,10 +474,6 @@ return browser_context_; } -HeadlessTabSocket* HeadlessWebContentsImpl::GetHeadlessTabSocket() const { - return headless_tab_socket_.get(); -} - void HeadlessWebContentsImpl::OnDisplayDidFinishFrame( const viz::BeginFrameAck& ack) { TRACE_EVENT2("headless", "HeadlessWebContentsImpl::OnDisplayDidFinishFrame", @@ -669,12 +599,6 @@ return *this; } -HeadlessWebContents::Builder& HeadlessWebContents::Builder::SetAllowTabSockets( - bool tab_sockets_allowed) { - tab_sockets_allowed_ = tab_sockets_allowed; - return *this; -} - HeadlessWebContents::Builder& HeadlessWebContents::Builder::SetEnableBeginFrameControl( bool enable_begin_frame_control) { @@ -686,16 +610,4 @@ return browser_context_->CreateWebContents(this); } -HeadlessWebContents::Builder::MojoService::MojoService() = default; - -HeadlessWebContents::Builder::MojoService::MojoService( - const MojoService& other) = default; - -HeadlessWebContents::Builder::MojoService::MojoService( - const std::string& service_name, - const ServiceFactoryCallback& service_factory) - : service_name(service_name), service_factory(service_factory) {} - -HeadlessWebContents::Builder::MojoService::~MojoService() = default; - } // namespace headless
diff --git a/headless/lib/browser/headless_web_contents_impl.h b/headless/lib/browser/headless_web_contents_impl.h index 19ea985c..467275c8 100644 --- a/headless/lib/browser/headless_web_contents_impl.h +++ b/headless/lib/browser/headless_web_contents_impl.h
@@ -19,7 +19,6 @@ #include "headless/public/headless_devtools_target.h" #include "headless/public/headless_export.h" #include "headless/public/headless_web_contents.h" -#include "services/service_manager/public/cpp/binder_registry.h" #include "ui/compositor/external_begin_frame_client.h" class SkBitmap; @@ -36,7 +35,6 @@ namespace headless { class HeadlessBrowser; class HeadlessBrowserImpl; -class HeadlessTabSocketImpl; // Exported for tests. class HEADLESS_EXPORT HeadlessWebContentsImpl @@ -65,7 +63,6 @@ void AddObserver(Observer* observer) override; void RemoveObserver(Observer* observer) override; HeadlessDevToolsTarget* GetDevToolsTarget() override; - HeadlessTabSocket* GetHeadlessTabSocket() const override; int GetMainFrameRenderProcessId() const override; int GetMainFrameTreeNodeId() const override; std::string GetMainFrameDevToolsId() const override; @@ -91,10 +88,6 @@ void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override; void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override; void RenderViewReady() override; - void OnInterfaceRequestFromFrame( - content::RenderFrameHost* render_frame_host, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle* interface_pipe) override; // ui::ExternalBeginFrameClient implementation: void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) override; @@ -129,8 +122,6 @@ // Set bounds of WebContent's platform window. void SetBounds(const gfx::Rect& bounds); - void CreateTabSocketMojoService(mojo::ScopedMessagePipeHandle handle); - bool begin_frame_control_enabled() const { return begin_frame_control_enabled_; } @@ -159,11 +150,6 @@ void InitializeWindow(const gfx::Rect& initial_bounds); - using MojoService = HeadlessWebContents::Builder::MojoService; - void CreateMojoService( - const MojoService::ServiceFactoryCallback& service_factory, - mojo::ScopedMessagePipeHandle handle); - void PendingFrameReadbackComplete(PendingFrame* pending_frame, const SkBitmap& bitmap); @@ -179,11 +165,8 @@ std::unique_ptr<HeadlessWindowTreeHost> window_tree_host_; int window_id_ = 0; std::string window_state_; - std::unique_ptr<HeadlessTabSocketImpl> headless_tab_socket_; std::unique_ptr<content::WebContents> web_contents_; scoped_refptr<content::DevToolsAgentHost> agent_host_; - std::list<MojoService> mojo_services_; - bool inject_mojo_services_into_isolated_world_; bool devtools_target_ready_notification_sent_ = false; bool render_process_exited_ = false; @@ -196,8 +179,6 @@ base::Closure quit_closure_; - service_manager::BinderRegistry registry_; - base::WeakPtrFactory<HeadlessWebContentsImpl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(HeadlessWebContentsImpl);
diff --git a/headless/lib/headless_render_frame_controller.mojom b/headless/lib/headless_render_frame_controller.mojom deleted file mode 100644 index 3b6b061a..0000000 --- a/headless/lib/headless_render_frame_controller.mojom +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module headless; - -import "mojo/public/mojom/base/big_string.mojom"; - -interface HeadlessRenderFrameController { - // Installs TabSocket bindings into a specified execution context. - InstallTabSocket(int32 v8_execution_context_id) => (bool success); - - // Installs TabSocket bindings into the main world. This is useful if you - // don't know the execution context id (e.g. you don't have devtools - // connected). - InstallMainWorldTabSocket() => (int32 v8_execution_context_id); - - // Send a message from the C++ embedder to the Tab. - SendMessageToTabSocket(mojo_base.mojom.BigString message, - int32 v8_execution_context_id); - - // To send a message from tab to the embedder use - // TabSocket::SendMessageToEmbedder. -};
diff --git a/headless/lib/headless_web_contents_browsertest.cc b/headless/lib/headless_web_contents_browsertest.cc index 6bd4265..9b0b059 100644 --- a/headless/lib/headless_web_contents_browsertest.cc +++ b/headless/lib/headless_web_contents_browsertest.cc
@@ -33,7 +33,6 @@ #include "headless/public/headless_web_contents.h" #include "headless/public/util/testing/test_in_memory_protocol_handler.h" #include "headless/test/headless_browser_test.h" -#include "headless/test/tab_socket_test.h" #include "printing/buildflags/buildflags.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -136,193 +135,6 @@ browser_context->RemoveObserver(&observer); } -class HeadlessWindowOpenTabSocketTest : public HeadlessBrowserTest, - public HeadlessTabSocket::Listener, - public HeadlessBrowserContext::Observer, - public HeadlessWebContents::Observer, - public runtime::Observer { - public: - HeadlessWindowOpenTabSocketTest() - : devtools_client_(HeadlessDevToolsClient::Create()) {} - - void SetUp() override { - options()->mojo_service_names.insert("headless::TabSocket"); - HeadlessBrowserTest::SetUp(); - } - - // HeadlessTabSocket::Listener implementation. - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { - message_ = message; - FinishAsynchronousTest(); - } - - // HeadlessBrowserContext::Observer implementation. - void OnChildContentsCreated(HeadlessWebContents* parent, - HeadlessWebContents* child) override { - EXPECT_EQ(nullptr, child_); - child_ = child; - child_->AddObserver(this); - } - - // HeadlessWebContents::Observer implementation. - void DevToolsTargetReady() override { - child_->RemoveObserver(this); - - // Verify tab socket of child_contents works. - child_->GetDevToolsTarget()->AttachClient(devtools_client_.get()); - - devtools_client_->GetPage()->Enable(); - devtools_client_->GetPage()->GetExperimental()->GetResourceTree( - page::GetResourceTreeParams::Builder().Build(), - base::BindOnce(&HeadlessWindowOpenTabSocketTest::OnResourceTree, - base::Unretained(this))); - } - - void OnResourceTree(std::unique_ptr<page::GetResourceTreeResult> result) { - child_frame_id_ = result->GetFrameTree()->GetFrame()->GetId(); - devtools_client_->GetRuntime()->AddObserver(this); - // This will trigger OnExecutionContextCreated getting called for all - // existing contexts. - devtools_client_->GetRuntime()->Enable(); - } - - // runtime::Observer implementation. - void OnExecutionContextCreated( - const runtime::ExecutionContextCreatedParams& params) override { - std::string frame_id; - if (!params.GetContext()->HasAuxData()) - return; - - const base::Value* frame_id_value = - params.GetContext()->GetAuxData()->FindKey("frameId"); - if (!frame_id_value || frame_id_value->GetString() != *child_frame_id_) - return; - - child_frame_execution_context_id_ = params.GetContext()->GetId(); - - HeadlessTabSocket* tab_socket = child_->GetHeadlessTabSocket(); - CHECK(tab_socket); - tab_socket->InstallHeadlessTabSocketBindings( - *child_frame_execution_context_id_, - base::BindOnce(&HeadlessWindowOpenTabSocketTest::OnTabSocketInstalled, - base::Unretained(this))); - } - - void OnTabSocketInstalled(bool success) { - ASSERT_TRUE(success); - HeadlessTabSocket* tab_socket = child_->GetHeadlessTabSocket(); - CHECK(tab_socket); - tab_socket->SendMessageToContext("One", *child_frame_execution_context_id_); - tab_socket->SetListener(this); - - devtools_client_->GetRuntime()->Evaluate( - R"(window.TabSocket.onmessage = - function(message) { - window.TabSocket.send('Embedder sent us: ' + message); - }; - )", - base::BindOnce(&HeadlessWindowOpenTabSocketTest::OnEvaluateResult, - base::Unretained(this))); - } - - void OnEvaluateResult(std::unique_ptr<runtime::EvaluateResult> result) { - child_->GetDevToolsTarget()->DetachClient(devtools_client_.get()); - } - - protected: - std::string message_; - base::Optional<std::string> child_frame_id_; - base::Optional<int> child_frame_execution_context_id_; - HeadlessWebContents* child_ = nullptr; - std::unique_ptr<HeadlessDevToolsClient> devtools_client_; -}; - -IN_PROC_BROWSER_TEST_F(HeadlessWindowOpenTabSocketTest, - WindowOpenWithTabSocket) { - EXPECT_TRUE(embedded_test_server()->Start()); - - HeadlessBrowserContext* browser_context = - browser()->CreateBrowserContextBuilder().Build(); - browser_context->AddObserver(this); - - HeadlessWebContents* web_contents = - browser_context->CreateWebContentsBuilder() - .SetAllowTabSockets(true) - .SetInitialURL(embedded_test_server()->GetURL("/window_open.html")) - .Build(); - EXPECT_TRUE(WaitForLoad(web_contents)); - - EXPECT_EQ(2u, browser_context->GetAllWebContents().size()); - EXPECT_NE(nullptr, child_); - - RunAsynchronousTest(); - EXPECT_EQ("Embedder sent us: One", message_); - - browser_context->RemoveObserver(this); -} - -class HeadlessNoDevToolsTabSocketTest : public HeadlessBrowserTest, - public HeadlessTabSocket::Listener { - public: - HeadlessNoDevToolsTabSocketTest() = default; - - void SetUp() override { - options()->mojo_service_names.insert("headless::TabSocket"); - HeadlessBrowserTest::SetUp(); - } - - // HeadlessTabSocket::Listener implementation. - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { - EXPECT_EQ(*execution_context_id_, execution_context_id); - messages_.push_back(message); - - if (messages_.size() == 2) { - EXPECT_THAT(messages_, - ElementsAre("Hello world!", "Embedder sent us: One")); - FinishAsynchronousTest(); - } - } - - void OnInstalledHeadlessTabSocket(base::Optional<int> execution_context_id) { - EXPECT_TRUE(!!execution_context_id); - if (!execution_context_id) { - FinishAsynchronousTest(); - } else { - execution_context_id_ = execution_context_id; - tab_socket_->SendMessageToContext("One", *execution_context_id); - } - } - - std::vector<std::string> messages_; - HeadlessTabSocket* tab_socket_; - base::Optional<int> execution_context_id_; -}; - -IN_PROC_BROWSER_TEST_F(HeadlessNoDevToolsTabSocketTest, Test) { - EXPECT_TRUE(embedded_test_server()->Start()); - - HeadlessBrowserContext* browser_context = - browser()->CreateBrowserContextBuilder().Build(); - - HeadlessWebContents* web_contents = - browser_context->CreateWebContentsBuilder() - .SetAllowTabSockets(true) - .SetInitialURL(embedded_test_server()->GetURL("/tabsocket.html")) - .Build(); - - tab_socket_ = web_contents->GetHeadlessTabSocket(); - CHECK(tab_socket_); - tab_socket_->InstallMainFrameMainWorldHeadlessTabSocketBindings( - base::BindOnce( - &HeadlessNoDevToolsTabSocketTest::OnInstalledHeadlessTabSocket, - base::Unretained(this))); - tab_socket_->SetListener(this); - - RunAsynchronousTest(); -} - IN_PROC_BROWSER_TEST_F(HeadlessWebContentsTest, FocusOfHeadlessWebContents_IsIndependent) { EXPECT_TRUE(embedded_test_server()->Start()); @@ -577,366 +389,6 @@ } }; -HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessWebContentsSecurityTest); - -class GetHeadlessTabSocketButNoTabSocket - : public HeadlessAsyncDevTooledBrowserTest { - public: - void SetUp() override { - options()->mojo_service_names.insert("headless::TabSocket"); - HeadlessAsyncDevTooledBrowserTest::SetUp(); - } - - void RunDevTooledTest() override { - ASSERT_THAT(web_contents_->GetHeadlessTabSocket(), testing::IsNull()); - FinishAsynchronousTest(); - } - - bool GetAllowTabSockets() override { return false; } -}; - -HEADLESS_ASYNC_DEVTOOLED_TEST_F(GetHeadlessTabSocketButNoTabSocket); - -class MainWorldHeadlessTabSocketTest : public TabSocketTest { - public: - void RunTabSocketTest() override { - CreateMainWorldTabSocket( - main_frame_id(), - base::BindOnce( - &MainWorldHeadlessTabSocketTest::OnInstalledHeadlessTabSocket, - base::Unretained(this))); - } - - void OnInstalledHeadlessTabSocket(int execution_context_id) { - devtools_client_->GetRuntime()->Evaluate( - R"(window.TabSocket.onmessage = - function(message) { - window.TabSocket.send('Embedder sent us: ' + message); - }; - )", - base::BindOnce( - &MainWorldHeadlessTabSocketTest::FailOnJsEvaluateException, - base::Unretained(this))); - - HeadlessTabSocket* headless_tab_socket = - web_contents_->GetHeadlessTabSocket(); - DCHECK(headless_tab_socket); - - headless_tab_socket->SendMessageToContext("One", execution_context_id); - headless_tab_socket->SendMessageToContext("Two", execution_context_id); - headless_tab_socket->SendMessageToContext("Three", execution_context_id); - headless_tab_socket->SetListener(this); - main_frame_execution_context_id_ = execution_context_id; - } - - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { - EXPECT_EQ(execution_context_id, *main_frame_execution_context_id_); - messages_.push_back(message); - if (messages_.size() == 3u) { - EXPECT_THAT(messages_, - ElementsAre("Embedder sent us: One", "Embedder sent us: Two", - "Embedder sent us: Three")); - FinishAsynchronousTest(); - } - } - - private: - std::vector<std::string> messages_; - base::Optional<int> main_frame_execution_context_id_; -}; - -HEADLESS_ASYNC_DEVTOOLED_TEST_F(MainWorldHeadlessTabSocketTest); - -class MainWorldHeadlessTabSocketBindingsNotInstalledTest - : public TabSocketTest { - public: - void RunTabSocketTest() override { - CreateIsolatedWorldTabSocket( - "Test World", main_frame_id(), - base::BindOnce(&MainWorldHeadlessTabSocketBindingsNotInstalledTest:: - OnIsolatedWorldCreated, - base::Unretained(this))); - } - - void OnIsolatedWorldCreated(int execution_context_id) { - // We expect this to fail because TabSocket bindings where injected into the - // isolated world not the main world. - devtools_client_->GetRuntime()->Evaluate( - "window.TabSocket.send('This should not work!');", - base::BindOnce(&MainWorldHeadlessTabSocketBindingsNotInstalledTest:: - ExpectJsException, - base::Unretained(this))); - - HeadlessTabSocket* headless_tab_socket = - web_contents_->GetHeadlessTabSocket(); - DCHECK(headless_tab_socket); - - headless_tab_socket->SetListener(this); - } - - void OnMessageFromContext(const std::string&, int) override { - FinishAsynchronousTest(); - FAIL() << "Should not receive a message from the tab!"; - } -}; - -HEADLESS_ASYNC_DEVTOOLED_TEST_F( - MainWorldHeadlessTabSocketBindingsNotInstalledTest); - -class IsolatedWorldHeadlessTabSocketTest : public TabSocketTest { - public: - void RunTabSocketTest() override { - CreateIsolatedWorldTabSocket( - "Test World", main_frame_id(), - base::BindOnce( - &IsolatedWorldHeadlessTabSocketTest::OnIsolatedWorldCreated, - base::Unretained(this))); - } - - void OnIsolatedWorldCreated(int execution_context_id) { - main_frame_execution_context_id_ = execution_context_id; - - HeadlessTabSocket* headless_tab_socket = - web_contents_->GetHeadlessTabSocket(); - DCHECK(headless_tab_socket); - headless_tab_socket->SendMessageToContext( - "Hello!!!", *main_frame_execution_context_id_); - headless_tab_socket->SetListener(this); - - devtools_client_->GetRuntime()->Evaluate( - runtime::EvaluateParams::Builder() - .SetExpression( - R"(window.TabSocket.onmessage = - function(message) { - TabSocket.send('Embedder sent us: ' + message); - }; - )") - .SetContextId(GetV8ExecutionContextIdByWorldName("Test World")) - .Build(), - base::BindOnce( - &IsolatedWorldHeadlessTabSocketTest::FailOnJsEvaluateException, - base::Unretained(this))); - } - - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { - EXPECT_EQ("Embedder sent us: Hello!!!", message); - EXPECT_EQ(*main_frame_execution_context_id_, execution_context_id); - FinishAsynchronousTest(); - } - - base::Optional<int> main_frame_execution_context_id_; -}; - -HEADLESS_ASYNC_DEVTOOLED_TEST_F(IsolatedWorldHeadlessTabSocketTest); - -class MultipleIframesIsolatedWorldHeadlessTabSocketTest : public TabSocketTest { - public: - void RunTabSocketTest() override { - EXPECT_TRUE(embedded_test_server()->Start()); - devtools_client_->GetPage()->Navigate( - embedded_test_server()->GetURL("/two_iframes.html").spec()); - } - - void OnLoadEventFired(const page::LoadEventFiredParams& params) override { - devtools_client_->GetPage()->Disable(); - devtools_client_->GetPage()->RemoveObserver(this); - devtools_client_->GetDOMSnapshot()->GetExperimental()->GetSnapshot( - dom_snapshot::GetSnapshotParams::Builder() - .SetComputedStyleWhitelist(std::vector<std::string>()) - .Build(), - base::BindOnce( - &MultipleIframesIsolatedWorldHeadlessTabSocketTest::OnSnapshot, - base::Unretained(this))); - } - - void OnSnapshot(std::unique_ptr<dom_snapshot::GetSnapshotResult> result) { - bool seen_main_frame = false; - for (const auto& node : *result->GetDomNodes()) { - if (node->HasFrameId()) { - std::string frame_name; - if (node->GetNodeName() == "IFRAME") { - // Use the iframe id attribute for the name. - for (const auto& key_value : *node->GetAttributes()) { - if (key_value->GetName() == "id") { - frame_name = key_value->GetValue(); - } - } - CHECK(!frame_name.empty()); - } else { - if (seen_main_frame) - continue; - seen_main_frame = true; - frame_name = "main frame"; - } - CreateIsolatedWorldTabSocket( - frame_name, node->GetFrameId(), - base::BindOnce(&MultipleIframesIsolatedWorldHeadlessTabSocketTest:: - OnIsolatedWorldCreated, - base::Unretained(this), frame_name)); - } - } - } - - void OnIsolatedWorldCreated(std::string frame_name, - int execution_context_id) { - HeadlessTabSocket* headless_tab_socket = - web_contents_->GetHeadlessTabSocket(); - DCHECK(headless_tab_socket); - headless_tab_socket->SendMessageToContext("Hello!!!", execution_context_id); - headless_tab_socket->SetListener(this); - - devtools_client_->GetRuntime()->Evaluate( - runtime::EvaluateParams::Builder() - .SetExpression(base::StringPrintf( - R"(window.TabSocket.onmessage = - function(message) { - TabSocket.send('Echo from %s: ' + message); - }; - )", - frame_name.c_str())) - .SetContextId(execution_context_id) - .Build(), - base::BindOnce(&MultipleIframesIsolatedWorldHeadlessTabSocketTest:: - FailOnJsEvaluateException, - base::Unretained(this))); - } - - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { - messages_.push_back(message); - if (messages_.size() < 3) - return; - EXPECT_THAT(messages_, - UnorderedElementsAre("Echo from main frame: Hello!!!", - "Echo from iframe1: Hello!!!", - "Echo from iframe2: Hello!!!")); - FinishAsynchronousTest(); - } - - std::vector<std::string> messages_; -}; - -HEADLESS_ASYNC_DEVTOOLED_TEST_F( - MultipleIframesIsolatedWorldHeadlessTabSocketTest); - -class SingleTabMultipleIsolatedWorldsHeadlessTabSocketTest - : public TabSocketTest { - public: - void RunTabSocketTest() override { - CreateIsolatedWorldTabSocket( - "Isolated World 1", main_frame_id(), - base::BindOnce(&SingleTabMultipleIsolatedWorldsHeadlessTabSocketTest:: - OnIsolatedWorldCreated, - base::Unretained(this), "Isolated World 1")); - - CreateIsolatedWorldTabSocket( - "Isolated World 2", main_frame_id(), - base::BindOnce(&SingleTabMultipleIsolatedWorldsHeadlessTabSocketTest:: - OnIsolatedWorldCreated, - base::Unretained(this), "Isolated World 2")); - - CreateIsolatedWorldTabSocket( - "Isolated World 3", main_frame_id(), - base::BindOnce(&SingleTabMultipleIsolatedWorldsHeadlessTabSocketTest:: - OnIsolatedWorldCreated, - base::Unretained(this), "Isolated World 3")); - } - - void OnIsolatedWorldCreated(std::string frame_name, - int execution_context_id) { - HeadlessTabSocket* headless_tab_socket = - web_contents_->GetHeadlessTabSocket(); - DCHECK(headless_tab_socket); - headless_tab_socket->SendMessageToContext("Hello!!!", execution_context_id); - headless_tab_socket->SetListener(this); - - devtools_client_->GetRuntime()->Evaluate( - runtime::EvaluateParams::Builder() - .SetExpression(base::StringPrintf( - R"(window.TabSocket.onmessage = - function(message) { - TabSocket.send('Echo from %s: ' + message); - }; - )", - frame_name.c_str())) - .SetContextId(execution_context_id) - .Build(), - base::BindOnce(&SingleTabMultipleIsolatedWorldsHeadlessTabSocketTest:: - FailOnJsEvaluateException, - base::Unretained(this))); - } - - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { - messages_.push_back(message); - if (messages_.size() < 3) - return; - EXPECT_THAT(messages_, - UnorderedElementsAre("Echo from Isolated World 1: Hello!!!", - "Echo from Isolated World 2: Hello!!!", - "Echo from Isolated World 3: Hello!!!")); - FinishAsynchronousTest(); - } - - std::vector<std::string> messages_; -}; - -HEADLESS_ASYNC_DEVTOOLED_TEST_F( - SingleTabMultipleIsolatedWorldsHeadlessTabSocketTest); - -class LargeStringTabSocketTest : public TabSocketTest { - public: - void RunTabSocketTest() override { - CreateMainWorldTabSocket( - main_frame_id(), - base::BindOnce(&LargeStringTabSocketTest::OnInstalledHeadlessTabSocket, - base::Unretained(this))); - } - - void OnInstalledHeadlessTabSocket(int execution_context_id) { - devtools_client_->GetRuntime()->Evaluate( - R"(window.TabSocket.onmessage = - function(message) { - window.TabSocket.send('Embedder sent us: ' + message); - }; - )", - base::BindOnce(&LargeStringTabSocketTest::FailOnJsEvaluateException, - base::Unretained(this))); - - HeadlessTabSocket* headless_tab_socket = - web_contents_->GetHeadlessTabSocket(); - DCHECK(headless_tab_socket); - - std::string big_string; - big_string.reserve(IPC::Channel::kMaximumMessageSize); - for (size_t i = 0; i < IPC::Channel::kMaximumMessageSize; i++) { - big_string.push_back('A' + (i % 24)); - } - - headless_tab_socket->SendMessageToContext(big_string, execution_context_id); - headless_tab_socket->SetListener(this); - main_frame_execution_context_id_ = execution_context_id; - } - - void OnMessageFromContext(const std::string& message, - int execution_context_id) override { - EXPECT_EQ(execution_context_id, *main_frame_execution_context_id_); - messages_.push_back(message); - if (messages_.size() == 1u) { - EXPECT_EQ(18 + IPC::Channel::kMaximumMessageSize, messages_[0].size()); - FinishAsynchronousTest(); - } - } - - private: - std::vector<std::string> messages_; - base::Optional<int> main_frame_execution_context_id_; -}; - -HEADLESS_ASYNC_DEVTOOLED_TEST_F(LargeStringTabSocketTest); - // Regression test for https://crbug.com/733569. class HeadlessWebContentsRequestStorageQuotaTest : public HeadlessAsyncDevTooledBrowserTest,
diff --git a/headless/lib/renderer/headless_content_renderer_client.cc b/headless/lib/renderer/headless_content_renderer_client.cc index 6af167a..4d972d67 100644 --- a/headless/lib/renderer/headless_content_renderer_client.cc +++ b/headless/lib/renderer/headless_content_renderer_client.cc
@@ -6,7 +6,6 @@ #include <memory> -#include "headless/lib/renderer/headless_render_frame_controller_impl.h" #include "printing/buildflags/buildflags.h" #if BUILDFLAG(ENABLE_PRINTING) @@ -26,7 +25,6 @@ new printing::PrintRenderFrameHelper( render_frame, std::make_unique<HeadlessPrintRenderFrameHelperDelegate>()); #endif - new HeadlessRenderFrameControllerImpl(render_frame); } } // namespace headless
diff --git a/headless/lib/renderer/headless_render_frame_controller_impl.cc b/headless/lib/renderer/headless_render_frame_controller_impl.cc deleted file mode 100644 index 9f695f6..0000000 --- a/headless/lib/renderer/headless_render_frame_controller_impl.cc +++ /dev/null
@@ -1,123 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "headless/lib/renderer/headless_render_frame_controller_impl.h" - -#include "content/public/common/isolated_world_ids.h" -#include "services/service_manager/public/cpp/binder_registry.h" -#include "services/service_manager/public/cpp/interface_provider.h" -#include "v8/include/v8-inspector.h" - -namespace headless { - -HeadlessRenderFrameControllerImpl::HeadlessRenderFrameControllerImpl( - content::RenderFrame* render_frame) - : content::RenderFrameObserver(render_frame), - render_frame_(render_frame), - weak_ptr_factory_(this) { - registry_.AddInterface(base::Bind( - &HeadlessRenderFrameControllerImpl::OnRenderFrameControllerRequest, - base::Unretained(this))); -} - -HeadlessRenderFrameControllerImpl::~HeadlessRenderFrameControllerImpl() = - default; - -void HeadlessRenderFrameControllerImpl::OnRenderFrameControllerRequest( - HeadlessRenderFrameControllerRequest request) { - headless_render_frame_controller_bindings_.AddBinding(this, - std::move(request)); -} - -void HeadlessRenderFrameControllerImpl::InstallTabSocket( - int32_t execution_context_id, - InstallTabSocketCallback callback) { - auto find_it = tab_socket_bindings_.find(execution_context_id); - if (find_it == tab_socket_bindings_.end()) { - LOG(WARNING) << "InstallTabSocket failed, unknown execution_context_id " - << execution_context_id; - std::move(callback).Run(false); - } else { - std::move(callback).Run(find_it->second.InitializeTabSocketBindings()); - } -} - -void HeadlessRenderFrameControllerImpl::InstallMainWorldTabSocket( - InstallMainWorldTabSocketCallback callback) { - // Check any pre-existing script contexts. - for (auto& pair : tab_socket_bindings_) { - if (pair.second.world_id() == content::ISOLATED_WORLD_ID_GLOBAL) { - std::move(callback).Run( - pair.second.InitializeTabSocketBindings() ? pair.first : -1); - return; - } - } - pending_install_main_world_tab_socket_callback_ = std::move(callback); -} - -void HeadlessRenderFrameControllerImpl::SendMessageToTabSocket( - const std::string& message, - int32_t world_id) { - auto find_it = tab_socket_bindings_.find(world_id); - if (find_it == tab_socket_bindings_.end()) { - LOG(WARNING) << "Dropping message for " << world_id - << " because the world doesn't exist."; - return; - } - - find_it->second.OnMessageFromEmbedder(message); -} - -void HeadlessRenderFrameControllerImpl::OnInterfaceRequestForFrame( - const std::string& interface_name, - mojo::ScopedMessagePipeHandle* interface_pipe) { - registry_.TryBindInterface(interface_name, interface_pipe); -} - -void HeadlessRenderFrameControllerImpl::DidCreateScriptContext( - v8::Local<v8::Context> context, - int world_id) { - int v8_execution_context_id = - v8_inspector::V8ContextInfo::executionContextId(context); - auto find_it = tab_socket_bindings_.find(v8_execution_context_id); - if (find_it != tab_socket_bindings_.end()) - tab_socket_bindings_.erase(find_it); - - auto emplace_result = tab_socket_bindings_.emplace( - std::piecewise_construct, std::forward_as_tuple(v8_execution_context_id), - std::forward_as_tuple(this, render_frame_, context, world_id)); - - // If main world tab socket bindings have been requested and this is the main - // world then install the bindings. - if (world_id == content::ISOLATED_WORLD_ID_GLOBAL && - !pending_install_main_world_tab_socket_callback_.is_null()) { - std::move(pending_install_main_world_tab_socket_callback_) - .Run(emplace_result.first->second.InitializeTabSocketBindings() - ? v8_execution_context_id - : -1); - pending_install_main_world_tab_socket_callback_ = - InstallMainWorldTabSocketCallback(); - } -} - -void HeadlessRenderFrameControllerImpl::WillReleaseScriptContext( - v8::Local<v8::Context> context, - int world_id) { - tab_socket_bindings_.erase( - v8_inspector::V8ContextInfo::executionContextId(context)); -} - -void HeadlessRenderFrameControllerImpl::OnDestruct() { - delete this; -} - -TabSocketPtr& HeadlessRenderFrameControllerImpl::EnsureTabSocketPtr() { - if (!tab_socket_ptr_.is_bound()) { - render_frame_->GetRemoteInterfaces()->GetInterface( - mojo::MakeRequest(&tab_socket_ptr_)); - } - return tab_socket_ptr_; -} - -} // namespace headless
diff --git a/headless/lib/renderer/headless_render_frame_controller_impl.h b/headless/lib/renderer/headless_render_frame_controller_impl.h deleted file mode 100644 index 1a657b99..0000000 --- a/headless/lib/renderer/headless_render_frame_controller_impl.h +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef HEADLESS_LIB_RENDERER_HEADLESS_RENDER_FRAME_CONTROLLER_IMPL_H_ -#define HEADLESS_LIB_RENDERER_HEADLESS_RENDER_FRAME_CONTROLLER_IMPL_H_ - -#include "content/public/renderer/render_frame.h" -#include "content/public/renderer/render_frame_observer.h" -#include "headless/lib/headless_render_frame_controller.mojom.h" -#include "headless/lib/renderer/headless_tab_socket_bindings.h" -#include "headless/lib/tab_socket.mojom.h" -#include "mojo/public/cpp/bindings/binding_set.h" -#include "services/service_manager/public/cpp/binder_registry.h" - -namespace headless { - -class HeadlessRenderFrameControllerImpl : public HeadlessRenderFrameController, - public content::RenderFrameObserver { - public: - explicit HeadlessRenderFrameControllerImpl( - content::RenderFrame* render_frame); - ~HeadlessRenderFrameControllerImpl() override; - - void OnRenderFrameControllerRequest( - HeadlessRenderFrameControllerRequest request); - - // HeadlessRenderFrameController implementation: - void InstallTabSocket(int32_t v8_execution_context_id, - InstallTabSocketCallback callback) override; - void InstallMainWorldTabSocket( - InstallMainWorldTabSocketCallback callback) override; - void SendMessageToTabSocket(const std::string& message, - int32_t world_id) override; - - // content::RenderFrameObserver implementation: - void OnInterfaceRequestForFrame( - const std::string& interface_name, - mojo::ScopedMessagePipeHandle* interface_pipe) override; - void DidCreateScriptContext(v8::Local<v8::Context> context, - int world_id) override; - - void WillReleaseScriptContext(v8::Local<v8::Context> context, - int world_id) override; - - void OnDestruct() override; - - TabSocketPtr& EnsureTabSocketPtr(); - - private: - content::RenderFrame* const render_frame_; // NOT OWNED - mojo::BindingSet<HeadlessRenderFrameController> - headless_render_frame_controller_bindings_; - std::map<int, HeadlessTabSocketBindings> tab_socket_bindings_; - TabSocketPtr tab_socket_ptr_; - InstallMainWorldTabSocketCallback - pending_install_main_world_tab_socket_callback_; - service_manager::BinderRegistry registry_; - base::WeakPtrFactory<HeadlessRenderFrameControllerImpl> weak_ptr_factory_; -}; - -} // namespace headless - -#endif // HEADLESS_LIB_RENDERER_HEADLESS_RENDER_FRAME_CONTROLLER_IMPL_H_
diff --git a/headless/lib/renderer/headless_tab_socket_bindings.cc b/headless/lib/renderer/headless_tab_socket_bindings.cc deleted file mode 100644 index 1890ec38..0000000 --- a/headless/lib/renderer/headless_tab_socket_bindings.cc +++ /dev/null
@@ -1,101 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "headless/lib/renderer/headless_tab_socket_bindings.h" - -#include "headless/lib/renderer/headless_render_frame_controller_impl.h" -#include "third_party/blink/public/web/blink.h" -#include "third_party/blink/public/web/web_local_frame.h" -#include "v8/include/v8-inspector.h" - -namespace headless { - -HeadlessTabSocketBindings::HeadlessTabSocketBindings( - HeadlessRenderFrameControllerImpl* parent_controller, - content::RenderFrame* render_frame, - v8::Local<v8::Context> context, - int world_id) - : parent_controller_(parent_controller), - render_frame_(render_frame), - context_(blink::MainThreadIsolate(), context), - world_id_(world_id), - installed_(false) {} - -HeadlessTabSocketBindings::~HeadlessTabSocketBindings() = default; - -bool HeadlessTabSocketBindings::InitializeTabSocketBindings() { - if (installed_) - return false; - - v8::Isolate* isolate = blink::MainThreadIsolate(); - v8::HandleScope handle_scope(isolate); - if (context_.IsEmpty()) - return false; - - v8::Local<v8::Context> context = context_.Get(blink::MainThreadIsolate()); - v8::Context::Scope context_scope(context); - gin::Handle<HeadlessTabSocketBindings> bindings = - gin::CreateHandle(isolate, this); - if (bindings.IsEmpty()) - return false; - - v8::Local<v8::Object> global = context->Global(); - global->Set(gin::StringToV8(isolate, "TabSocket"), bindings.ToV8()); - installed_ = true; - return true; -} - -void HeadlessTabSocketBindings::OnMessageFromEmbedder( - const std::string& message) { - if (on_message_callback_.IsEmpty()) { - pending_messages_.push_back(message); - return; - } - - v8::Isolate* isolate = blink::MainThreadIsolate(); - v8::HandleScope handle_scope(isolate); - v8::Local<v8::Context> context = context_.Get(isolate); - v8::Local<v8::Value> argv[] = { - gin::Converter<std::string>::ToV8(isolate, message), - }; - - render_frame_->GetWebFrame()->RequestExecuteV8Function( - context, GetOnMessageCallback(), context->Global(), arraysize(argv), argv, - this); -} - -gin::ObjectTemplateBuilder HeadlessTabSocketBindings::GetObjectTemplateBuilder( - v8::Isolate* isolate) { - return gin::Wrappable<HeadlessTabSocketBindings>::GetObjectTemplateBuilder( - isolate) - .SetMethod("send", &HeadlessTabSocketBindings::SendImpl) - .SetProperty("onmessage", &HeadlessTabSocketBindings::GetOnMessage, - &HeadlessTabSocketBindings::SetOnMessage); -} - -void HeadlessTabSocketBindings::SendImpl(const std::string& message) { - v8::Local<v8::Context> context = context_.Get(blink::MainThreadIsolate()); - int execution_context_id = - v8_inspector::V8ContextInfo::executionContextId(context); - parent_controller_->EnsureTabSocketPtr()->SendMessageToEmbedder( - message, execution_context_id); -} - -void HeadlessTabSocketBindings::SetOnMessage(v8::Local<v8::Function> callback) { - on_message_callback_.Reset(blink::MainThreadIsolate(), callback); - for (const std::string& message : pending_messages_) { - OnMessageFromEmbedder(message); - } - pending_messages_.clear(); -} - -v8::Local<v8::Function> HeadlessTabSocketBindings::GetOnMessageCallback() { - return v8::Local<v8::Function>::New(blink::MainThreadIsolate(), - on_message_callback_); -} - -gin::WrapperInfo HeadlessTabSocketBindings::kWrapperInfo = { - gin::kEmbedderNativeGin}; - -} // namespace headless
diff --git a/headless/lib/renderer/headless_tab_socket_bindings.h b/headless/lib/renderer/headless_tab_socket_bindings.h deleted file mode 100644 index 0be27bb9..0000000 --- a/headless/lib/renderer/headless_tab_socket_bindings.h +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef HEADLESS_LIB_RENDERER_HEADLESS_TAB_SOCKET_BINDINGS_H_ -#define HEADLESS_LIB_RENDERER_HEADLESS_TAB_SOCKET_BINDINGS_H_ - -#include "content/public/renderer/render_frame.h" -#include "gin/handle.h" -#include "gin/object_template_builder.h" -#include "gin/wrappable.h" -#include "headless/lib/tab_socket.mojom.h" -#include "third_party/blink/public/web/web_script_execution_callback.h" - -namespace headless { -class HeadlessRenderFrameControllerImpl; - -class HeadlessTabSocketBindings - : public gin::Wrappable<HeadlessTabSocketBindings>, - public blink::WebScriptExecutionCallback { - public: - HeadlessTabSocketBindings( - HeadlessRenderFrameControllerImpl* parent_controller, - content::RenderFrame* render_frame, - v8::Local<v8::Context> context, - int world_id); - - ~HeadlessTabSocketBindings() override; - - // Add TabSocket bindings to |context_|. - bool InitializeTabSocketBindings(); - - void OnMessageFromEmbedder(const std::string& message); - - // gin::WrappableBase implementation: - gin::ObjectTemplateBuilder GetObjectTemplateBuilder( - v8::Isolate* isolate) override; - - static gin::WrapperInfo kWrapperInfo; - - int world_id() const { return world_id_; } - - private: - void SendImpl(const std::string& message); - - v8::Local<v8::Value> GetOnMessage() { return GetOnMessageCallback(); } - - void SetOnMessage(v8::Local<v8::Function> callback); - - v8::Local<v8::Function> GetOnMessageCallback(); - - HeadlessRenderFrameControllerImpl* const parent_controller_; // NOT OWNED - content::RenderFrame* const render_frame_; // NOT OWNED - const v8::UniquePersistent<v8::Context> context_; - const int world_id_; - bool installed_; - std::list<std::string> pending_messages_; - v8::UniquePersistent<v8::Function> on_message_callback_; -}; - -} // namespace headless - -#endif // HEADLESS_LIB_RENDERER_HEADLESS_TAB_SOCKET_BINDINGS_H_
diff --git a/headless/lib/resources/headless_lib_resources.grd b/headless/lib/resources/headless_lib_resources.grd index 9322c4c..8162c847 100644 --- a/headless/lib/resources/headless_lib_resources.grd +++ b/headless/lib/resources/headless_lib_resources.grd
@@ -13,7 +13,6 @@ <include name="IDR_HEADLESS_BROWSER_MANIFEST_OVERLAY" file="${mojom_root}/headless/headless_browser_manifest_overlay.json" use_base_dir="false" type="BINDATA" /> <include name="IDR_HEADLESS_RENDERER_MANIFEST_OVERLAY" file="../renderer/headless_renderer_manifest_overlay.json" type="BINDATA" /> <include name="IDR_HEADLESS_PACKAGED_SERVICES_MANIFEST_OVERLAY" file="${mojom_root}/headless/headless_packaged_services_manifest_overlay.json" use_base_dir="false" type="BINDATA" /> - <include name="IDR_HEADLESS_TAB_SOCKET_MOJOM_JS" file="${mojom_root}/headless/lib/tab_socket.mojom.js" use_base_dir="false" type="BINDATA" /> <include name="IDR_PDF_COMPOSITOR_MANIFEST" file="${mojom_root}/components/printing/service/pdf_compositor_manifest.json" use_base_dir="false" type="BINDATA" /> </includes> </release>
diff --git a/headless/lib/tab_socket.mojom b/headless/lib/tab_socket.mojom deleted file mode 100644 index 07c5649..0000000 --- a/headless/lib/tab_socket.mojom +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module headless; - -import "mojo/public/mojom/base/big_string.mojom"; - -interface TabSocket { - // Send a message from the Tab to C++ embedder. - SendMessageToEmbedder(mojo_base.mojom.BigString message, - int32 v8_execution_context_id); - - // To send a message to the tab use - // HeadlessRenderFrameController::SendMessageToTabSocket. -};
diff --git a/headless/public/headless_browser.cc b/headless/public/headless_browser.cc index 5e5dc03..41e4b1b 100644 --- a/headless/public/headless_browser.cc +++ b/headless/public/headless_browser.cc
@@ -134,11 +134,6 @@ return *this; } -Builder& Builder::AddMojoServiceName(const std::string& mojo_service_name) { - options_.mojo_service_names.insert(mojo_service_name); - return *this; -} - Builder& Builder::SetAppendCommandLineFlagsCallback( const Options::AppendCommandLineFlagsCallback& callback) { options_.append_command_line_flags_callback = callback;
diff --git a/headless/public/headless_browser.h b/headless/public/headless_browser.h index 47cb798d..532f250 100644 --- a/headless/public/headless_browser.h +++ b/headless/public/headless_browser.h
@@ -148,10 +148,6 @@ // string can be used to disable GL rendering (e.g., WebGL support). std::string gl_implementation; - // Names of mojo services exposed by the browser to the renderer. These - // services will be added to the browser's service manifest. - std::unordered_set<std::string> mojo_service_names; - // Default per-context options, can be specialized on per-context basis. std::string product_name_and_version; @@ -251,7 +247,6 @@ Builder& SetDisableSandbox(bool disable_sandbox); Builder& SetEnableResourceScheduler(bool enable_resource_scheduler); Builder& SetGLImplementation(const std::string& gl_implementation); - Builder& AddMojoServiceName(const std::string& mojo_service_name); Builder& SetAppendCommandLineFlagsCallback( const Options::AppendCommandLineFlagsCallback& callback); #if defined(OS_WIN)
diff --git a/headless/public/headless_browser_context.h b/headless/public/headless_browser_context.h index 84532dc..3665efb 100644 --- a/headless/public/headless_browser_context.h +++ b/headless/public/headless_browser_context.h
@@ -120,8 +120,6 @@ // fetching for different network schemes. Builder& SetProtocolHandlers(ProtocolHandlerMap protocol_handlers); - Builder& AddTabSocketMojoBindings(); - // By default if you add mojo bindings, http and https are disabled because // its almost certinly unsafe for arbitary sites on the internet to have // access to these bindings. If you know what you're doing it may be OK to
diff --git a/headless/public/headless_tab_socket.h b/headless/public/headless_tab_socket.h deleted file mode 100644 index 51cb7d3..0000000 --- a/headless/public/headless_tab_socket.h +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef HEADLESS_PUBLIC_HEADLESS_TAB_SOCKET_H_ -#define HEADLESS_PUBLIC_HEADLESS_TAB_SOCKET_H_ - -#include <string> - -#include "base/macros.h" -#include "base/optional.h" -#include "headless/public/headless_export.h" - -namespace headless { - -// A bidirectional communications channel between C++ and JS. -class HEADLESS_EXPORT HeadlessTabSocket { - public: - class HEADLESS_EXPORT Listener { - public: - Listener() {} - virtual ~Listener() {} - - // The |message| and |v8_execution_context_id| may be potentially sent by - // untrusted web content so it should be validated carefully. - virtual void OnMessageFromContext(const std::string& message, - int v8_execution_context_id) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(Listener); - }; - - // Installs headless tab socket bindings into the specified execution context. - // If the bindings are successfully installed then the |callback| is run with - // |success| = true, otherwise with |success| = false. - virtual void InstallHeadlessTabSocketBindings( - int v8_execution_context_id, - base::OnceCallback<void(bool success)> callback) = 0; - - // Installs headless tab socket bindings into the main frame main world. If - // the bindings were installed correctly then |callback| is run with a - // non-empty base::Optional<int> containing the main world - // v8_execution_context_id, otherwise |callback| is run with an empty - // base::Optional<int>. - virtual void InstallMainFrameMainWorldHeadlessTabSocketBindings( - base::OnceCallback<void(base::Optional<int> v8_execution_context_id)> - callback) = 0; - - // Note this will fail unless the bindings have been installed. - virtual void SendMessageToContext(const std::string& message, - int v8_execution_context_id) = 0; - - virtual void SetListener(Listener* listener) = 0; - - protected: - HeadlessTabSocket() {} - virtual ~HeadlessTabSocket() {} - - private: - DISALLOW_COPY_AND_ASSIGN(HeadlessTabSocket); -}; - -} // namespace headless - -#endif // HEADLESS_PUBLIC_HEADLESS_TAB_SOCKET_H_
diff --git a/headless/public/headless_web_contents.h b/headless/public/headless_web_contents.h index f05595fe..6f67659 100644 --- a/headless/public/headless_web_contents.h +++ b/headless/public/headless_web_contents.h
@@ -21,7 +21,6 @@ class HeadlessBrowserContextImpl; class HeadlessBrowserImpl; class HeadlessDevToolsTarget; -class HeadlessTabSocket; // Class representing contents of a browser tab. Should be accessed from browser // main thread. @@ -80,10 +79,6 @@ // Close this page. |HeadlessWebContents| object will be destroyed. virtual void Close() = 0; - // Returns the headless tab socket interface for C++ <---> JS, or null if tab - // sockets are not allowed. - virtual HeadlessTabSocket* GetHeadlessTabSocket() const = 0; - // Returns the main frame's process id or -1 if there's no main frame. virtual int GetMainFrameRenderProcessId() const = 0; @@ -113,9 +108,6 @@ // Specify the initial window size (default is configured in browser options). Builder& SetWindowSize(const gfx::Size& size); - // Specify whether or not TabSockets are allowed. - Builder& SetAllowTabSockets(bool tab_sockets_allowed); - // Specify whether BeginFrames should be controlled via DevTools commands. Builder& SetEnableBeginFrameControl(bool enable_begin_frame_control); @@ -130,27 +122,10 @@ explicit Builder(HeadlessBrowserContextImpl* browser_context); - struct MojoService { - using ServiceFactoryCallback = - base::RepeatingCallback<void(HeadlessWebContents*, - mojo::ScopedMessagePipeHandle)>; - - MojoService(); - MojoService(const MojoService& other); - MojoService(const std::string& service_name, - const ServiceFactoryCallback& service_factory); - ~MojoService(); - - std::string service_name; - ServiceFactoryCallback service_factory; - }; - HeadlessBrowserContextImpl* browser_context_; GURL initial_url_ = GURL("about:blank"); gfx::Size window_size_; - std::list<MojoService> mojo_services_; - bool tab_sockets_allowed_ = false; bool enable_begin_frame_control_ = false; DISALLOW_COPY_AND_ASSIGN(Builder);
diff --git a/headless/test/data/tabsocket.html b/headless/test/data/tabsocket.html deleted file mode 100644 index 789191f..0000000 --- a/headless/test/data/tabsocket.html +++ /dev/null
@@ -1,21 +0,0 @@ -<html> -<script> -function tabsocketTest() { - // Unfortunately, the order in which - // HeadlessRenderFrameControllerImpl::DidCreateScriptContext and - // HeadlessRenderFrameControllerImpl::InstallMainWorldTabSocket are called - // is non-deterministic. This means the TabSocket might not have been - // installed yet. If that happens just try again a bit later. - if (window.hasOwnProperty('TabSocket')) { - window.TabSocket.send('Hello world!'); - - window.TabSocket.onmessage = function(message) { - window.TabSocket.send('Embedder sent us: ' + message); - }; - } else { - setTimeout(tabsocketTest, 1); - } -} -tabsocketTest(); -</script> -</html>
diff --git a/headless/test/headless_browser_test.cc b/headless/test/headless_browser_test.cc index 7f1312b..0a862f41 100644 --- a/headless/test/headless_browser_test.cc +++ b/headless/test/headless_browser_test.cc
@@ -256,10 +256,6 @@ HeadlessBrowserContext::Builder builder = browser()->CreateBrowserContextBuilder(); builder.SetProtocolHandlers(GetProtocolHandlers()); - if (GetAllowTabSockets()) { - builder.EnableUnsafeNetworkAccessWithMojoBindings(true); - builder.AddTabSocketMojoBindings(); - } CustomizeHeadlessBrowserContext(builder); browser_context_ = builder.Build(); @@ -268,7 +264,6 @@ HeadlessWebContents::Builder web_contents_builder = browser_context_->CreateWebContentsBuilder(); - web_contents_builder.SetAllowTabSockets(GetAllowTabSockets()); web_contents_builder.SetEnableBeginFrameControl(GetEnableBeginFrameControl()); CustomizeHeadlessWebContents(web_contents_builder); web_contents_ = web_contents_builder.Build(); @@ -291,10 +286,6 @@ return ProtocolHandlerMap(); } -bool HeadlessAsyncDevTooledBrowserTest::GetAllowTabSockets() { - return false; -} - bool HeadlessAsyncDevTooledBrowserTest::GetEnableBeginFrameControl() { return false; }
diff --git a/headless/test/headless_browser_test.h b/headless/test/headless_browser_test.h index 1e3f027cc..defe5e3 100644 --- a/headless/test/headless_browser_test.h +++ b/headless/test/headless_browser_test.h
@@ -144,9 +144,6 @@ // the map returned is empty. virtual ProtocolHandlerMap GetProtocolHandlers(); - // Whether to allow TabSockets when creating |web_contents_|. - virtual bool GetAllowTabSockets(); - // Whether to enable BeginFrameControl when creating |web_contents_|. virtual bool GetEnableBeginFrameControl();
diff --git a/headless/test/headless_js_bindings_browsertest.cc b/headless/test/headless_js_bindings_browsertest.cc index 295f722..abdb42be 100644 --- a/headless/test/headless_js_bindings_browsertest.cc +++ b/headless/test/headless_js_bindings_browsertest.cc
@@ -8,6 +8,7 @@ #include "base/base64.h" #include "base/json/json_reader.h" +#include "base/memory/weak_ptr.h" #include "base/path_service.h" #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" @@ -19,10 +20,9 @@ #include "headless/public/devtools/domains/runtime.h" #include "headless/public/headless_browser.h" #include "headless/public/headless_devtools_client.h" -#include "headless/public/headless_tab_socket.h" #include "headless/public/headless_web_contents.h" #include "headless/public/util/testing/test_in_memory_protocol_handler.h" -#include "headless/test/tab_socket_test.h" +#include "headless/test/headless_browser_test.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/resource/resource_bundle.h" @@ -30,26 +30,34 @@ namespace headless { namespace { -static constexpr char kIndexHtml[] = R"( +const char kIndexHtml[] = R"( <html> <body> <script src="bindings.js"></script> </body> </html> )"; + +const char kTabSocketScript[] = R"( +window.TabSocket = {}; +window.TabSocket.onmessage = () => {}; +window.TabSocket.send = (json) => console.debug(json); +)"; + } // namespace class HeadlessJsBindingsTest : public HeadlessAsyncDevTooledBrowserTest, public HeadlessDevToolsClient::RawProtocolListener, public TestInMemoryProtocolHandler::RequestDeferrer, - public HeadlessTabSocket::Listener, + public headless::runtime::Observer, public page::ExperimentalObserver { public: - void SetUp() override { - options()->mojo_service_names.insert("headless::TabSocket"); - HeadlessAsyncDevTooledBrowserTest::SetUp(); - } + using ConsoleAPICalledParams = headless::runtime::ConsoleAPICalledParams; + using EvaluateResult = headless::runtime::EvaluateResult; + using RemoteObject = headless::runtime::RemoteObject; + + HeadlessJsBindingsTest() : weak_factory_(this) {} void SetUpOnMainThread() override { base::ThreadRestrictions::SetIOAllowed(true); @@ -62,7 +70,6 @@ void CustomizeHeadlessBrowserContext( HeadlessBrowserContext::Builder& builder) override { - builder.AddTabSocketMojoBindings(); builder.EnableUnsafeNetworkAccessWithMojoBindings(true); } @@ -74,8 +81,6 @@ http_handler_->SetHeadlessBrowserContext(browser_context_); } - bool GetAllowTabSockets() override { return true; } - ProtocolHandlerMap GetProtocolHandlers() override { ProtocolHandlerMap protocol_handlers; std::unique_ptr<TestInMemoryProtocolHandler> http_handler( @@ -96,28 +101,24 @@ void RunDevTooledTest() override { devtools_client_->GetPage()->GetExperimental()->AddObserver(this); devtools_client_->GetPage()->Enable(); - headless_tab_socket_ = web_contents_->GetHeadlessTabSocket(); - CHECK(headless_tab_socket_); - headless_tab_socket_->SetListener(this); + devtools_client_->GetPage()->AddScriptToEvaluateOnNewDocument( + kTabSocketScript); + devtools_client_->GetRuntime()->AddObserver(this); + devtools_client_->GetRuntime()->Enable(); + devtools_client_->GetRuntime()->Evaluate( + kTabSocketScript, + base::BindOnce(&HeadlessJsBindingsTest::ConnectionEstablished, + weak_factory_.GetWeakPtr())); devtools_client_->SetRawProtocolListener(this); - - headless_tab_socket_->InstallMainFrameMainWorldHeadlessTabSocketBindings( - base::BindOnce(&HeadlessJsBindingsTest::OnInstalledHeadlessTabSocket, - base::Unretained(this))); } void OnRequest(const GURL& url, base::RepeatingClosure complete_request) override { - if (!tab_socket_installed_ && url.spec() == "http://test.com/bindings.js") { - complete_request_ = std::move(complete_request); - } else { - complete_request.Run(); - } + complete_request.Run(); } - void OnInstalledHeadlessTabSocket(base::Optional<int> context_id) { - main_world_execution_context_id_ = *context_id; - tab_socket_installed_ = true; + void ConnectionEstablished(std::unique_ptr<EvaluateResult>) { + connection_established_ = true; if (complete_request_) { browser()->BrowserIOThread()->PostTask(FROM_HERE, complete_request_); complete_request_ = base::RepeatingClosure(); @@ -147,9 +148,28 @@ : ""); } - void OnMessageFromContext(const std::string& json_message, - int v8_execution_context_id) override { - EXPECT_EQ(main_world_execution_context_id_, v8_execution_context_id); + void OnConsoleAPICalled(const ConsoleAPICalledParams& params) override { + const std::vector<std::unique_ptr<RemoteObject>>& args = *params.GetArgs(); + if (args.empty()) + return; + if (params.GetType() != headless::runtime::ConsoleAPICalledType::DEBUG) + return; + + RemoteObject* object = args[0].get(); + if (object->GetType() != headless::runtime::RemoteObjectType::STRING) + return; + + OnMessageFromJS(object->GetValue()->GetString()); + } + + void SendMessageToJS(const std::string& message) { + std::string encoded; + base::Base64Encode(message, &encoded); + devtools_client_->GetRuntime()->Evaluate( + "window.TabSocket.onmessage(atob(\"" + encoded + "\"))"); + } + + void OnMessageFromJS(const std::string& json_message) { std::unique_ptr<base::Value> message = base::JSONReader::Read(json_message, base::JSON_PARSE_RFC); const base::Value* method_value = message->FindKey("method"); @@ -184,7 +204,7 @@ bool OnProtocolMessage(const std::string& devtools_agent_host_id, const std::string& json_message, const base::DictionaryValue& parsed_message) override { - if (main_world_execution_context_id_ == -1) + if (!connection_established_) return false; const base::Value* id_value = parsed_message.FindKey("id"); @@ -198,8 +218,7 @@ if ((id % 2) == 0) return false; - headless_tab_socket_->SendMessageToContext( - json_message, main_world_execution_context_id_); + SendMessageToJS(json_message); return true; } @@ -207,24 +226,28 @@ if (!method_value) return false; - headless_tab_socket_->SendMessageToContext( - json_message, main_world_execution_context_id_); + if (method_value->GetString() == "Runtime.consoleAPICalled") { + // console.debug is used for transport. + return false; + } + + SendMessageToJS(json_message); // Check which domain the event belongs to, if it's the DOM domain then // assume js handled it. std::vector<base::StringPiece> sections = SplitStringPiece(method_value->GetString(), ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); + return sections[0] == "DOM" || sections[0] == "Runtime"; } protected: TestInMemoryProtocolHandler* http_handler_; // NOT OWNED - HeadlessTabSocket* headless_tab_socket_; // NOT OWNED - int main_world_execution_context_id_ = -1; std::string bindings_js_; base::RepeatingClosure complete_request_; - bool tab_socket_installed_ = false; + bool connection_established_ = false; + base::WeakPtrFactory<HeadlessJsBindingsTest> weak_factory_; }; class SimpleCommandJsBindingsTest : public HeadlessJsBindingsTest { @@ -316,8 +339,6 @@ EXPECT_EQ("2", result); if (first_result) { - tab_socket_installed_ = false; - main_world_execution_context_id_ = -1; devtools_client_->GetPage()->Reload(); } else { EXPECT_TRUE(metadata_received_); @@ -326,25 +347,6 @@ first_result = false; } - // Called on the IO thread. - void OnRequest(const GURL& url, - base::RepeatingClosure complete_request) override { - HeadlessJsBindingsTest::OnRequest(url, complete_request); - if (!first_result && url.spec() == "http://test.com/bindings.js") { - browser()->BrowserMainThread()->PostTask( - FROM_HERE, - base::BindOnce(&CachedJsBindingsTest::ReinstallTabSocketBindings, - base::Unretained(this))); - } - } - - void ReinstallTabSocketBindings() { - headless_tab_socket_->InstallMainFrameMainWorldHeadlessTabSocketBindings( - base::BindRepeating( - &HeadlessJsBindingsTest::OnInstalledHeadlessTabSocket, - base::Unretained(this))); - } - void OnMetadataForResource(const GURL& url, net::IOBuffer* buf, int buf_len) override {
diff --git a/headless/test/tab_socket_test.cc b/headless/test/tab_socket_test.cc deleted file mode 100644 index ee7d58d8..0000000 --- a/headless/test/tab_socket_test.cc +++ /dev/null
@@ -1,162 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "headless/test/tab_socket_test.h" - -#include "headless/public/headless_devtools_client.h" -#include "headless/public/headless_tab_socket.h" - -namespace headless { - -TabSocketTest::TabSocketTest() = default; -TabSocketTest::~TabSocketTest() = default; - -void TabSocketTest::SetUp() { - options()->mojo_service_names.insert("headless::TabSocket"); - HeadlessAsyncDevTooledBrowserTest::SetUp(); -} - -void TabSocketTest::RunDevTooledTest() { - devtools_client_->GetRuntime()->AddObserver(this); - devtools_client_->GetRuntime()->Enable(); - // Note we must enable the page domain or the browser won't get told the - // devtools frame ids. - devtools_client_->GetPage()->AddObserver(this); - devtools_client_->GetPage()->Enable( - page::EnableParams::Builder().Build(), - base::BindOnce(&TabSocketTest::OnPageEnabled, base::Unretained(this))); -} - -void TabSocketTest::OnPageEnabled(std::unique_ptr<page::EnableResult> result) { - devtools_client_->GetPage()->GetExperimental()->GetResourceTree( - page::GetResourceTreeParams::Builder().Build(), - base::BindOnce(&TabSocketTest::OnResourceTree, base::Unretained(this))); -} - -void TabSocketTest::OnResourceTree( - std::unique_ptr<page::GetResourceTreeResult> result) { - main_frame_id_ = result->GetFrameTree()->GetFrame()->GetId(); - RunTabSocketTest(); -} - -void TabSocketTest::OnExecutionContextCreated( - const runtime::ExecutionContextCreatedParams& params) { - const base::DictionaryValue* dictionary; - bool is_main_world; - if (params.GetContext()->HasAuxData() && - params.GetContext()->GetAuxData()->GetAsDictionary(&dictionary)) { - if (dictionary->GetBoolean("isDefault", &is_main_world) && !is_main_world) { - world_name_to_v8_execution_context_id_[params.GetContext()->GetName()] = - params.GetContext()->GetId(); - } - std::string frame_id; - if (dictionary->GetString("frameId", &frame_id)) { - frame_id_to_v8_execution_context_ids_[frame_id].insert( - params.GetContext()->GetId()); - } - } -} - -void TabSocketTest::ExpectJsException( - std::unique_ptr<runtime::EvaluateResult> result) { - EXPECT_TRUE(result->HasExceptionDetails()); - FinishAsynchronousTest(); -} - -void TabSocketTest::FailOnJsEvaluateException( - std::unique_ptr<runtime::EvaluateResult> result) { - if (!result->HasExceptionDetails()) - return; - - FinishAsynchronousTest(); - - const runtime::ExceptionDetails* exception_details = - result->GetExceptionDetails(); - FAIL() << exception_details->GetText() - << (exception_details->HasException() - ? exception_details->GetException()->GetDescription().c_str() - : ""); -} - -bool TabSocketTest::GetAllowTabSockets() { - return true; -} - -int TabSocketTest::GetV8ExecutionContextIdByWorldName(const std::string& name) { - const auto find_it = world_name_to_v8_execution_context_id_.find(name); - if (find_it == world_name_to_v8_execution_context_id_.end()) { - FinishAsynchronousTest(); - CHECK(false) << "Unknown isolated world: " << name; - return -1; - } - return find_it->second; -} - -const std::set<int>* TabSocketTest::GetV8ExecutionContextIdsForFrame( - const std::string& devtools_frame_id) const { - const auto find_it = - frame_id_to_v8_execution_context_ids_.find(devtools_frame_id); - if (find_it == frame_id_to_v8_execution_context_ids_.end()) - return nullptr; - return &find_it->second; -} - -void TabSocketTest::CreateMainWorldTabSocket( - std::string devtools_frame_id, - base::OnceCallback<void(int)> callback) { - const auto find_it = - frame_id_to_v8_execution_context_ids_.find(devtools_frame_id); - CHECK(find_it != frame_id_to_v8_execution_context_ids_.end()); - if (find_it->second.size() != 1u) { - FinishAsynchronousTest(); - FAIL() << "More than one v8 execution context exists for the main frame!"; - } - InstallHeadlessTabSocketBindings(std::move(callback), - *find_it->second.begin()); -} - -void TabSocketTest::CreateIsolatedWorldTabSocket( - std::string isolated_world_name, - std::string devtools_frame_id, - base::OnceCallback<void(int)> callback) { - devtools_client_->GetPage()->GetExperimental()->CreateIsolatedWorld( - page::CreateIsolatedWorldParams::Builder() - .SetFrameId(devtools_frame_id) - .SetWorldName(isolated_world_name) - .Build(), - base::BindOnce(&TabSocketTest::OnCreatedIsolatedWorld, - base::Unretained(this), std::move(callback))); -} - -void TabSocketTest::OnCreatedIsolatedWorld( - base::OnceCallback<void(int)> callback, - std::unique_ptr<page::CreateIsolatedWorldResult> result) { - InstallHeadlessTabSocketBindings(std::move(callback), - result->GetExecutionContextId()); -} - -void TabSocketTest::InstallHeadlessTabSocketBindings( - base::OnceCallback<void(int)> callback, - int execution_context_id) { - HeadlessTabSocket* tab_socket = web_contents_->GetHeadlessTabSocket(); - CHECK(tab_socket); - tab_socket->InstallHeadlessTabSocketBindings( - execution_context_id, - base::BindOnce(&TabSocketTest::OnInstalledHeadlessTabSocketBindings, - base::Unretained(this), execution_context_id, - std::move(callback))); -} - -void TabSocketTest::OnInstalledHeadlessTabSocketBindings( - int execution_context_id, - base::OnceCallback<void(int)> callback, - bool success) { - if (!success) { - FinishAsynchronousTest(); - CHECK(false) << "InstallHeadlessTabSocketBindings failed"; - } - std::move(callback).Run(execution_context_id); -} - -} // namespace headless
diff --git a/headless/test/tab_socket_test.h b/headless/test/tab_socket_test.h deleted file mode 100644 index e4065b7..0000000 --- a/headless/test/tab_socket_test.h +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef HEADLESS_TEST_TAB_SOCKET_TEST_H_ -#define HEADLESS_TEST_TAB_SOCKET_TEST_H_ - -#include "headless/public/devtools/domains/page.h" -#include "headless/public/devtools/domains/runtime.h" -#include "headless/public/headless_tab_socket.h" -#include "headless/test/headless_browser_test.h" - -namespace headless { - -class TabSocketTest : public HeadlessAsyncDevTooledBrowserTest, - public HeadlessTabSocket::Listener, - public page::Observer, - public runtime::Observer { - public: - TabSocketTest(); - ~TabSocketTest() override; - - // HeadlessAsyncDevTooledBrowserTest implementation: - void SetUp() override; - void RunDevTooledTest() override; - bool GetAllowTabSockets() override; - - // runtime::Observer implementation: - void OnExecutionContextCreated( - const runtime::ExecutionContextCreatedParams& params) override; - - void ExpectJsException(std::unique_ptr<runtime::EvaluateResult> result); - - void FailOnJsEvaluateException( - std::unique_ptr<runtime::EvaluateResult> result); - - // Note this will fail the test if an execution context corresponding to - // |name| doesn't exist. - int GetV8ExecutionContextIdByWorldName(const std::string& name); - - // Returns a pointer to the set of v8 execution context ids corresponding to - // |devtools_frame_id| or null if none exist. - const std::set<int>* GetV8ExecutionContextIdsForFrame( - const std::string& devtools_frame_id) const; - - // Attempts to install a main world TabSocket in |devtools_frame_id|. - // If successful |callback| will run with the execution context id of the - // main world tab socket. - void CreateMainWorldTabSocket(std::string devtools_frame_id, - base::OnceCallback<void(int)> callback); - - // Attempts to create an isolated world in |isolated_world_name| and then - // install a world TabSocket. If successful |callback| will run with the - // execution context id of the newly created isolated world as a parameter. - // Note |isolated_world_name| must be unique. - void CreateIsolatedWorldTabSocket(std::string isolated_world_name, - std::string devtools_frame_id, - base::OnceCallback<void(int)> callback); - - virtual void RunTabSocketTest() = 0; - - const std::string& main_frame_id() const { return *main_frame_id_; } - - private: - void OnPageEnabled(std::unique_ptr<page::EnableResult> result); - - void OnResourceTree(std::unique_ptr<page::GetResourceTreeResult> result); - - void CreateMainWorldTabSocketStep2(std::string devtools_frame_id, - base::OnceCallback<void(int)> callback, - int v8_execution_context_id); - - void OnCreatedIsolatedWorld( - base::OnceCallback<void(int)> callback, - std::unique_ptr<page::CreateIsolatedWorldResult> result); - - void InstallHeadlessTabSocketBindings(base::OnceCallback<void(int)> callback, - int execution_context_id); - - void OnInstalledHeadlessTabSocketBindings( - int execution_context_id, - base::OnceCallback<void(int)> callback, - bool success); - - std::map<std::string, int> world_name_to_v8_execution_context_id_; - std::map<std::string, std::set<int>> frame_id_to_v8_execution_context_ids_; - base::Optional<std::string> main_frame_id_; -}; - -} // namespace headless - -#endif // HEADLESS_TEST_TAB_SOCKET_TEST_H_
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg index 0f5a17dd9..9c90ef05 100644 --- a/infra/config/global/cr-buildbucket.cfg +++ b/infra/config/global/cr-buildbucket.cfg
@@ -134,6 +134,14 @@ } builder_mixins { + name: "android-gpu-ci" + dimensions: "os:Ubuntu-14.04" + recipe { + properties: "mastername:chromium.gpu" + } +} + +builder_mixins { name: "android-gpu-fyi-ci" dimensions: "os:Ubuntu-14.04" mixins: "gpu-fyi-ci" @@ -387,6 +395,14 @@ } } +builder_mixins { + name: "win-gpu-ci" + mixins: "win" + recipe { + properties: "mastername:chromium.gpu" + } +} + # GPU bots run very long tests sometimes on a single tester. The regular # timeout isn't enough on some testers during the migration when they run both # the buildbot and LUCI tests. Double the timeout for them. @@ -525,6 +541,11 @@ } builders { + name: "Android Release (Nexus 5X)" + mixins: "android-gpu-ci" + } + + builders { name: "Android Tests (trial)(dbg)" mixins: "android-fyi-ci" dimensions: "os:Ubuntu-14.04" @@ -713,11 +734,6 @@ } builders { - name: "GPU Linux Builder" - mixins: "linux-gpu-ci" - } - - builders { name: "Deterministic Linux" mixins: "linux-ci" recipe { @@ -763,11 +779,6 @@ } builders { - name: "Linux Release (NVIDIA)" - mixins: "linux-gpu-ci" - } - - builders { name: "Linux Tests" mixins: "linux-ci" } @@ -854,6 +865,28 @@ mixins: "memory-ci" } + # chromium.gpu + builders { + name: "GPU Linux Builder" + mixins: "linux-gpu-ci" + } + + builders { + name: "GPU Linux Builder (dbg)" + mixins: "linux-gpu-ci" + } + + builders { + name: "Linux Debug (NVIDIA)" + mixins: "linux-gpu-ci" + } + + builders { + name: "Linux Release (NVIDIA)" + mixins: "linux-gpu-ci" + } + + # chromium.gpu.fyi builders { name: "GPU FYI Linux Builder" mixins: "linux-gpu-fyi-ci" @@ -1133,6 +1166,26 @@ dimensions: "cpu:x86-64" dimensions: "cores:8" } + + # chromium.gpu + builders { + name: "GPU Win Builder" + mixins: "win-gpu-ci" + } + builders { + name: "GPU Win Builder (dbg)" + mixins: "win-gpu-ci" + } + builders { + name: "Win10 Debug (NVIDIA)" + mixins: "win-gpu-ci" + } + builders { + name: "Win10 Release (NVIDIA)" + mixins: "win-gpu-ci" + } + + # chromium.gpu.fyi builders { name: "GPU FYI Win Builder" mixins: "win-gpu-fyi-ci"
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg index 9d28ad6..08f8d5a1 100644 --- a/infra/config/global/luci-milo.cfg +++ b/infra/config/global/luci-milo.cfg
@@ -1617,83 +1617,73 @@ short_name: "bb" } builders { - name: "buildbucket/luci.chromium.ci/Android arm Builder (dbg)" - category: "android|builder|arm|debug|32" + name: "buildbucket/luci.chromium.ci/GPU Win Builder" + category: "gpu|win|release|builder" short_name: "ci" } builders { - name: "buildbot/chromium.android/Android arm Builder (dbg)" - category: "android|builder|arm|debug|32" + name: "buildbot/chromium.gpu/GPU Win Builder" + category: "gpu|win|release|builder" short_name: "bb" } builders { - name: "buildbucket/luci.chromium.ci/Android WebView L (dbg)" - category: "android|builder|arm|tester|32" + name: "buildbucket/luci.chromium.ci/GPU Win Builder (dbg)" + category: "gpu|win|debug|builder" short_name: "ci" } builders { - name: "buildbucket/luci.chromium.ci/Android WebView M (dbg)" - category: "android|builder|arm|tester|32" - short_name: "ci" - } - builders { - name: "buildbucket/luci.chromium.ci/KitKat Phone Tester (dbg)" - category: "android|builder|arm|tester|32" - short_name: "ci" - } - builders { - name: "buildbot/chromium.android/KitKat Phone Tester (dbg)" - category: "android|builder|arm|tester|32" + name: "buildbot/chromium.gpu/GPU Win Builder (dbg)" + category: "gpu|win|debug|builder" short_name: "bb" } builders { - name: "buildbucket/luci.chromium.ci/KitKat Tablet Tester" - category: "android|builder|arm|tester|32" + name: "buildbucket/luci.chromium.ci/Win10 Release (NVIDIA)" + category: "gpu|win|release|tester" short_name: "ci" } builders { - name: "buildbot/chromium.android/KitKat Tablet Tester" - category: "android|builder|arm|tester|32" + name: "buildbot/chromium.gpu/Win10 Release (NVIDIA)" + category: "gpu|win|release|tester" short_name: "bb" } builders { - name: "buildbucket/luci.chromium.ci/Lollipop Phone Tester" - category: "android|builder|arm|tester|32" + name: "buildbucket/luci.chromium.ci/Win10 Debug (NVIDIA)" + category: "gpu|win|debug|tester" short_name: "ci" } builders { - name: "buildbot/chromium.android/Lollipop Phone Tester" - category: "android|builder|arm|tester|32" + name: "buildbot/chromium.gpu/Win10 Debug (NVIDIA)" + category: "gpu|win|debug|tester" short_name: "bb" } builders { - name: "buildbucket/luci.chromium.ci/Lollipop Tablet Tester" - category: "android|builder|arm|tester|32" + name: "buildbucket/luci.chromium.ci/GPU Linux Builder (dbg)" + category: "gpu|linux|debug|builder" short_name: "ci" } builders { - name: "buildbot/chromium.android/Lollipop Tablet Tester" - category: "android|builder|arm|tester|32" + name: "buildbot/chromium.gpu/GPU Linux Builder (dbg)" + category: "gpu|linux|debug|builder" short_name: "bb" } builders { - name: "buildbucket/luci.chromium.ci/Marshmallow Tablet Tester" - category: "android|builder|arm|tester|32" + name: "buildbucket/luci.chromium.ci/Linux Debug (NVIDIA)" + category: "gpu|linux|debug|tester" short_name: "ci" } builders { - name: "buildbot/chromium.android/Marshmallow Tablet Tester" - category: "android|builder|arm|tester|32" + name: "buildbot/chromium.gpu/Linux Debug (NVIDIA)" + category: "gpu|linux|debug|tester" short_name: "bb" } builders { - name: "buildbucket/luci.chromium.ci/Lollipop Low-end Tester" - category: "android|builder|arm|tester|32" + name: "buildbucket/luci.chromium.ci/Android Release (Nexus 5X)" + category: "gpu|android|release" short_name: "ci" } builders { - name: "buildbot/chromium.android.fyi/Lollipop Low-end Tester" - category: "android|builder|arm|tester|32" + name: "buildbot/chromium.gpu/Android Release (Nexus 5X)" + category: "gpu|android|release" short_name: "bb" } include_experimental_builds: true @@ -1808,7 +1798,6 @@ short_name: "dbg" } builders { - name: "buildbot/chromium.android/Android arm Builder (dbg)" name: "buildbucket/luci.chromium.ci/Android arm Builder (dbg)" category: "builder|arm" short_name: "32" @@ -1839,13 +1828,11 @@ short_name: "dbg" } builders { - name: "buildbot/chromium.android/KitKat Phone Tester (dbg)" name: "buildbucket/luci.chromium.ci/KitKat Phone Tester (dbg)" category: "tester|phone" short_name: "K" } builders { - name: "buildbot/chromium.android/Lollipop Phone Tester" name: "buildbucket/luci.chromium.ci/Lollipop Phone Tester" category: "tester|phone" short_name: "L" @@ -1861,19 +1848,16 @@ short_name: "N" } builders { - name: "buildbot/chromium.android/KitKat Tablet Tester" name: "buildbucket/luci.chromium.ci/KitKat Tablet Tester" category: "tester|tablet" short_name: "K" } builders { - name: "buildbot/chromium.android/Lollipop Tablet Tester" name: "buildbucket/luci.chromium.ci/Lollipop Tablet Tester" category: "tester|tablet" short_name: "L" } builders { - name: "buildbot/chromium.android/Marshmallow Tablet Tester" name: "buildbucket/luci.chromium.ci/Marshmallow Tablet Tester" category: "tester|tablet" short_name: "M" @@ -2826,7 +2810,6 @@ category: "Mac" } builders { - name: "buildbot/chromium.gpu/GPU Linux Builder" name: "buildbucket/luci.chromium.ci/GPU Linux Builder" category: "Linux" } @@ -2841,7 +2824,6 @@ category: "Linux" } builders { - name: "buildbot/chromium.gpu/Linux Release (NVIDIA)" name: "buildbucket/luci.chromium.ci/Linux Release (NVIDIA)" category: "Linux" } @@ -4005,7 +3987,7 @@ name: "buildbot/tryserver.chromium.android/android_clang_dbg_recipe" } builders { - name: "buildbot/tryserver.chromium.android/android_compile_dbg" + name: "buildbucket/luci.chromium.try/android_compile_dbg" } builders { name: "buildbot/tryserver.chromium.android/android_compile_rel"
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg index bdc3035..28221dd 100644 --- a/infra/config/global/luci-scheduler.cfg +++ b/infra/config/global/luci-scheduler.cfg
@@ -67,6 +67,7 @@ triggers: "Android FYI Release (Nexus 6P)" triggers: "Android FYI Release (Nexus 9)" triggers: "Android FYI Release (NVIDIA Shield TV)" + triggers: "Android Release (Nexus 5X)" triggers: "Android x64 Builder (dbg)" triggers: "Android x86 Builder (dbg)" triggers: "android-kitkat-arm-rel" @@ -98,6 +99,7 @@ triggers: "GPU FYI Linux dEQP Builder" triggers: "GPU FYI Linux Ozone Builder" triggers: "GPU Linux Builder" + triggers: "GPU Linux Builder (dbg)" triggers: "Headless Linux (dbg)" triggers: "Leak Detection Linux" triggers: "linux-blink-heap-incremental-marking" @@ -133,6 +135,8 @@ triggers: "GPU FYI Win x64 Builder" triggers: "GPU FYI Win x64 Builder (dbg)" triggers: "GPU FYI Win x64 dEQP Builder" + triggers: "GPU Win Builder" + triggers: "GPU Win Builder (dbg)" triggers: "win-jumbo-rel" triggers: "Win Builder" triggers: "Win Builder (dbg)" @@ -297,6 +301,16 @@ } job { + id: "Android Release (Nexus 5X)" + acl_sets: "default" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Android Release (Nexus 5X)" + } +} + +job { id: "Android Tests (trial)(dbg)" # triggered by "Android arm Builder (dbg)" acl_sets: "triggered-by-parent-builders" @@ -855,6 +869,27 @@ } job { + id: "GPU Linux Builder (dbg)" + acl_sets: "default" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "GPU Linux Builder (dbg)" + } +} + +job { + id: "Linux Debug (NVIDIA)" + # Triggered by "GPU Linux Builder (dbg)". + acl_sets: "triggered-by-parent-builders" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Linux Debug (NVIDIA)" + } +} + +job { id: "Headless Linux (dbg)" acl_sets: "default" buildbucket: { @@ -1661,6 +1696,48 @@ } job { + id: "GPU Win Builder" + acl_sets: "default" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "GPU Win Builder" + } +} + +job { + id: "Win10 Release (NVIDIA)" + # Triggered by "GPU Win Builder" + acl_sets: "triggered-by-parent-builders" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Win10 Release (NVIDIA)" + } +} + +job { + id: "GPU Win Builder (dbg)" + acl_sets: "default" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "GPU Win Builder (dbg)" + } +} + +job { + id: "Win10 Debug (NVIDIA)" + # Triggered by "GPU Win Builder (dbg)" + acl_sets: "triggered-by-parent-builders" + buildbucket: { + server: "cr-buildbucket.appspot.com" + bucket: "luci.chromium.ci" + builder: "Win10 Debug (NVIDIA)" + } +} + +job { id: "Win Builder (dbg)" acl_sets: "default" buildbucket: {
diff --git a/mojo/public/tools/bindings/generators/mojom_js_generator.py b/mojo/public/tools/bindings/generators/mojom_js_generator.py index 724268d..e403df6 100644 --- a/mojo/public/tools/bindings/generators/mojom_js_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_js_generator.py
@@ -332,7 +332,9 @@ def _ClosureType(self, kind): if kind in mojom.PRIMITIVES: return _kind_to_closure_type[kind] - if (mojom.IsStructKind(kind) or mojom.IsInterfaceKind(kind) or + if mojom.IsInterfaceKind(kind): + return kind.module.namespace + "." + kind.name + "Ptr" + if (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)): return kind.module.namespace + "." + kind.name # TODO(calamity): Support unions properly.
diff --git a/net/data/ssl/certificates/README b/net/data/ssl/certificates/README index 65c3e681..85de448 100644 --- a/net/data/ssl/certificates/README +++ b/net/data/ssl/certificates/README
@@ -191,6 +191,11 @@ https://g.co/chrome/symantecpkicerts. (Note, however, that the leaf and root do not actually form a chain.) +- may_2018.pem + An 825-day certificate issued on May 1, 2018, the official start of + enforcement requiring Certificate Transparency for new certificates. This + certificate does not have any embedded SCTs. + - tls_feature_extension.pem A certificate that contains the TLS Feature Extension.
diff --git a/net/data/ssl/certificates/may_2018.pem b/net/data/ssl/certificates/may_2018.pem new file mode 100644 index 0000000..3b275fc --- /dev/null +++ b/net/data/ssl/certificates/may_2018.pem
@@ -0,0 +1,84 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 31 (0x1f) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=California, L=Mountain View, O=Test CA, CN=Test Root CA + Validity + Not Before: May 1 00:00:00 2018 GMT + Not After : Aug 3 00:00:00 2020 GMT + Subject: C=US, ST=California, L=Mountain View, O=Test CA, CN=127.0.0.1 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:dc:25:f0:b1:e7:f4:9a:33:24:c7:c7:55:bf:9f: + 06:3f:3d:61:ec:6e:38:21:04:87:7b:ea:c9:37:1d: + ad:61:46:3d:0f:43:54:ea:b0:01:45:a8:5f:fc:04: + 44:36:a5:0b:0e:53:49:ad:d4:de:70:b3:0e:9a:42: + 35:17:44:c8:7b:80:6e:a3:1b:3e:16:21:1d:b3:b5: + 08:89:97:ec:83:61:c6:a1:a5:6b:e7:f1:38:96:1b: + d1:db:2d:7e:93:90:3c:07:5b:77:6b:e0:18:63:f3: + ca:42:f1:97:7f:5b:44:9d:c1:65:34:cf:e8:4d:db: + b7:b2:8f:11:f9:0d:99:97:bd:56:24:22:aa:9a:02: + cb:93:e4:b2:55:bf:2d:82:2b:49:4f:2e:69:e2:e9: + a0:a5:18:95:f4:40:90:d7:90:34:cb:ad:a9:d8:a3: + 1b:3c:a9:d9:0b:00:60:6c:43:1f:42:82:07:f0:99: + 4b:d1:a6:66:7a:4e:69:3a:2f:c6:db:20:d0:58:80: + 90:c2:dc:70:ee:22:85:fb:59:bb:25:ba:12:1a:27: + 44:d6:f0:14:1a:71:f7:f9:fc:e5:3e:a5:7d:ad:e3: + 35:9b:c8:61:f5:13:e4:b6:58:e6:8f:46:1f:f4:18: + 69:76:78:eb:f9:ad:75:90:7c:69:dc:89:39:37:d7: + fc:2f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Subject Key Identifier: + FE:66:FC:2C:74:C7:2C:BB:9D:03:C1:68:2F:63:DC:AA:E7:7B:5F:F3 + X509v3 Authority Key Identifier: + keyid:9B:26:0B:8A:98:A9:BB:1D:B9:1F:1C:E3:1A:40:33:ED:8E:17:88:AB + + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 Subject Alternative Name: + IP Address:127.0.0.1 + Signature Algorithm: sha256WithRSAEncryption + 2a:c8:c1:eb:97:c0:a7:01:7e:36:67:9b:8d:fe:ce:7d:30:25: + 7c:63:9b:be:fd:b0:b8:1d:25:ef:bf:f8:3a:58:78:24:08:de: + 37:b9:a9:48:66:8e:b7:db:e3:57:49:7f:f4:09:64:72:45:83: + c2:d2:d7:0b:01:85:cc:4a:d9:1c:bc:0f:88:f2:2e:fa:e6:ee: + 3c:76:b3:f7:5d:ec:57:f1:23:be:54:18:b3:6f:95:56:c6:fe: + 29:ca:85:3f:4d:d8:d5:23:63:8f:fd:68:c0:54:d0:e0:7f:b3: + 2f:36:fb:3b:60:ec:5a:25:2a:88:0b:00:94:a5:c4:13:c6:d0: + da:a6:f2:de:00:aa:ac:11:32:c3:30:ae:52:75:86:91:e5:5c: + 6a:b3:22:8d:2f:31:91:34:d1:2f:e3:59:53:4a:95:b9:17:34: + e7:ab:15:9f:96:a0:61:e7:ad:a2:dc:ac:3b:71:65:3b:e5:a5: + 36:56:69:a3:ce:c5:fc:44:f6:28:85:72:7b:90:0e:c1:df:a5: + 36:0a:3b:d6:76:9c:1d:2c:b7:3f:9a:c0:95:93:e8:31:e7:e4: + 8b:07:67:06:20:44:56:be:a1:1f:9a:aa:24:53:93:3e:f2:0d: + e4:f4:16:47:68:c5:6d:f4:c1:a6:c0:92:97:75:4e:f4:49:77: + 08:24:5e:8a +-----BEGIN CERTIFICATE----- +MIIDvzCCAqegAwIBAgIBHzANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzET +MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G +A1UECgwHVGVzdCBDQTEVMBMGA1UEAwwMVGVzdCBSb290IENBMB4XDTE4MDUwMTAw +MDAwMFoXDTIwMDgwMzAwMDAwMFowYDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh +bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEDAOBgNVBAoMB1Rlc3Qg +Q0ExEjAQBgNVBAMMCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANwl8LHn9JozJMfHVb+fBj89YexuOCEEh3vqyTcdrWFGPQ9DVOqwAUWo +X/wERDalCw5TSa3U3nCzDppCNRdEyHuAbqMbPhYhHbO1CImX7INhxqGla+fxOJYb +0dstfpOQPAdbd2vgGGPzykLxl39bRJ3BZTTP6E3bt7KPEfkNmZe9ViQiqpoCy5Pk +slW/LYIrSU8uaeLpoKUYlfRAkNeQNMutqdijGzyp2QsAYGxDH0KCB/CZS9GmZnpO +aTovxtsg0FiAkMLccO4ihftZuyW6EhonRNbwFBpx9/n85T6lfa3jNZvIYfUT5LZY +5o9GH/QYaXZ46/mtdZB8adyJOTfX/C8CAwEAAaOBgDB+MAwGA1UdEwEB/wQCMAAw +HQYDVR0OBBYEFP5m/Cx0xyy7nQPBaC9j3Krne1/zMB8GA1UdIwQYMBaAFJsmC4qY +qbsduR8c4xpAM+2OF4irMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAP +BgNVHREECDAGhwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQAqyMHrl8CnAX42Z5uN +/s59MCV8Y5u+/bC4HSXvv/g6WHgkCN43ualIZo632+NXSX/0CWRyRYPC0tcLAYXM +StkcvA+I8i765u48drP3XexX8SO+VBizb5VWxv4pyoU/TdjVI2OP/WjAVNDgf7Mv +Nvs7YOxaJSqICwCUpcQTxtDapvLeAKqsETLDMK5SdYaR5VxqsyKNLzGRNNEv41lT +SpW5FzTnqxWflqBh562i3Kw7cWU75aU2VmmjzsX8RPYohXJ7kA7B36U2CjvWdpwd +LLc/msCVk+gx5+SLB2cGIERWvqEfmqokU5M+8g3k9BZHaMVt9MGmwJKXdU70SXcI +JF6K +-----END CERTIFICATE-----
diff --git a/net/data/ssl/scripts/generate-test-certs.sh b/net/data/ssl/scripts/generate-test-certs.sh index a4e309f..c5b4fe9 100755 --- a/net/data/ssl/scripts/generate-test-certs.sh +++ b/net/data/ssl/scripts/generate-test-certs.sh
@@ -528,6 +528,22 @@ -out ../certificates/dec_2017.pem \ -config ca.cnf +# Issued on 1 May 2018 (after the 30 Apr 2018 CT Requirement date) +openssl req \ + -config ../scripts/ee.cnf \ + -newkey rsa:2048 \ + -text \ + -out out/may_2018.req +CA_NAME="req_ca_dn" \ + openssl ca \ + -batch \ + -extensions user_cert \ + -startdate 180501000000Z \ + -enddate 200803000000Z \ + -in out/may_2018.req \ + -out ../certificates/may_2018.pem \ + -config ca.cnf + # Regenerate CRLSets ## Block a leaf cert directly by SPKI python crlsetutil.py -o ../certificates/crlset_by_leaf_spki.raw \
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc index 2d04890..0dff0ec 100644 --- a/net/nqe/network_quality_estimator.cc +++ b/net/nqe/network_quality_estimator.cc
@@ -1357,8 +1357,6 @@ nqe::internal::NetworkQuality network_quality = cached_network_quality.network_quality(); - const base::TimeTicks now = tick_clock_->NowTicks(); - bool update_network_quality_store = false; // Populate |network_quality| with synthetic RTT and throughput observations @@ -1387,25 +1385,25 @@ } if (update_network_quality_store) { - network_quality_store_->Add( - current_network_id_, - nqe::internal::CachedNetworkQuality(now, network_quality, - effective_connection_type)); + network_quality_store_->Add(current_network_id_, + nqe::internal::CachedNetworkQuality( + tick_clock_->NowTicks(), network_quality, + effective_connection_type)); } Observation http_rtt_observation( - network_quality.http_rtt().InMilliseconds(), now, INT32_MIN, - NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE); + network_quality.http_rtt().InMilliseconds(), tick_clock_->NowTicks(), + INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE); AddAndNotifyObserversOfRTT(http_rtt_observation); Observation transport_rtt_observation( - network_quality.transport_rtt().InMilliseconds(), now, INT32_MIN, - NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE); + network_quality.transport_rtt().InMilliseconds(), tick_clock_->NowTicks(), + INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_TRANSPORT_CACHED_ESTIMATE); AddAndNotifyObserversOfRTT(transport_rtt_observation); Observation througphput_observation( - network_quality.downstream_throughput_kbps(), now, INT32_MIN, - NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE); + network_quality.downstream_throughput_kbps(), tick_clock_->NowTicks(), + INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP_CACHED_ESTIMATE); AddAndNotifyObserversOfThroughput(througphput_observation); ComputeEffectiveConnectionType();
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc index 62f996ab..00b425eb 100644 --- a/services/network/cors/cors_url_loader.cc +++ b/services/network/cors/cors_url_loader.cc
@@ -81,7 +81,8 @@ const ResourceRequest& resource_request, mojom::URLLoaderClientPtr client, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, - mojom::URLLoaderFactory* network_loader_factory) + mojom::URLLoaderFactory* network_loader_factory, + const base::RepeatingCallback<void(int)>& preflight_finalizer) : network_loader_factory_(network_loader_factory), network_client_binding_(this), request_(resource_request), @@ -123,13 +124,19 @@ return; } + base::OnceCallback<void()> preflight_finalizer_for_request; + if (preflight_finalizer) { + preflight_finalizer_for_request = + base::BindOnce(preflight_finalizer, request_id); + } + PreflightController::GetDefaultController()->PerformPreflightCheck( base::BindOnce(&CORSURLLoader::StartNetworkRequest, weak_factory_.GetWeakPtr(), routing_id, request_id, options, traffic_annotation), request_id, request_, net::NetworkTrafficAnnotationTag(traffic_annotation), - network_loader_factory); + network_loader_factory, std::move(preflight_finalizer_for_request)); } CORSURLLoader::~CORSURLLoader() {}
diff --git a/services/network/cors/cors_url_loader.h b/services/network/cors/cors_url_loader.h index a3eee10f..00119620 100644 --- a/services/network/cors/cors_url_loader.h +++ b/services/network/cors/cors_url_loader.h
@@ -29,6 +29,8 @@ public mojom::URLLoaderClient { public: // Assumes network_loader_factory outlives this loader. + // TODO(yhirano): Remove |preflight_finalizer| when the network service is + // fully enabled. CORSURLLoader( int32_t routing_id, int32_t request_id, @@ -36,7 +38,8 @@ const ResourceRequest& resource_request, mojom::URLLoaderClientPtr client, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, - mojom::URLLoaderFactory* network_loader_factory); + mojom::URLLoaderFactory* network_loader_factory, + const base::RepeatingCallback<void(int)>& preflight_finalizer); ~CORSURLLoader() override;
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc index 14cbb44..c7c399f6 100644 --- a/services/network/cors/cors_url_loader_factory.cc +++ b/services/network/cors/cors_url_loader_factory.cc
@@ -15,6 +15,12 @@ std::unique_ptr<mojom::URLLoaderFactory> network_loader_factory) : network_loader_factory_(std::move(network_loader_factory)) {} +CORSURLLoaderFactory::CORSURLLoaderFactory( + std::unique_ptr<mojom::URLLoaderFactory> network_loader_factory, + const base::RepeatingCallback<void(int)>& preflight_finalizer) + : network_loader_factory_(std::move(network_loader_factory)), + preflight_finalizer_(preflight_finalizer) {} + CORSURLLoaderFactory::~CORSURLLoaderFactory() = default; void CORSURLLoaderFactory::CreateLoaderAndStart( @@ -27,10 +33,10 @@ const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { if (base::FeatureList::IsEnabled(features::kOutOfBlinkCORS)) { loader_bindings_.AddBinding( - std::make_unique<CORSURLLoader>(routing_id, request_id, options, - resource_request, std::move(client), - traffic_annotation, - network_loader_factory_.get()), + std::make_unique<CORSURLLoader>( + routing_id, request_id, options, resource_request, + std::move(client), traffic_annotation, + network_loader_factory_.get(), preflight_finalizer_), std::move(request)); } else { network_loader_factory_->CreateLoaderAndStart(
diff --git a/services/network/cors/cors_url_loader_factory.h b/services/network/cors/cors_url_loader_factory.h index 13f90e13..7fa3846 100644 --- a/services/network/cors/cors_url_loader_factory.h +++ b/services/network/cors/cors_url_loader_factory.h
@@ -7,6 +7,7 @@ #include <memory> +#include "base/callback_forward.h" #include "base/macros.h" #include "mojo/public/cpp/bindings/strong_binding_set.h" #include "net/traffic_annotation/network_traffic_annotation.h" @@ -27,6 +28,11 @@ public: explicit CORSURLLoaderFactory( std::unique_ptr<mojom::URLLoaderFactory> network_loader_factory); + // TODO(yhirano): Remove |preflight_finalizer| when the network service is + // fully enabled. + CORSURLLoaderFactory( + std::unique_ptr<mojom::URLLoaderFactory> network_loader_factory, + const base::RepeatingCallback<void(int)>& preflight_finalizer); ~CORSURLLoaderFactory() override; private: @@ -45,6 +51,8 @@ std::unique_ptr<mojom::URLLoaderFactory> network_loader_factory_; + base::RepeatingCallback<void(int)> preflight_finalizer_; + // The factory owns the CORSURLLoader it creates. mojo::StrongBindingSet<mojom::URLLoader> loader_bindings_;
diff --git a/services/network/cors/preflight_controller.cc b/services/network/cors/preflight_controller.cc index f161962..2394437 100644 --- a/services/network/cors/preflight_controller.cc +++ b/services/network/cors/preflight_controller.cc
@@ -225,10 +225,12 @@ PreflightLoader(PreflightController* controller, CompletionCallback completion_callback, const ResourceRequest& request, - const net::NetworkTrafficAnnotationTag& annotation_tag) + const net::NetworkTrafficAnnotationTag& annotation_tag, + base::OnceCallback<void()> preflight_finalizer) : controller_(controller), completion_callback_(std::move(completion_callback)), - original_request_(request) { + original_request_(request), + preflight_finalizer_(std::move(preflight_finalizer)) { loader_ = SimpleURLLoader::Create(CreatePreflightRequest(request), annotation_tag); } @@ -310,6 +312,8 @@ void FinalizeLoader() { DCHECK(loader_); + if (preflight_finalizer_) + std::move(preflight_finalizer_).Run(); loader_.reset(); } @@ -327,6 +331,11 @@ PreflightController::CompletionCallback completion_callback_; const ResourceRequest original_request_; + // This is needed because we sometimes need to cancel the preflight loader + // synchronously. + // TODO(yhirano): Remove this when the network service is fully enabled. + base::OnceCallback<void()> preflight_finalizer_; + DISALLOW_COPY_AND_ASSIGN(PreflightLoader); }; @@ -352,7 +361,8 @@ int32_t request_id, const ResourceRequest& request, const net::NetworkTrafficAnnotationTag& annotation_tag, - mojom::URLLoaderFactory* loader_factory) { + mojom::URLLoaderFactory* loader_factory, + base::OnceCallback<void()> preflight_finalizer) { DCHECK(request.request_initiator); if (!request.is_external_request && @@ -364,7 +374,8 @@ } auto emplaced_pair = loaders_.emplace(std::make_unique<PreflightLoader>( - this, std::move(callback), request, annotation_tag)); + this, std::move(callback), request, annotation_tag, + std::move(preflight_finalizer))); (*emplaced_pair.first)->Request(loader_factory, request_id); }
diff --git a/services/network/cors/preflight_controller.h b/services/network/cors/preflight_controller.h index b280625..eb8707b 100644 --- a/services/network/cors/preflight_controller.h +++ b/services/network/cors/preflight_controller.h
@@ -49,13 +49,21 @@ // Determines if a CORS-preflight request is needed, and checks the cache, or // makes a preflight request if it is needed. A result will be notified // synchronously or asynchronously. + // |request_id| and |preflight_finalizer| are needed when the Network Service + // is disabled, in such a case, we need to use the actual request's request + // ID for the preflight request (thus we need |request_id|) and we need to + // cancel the preflight request synchronously before starting the actual + // request (thus we need |preflight_finalizer|). // TODO(toyoshim): Remove |request_id| once the Network Service is enabled. + // TODO(yhirano): Remove |preflight_finalizer| once the Network Service is + // fully enabled. void PerformPreflightCheck( CompletionCallback callback, int32_t request_id, const ResourceRequest& resource_request, const net::NetworkTrafficAnnotationTag& traffic_annotation, - mojom::URLLoaderFactory* loader_factory); + mojom::URLLoaderFactory* loader_factory, + base::OnceCallback<void()> preflight_finalizer); private: class PreflightLoader;
diff --git a/services/network/cors/preflight_controller_unittest.cc b/services/network/cors/preflight_controller_unittest.cc index 777cf9f..43b7608 100644 --- a/services/network/cors/preflight_controller_unittest.cc +++ b/services/network/cors/preflight_controller_unittest.cc
@@ -163,13 +163,16 @@ base::BindOnce(&PreflightControllerTest::HandleRequestCompletion, base::Unretained(this)), 0 /* request_id */, request, TRAFFIC_ANNOTATION_FOR_TESTS, - url_loader_factory_ptr_.get()); + url_loader_factory_ptr_.get(), + base::BindOnce(&PreflightControllerTest::CancelPreflight, + base::Unretained(this))); run_loop_->Run(); } base::Optional<CORSErrorStatus> status() { return status_; } base::Optional<CORSErrorStatus> success() { return base::nullopt; } size_t access_count() { return access_count_; } + bool cancel_preflight_called() const { return cancel_preflight_called_; } private: void SetUp() override { @@ -207,6 +210,8 @@ return response; } + void CancelPreflight() { cancel_preflight_called_ = true; } + base::test::ScopedTaskEnvironment scoped_task_environment_; std::unique_ptr<base::RunLoop> run_loop_; @@ -216,6 +221,7 @@ net::test_server::EmbeddedTestServer test_server_; size_t access_count_ = 0; + bool cancel_preflight_called_ = false; std::unique_ptr<PreflightController> preflight_controller_; base::Optional<CORSErrorStatus> status_; @@ -246,6 +252,20 @@ EXPECT_EQ(1u, access_count()); // Should be from the preflight cache. } +// TODO(yhirano): Remove this test case when the network service is fully +// enabled. +TEST_F(PreflightControllerTest, CancelPreflightIsCalled) { + ResourceRequest request; + request.url = GetURL("/allow"); + request.request_initiator = url::Origin::Create(request.url); + + EXPECT_FALSE(cancel_preflight_called()); + PerformPreflightCheck(request); + ASSERT_FALSE(status()); + EXPECT_TRUE(cancel_preflight_called()); + EXPECT_EQ(1u, access_count()); +} + } // namespace } // namespace cors
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 7e24e6f..9ca169e8 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -18,7 +18,7 @@ #include "base/task_scheduler/task_traits.h" #include "build/build_config.h" #include "components/certificate_transparency/chrome_ct_policy_enforcer.h" -#include "components/certificate_transparency/ct_policy_manager.h" +#include "components/certificate_transparency/chrome_require_ct_delegate.h" #include "components/certificate_transparency/features.h" #include "components/certificate_transparency/sth_distributor.h" #include "components/certificate_transparency/sth_reporter.h" @@ -228,7 +228,7 @@ builder.get(), params_.get(), network_service->quic_disabled(), network_service->net_log(), network_service->network_quality_estimator(), network_service_->sth_reporter(), &ct_tree_tracker_, - &user_agent_settings_); + &require_ct_delegate_, &user_agent_settings_); url_request_context_ = url_request_context_owner_.url_request_context.get(); network_service_->RegisterNetworkContext(this); @@ -264,7 +264,8 @@ network_service_->DeregisterNetworkContext(this); if (url_request_context_ && - url_request_context_->transport_security_state()) { + url_request_context_->transport_security_state() && + require_ct_delegate_) { url_request_context_->transport_security_state()->SetRequireCTDelegate( nullptr); } @@ -524,13 +525,11 @@ const std::vector<std::string>& excluded_hosts, const std::vector<std::string>& excluded_spkis, const std::vector<std::string>& excluded_legacy_spkis) { - if (!ct_policy_manager_) { - ct_policy_manager_.reset(new certificate_transparency::CTPolicyManager()); - url_request_context_->transport_security_state()->SetRequireCTDelegate( - ct_policy_manager_->GetDelegate()); - } - ct_policy_manager_->UpdateCTPolicies(required_hosts, excluded_hosts, - excluded_spkis, excluded_legacy_spkis); + if (!require_ct_delegate_) + return; + + require_ct_delegate_->UpdateCTPolicies(required_hosts, excluded_hosts, + excluded_spkis, excluded_legacy_spkis); } void NetworkContext::CreateUDPSocket(mojom::UDPSocketRequest request, @@ -623,6 +622,8 @@ certificate_transparency::STHReporter* sth_reporter, std::unique_ptr<certificate_transparency::TreeStateTracker>* out_ct_tree_tracker, + std::unique_ptr<certificate_transparency::ChromeRequireCTDelegate>* + out_require_ct_delegate, net::StaticHttpUserAgentSettings** out_http_user_agent_settings) { if (net_log) builder->set_net_log(net_log); @@ -790,6 +791,14 @@ } #endif + if (out_require_ct_delegate && + network_context_params->enforce_chrome_ct_policy) { + *out_require_ct_delegate = + std::make_unique<certificate_transparency::ChromeRequireCTDelegate>(); + result.url_request_context->transport_security_state() + ->SetRequireCTDelegate(out_require_ct_delegate->get()); + } + return result; } @@ -908,7 +917,7 @@ network_service_ ? network_service_->network_quality_estimator() : nullptr, network_service_ ? network_service_->sth_reporter() : nullptr, - &ct_tree_tracker_, &user_agent_settings_); + &ct_tree_tracker_, &require_ct_delegate_, &user_agent_settings_); return result; }
diff --git a/services/network/network_context.h b/services/network/network_context.h index 779b2bebc..9ee4c51 100644 --- a/services/network/network_context.h +++ b/services/network/network_context.h
@@ -40,7 +40,7 @@ } // namespace net namespace certificate_transparency { -class CTPolicyManager; +class ChromeRequireCTDelegate; class TreeStateTracker; class STHReporter; } // namespace certificate_transparency @@ -200,6 +200,8 @@ certificate_transparency::STHReporter* sth_reporter, std::unique_ptr<certificate_transparency::TreeStateTracker>* out_tree_state_tracker, + std::unique_ptr<certificate_transparency::ChromeRequireCTDelegate>* + out_require_ct_delegate, net::StaticHttpUserAgentSettings** out_http_user_agent_settings); // Invoked when the HTTP cache was cleared. Invokes |callback|. @@ -254,7 +256,8 @@ // TODO(yhirano): Consult with switches::kDisableResourceScheduler. constexpr static bool enable_resource_scheduler_ = true; - std::unique_ptr<certificate_transparency::CTPolicyManager> ct_policy_manager_; + std::unique_ptr<certificate_transparency::ChromeRequireCTDelegate> + require_ct_delegate_; std::unique_ptr<certificate_transparency::TreeStateTracker> ct_tree_tracker_; DISALLOW_COPY_AND_ASSIGN(NetworkContext);
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 99d7a7f1..ed89f47 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -324,7 +324,10 @@ // Updates the Accept-Language header to be used for requests. SetAcceptLanguage(string new_accept_language); - // Updates the CT policy to be used for requests. + // Updates the CT policy to be used for requests. Only applies if the + // NetworkContextParams set enforce_chrome_ct_policy to true. + // TODO(rsleevi): Remove this once Chrome-specific policies are moved out + // of the network service. SetCTPolicy(array<string> required_hosts, array<string> excluded_hosts, array<string> excluded_spkis,
diff --git a/services/network/url_request_context_builder_mojo.cc b/services/network/url_request_context_builder_mojo.cc index a4e4c48..94187ad 100644 --- a/services/network/url_request_context_builder_mojo.cc +++ b/services/network/url_request_context_builder_mojo.cc
@@ -41,6 +41,7 @@ this, params, quic_disabled, net_log, network_quality_estimator, nullptr, /* sth_distributor */ nullptr, /* out_ct_tree_tracker */ + nullptr, /* out_require_ct_delegate */ nullptr /* out_static_user_agent_settings */); }
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 1658e5d..ec9071d 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -8098,6 +8098,19 @@ } ] }, + "test": "cros_vm_sanity_test" + }, + { + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "kvm": "1", + "os": "Ubuntu-14.04", + "pool": "Chrome-CrOS-VM" + } + ] + }, "test": "net_unittests" } ],
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 9f15556a..36ed932 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -483,6 +483,10 @@ "label": "//components/cronet/android:cronet_test_instrumentation_apk", "type": "additional_compile_target", }, + "cros_vm_sanity_test": { + "label": "//chromeos:cros_vm_sanity_test", + "type": "raw", + }, "crypto_unittests": { "label": "//crypto:crypto_unittests", "type": "console_test_launcher",
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 0112d7f..dc83b7d 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -371,6 +371,7 @@ 'chromeos_gtests_experimental': { 'base_unittests': {}, + 'cros_vm_sanity_test': {}, 'net_unittests': {}, },
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index d0aafe89..ca76fcf0 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -1388,6 +1388,7 @@ crbug.com/591099 fast/spatial-navigation/snav-fully-aligned-vertically.html [ Failure ] crbug.com/591099 fast/sub-pixel/computedstylemargin.html [ Failure ] crbug.com/591099 fast/sub-pixel/inline-block-with-padding.html [ Failure ] +crbug.com/708452 fast/sub-pixel/selection/selection-rect-in-sub-pixel-table.html [ Failure ] crbug.com/591099 fast/sub-pixel/sub-pixel-border-2.html [ Failure ] crbug.com/591099 fast/table/032.html [ Failure ] crbug.com/591099 fast/table/background-gradient-border-collapsed.html [ Failure ] @@ -1912,6 +1913,8 @@ crbug.com/591099 paint/selection/text-selection-drag-in-frame-scrolled.html [ Failure ] crbug.com/591099 paint/selection/text-selection-drag-in-frame.html [ Failure ] crbug.com/714962 paint/selection/text-selection-drag.html [ Failure ] +crbug.com/708452 paint/selection/text-selection-inline-block-rtl.html [ Failure ] +crbug.com/708452 paint/selection/text-selection-inline-block.html [ Failure ] crbug.com/591099 paint/selection/text-selection-newline-across-blocks-line-beginning-end.html [ Failure ] crbug.com/591099 paint/selection/text-selection-newline-across-blocks.html [ Failure ] crbug.com/591099 paint/selection/text-selection-newline-br.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index a64b13d1..b5f6f63 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1750,6 +1750,8 @@ # ====== IncrementalShadowDOM-only failures until here ====== +crbug.com/840238 http/tests/devtools/elements/shadow/shadow-distribution.js [ Failure ] + crbug.com/667560 [ Debug ] http/tests/devtools/elements/styles-3/styles-change-node-while-editing.js [ Pass Failure ] crbug.com/778515 http/tests/devtools/elements/styles-3/styles-add-new-rule.js [ Pass Failure ] @@ -2823,6 +2825,7 @@ crbug.com/832071 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/worker-client-id.https.html [ Failure ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Mac10.12 ] external/wpt/html/semantics/scripting-1/the-script-element/execution-timing/078.html [ Timeout ] crbug.com/626703 [ Mac10.13 ] external/wpt/pointerevents/pointerevent_touch-action-svg-test_touch-manual.html [ Skip ] crbug.com/626703 [ Retina ] external/wpt/pointerevents/pointerevent_touch-action-svg-test_touch-manual.html [ Skip ] crbug.com/626703 [ Win7 ] external/wpt/pointerevents/pointerevent_pointerout_received_once-manual.html [ Skip ] @@ -4690,6 +4693,7 @@ crbug.com/832842 [ Win7 ] virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Failure ] crbug.com/833655 [ Linux ] media/controls/closed-captions-dynamic-update.html [ Skip ] crbug.com/833655 [ Linux ] virtual/new-remote-playback-pipeline/media/controls/closed-captions-dynamic-update.html [ Skip ] +crbug.com/833655 [ Linux ] virtual/incremental-shadow-dom/media/controls/closed-captions-dynamic-update.html [ Skip ] crbug.com/833655 [ Linux ] virtual/video-surface-layer/media/controls/closed-captions-dynamic-update.html [ Skip ] crbug.com/833658 [ Linux Win Mac ] media/video-controls-focus-movement-on-hide.html [ Pass Failure ] crbug.com/833100 [ Mac ] external/wpt/battery-status/battery-full-manual.https.html [ Failure ] @@ -4711,12 +4715,9 @@ crbug.com/839332 [ Mac ] virtual/video-surface-layer/media/video-no-audio.html [ Pass Failure ] -# Sheriff 2018-05-14 -crbug.com/842793 [ Linux ] virtual/incremental-shadow-dom/media/controls/closed-captions-dynamic-update.html [ Pass Failure ] - # Sheriff 2018-05-17 crbug.com/840792 [ Mac10.12 Mac10.13 ] external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html [ Pass Timeout ] crbug.com/810437 fast/events/hr-timestamp/input-events.html [ Pass Timeout ] # This will break for now -crbug.com/841933 http/tests/webaudio/autoplay-crossorigin.html [ Skip ] \ No newline at end of file +crbug.com/841933 http/tests/webaudio/autoplay-crossorigin.html [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index dac1f6c..a6f9c8d4 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -108961,11 +108961,6 @@ {} ] ], - "css/css-backgrounds/resources/parsing-testcommon.js": [ - [ - {} - ] - ], "css/css-backgrounds/support/100x100-blue-and-orange.png": [ [ {} @@ -120216,7 +120211,7 @@ {} ] ], - "css/css-images/parsing/image-resolution-invalid-expected.txt": [ + "css/css-images/parsing/image-resolution-valid-expected.txt": [ [ {} ] @@ -160301,6 +160296,16 @@ {} ] ], + "server-timing/resources/blue_tao.png": [ + [ + {} + ] + ], + "server-timing/resources/blue_tao.png.sub.headers": [ + [ + {} + ] + ], "server-timing/resources/green.png": [ [ {} @@ -262558,7 +262563,7 @@ "testharness" ], "cookie-store/OWNERS": [ - "2118c49146d7ca543b37104c35c79aea5839de32", + "a99b955e85074ac568413a5cc12f675a01b2a431", "support" ], "cookie-store/README.md": [ @@ -280806,7 +280811,7 @@ "reftest" ], "css/css-backgrounds/box-shadow-syntax-001.html": [ - "90c15e29e3675b2dada46ea9d9d940fcb37c5b79", + "fcf77540a8d60885c814fedad81ce86e8b5255c9", "testharness" ], "css/css-backgrounds/box-shadow/box-shadow-blur-definition-001.xht": [ @@ -281090,7 +281095,7 @@ "testharness" ], "css/css-backgrounds/parsing/resources/parsing-testcommon.js": [ - "b5cc6f7c0c7729328bbbc45ec2a8147dae8d8668", + "14f32b772f27a9bc75fe90e2ea1d8e4fb3649e95", "support" ], "css/css-backgrounds/reference/60x60-green-background.html": [ @@ -281333,10 +281338,6 @@ "121d1dcc21d4fb64b984bf54456bbe40d10f5dd9", "support" ], - "css/css-backgrounds/resources/parsing-testcommon.js": [ - "b5cc6f7c0c7729328bbbc45ec2a8147dae8d8668", - "support" - ], "css/css-backgrounds/scroll-positioned-multiple-background-images.html": [ "2fafa8d282711ae7b4a996ca5fe0fd9079c350c6", "reftest" @@ -286502,11 +286503,11 @@ "support" ], "css/css-fonts/alternates-order-ref.html": [ - "5ca219e9f3b14418a44e771d6b00d487debe15af", + "9c5fe651a47243060ec7a30bc02cba7d85f853f2", "support" ], "css/css-fonts/alternates-order.html": [ - "9232ad7768f5bea41d87469113b210b3c663750e", + "104ef4541a76b22dc574fc1a0dfbcb0fc822ef88", "reftest" ], "css/css-fonts/calc-in-font-variation-settings.html": [ @@ -296305,14 +296306,14 @@ "ee2bd095839ad643e8e1fc4e9924d11ee8befc22", "testharness" ], - "css/css-images/parsing/image-resolution-invalid-expected.txt": [ - "5b3eb98fba42f93d7154afd9d1eb6ca3ed316179", - "support" - ], "css/css-images/parsing/image-resolution-invalid.html": [ "f48b7620d2e486815c51c616ddfa211739921dd4", "testharness" ], + "css/css-images/parsing/image-resolution-valid-expected.txt": [ + "e4e56177c6b1d1a945cc13ecbf03a5858065ef02", + "support" + ], "css/css-images/parsing/image-resolution-valid.html": [ "b5306320fe0ab963bfcd81874616d19866d9fea6", "testharness" @@ -296338,7 +296339,7 @@ "testharness" ], "css/css-images/parsing/resources/parsing-testcommon.js": [ - "b5cc6f7c0c7729328bbbc45ec2a8147dae8d8668", + "14f32b772f27a9bc75fe90e2ea1d8e4fb3649e95", "support" ], "css/css-images/support/1x1-green.gif": [ @@ -299422,7 +299423,7 @@ "testharness" ], "css/css-shapes/parsing/resources/parsing-testcommon.js": [ - "b5cc6f7c0c7729328bbbc45ec2a8147dae8d8668", + "14f32b772f27a9bc75fe90e2ea1d8e4fb3649e95", "support" ], "css/css-shapes/parsing/shape-image-threshold-invalid.html": [ @@ -308878,7 +308879,7 @@ "testharness" ], "css/css-transforms/parsing/resources/parsing-testcommon.js": [ - "b5cc6f7c0c7729328bbbc45ec2a8147dae8d8668", + "14f32b772f27a9bc75fe90e2ea1d8e4fb3649e95", "support" ], "css/css-transforms/parsing/rotate-parsing-invalid.html": [ @@ -316562,7 +316563,7 @@ "testharness" ], "css/css-ui/parsing/resources/parsing-testcommon.js": [ - "b5cc6f7c0c7729328bbbc45ec2a8147dae8d8668", + "14f32b772f27a9bc75fe90e2ea1d8e4fb3649e95", "support" ], "css/css-ui/parsing/text-overflow-invalid.html": [ @@ -325970,7 +325971,7 @@ "testharness" ], "css/motion/parsing/offset-path-parsing-valid-expected.txt": [ - "b5f9bc844990511e454dd8323793a9aa9282399b", + "dd8003dfba27d2c6b4b90621085ac4b9f1001ce5", "support" ], "css/motion/parsing/offset-path-parsing-valid.html": [ @@ -325994,7 +325995,7 @@ "testharness" ], "css/motion/parsing/resources/parsing-testcommon.js": [ - "bb1376de12185a14f77fd28be757cc8db2a9929d", + "14f32b772f27a9bc75fe90e2ea1d8e4fb3649e95", "support" ], "css/reference/black_box_ends_when_blue_box_ends_6_boxes_ahem.html": [ @@ -337126,7 +337127,7 @@ "testharness" ], "fetch/api/response/response-stream-disturbed-6.html": [ - "af3dcd2f8918b5c1365191490d127dcf2cc35cd9", + "f55b1c4a1fd57c227f52abddf002bbf5f76bc455", "testharness" ], "fetch/api/response/response-stream-with-broken-then.any.js": [ @@ -377806,7 +377807,7 @@ "support" ], "server-timing/cross_origin.html": [ - "661cf7f329590a89aa2644a102a10d1ba34feb75", + "e20e60bef34167b4608a837d0ddb311effa20773", "testharness" ], "server-timing/navigation_timing_idl.html": [ @@ -377833,6 +377834,14 @@ "549289fb534722e17eea4477638e8da59e043c13", "support" ], + "server-timing/resources/blue_tao.png": [ + "7de5cdb5ad04ac365430b3b5f5ba01d2ba57ea23", + "support" + ], + "server-timing/resources/blue_tao.png.sub.headers": [ + "b946f1d6581cf7a62aa01e0deda46cd04ef858c4", + "support" + ], "server-timing/resources/green.png": [ "ef91d21307a12b2cfaf33a90dffe16aa1cba42c9", "support" @@ -384322,7 +384331,7 @@ "support" ], "url/README.md": [ - "165b2a70da8bc2a7df3fe424a540f36b4f7be899", + "67bbc49a62ee08a94b7b55fff97e1160bf88bc33", "support" ], "url/a-element-origin-xhtml.xhtml": [ @@ -384358,7 +384367,7 @@ "testharness" ], "url/failure.html": [ - "908456e354703473b0806bbdac6d60216505905f", + "82c87b01a847f2821d1d71ea5e1c2ce8528f4deb", "testharness" ], "url/historical.any-expected.txt": [ @@ -384470,7 +384479,7 @@ "testharness" ], "url/urltestdata.json": [ - "59d1f7c678f29a70df885bdfbf9d491899f0038c", + "442c5f9d5faeb6752c8b33a04c73f3f3ba82ccb7", "support" ], "user-timing/OWNERS": [ @@ -388742,7 +388751,7 @@ "support" ], "webstorage/OWNERS": [ - "4e5fe0528ae51c9ac475c29195e1c473a5a01e1f", + "1efc045eed87783f0c6933f59d3dafa765b04ba9", "support" ], "webstorage/README.md": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/box-shadow-syntax-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/box-shadow-syntax-001.html index a66c3b60..e7c83b3ec2 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/box-shadow-syntax-001.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/box-shadow-syntax-001.html
@@ -5,7 +5,7 @@ <meta name="assert" content="Box shadow color, inset, and length parameters can be mixed in any order, but lengths must stay adjacent." /> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<script src="resources/parsing-testcommon.js"></script> +<script src="parsing/resources/parsing-testcommon.js"></script> <script> // color only test_valid_value("box-shadow", "4px 4px green", "green 4px 4px");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/parsing/resources/parsing-testcommon.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/parsing/resources/parsing-testcommon.js index 9427f53..b075882 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/parsing/resources/parsing-testcommon.js +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/parsing/resources/parsing-testcommon.js
@@ -12,18 +12,18 @@ test(function(){ var div = document.createElement('div'); div.style[property] = value; - assert_not_equals(div.style[property], "", "property should be set"); + assert_not_equals(div.style.getPropertyValue(property), "", "property should be set"); var div = document.createElement('div'); div.style[property] = value; - var readValue = div.style[property]; + var readValue = div.style.getPropertyValue(property); if (serializedValue instanceof Array) - assert_true(serializedValue.includes(readValue), "serialization should be sound"); + assert_in_array(readValue, serializedValue, "serialization should be sound"); else assert_equals(readValue, serializedValue, "serialization should be canonical"); div.style[property] = readValue; - assert_equals(div.style[property], readValue, "serialization should round-trip"); + assert_equals(div.style.getPropertyValue(property), readValue, "serialization should round-trip"); }, "e.style['" + property + "'] = " + stringifiedValue + " should set the property value"); } @@ -34,6 +34,6 @@ test(function(){ var div = document.createElement('div'); div.style[property] = value; - assert_equals(div.style[property], ""); + assert_equals(div.style.getPropertyValue(property), ""); }, "e.style['" + property + "'] = " + stringifiedValue + " should not set the property value"); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/resources/parsing-testcommon.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/resources/parsing-testcommon.js deleted file mode 100644 index 9427f53..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/resources/parsing-testcommon.js +++ /dev/null
@@ -1,39 +0,0 @@ -'use strict'; - -// serializedValue can be the expected serialization of value, -// or an array of permitted serializations, -// or omitted if value should serialize as value. -function test_valid_value(property, value, serializedValue) { - if (arguments.length < 3) - serializedValue = value; - - var stringifiedValue = JSON.stringify(value); - - test(function(){ - var div = document.createElement('div'); - div.style[property] = value; - assert_not_equals(div.style[property], "", "property should be set"); - - var div = document.createElement('div'); - div.style[property] = value; - var readValue = div.style[property]; - if (serializedValue instanceof Array) - assert_true(serializedValue.includes(readValue), "serialization should be sound"); - else - assert_equals(readValue, serializedValue, "serialization should be canonical"); - - div.style[property] = readValue; - assert_equals(div.style[property], readValue, "serialization should round-trip"); - - }, "e.style['" + property + "'] = " + stringifiedValue + " should set the property value"); -} - -function test_invalid_value(property, value) { - var stringifiedValue = JSON.stringify(value); - - test(function(){ - var div = document.createElement('div'); - div.style[property] = value; - assert_equals(div.style[property], ""); - }, "e.style['" + property + "'] = " + stringifiedValue + " should not set the property value"); -}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/alternates-order-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/alternates-order-ref.html index ed53a27..fdb477f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/alternates-order-ref.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/alternates-order-ref.html
@@ -19,6 +19,9 @@ font-feature-settings: "ss05"; /* crossed W */ } +/* tests that should NOT use the feature, due to case-sensitivity of font-feature-values names */ +#test2, #test3 { font-feature-settings: "ss05" off; } + </style> </head> <body lang="en">
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/alternates-order.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/alternates-order.html index e5310b3..d47cbce 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/alternates-order.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/alternates-order.html
@@ -65,13 +65,13 @@ } #test2 { - /* testing case-insensitivity of styleset name */ + /* testing case-sensitivity of styleset name */ font-family: fontB; font-variant-alternates: styleset(altW); } #test3 { - /* testing case-insensitivity of styleset name */ + /* testing case-sensitivity of styleset name */ font-family: fontB; font-variant-alternates: styleset(ALTW); } @@ -79,7 +79,7 @@ #test4 { /* testing escapes in styleset name */ font-family: fontB; - font-variant-alternates: styleset(\41 ltW); + font-variant-alternates: styleset(\41 lTw); } #test5 {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-images/parsing/image-resolution-invalid-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-images/parsing/image-resolution-invalid-expected.txt deleted file mode 100644 index e41d26f..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-images/parsing/image-resolution-invalid-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -FAIL e.style['image-resolution'] = "auto" should not set the property value assert_equals: expected "" but got "auto" -FAIL e.style['image-resolution'] = "100%" should not set the property value assert_equals: expected "" but got "100%" -FAIL e.style['image-resolution'] = "2" should not set the property value assert_equals: expected "" but got "2" -FAIL e.style['image-resolution'] = "3dpi snap from-image" should not set the property value assert_equals: expected "" but got "3dpi snap from-image" -FAIL e.style['image-resolution'] = "from-image snap 4dppx" should not set the property value assert_equals: expected "" but got "from-image snap 4dppx" -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-images/parsing/image-resolution-valid-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-images/parsing/image-resolution-valid-expected.txt new file mode 100644 index 0000000..feb98a4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-images/parsing/image-resolution-valid-expected.txt
@@ -0,0 +1,15 @@ +This is a testharness.js-based test. +FAIL e.style['image-resolution'] = "1dpi" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['image-resolution'] = "2dpcm from-image" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['image-resolution'] = "3dppx from-image snap" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['image-resolution'] = "4dpi snap" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['image-resolution'] = "from-image" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['image-resolution'] = "from-image 5dpcm" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['image-resolution'] = "from-image 6dppx snap" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['image-resolution'] = "from-image snap" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['image-resolution'] = "snap 7.5dpi" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['image-resolution'] = "snap -8dpcm from-image" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['image-resolution'] = "snap from-image" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['image-resolution'] = "snap from-image 0dppx" should set the property value assert_not_equals: property should be set got disallowed value "" +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-images/parsing/resources/parsing-testcommon.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-images/parsing/resources/parsing-testcommon.js index 9427f53..b075882 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-images/parsing/resources/parsing-testcommon.js +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-images/parsing/resources/parsing-testcommon.js
@@ -12,18 +12,18 @@ test(function(){ var div = document.createElement('div'); div.style[property] = value; - assert_not_equals(div.style[property], "", "property should be set"); + assert_not_equals(div.style.getPropertyValue(property), "", "property should be set"); var div = document.createElement('div'); div.style[property] = value; - var readValue = div.style[property]; + var readValue = div.style.getPropertyValue(property); if (serializedValue instanceof Array) - assert_true(serializedValue.includes(readValue), "serialization should be sound"); + assert_in_array(readValue, serializedValue, "serialization should be sound"); else assert_equals(readValue, serializedValue, "serialization should be canonical"); div.style[property] = readValue; - assert_equals(div.style[property], readValue, "serialization should round-trip"); + assert_equals(div.style.getPropertyValue(property), readValue, "serialization should round-trip"); }, "e.style['" + property + "'] = " + stringifiedValue + " should set the property value"); } @@ -34,6 +34,6 @@ test(function(){ var div = document.createElement('div'); div.style[property] = value; - assert_equals(div.style[property], ""); + assert_equals(div.style.getPropertyValue(property), ""); }, "e.style['" + property + "'] = " + stringifiedValue + " should not set the property value"); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-shapes/parsing/resources/parsing-testcommon.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-shapes/parsing/resources/parsing-testcommon.js index 9427f53..b075882 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-shapes/parsing/resources/parsing-testcommon.js +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-shapes/parsing/resources/parsing-testcommon.js
@@ -12,18 +12,18 @@ test(function(){ var div = document.createElement('div'); div.style[property] = value; - assert_not_equals(div.style[property], "", "property should be set"); + assert_not_equals(div.style.getPropertyValue(property), "", "property should be set"); var div = document.createElement('div'); div.style[property] = value; - var readValue = div.style[property]; + var readValue = div.style.getPropertyValue(property); if (serializedValue instanceof Array) - assert_true(serializedValue.includes(readValue), "serialization should be sound"); + assert_in_array(readValue, serializedValue, "serialization should be sound"); else assert_equals(readValue, serializedValue, "serialization should be canonical"); div.style[property] = readValue; - assert_equals(div.style[property], readValue, "serialization should round-trip"); + assert_equals(div.style.getPropertyValue(property), readValue, "serialization should round-trip"); }, "e.style['" + property + "'] = " + stringifiedValue + " should set the property value"); } @@ -34,6 +34,6 @@ test(function(){ var div = document.createElement('div'); div.style[property] = value; - assert_equals(div.style[property], ""); + assert_equals(div.style.getPropertyValue(property), ""); }, "e.style['" + property + "'] = " + stringifiedValue + " should not set the property value"); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-transforms/parsing/resources/parsing-testcommon.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-transforms/parsing/resources/parsing-testcommon.js index 9427f53..b075882 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-transforms/parsing/resources/parsing-testcommon.js +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-transforms/parsing/resources/parsing-testcommon.js
@@ -12,18 +12,18 @@ test(function(){ var div = document.createElement('div'); div.style[property] = value; - assert_not_equals(div.style[property], "", "property should be set"); + assert_not_equals(div.style.getPropertyValue(property), "", "property should be set"); var div = document.createElement('div'); div.style[property] = value; - var readValue = div.style[property]; + var readValue = div.style.getPropertyValue(property); if (serializedValue instanceof Array) - assert_true(serializedValue.includes(readValue), "serialization should be sound"); + assert_in_array(readValue, serializedValue, "serialization should be sound"); else assert_equals(readValue, serializedValue, "serialization should be canonical"); div.style[property] = readValue; - assert_equals(div.style[property], readValue, "serialization should round-trip"); + assert_equals(div.style.getPropertyValue(property), readValue, "serialization should round-trip"); }, "e.style['" + property + "'] = " + stringifiedValue + " should set the property value"); } @@ -34,6 +34,6 @@ test(function(){ var div = document.createElement('div'); div.style[property] = value; - assert_equals(div.style[property], ""); + assert_equals(div.style.getPropertyValue(property), ""); }, "e.style['" + property + "'] = " + stringifiedValue + " should not set the property value"); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resources/parsing-testcommon.js b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resources/parsing-testcommon.js index 9427f53..b075882 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resources/parsing-testcommon.js +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-ui/parsing/resources/parsing-testcommon.js
@@ -12,18 +12,18 @@ test(function(){ var div = document.createElement('div'); div.style[property] = value; - assert_not_equals(div.style[property], "", "property should be set"); + assert_not_equals(div.style.getPropertyValue(property), "", "property should be set"); var div = document.createElement('div'); div.style[property] = value; - var readValue = div.style[property]; + var readValue = div.style.getPropertyValue(property); if (serializedValue instanceof Array) - assert_true(serializedValue.includes(readValue), "serialization should be sound"); + assert_in_array(readValue, serializedValue, "serialization should be sound"); else assert_equals(readValue, serializedValue, "serialization should be canonical"); div.style[property] = readValue; - assert_equals(div.style[property], readValue, "serialization should round-trip"); + assert_equals(div.style.getPropertyValue(property), readValue, "serialization should round-trip"); }, "e.style['" + property + "'] = " + stringifiedValue + " should set the property value"); } @@ -34,6 +34,6 @@ test(function(){ var div = document.createElement('div'); div.style[property] = value; - assert_equals(div.style[property], ""); + assert_equals(div.style.getPropertyValue(property), ""); }, "e.style['" + property + "'] = " + stringifiedValue + " should not set the property value"); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/motion/parsing/offset-path-parsing-valid-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/motion/parsing/offset-path-parsing-valid-expected.txt index 2d0ddaa..bfae70a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/motion/parsing/offset-path-parsing-valid-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/css/motion/parsing/offset-path-parsing-valid-expected.txt
@@ -1,31 +1,17 @@ This is a testharness.js-based test. PASS e.style['offset-path'] = "none" should set the property value -PASS Serialization should round-trip after setting e.style['offset-path'] = "none" PASS e.style['offset-path'] = "ray(0rad closest-side)" should set the property value -PASS Serialization should round-trip after setting e.style['offset-path'] = "ray(0rad closest-side)" PASS e.style['offset-path'] = "ray(0.25turn closest-corner contain)" should set the property value -PASS Serialization should round-trip after setting e.style['offset-path'] = "ray(0.25turn closest-corner contain)" PASS e.style['offset-path'] = "ray(200grad farthest-side)" should set the property value -PASS Serialization should round-trip after setting e.style['offset-path'] = "ray(200grad farthest-side)" PASS e.style['offset-path'] = "ray(270deg farthest-corner contain)" should set the property value -PASS Serialization should round-trip after setting e.style['offset-path'] = "ray(270deg farthest-corner contain)" PASS e.style['offset-path'] = "ray(-720deg sides)" should set the property value -PASS Serialization should round-trip after setting e.style['offset-path'] = "ray(-720deg sides)" PASS e.style['offset-path'] = "ray(calc(180deg - 45deg) farthest-side)" should set the property value -PASS Serialization should round-trip after setting e.style['offset-path'] = "ray(calc(180deg - 45deg) farthest-side)" PASS e.style['offset-path'] = "path('m 0 0 h -100')" should set the property value -PASS Serialization should round-trip after setting e.style['offset-path'] = "path('m 0 0 h -100')" PASS e.style['offset-path'] = "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 300 300 Z')" should set the property value -PASS Serialization should round-trip after setting e.style['offset-path'] = "path('M 0 0 L 100 100 M 100 200 L 200 200 Z L 300 300 Z')" -FAIL e.style['offset-path'] = "url(\"http://www.example.com/index.html#polyline1\")" should set the property value assert_not_equals: got disallowed value "" -FAIL Serialization should round-trip after setting e.style['offset-path'] = "url(\"http://www.example.com/index.html#polyline1\")" assert_equals: expected "url(\"http://www.example.com/index.html#polyline1\")" but got "" -FAIL e.style['offset-path'] = "circle(100px)" should set the property value assert_not_equals: got disallowed value "" -FAIL Serialization should round-trip after setting e.style['offset-path'] = "circle(100px)" assert_equals: expected "circle(100px)" but got "" -FAIL e.style['offset-path'] = "margin-box" should set the property value assert_not_equals: got disallowed value "" -FAIL Serialization should round-trip after setting e.style['offset-path'] = "margin-box" assert_equals: expected "margin-box" but got "" -FAIL e.style['offset-path'] = "inset(10% 20% 30% 40%) border-box" should set the property value assert_not_equals: got disallowed value "" -FAIL Serialization should round-trip after setting e.style['offset-path'] = "inset(10% 20% 30% 40%) border-box" assert_equals: expected "inset(10% 20% 30% 40%) border-box" but got "" -FAIL e.style['offset-path'] = "fill-box ellipse(50% 60%)" should set the property value assert_not_equals: got disallowed value "" -FAIL Serialization should round-trip after setting e.style['offset-path'] = "fill-box ellipse(50% 60%)" assert_equals: expected "ellipse(50% 60%) fill-box" but got "" +FAIL e.style['offset-path'] = "url(\"http://www.example.com/index.html#polyline1\")" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['offset-path'] = "circle(100px)" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['offset-path'] = "margin-box" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['offset-path'] = "inset(10% 20% 30% 40%) border-box" should set the property value assert_not_equals: property should be set got disallowed value "" +FAIL e.style['offset-path'] = "fill-box ellipse(50% 60%)" should set the property value assert_not_equals: property should be set got disallowed value "" Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/motion/parsing/resources/parsing-testcommon.js b/third_party/WebKit/LayoutTests/external/wpt/css/motion/parsing/resources/parsing-testcommon.js index 688356b..b075882 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/motion/parsing/resources/parsing-testcommon.js +++ b/third_party/WebKit/LayoutTests/external/wpt/css/motion/parsing/resources/parsing-testcommon.js
@@ -1,5 +1,8 @@ 'use strict'; +// serializedValue can be the expected serialization of value, +// or an array of permitted serializations, +// or omitted if value should serialize as value. function test_valid_value(property, value, serializedValue) { if (arguments.length < 3) serializedValue = value; @@ -9,17 +12,20 @@ test(function(){ var div = document.createElement('div'); div.style[property] = value; - assert_not_equals(div.style[property], ""); - }, "e.style['" + property + "'] = " + stringifiedValue + " should set the property value"); + assert_not_equals(div.style.getPropertyValue(property), "", "property should be set"); - test(function(){ var div = document.createElement('div'); div.style[property] = value; - var readValue = div.style[property]; - assert_equals(readValue, serializedValue); + var readValue = div.style.getPropertyValue(property); + if (serializedValue instanceof Array) + assert_in_array(readValue, serializedValue, "serialization should be sound"); + else + assert_equals(readValue, serializedValue, "serialization should be canonical"); + div.style[property] = readValue; - assert_equals(div.style[property], readValue); - }, "Serialization should round-trip after setting e.style['" + property + "'] = " + stringifiedValue); + assert_equals(div.style.getPropertyValue(property), readValue, "serialization should round-trip"); + + }, "e.style['" + property + "'] = " + stringifiedValue + " should set the property value"); } function test_invalid_value(property, value) { @@ -28,6 +34,6 @@ test(function(){ var div = document.createElement('div'); div.style[property] = value; - assert_equals(div.style[property], ""); + assert_equals(div.style.getPropertyValue(property), ""); }, "e.style['" + property + "'] = " + stringifiedValue + " should not set the property value"); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/response/response-stream-disturbed-6.html b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/response/response-stream-disturbed-6.html index 15c8dfd..30492d4 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/response/response-stream-disturbed-6.html +++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/response/response-stream-disturbed-6.html
@@ -65,7 +65,7 @@ const reader = stream.getReader(); assert_false(response.bodyUsed, "After getting a reader"); - reader.read(); + reader.read().then(() => { }, () => { }); assert_true(response.bodyUsed, "After calling stream.read()"); }, "An errored stream on which read() has been called"); @@ -81,7 +81,7 @@ const reader = stream.getReader(); assert_false(response.bodyUsed, "After getting a reader"); - reader.cancel(); + reader.cancel().then(() => { }, () => { }); assert_true(response.bodyUsed, "After calling stream.cancel()"); }, "An errored stream on which cancel() has been called");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/cross_origin.html b/third_party/WebKit/LayoutTests/external/wpt/server-timing/cross_origin.html index f525103..94c502ee 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/cross_origin.html +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/cross_origin.html
@@ -9,10 +9,10 @@ setup({explicit_done: true}) const hostInfo = get_host_info() - const resourceUrl = 'server-timing/resources/blue.png' const urls = { - 'same-origin': `${hostInfo.HTTP_ORIGIN}/${resourceUrl}`, - 'cross-origin': `${hostInfo.HTTP_REMOTE_ORIGIN}/${resourceUrl}` + 'same-origin': `${hostInfo.HTTP_ORIGIN}/server-timing/resources/blue.png`, + 'cross-origin': `${hostInfo.HTTP_REMOTE_ORIGIN}/server-timing/resources/blue.png`, + 'cross-origin-tao': `${hostInfo.HTTP_REMOTE_ORIGIN}/server-timing/resources/blue_tao.png` } Object.keys(urls).forEach(function(key) { const img = document.createElement('img') @@ -28,6 +28,7 @@ } assertServerTimingEntries(urls['same-origin'], 1) assertServerTimingEntries(urls['cross-origin'], 0) + assertServerTimingEntries(urls['cross-origin-tao'], 1) done() }) </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/blue_tao.png b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/blue_tao.png new file mode 100644 index 0000000..4498dd2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/blue_tao.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/blue_tao.png.sub.headers b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/blue_tao.png.sub.headers new file mode 100644 index 0000000..3ca09d6a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/blue_tao.png.sub.headers
@@ -0,0 +1,2 @@ +Timing-Allow-Origin: * +Server-Timing: metric2; dur=2.1; desc=blue.png
diff --git a/third_party/WebKit/LayoutTests/external/wpt/url/README.md b/third_party/WebKit/LayoutTests/external/wpt/url/README.md index 4cb3c00..cc63177a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/url/README.md +++ b/third_party/WebKit/LayoutTests/external/wpt/url/README.md
@@ -1,10 +1,10 @@ These tests are for browsers, but the data for -`a-element.html`, `url-constructor.html`, and `a-element-xhtml.xhtml` +`a-element.html`, `url-constructor.html`, `a-element-xhtml.xhtml`, and `failure.html` is in `urltestdata.json` and can be re-used by non-browser implementations. This file contains a JSON array of comments as strings and test cases as objects. The keys for each test case are: -* `base`: an absolute URL as a string whose [parsing] without a base of its own should succeed. +* `base`: an absolute URL as a string whose [parsing] without a base of its own must succeed. This key is always present, and may have a value like `"about:blank"` when `input` is an absolute URL. * `input`: an URL as a string to be [parsed][parsing] with `base` as its base URL. @@ -19,5 +19,11 @@ The `origin` key may be missing. In that case, the API’s `origin` attribute is not tested. +In addition to testing that parsing `input` against `base` gives the result, a test harness for the +`URL` constructor (or similar APIs) should additionally test the following pattern: if `failure` is +true, parsing `about:blank` against `base` must give failure. This tests that the logic for +converting base URLs into strings properly fails the whole parsing algorithm if the base URL cannot +be parsed. + [parsing]: https://url.spec.whatwg.org/#concept-basic-url-parser [API]: https://url.spec.whatwg.org/#api
diff --git a/third_party/WebKit/LayoutTests/external/wpt/url/failure.html b/third_party/WebKit/LayoutTests/external/wpt/url/failure.html index d097d4e3..8ae9da7 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/url/failure.html +++ b/third_party/WebKit/LayoutTests/external/wpt/url/failure.html
@@ -16,7 +16,13 @@ const name = test.input + " should throw" - self.test(() => { // new URL itself is already tested by url-constructor.html + self.test(() => { // URL's constructor's first argument is tested by url-constructor.html + // If a URL fails to parse with any valid base, it must also fail to parse with no base, i.e. + // when used as a base URL itself. + assert_throws(new TypeError(), () => new URL("about:blank", test.input)); + }, "URL's constructor's base argument: " + name) + + self.test(() => { const url = new URL("about:blank") assert_throws(new TypeError, () => url.href = test.input) }, "URL's href: " + name)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/url/urltestdata.json b/third_party/WebKit/LayoutTests/external/wpt/url/urltestdata.json index 8670566..8c87da2b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/url/urltestdata.json +++ b/third_party/WebKit/LayoutTests/external/wpt/url/urltestdata.json
@@ -6521,28 +6521,35 @@ "search": "?a", "hash": "#%GH" }, - "Bad bases", + "URLs that require a non-about:blank base. (Also serve as invalid base tests.)", { - "input": "test-a.html", - "base": "a", + "input": "a", + "base": "about:blank", "failure": true }, { - "input": "test-a-slash.html", - "base": "a/", + "input": "a/", + "base": "about:blank", "failure": true }, { - "input": "test-a-slash-slash.html", - "base": "a//", + "input": "a//", + "base": "about:blank", "failure": true }, + "Bases that don't fail to parse but fail to be bases", { "input": "test-a-colon.html", "base": "a:", "failure": true }, { + "input": "test-a-colon-b.html", + "base": "a:b", + "failure": true + }, + "Other base URL tests, that must succeed", + { "input": "test-a-colon-slash.html", "base": "a:/", "href": "a:/test-a-colon-slash.html", @@ -6571,11 +6578,6 @@ "hash": "" }, { - "input": "test-a-colon-b.html", - "base": "a:b", - "failure": true - }, - { "input": "test-a-colon-slash-b.html", "base": "a:/b", "href": "a:/test-a-colon-slash-b.html",
diff --git a/third_party/WebKit/LayoutTests/external/wpt/worklets/resources/service-worker-interception-tests.js b/third_party/WebKit/LayoutTests/external/wpt/worklets/resources/service-worker-interception-tests.js index 310b26d..16d29873 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/worklets/resources/service-worker-interception-tests.js +++ b/third_party/WebKit/LayoutTests/external/wpt/worklets/resources/service-worker-interception-tests.js
@@ -120,6 +120,4 @@ }) .then(msg_event => assert_equals(msg_event.data, 'RESOLVED')); }, 'Static import should be intercepted by a service worker.'); - - // TODO(nhiroki): Add tests for dynamic import. }
diff --git a/third_party/WebKit/LayoutTests/http/tests/performance-timing/custom-user-timing/po-customusertiming-featuredetection.html b/third_party/WebKit/LayoutTests/http/tests/performance-timing/custom-user-timing/po-customusertiming-featuredetection.html index 66ff5a8..94c4681 100644 --- a/third_party/WebKit/LayoutTests/http/tests/performance-timing/custom-user-timing/po-customusertiming-featuredetection.html +++ b/third_party/WebKit/LayoutTests/http/tests/performance-timing/custom-user-timing/po-customusertiming-featuredetection.html
@@ -10,8 +10,15 @@ async_test(function (t) { self.performance.clearMeasures(); const measure = self.performance.measure("measure1", - { startTime: 12, endTime:23, detail: {info: 45 }}); + { startTime: 12, endTime:23 }); assert_equals(measure.startTime, 12); t.done(); }, "L3 measure API returns a measure object."); + + async_test(function (t) { + self.performance.clearMarks(); + const mark = self.performance.mark("mark1", { startTime: 34 }); + assert_equals(mark.startTime, 34); + t.done(); + }, "L3 mark API returns a mark object."); </script>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-expected.txt index 36a4506db..eb650196 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-expected.txt
@@ -513,13 +513,13 @@ PASS Parsing: <http://example.org/test?%GH> against <about:blank> PASS Parsing: <http://example.org/test?a#%EF> against <about:blank> PASS Parsing: <http://example.org/test?a#%GH> against <about:blank> -FAIL Parsing: <test-a.html> against <a> assert_unreached: Expected URL to fail parsing Reached unreachable code -FAIL Parsing: <test-a-slash.html> against <a/> assert_unreached: Expected URL to fail parsing Reached unreachable code -FAIL Parsing: <test-a-slash-slash.html> against <a//> assert_unreached: Expected URL to fail parsing Reached unreachable code +FAIL Parsing: <a> against <about:blank> assert_equals: failure should set href to input expected "a" but got "" +FAIL Parsing: <a/> against <about:blank> assert_equals: failure should set href to input expected "a/" but got "" +FAIL Parsing: <a//> against <about:blank> assert_equals: failure should set href to input expected "a//" but got "" FAIL Parsing: <test-a-colon.html> against <a:> assert_equals: failure should set href to input expected "test-a-colon.html" but got "" +FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_equals: failure should set href to input expected "test-a-colon-b.html" but got "" PASS Parsing: <test-a-colon-slash.html> against <a:/> FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> assert_equals: href expected "a:///test-a-colon-slash-slash.html" but got "" -FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_equals: failure should set href to input expected "test-a-colon-b.html" but got "" PASS Parsing: <test-a-colon-slash-b.html> against <a:/b> FAIL Parsing: <test-a-colon-slash-slash-b.html> against <a://b> assert_equals: href expected "a://b/test-a-colon-slash-slash-b.html" but got "a://b" PASS Parsing: <http://example.org/test?a#b\0c> against <about:blank>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-xhtml-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-xhtml-expected.txt index 36a4506db..eb650196 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-xhtml-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/a-element-xhtml-expected.txt
@@ -513,13 +513,13 @@ PASS Parsing: <http://example.org/test?%GH> against <about:blank> PASS Parsing: <http://example.org/test?a#%EF> against <about:blank> PASS Parsing: <http://example.org/test?a#%GH> against <about:blank> -FAIL Parsing: <test-a.html> against <a> assert_unreached: Expected URL to fail parsing Reached unreachable code -FAIL Parsing: <test-a-slash.html> against <a/> assert_unreached: Expected URL to fail parsing Reached unreachable code -FAIL Parsing: <test-a-slash-slash.html> against <a//> assert_unreached: Expected URL to fail parsing Reached unreachable code +FAIL Parsing: <a> against <about:blank> assert_equals: failure should set href to input expected "a" but got "" +FAIL Parsing: <a/> against <about:blank> assert_equals: failure should set href to input expected "a/" but got "" +FAIL Parsing: <a//> against <about:blank> assert_equals: failure should set href to input expected "a//" but got "" FAIL Parsing: <test-a-colon.html> against <a:> assert_equals: failure should set href to input expected "test-a-colon.html" but got "" +FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_equals: failure should set href to input expected "test-a-colon-b.html" but got "" PASS Parsing: <test-a-colon-slash.html> against <a:/> FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> assert_equals: href expected "a:///test-a-colon-slash-slash.html" but got "" -FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_equals: failure should set href to input expected "test-a-colon-b.html" but got "" PASS Parsing: <test-a-colon-slash-b.html> against <a:/b> FAIL Parsing: <test-a-colon-slash-slash-b.html> against <a://b> assert_equals: href expected "a://b/test-a-colon-slash-slash-b.html" but got "a://b" PASS Parsing: <http://example.org/test?a#b\0c> against <about:blank>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/failure-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/failure-expected.txt index 2ec1c09..8b80809 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/failure-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/failure-expected.txt
@@ -1,250 +1,317 @@ This is a testharness.js-based test. -Found 246 tests; 101 PASS, 145 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 313 tests; 142 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… +PASS URL's constructor's base argument: file://example:1/ should throw FAIL URL's href: file://example:1/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://example:1/ should throw PASS sendBeacon(): file://example:1/ should throw FAIL Location's href: file://example:1/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'file://example:1/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): file://example:1/ should throw +PASS URL's constructor's base argument: file://example:test/ should throw FAIL URL's href: file://example:test/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://example:test/ should throw PASS sendBeacon(): file://example:test/ should throw FAIL Location's href: file://example:test/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'file://example:test/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): file://example:test/ should throw +PASS URL's constructor's base argument: file://example%/ should throw FAIL URL's href: file://example%/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://example%/ should throw PASS sendBeacon(): file://example%/ should throw FAIL Location's href: file://example%/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'file://example%/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): file://example%/ should throw +PASS URL's constructor's base argument: file://[example]/ should throw FAIL URL's href: file://[example]/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://[example]/ should throw PASS sendBeacon(): file://[example]/ should throw FAIL Location's href: file://[example]/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'file://[example]/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): file://[example]/ should throw +PASS URL's constructor's base argument: http://user:pass@/ should throw FAIL URL's href: http://user:pass@/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://user:pass@/ should throw PASS sendBeacon(): http://user:pass@/ should throw FAIL Location's href: http://user:pass@/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://user:pass@/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://user:pass@/ should throw +PASS URL's constructor's base argument: http://foo:-80/ should throw FAIL URL's href: http://foo:-80/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://foo:-80/ should throw PASS sendBeacon(): http://foo:-80/ should throw FAIL Location's href: http://foo:-80/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://foo:-80/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://foo:-80/ should throw +PASS URL's constructor's base argument: http:/:@/www.example.com should throw FAIL URL's href: http:/:@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:/:@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:/:@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:/:@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:/:@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://user@/www.example.com should throw FAIL URL's href: http://user@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://user@/www.example.com should throw PASS sendBeacon(): http://user@/www.example.com should throw FAIL Location's href: http://user@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://user@/www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://user@/www.example.com should throw +PASS URL's constructor's base argument: http:@/www.example.com should throw FAIL URL's href: http:@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http:/@/www.example.com should throw FAIL URL's href: http:/@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:/@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:/@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:/@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:/@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://@/www.example.com should throw FAIL URL's href: http://@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://@/www.example.com should throw PASS sendBeacon(): http://@/www.example.com should throw FAIL Location's href: http://@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://@/www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://@/www.example.com should throw +PASS URL's constructor's base argument: https:@/www.example.com should throw FAIL URL's href: https:@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https:@/www.example.com should throw PASS sendBeacon(): https:@/www.example.com should throw FAIL Location's href: https:@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https:@/www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https:@/www.example.com should throw +PASS URL's constructor's base argument: http:a:b@/www.example.com should throw FAIL URL's href: http:a:b@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:a:b@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:a:b@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:a:b@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:a:b@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http:/a:b@/www.example.com should throw FAIL URL's href: http:/a:b@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:/a:b@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:/a:b@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:/a:b@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:/a:b@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://a:b@/www.example.com should throw FAIL URL's href: http://a:b@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://a:b@/www.example.com should throw PASS sendBeacon(): http://a:b@/www.example.com should throw FAIL Location's href: http://a:b@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a:b@/www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://a:b@/www.example.com should throw +PASS URL's constructor's base argument: http::@/www.example.com should throw FAIL URL's href: http::@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http::@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http::@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http::@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http::@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http:@:www.example.com should throw FAIL URL's href: http:@:www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:@:www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:@:www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:@:www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:@:www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http:/@:www.example.com should throw FAIL URL's href: http:/@:www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:/@:www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:/@:www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:/@:www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:/@:www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://@:www.example.com should throw FAIL URL's href: http://@:www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://@:www.example.com should throw PASS sendBeacon(): http://@:www.example.com should throw FAIL Location's href: http://@:www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://@:www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://@:www.example.com should throw +PASS URL's constructor's base argument: https://� should throw FAIL URL's href: https://� should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://� should throw PASS sendBeacon(): https://� should throw FAIL Location's href: https://� should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://�' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://� should throw +PASS URL's constructor's base argument: https://%EF%BF%BD should throw FAIL URL's href: https://%EF%BF%BD should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://%EF%BF%BD should throw PASS sendBeacon(): https://%EF%BF%BD should throw FAIL Location's href: https://%EF%BF%BD should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://%EF%BF%BD' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://%EF%BF%BD should throw +FAIL URL's constructor's base argument: https://x x:12 should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: https://x x:12 should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: https://x x:12 should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): https://x x:12 should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: https://x x:12 should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): https://x x:12 should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://[www.google.com]/ should throw FAIL URL's href: http://[www.google.com]/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://[www.google.com]/ should throw PASS sendBeacon(): http://[www.google.com]/ should throw FAIL Location's href: http://[www.google.com]/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://[www.google.com]/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://[www.google.com]/ should throw +FAIL URL's constructor's base argument: sc://\0/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://\0/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://\0/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://\0/ should throw FAIL Location's href: sc://\0/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://\0/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc:// / should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc:// / should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc:// / should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc:// / should throw FAIL Location's href: sc:// / should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc:// / should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://@/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://@/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://@/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://@/ should throw FAIL Location's href: sc://@/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://@/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://te@s:t@/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://te@s:t@/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://te@s:t@/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://te@s:t@/ should throw FAIL Location's href: sc://te@s:t@/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://te@s:t@/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://:/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://:/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://:/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://:/ should throw FAIL Location's href: sc://:/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://:/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://:12/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://:12/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://:12/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://:12/ should throw FAIL Location's href: sc://:12/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://:12/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://[/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://[/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://[/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://[/ should throw FAIL Location's href: sc://[/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://[/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://\/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://\/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://\/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://\/ should throw FAIL Location's href: sc://\/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://\/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://]/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://]/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://]/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://]/ should throw FAIL Location's href: sc://]/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://]/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: ftp://example.com%80/ should throw FAIL URL's href: ftp://example.com%80/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: ftp://example.com%80/ should throw PASS sendBeacon(): ftp://example.com%80/ should throw FAIL Location's href: ftp://example.com%80/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'ftp://example.com%80/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): ftp://example.com%80/ should throw +PASS URL's constructor's base argument: ftp://example.com%A0/ should throw FAIL URL's href: ftp://example.com%A0/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: ftp://example.com%A0/ should throw PASS sendBeacon(): ftp://example.com%A0/ should throw FAIL Location's href: ftp://example.com%A0/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'ftp://example.com%A0/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): ftp://example.com%A0/ should throw +PASS URL's constructor's base argument: https://example.com%80/ should throw FAIL URL's href: https://example.com%80/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://example.com%80/ should throw PASS sendBeacon(): https://example.com%80/ should throw FAIL Location's href: https://example.com%80/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://example.com%80/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://example.com%80/ should throw +PASS URL's constructor's base argument: https://example.com%A0/ should throw FAIL URL's href: https://example.com%A0/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://example.com%A0/ should throw PASS sendBeacon(): https://example.com%A0/ should throw FAIL Location's href: https://example.com%A0/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://example.com%A0/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://example.com%A0/ should throw +PASS URL's constructor's base argument: https://0x100000000/test should throw FAIL URL's href: https://0x100000000/test should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://0x100000000/test should throw PASS sendBeacon(): https://0x100000000/test should throw FAIL Location's href: https://0x100000000/test should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://0x100000000/test' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://0x100000000/test should throw +PASS URL's constructor's base argument: https://256.0.0.1/test should throw FAIL URL's href: https://256.0.0.1/test should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://256.0.0.1/test should throw PASS sendBeacon(): https://256.0.0.1/test should throw FAIL Location's href: https://256.0.0.1/test should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://256.0.0.1/test' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://256.0.0.1/test should throw +PASS URL's constructor's base argument: https://[0::0::0] should throw FAIL URL's href: https://[0::0::0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0::0::0] should throw PASS sendBeacon(): https://[0::0::0] should throw FAIL Location's href: https://[0::0::0] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0::0::0]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0::0::0] should throw +PASS URL's constructor's base argument: https://[0:.0] should throw FAIL URL's href: https://[0:.0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:.0] should throw PASS sendBeacon(): https://[0:.0] should throw FAIL Location's href: https://[0:.0] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:.0]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:.0] should throw +PASS URL's constructor's base argument: https://[0:0:] should throw FAIL URL's href: https://[0:0:] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:0:] should throw PASS sendBeacon(): https://[0:0:] should throw FAIL Location's href: https://[0:0:] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:0:]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:0:] should throw +PASS URL's constructor's base argument: https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw FAIL URL's href: https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw PASS sendBeacon(): https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw FAIL Location's href: https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:1:2:3:4:5:6:7.0.0.0.1]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw +PASS URL's constructor's base argument: https://[0:1.00.0.0.0] should throw FAIL URL's href: https://[0:1.00.0.0.0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:1.00.0.0.0] should throw PASS sendBeacon(): https://[0:1.00.0.0.0] should throw FAIL Location's href: https://[0:1.00.0.0.0] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:1.00.0.0.0]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:1.00.0.0.0] should throw +PASS URL's constructor's base argument: https://[0:1.290.0.0.0] should throw FAIL URL's href: https://[0:1.290.0.0.0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:1.290.0.0.0] should throw PASS sendBeacon(): https://[0:1.290.0.0.0] should throw FAIL Location's href: https://[0:1.290.0.0.0] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:1.290.0.0.0]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:1.290.0.0.0] should throw +PASS URL's constructor's base argument: https://[0:1.23.23] should throw FAIL URL's href: https://[0:1.23.23] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:1.23.23] should throw PASS sendBeacon(): https://[0:1.23.23] should throw FAIL Location's href: https://[0:1.23.23] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:1.23.23]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:1.23.23] should throw +PASS URL's constructor's base argument: http://? should throw FAIL URL's href: http://? should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://? should throw PASS sendBeacon(): http://? should throw FAIL Location's href: http://? should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://?' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://? should throw +PASS URL's constructor's base argument: http://# should throw FAIL URL's href: http://# should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://# should throw PASS sendBeacon(): http://# should throw FAIL Location's href: http://# should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://#' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://# should throw +FAIL URL's constructor's base argument: non-special://[:80/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: non-special://[:80/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: non-special://[:80/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): non-special://[:80/ should throw FAIL Location's href: non-special://[:80/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): non-special://[:80/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://[::127.0.0.0.1] should throw FAIL URL's href: http://[::127.0.0.0.1] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://[::127.0.0.0.1] should throw PASS sendBeacon(): http://[::127.0.0.0.1] should throw FAIL Location's href: http://[::127.0.0.0.1] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://[::127.0.0.0.1]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://[::127.0.0.0.1] should throw +PASS URL's constructor's base argument: a should throw +FAIL URL's href: a should throw assert_throws: function "() => url.href = test.input" did not throw +FAIL XHR: a should throw assert_throws: function "() => client.open("GET", test.input)" did not throw +FAIL sendBeacon(): a should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw +FAIL Location's href: a should throw assert_throws: function "() => self[0].location = test.input" did not throw +FAIL window.open(): a should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: a/ should throw +FAIL URL's href: a/ should throw assert_throws: function "() => url.href = test.input" did not throw +FAIL XHR: a/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw +FAIL sendBeacon(): a/ should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw +FAIL Location's href: a/ should throw assert_throws: function "() => self[0].location = test.input" did not throw +FAIL window.open(): a/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: a// should throw +FAIL URL's href: a// should throw assert_throws: function "() => url.href = test.input" did not throw +FAIL XHR: a// should throw assert_throws: function "() => client.open("GET", test.input)" did not throw +FAIL sendBeacon(): a// should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw +FAIL Location's href: a// should throw assert_throws: function "() => self[0].location = test.input" did not throw +FAIL window.open(): a// should throw assert_throws: function "() => self.open(test.input).close()" did not throw Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/url-constructor-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/url-constructor-expected.txt index 201e4a9..7e91ddd 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/url-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/url/url-constructor-expected.txt
@@ -559,13 +559,13 @@ PASS Parsing: <http://example.org/test?%GH> against <about:blank> PASS Parsing: <http://example.org/test?a#%EF> against <about:blank> PASS Parsing: <http://example.org/test?a#%GH> against <about:blank> -PASS Parsing: <test-a.html> against <a> -PASS Parsing: <test-a-slash.html> against <a/> -PASS Parsing: <test-a-slash-slash.html> against <a//> +PASS Parsing: <a> against <about:blank> +PASS Parsing: <a/> against <about:blank> +PASS Parsing: <a//> against <about:blank> PASS Parsing: <test-a-colon.html> against <a:> +PASS Parsing: <test-a-colon-b.html> against <a:b> PASS Parsing: <test-a-colon-slash.html> against <a:/> FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> Failed to construct 'URL': Invalid URL -PASS Parsing: <test-a-colon-b.html> against <a:b> PASS Parsing: <test-a-colon-slash-b.html> against <a:/b> FAIL Parsing: <test-a-colon-slash-slash-b.html> against <a://b> Failed to construct 'URL': Invalid URL PASS Parsing: <http://example.org/test?a#b\0c> against <about:blank>
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-expected.txt index 36a4506db..eb650196 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-expected.txt
@@ -513,13 +513,13 @@ PASS Parsing: <http://example.org/test?%GH> against <about:blank> PASS Parsing: <http://example.org/test?a#%EF> against <about:blank> PASS Parsing: <http://example.org/test?a#%GH> against <about:blank> -FAIL Parsing: <test-a.html> against <a> assert_unreached: Expected URL to fail parsing Reached unreachable code -FAIL Parsing: <test-a-slash.html> against <a/> assert_unreached: Expected URL to fail parsing Reached unreachable code -FAIL Parsing: <test-a-slash-slash.html> against <a//> assert_unreached: Expected URL to fail parsing Reached unreachable code +FAIL Parsing: <a> against <about:blank> assert_equals: failure should set href to input expected "a" but got "" +FAIL Parsing: <a/> against <about:blank> assert_equals: failure should set href to input expected "a/" but got "" +FAIL Parsing: <a//> against <about:blank> assert_equals: failure should set href to input expected "a//" but got "" FAIL Parsing: <test-a-colon.html> against <a:> assert_equals: failure should set href to input expected "test-a-colon.html" but got "" +FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_equals: failure should set href to input expected "test-a-colon-b.html" but got "" PASS Parsing: <test-a-colon-slash.html> against <a:/> FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> assert_equals: href expected "a:///test-a-colon-slash-slash.html" but got "" -FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_equals: failure should set href to input expected "test-a-colon-b.html" but got "" PASS Parsing: <test-a-colon-slash-b.html> against <a:/b> FAIL Parsing: <test-a-colon-slash-slash-b.html> against <a://b> assert_equals: href expected "a://b/test-a-colon-slash-slash-b.html" but got "a://b" PASS Parsing: <http://example.org/test?a#b\0c> against <about:blank>
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-xhtml-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-xhtml-expected.txt index 36a4506db..eb650196 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-xhtml-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/a-element-xhtml-expected.txt
@@ -513,13 +513,13 @@ PASS Parsing: <http://example.org/test?%GH> against <about:blank> PASS Parsing: <http://example.org/test?a#%EF> against <about:blank> PASS Parsing: <http://example.org/test?a#%GH> against <about:blank> -FAIL Parsing: <test-a.html> against <a> assert_unreached: Expected URL to fail parsing Reached unreachable code -FAIL Parsing: <test-a-slash.html> against <a/> assert_unreached: Expected URL to fail parsing Reached unreachable code -FAIL Parsing: <test-a-slash-slash.html> against <a//> assert_unreached: Expected URL to fail parsing Reached unreachable code +FAIL Parsing: <a> against <about:blank> assert_equals: failure should set href to input expected "a" but got "" +FAIL Parsing: <a/> against <about:blank> assert_equals: failure should set href to input expected "a/" but got "" +FAIL Parsing: <a//> against <about:blank> assert_equals: failure should set href to input expected "a//" but got "" FAIL Parsing: <test-a-colon.html> against <a:> assert_equals: failure should set href to input expected "test-a-colon.html" but got "" +FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_equals: failure should set href to input expected "test-a-colon-b.html" but got "" PASS Parsing: <test-a-colon-slash.html> against <a:/> FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> assert_equals: href expected "a:///test-a-colon-slash-slash.html" but got "" -FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_equals: failure should set href to input expected "test-a-colon-b.html" but got "" PASS Parsing: <test-a-colon-slash-b.html> against <a:/b> FAIL Parsing: <test-a-colon-slash-slash-b.html> against <a://b> assert_equals: href expected "a://b/test-a-colon-slash-slash-b.html" but got "a://b" PASS Parsing: <http://example.org/test?a#b\0c> against <about:blank>
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/failure-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/failure-expected.txt index 2ec1c09..8b80809 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/failure-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/failure-expected.txt
@@ -1,250 +1,317 @@ This is a testharness.js-based test. -Found 246 tests; 101 PASS, 145 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 313 tests; 142 PASS, 171 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… +PASS URL's constructor's base argument: file://example:1/ should throw FAIL URL's href: file://example:1/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://example:1/ should throw PASS sendBeacon(): file://example:1/ should throw FAIL Location's href: file://example:1/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'file://example:1/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): file://example:1/ should throw +PASS URL's constructor's base argument: file://example:test/ should throw FAIL URL's href: file://example:test/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://example:test/ should throw PASS sendBeacon(): file://example:test/ should throw FAIL Location's href: file://example:test/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'file://example:test/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): file://example:test/ should throw +PASS URL's constructor's base argument: file://example%/ should throw FAIL URL's href: file://example%/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://example%/ should throw PASS sendBeacon(): file://example%/ should throw FAIL Location's href: file://example%/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'file://example%/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): file://example%/ should throw +PASS URL's constructor's base argument: file://[example]/ should throw FAIL URL's href: file://[example]/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://[example]/ should throw PASS sendBeacon(): file://[example]/ should throw FAIL Location's href: file://[example]/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'file://[example]/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): file://[example]/ should throw +PASS URL's constructor's base argument: http://user:pass@/ should throw FAIL URL's href: http://user:pass@/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://user:pass@/ should throw PASS sendBeacon(): http://user:pass@/ should throw FAIL Location's href: http://user:pass@/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://user:pass@/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://user:pass@/ should throw +PASS URL's constructor's base argument: http://foo:-80/ should throw FAIL URL's href: http://foo:-80/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://foo:-80/ should throw PASS sendBeacon(): http://foo:-80/ should throw FAIL Location's href: http://foo:-80/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://foo:-80/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://foo:-80/ should throw +PASS URL's constructor's base argument: http:/:@/www.example.com should throw FAIL URL's href: http:/:@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:/:@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:/:@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:/:@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:/:@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://user@/www.example.com should throw FAIL URL's href: http://user@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://user@/www.example.com should throw PASS sendBeacon(): http://user@/www.example.com should throw FAIL Location's href: http://user@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://user@/www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://user@/www.example.com should throw +PASS URL's constructor's base argument: http:@/www.example.com should throw FAIL URL's href: http:@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http:/@/www.example.com should throw FAIL URL's href: http:/@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:/@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:/@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:/@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:/@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://@/www.example.com should throw FAIL URL's href: http://@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://@/www.example.com should throw PASS sendBeacon(): http://@/www.example.com should throw FAIL Location's href: http://@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://@/www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://@/www.example.com should throw +PASS URL's constructor's base argument: https:@/www.example.com should throw FAIL URL's href: https:@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https:@/www.example.com should throw PASS sendBeacon(): https:@/www.example.com should throw FAIL Location's href: https:@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https:@/www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https:@/www.example.com should throw +PASS URL's constructor's base argument: http:a:b@/www.example.com should throw FAIL URL's href: http:a:b@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:a:b@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:a:b@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:a:b@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:a:b@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http:/a:b@/www.example.com should throw FAIL URL's href: http:/a:b@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:/a:b@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:/a:b@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:/a:b@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:/a:b@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://a:b@/www.example.com should throw FAIL URL's href: http://a:b@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://a:b@/www.example.com should throw PASS sendBeacon(): http://a:b@/www.example.com should throw FAIL Location's href: http://a:b@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a:b@/www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://a:b@/www.example.com should throw +PASS URL's constructor's base argument: http::@/www.example.com should throw FAIL URL's href: http::@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http::@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http::@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http::@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http::@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http:@:www.example.com should throw FAIL URL's href: http:@:www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:@:www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:@:www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:@:www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:@:www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http:/@:www.example.com should throw FAIL URL's href: http:/@:www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:/@:www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:/@:www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:/@:www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:/@:www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://@:www.example.com should throw FAIL URL's href: http://@:www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://@:www.example.com should throw PASS sendBeacon(): http://@:www.example.com should throw FAIL Location's href: http://@:www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://@:www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://@:www.example.com should throw +PASS URL's constructor's base argument: https://� should throw FAIL URL's href: https://� should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://� should throw PASS sendBeacon(): https://� should throw FAIL Location's href: https://� should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://�' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://� should throw +PASS URL's constructor's base argument: https://%EF%BF%BD should throw FAIL URL's href: https://%EF%BF%BD should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://%EF%BF%BD should throw PASS sendBeacon(): https://%EF%BF%BD should throw FAIL Location's href: https://%EF%BF%BD should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://%EF%BF%BD' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://%EF%BF%BD should throw +FAIL URL's constructor's base argument: https://x x:12 should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: https://x x:12 should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: https://x x:12 should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): https://x x:12 should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: https://x x:12 should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): https://x x:12 should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://[www.google.com]/ should throw FAIL URL's href: http://[www.google.com]/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://[www.google.com]/ should throw PASS sendBeacon(): http://[www.google.com]/ should throw FAIL Location's href: http://[www.google.com]/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://[www.google.com]/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://[www.google.com]/ should throw +FAIL URL's constructor's base argument: sc://\0/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://\0/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://\0/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://\0/ should throw FAIL Location's href: sc://\0/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://\0/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc:// / should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc:// / should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc:// / should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc:// / should throw FAIL Location's href: sc:// / should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc:// / should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://@/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://@/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://@/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://@/ should throw FAIL Location's href: sc://@/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://@/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://te@s:t@/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://te@s:t@/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://te@s:t@/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://te@s:t@/ should throw FAIL Location's href: sc://te@s:t@/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://te@s:t@/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://:/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://:/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://:/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://:/ should throw FAIL Location's href: sc://:/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://:/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://:12/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://:12/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://:12/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://:12/ should throw FAIL Location's href: sc://:12/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://:12/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://[/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://[/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://[/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://[/ should throw FAIL Location's href: sc://[/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://[/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://\/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://\/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://\/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://\/ should throw FAIL Location's href: sc://\/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://\/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://]/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://]/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://]/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://]/ should throw FAIL Location's href: sc://]/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://]/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: ftp://example.com%80/ should throw FAIL URL's href: ftp://example.com%80/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: ftp://example.com%80/ should throw PASS sendBeacon(): ftp://example.com%80/ should throw FAIL Location's href: ftp://example.com%80/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'ftp://example.com%80/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): ftp://example.com%80/ should throw +PASS URL's constructor's base argument: ftp://example.com%A0/ should throw FAIL URL's href: ftp://example.com%A0/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: ftp://example.com%A0/ should throw PASS sendBeacon(): ftp://example.com%A0/ should throw FAIL Location's href: ftp://example.com%A0/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'ftp://example.com%A0/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): ftp://example.com%A0/ should throw +PASS URL's constructor's base argument: https://example.com%80/ should throw FAIL URL's href: https://example.com%80/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://example.com%80/ should throw PASS sendBeacon(): https://example.com%80/ should throw FAIL Location's href: https://example.com%80/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://example.com%80/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://example.com%80/ should throw +PASS URL's constructor's base argument: https://example.com%A0/ should throw FAIL URL's href: https://example.com%A0/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://example.com%A0/ should throw PASS sendBeacon(): https://example.com%A0/ should throw FAIL Location's href: https://example.com%A0/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://example.com%A0/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://example.com%A0/ should throw +PASS URL's constructor's base argument: https://0x100000000/test should throw FAIL URL's href: https://0x100000000/test should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://0x100000000/test should throw PASS sendBeacon(): https://0x100000000/test should throw FAIL Location's href: https://0x100000000/test should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://0x100000000/test' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://0x100000000/test should throw +PASS URL's constructor's base argument: https://256.0.0.1/test should throw FAIL URL's href: https://256.0.0.1/test should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://256.0.0.1/test should throw PASS sendBeacon(): https://256.0.0.1/test should throw FAIL Location's href: https://256.0.0.1/test should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://256.0.0.1/test' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://256.0.0.1/test should throw +PASS URL's constructor's base argument: https://[0::0::0] should throw FAIL URL's href: https://[0::0::0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0::0::0] should throw PASS sendBeacon(): https://[0::0::0] should throw FAIL Location's href: https://[0::0::0] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0::0::0]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0::0::0] should throw +PASS URL's constructor's base argument: https://[0:.0] should throw FAIL URL's href: https://[0:.0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:.0] should throw PASS sendBeacon(): https://[0:.0] should throw FAIL Location's href: https://[0:.0] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:.0]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:.0] should throw +PASS URL's constructor's base argument: https://[0:0:] should throw FAIL URL's href: https://[0:0:] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:0:] should throw PASS sendBeacon(): https://[0:0:] should throw FAIL Location's href: https://[0:0:] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:0:]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:0:] should throw +PASS URL's constructor's base argument: https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw FAIL URL's href: https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw PASS sendBeacon(): https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw FAIL Location's href: https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:1:2:3:4:5:6:7.0.0.0.1]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw +PASS URL's constructor's base argument: https://[0:1.00.0.0.0] should throw FAIL URL's href: https://[0:1.00.0.0.0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:1.00.0.0.0] should throw PASS sendBeacon(): https://[0:1.00.0.0.0] should throw FAIL Location's href: https://[0:1.00.0.0.0] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:1.00.0.0.0]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:1.00.0.0.0] should throw +PASS URL's constructor's base argument: https://[0:1.290.0.0.0] should throw FAIL URL's href: https://[0:1.290.0.0.0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:1.290.0.0.0] should throw PASS sendBeacon(): https://[0:1.290.0.0.0] should throw FAIL Location's href: https://[0:1.290.0.0.0] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:1.290.0.0.0]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:1.290.0.0.0] should throw +PASS URL's constructor's base argument: https://[0:1.23.23] should throw FAIL URL's href: https://[0:1.23.23] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:1.23.23] should throw PASS sendBeacon(): https://[0:1.23.23] should throw FAIL Location's href: https://[0:1.23.23] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:1.23.23]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:1.23.23] should throw +PASS URL's constructor's base argument: http://? should throw FAIL URL's href: http://? should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://? should throw PASS sendBeacon(): http://? should throw FAIL Location's href: http://? should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://?' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://? should throw +PASS URL's constructor's base argument: http://# should throw FAIL URL's href: http://# should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://# should throw PASS sendBeacon(): http://# should throw FAIL Location's href: http://# should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://#' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://# should throw +FAIL URL's constructor's base argument: non-special://[:80/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: non-special://[:80/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: non-special://[:80/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): non-special://[:80/ should throw FAIL Location's href: non-special://[:80/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): non-special://[:80/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://[::127.0.0.0.1] should throw FAIL URL's href: http://[::127.0.0.0.1] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://[::127.0.0.0.1] should throw PASS sendBeacon(): http://[::127.0.0.0.1] should throw FAIL Location's href: http://[::127.0.0.0.1] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://[::127.0.0.0.1]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://[::127.0.0.0.1] should throw +PASS URL's constructor's base argument: a should throw +FAIL URL's href: a should throw assert_throws: function "() => url.href = test.input" did not throw +FAIL XHR: a should throw assert_throws: function "() => client.open("GET", test.input)" did not throw +FAIL sendBeacon(): a should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw +FAIL Location's href: a should throw assert_throws: function "() => self[0].location = test.input" did not throw +FAIL window.open(): a should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: a/ should throw +FAIL URL's href: a/ should throw assert_throws: function "() => url.href = test.input" did not throw +FAIL XHR: a/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw +FAIL sendBeacon(): a/ should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw +FAIL Location's href: a/ should throw assert_throws: function "() => self[0].location = test.input" did not throw +FAIL window.open(): a/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: a// should throw +FAIL URL's href: a// should throw assert_throws: function "() => url.href = test.input" did not throw +FAIL XHR: a// should throw assert_throws: function "() => client.open("GET", test.input)" did not throw +FAIL sendBeacon(): a// should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw +FAIL Location's href: a// should throw assert_throws: function "() => self[0].location = test.input" did not throw +FAIL window.open(): a// should throw assert_throws: function "() => self.open(test.input).close()" did not throw Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/url-constructor-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/url-constructor-expected.txt index 201e4a9..7e91ddd 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/url-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/url/url-constructor-expected.txt
@@ -559,13 +559,13 @@ PASS Parsing: <http://example.org/test?%GH> against <about:blank> PASS Parsing: <http://example.org/test?a#%EF> against <about:blank> PASS Parsing: <http://example.org/test?a#%GH> against <about:blank> -PASS Parsing: <test-a.html> against <a> -PASS Parsing: <test-a-slash.html> against <a/> -PASS Parsing: <test-a-slash-slash.html> against <a//> +PASS Parsing: <a> against <about:blank> +PASS Parsing: <a/> against <about:blank> +PASS Parsing: <a//> against <about:blank> PASS Parsing: <test-a-colon.html> against <a:> +PASS Parsing: <test-a-colon-b.html> against <a:b> PASS Parsing: <test-a-colon-slash.html> against <a:/> FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> Failed to construct 'URL': Invalid URL -PASS Parsing: <test-a-colon-b.html> against <a:b> PASS Parsing: <test-a-colon-slash-b.html> against <a:/b> FAIL Parsing: <test-a-colon-slash-slash-b.html> against <a://b> Failed to construct 'URL': Invalid URL PASS Parsing: <http://example.org/test?a#b\0c> against <about:blank>
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-expected.txt index 49952f9..006c103 100644 --- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-expected.txt
@@ -513,13 +513,13 @@ PASS Parsing: <http://example.org/test?%GH> against <about:blank> PASS Parsing: <http://example.org/test?a#%EF> against <about:blank> PASS Parsing: <http://example.org/test?a#%GH> against <about:blank> -FAIL Parsing: <test-a.html> against <a> assert_unreached: Expected URL to fail parsing Reached unreachable code -FAIL Parsing: <test-a-slash.html> against <a/> assert_unreached: Expected URL to fail parsing Reached unreachable code -FAIL Parsing: <test-a-slash-slash.html> against <a//> assert_unreached: Expected URL to fail parsing Reached unreachable code +FAIL Parsing: <a> against <about:blank> assert_equals: failure should set href to input expected "a" but got "" +FAIL Parsing: <a/> against <about:blank> assert_equals: failure should set href to input expected "a/" but got "" +FAIL Parsing: <a//> against <about:blank> assert_equals: failure should set href to input expected "a//" but got "" FAIL Parsing: <test-a-colon.html> against <a:> assert_unreached: Expected URL to fail parsing Reached unreachable code +FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_unreached: Expected URL to fail parsing Reached unreachable code FAIL Parsing: <test-a-colon-slash.html> against <a:/> assert_equals: href expected "a:/test-a-colon-slash.html" but got "file:///A:/test-a-colon-slash.html" FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> assert_equals: href expected "a:///test-a-colon-slash-slash.html" but got "file:///A://test-a-colon-slash-slash.html" -FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_unreached: Expected URL to fail parsing Reached unreachable code FAIL Parsing: <test-a-colon-slash-b.html> against <a:/b> assert_equals: href expected "a:/test-a-colon-slash-b.html" but got "file:///A:/test-a-colon-slash-b.html" FAIL Parsing: <test-a-colon-slash-slash-b.html> against <a://b> assert_equals: href expected "a://b/test-a-colon-slash-slash-b.html" but got "file:///A://test-a-colon-slash-slash-b.html" PASS Parsing: <http://example.org/test?a#b\0c> against <about:blank>
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-xhtml-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-xhtml-expected.txt index 49952f9..006c103 100644 --- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-xhtml-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/a-element-xhtml-expected.txt
@@ -513,13 +513,13 @@ PASS Parsing: <http://example.org/test?%GH> against <about:blank> PASS Parsing: <http://example.org/test?a#%EF> against <about:blank> PASS Parsing: <http://example.org/test?a#%GH> against <about:blank> -FAIL Parsing: <test-a.html> against <a> assert_unreached: Expected URL to fail parsing Reached unreachable code -FAIL Parsing: <test-a-slash.html> against <a/> assert_unreached: Expected URL to fail parsing Reached unreachable code -FAIL Parsing: <test-a-slash-slash.html> against <a//> assert_unreached: Expected URL to fail parsing Reached unreachable code +FAIL Parsing: <a> against <about:blank> assert_equals: failure should set href to input expected "a" but got "" +FAIL Parsing: <a/> against <about:blank> assert_equals: failure should set href to input expected "a/" but got "" +FAIL Parsing: <a//> against <about:blank> assert_equals: failure should set href to input expected "a//" but got "" FAIL Parsing: <test-a-colon.html> against <a:> assert_unreached: Expected URL to fail parsing Reached unreachable code +FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_unreached: Expected URL to fail parsing Reached unreachable code FAIL Parsing: <test-a-colon-slash.html> against <a:/> assert_equals: href expected "a:/test-a-colon-slash.html" but got "file:///A:/test-a-colon-slash.html" FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> assert_equals: href expected "a:///test-a-colon-slash-slash.html" but got "file:///A://test-a-colon-slash-slash.html" -FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_unreached: Expected URL to fail parsing Reached unreachable code FAIL Parsing: <test-a-colon-slash-b.html> against <a:/b> assert_equals: href expected "a:/test-a-colon-slash-b.html" but got "file:///A:/test-a-colon-slash-b.html" FAIL Parsing: <test-a-colon-slash-slash-b.html> against <a://b> assert_equals: href expected "a://b/test-a-colon-slash-slash-b.html" but got "file:///A://test-a-colon-slash-slash-b.html" PASS Parsing: <http://example.org/test?a#b\0c> against <about:blank>
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/failure-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/failure-expected.txt index 4a0ed3e..ce03431 100644 --- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/failure-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/failure-expected.txt
@@ -1,250 +1,317 @@ This is a testharness.js-based test. -Found 246 tests; 102 PASS, 144 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 313 tests; 143 PASS, 170 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… +PASS URL's constructor's base argument: file://example:1/ should throw FAIL URL's href: file://example:1/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://example:1/ should throw PASS sendBeacon(): file://example:1/ should throw FAIL Location's href: file://example:1/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'file://example:1/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): file://example:1/ should throw +PASS URL's constructor's base argument: file://example:test/ should throw FAIL URL's href: file://example:test/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://example:test/ should throw PASS sendBeacon(): file://example:test/ should throw FAIL Location's href: file://example:test/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'file://example:test/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): file://example:test/ should throw +PASS URL's constructor's base argument: file://example%/ should throw FAIL URL's href: file://example%/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://example%/ should throw PASS sendBeacon(): file://example%/ should throw FAIL Location's href: file://example%/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'file://example%/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): file://example%/ should throw +PASS URL's constructor's base argument: file://[example]/ should throw FAIL URL's href: file://[example]/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: file://[example]/ should throw PASS sendBeacon(): file://[example]/ should throw FAIL Location's href: file://[example]/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'file://[example]/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): file://[example]/ should throw +PASS URL's constructor's base argument: http://user:pass@/ should throw FAIL URL's href: http://user:pass@/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://user:pass@/ should throw PASS sendBeacon(): http://user:pass@/ should throw FAIL Location's href: http://user:pass@/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://user:pass@/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://user:pass@/ should throw +PASS URL's constructor's base argument: http://foo:-80/ should throw FAIL URL's href: http://foo:-80/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://foo:-80/ should throw PASS sendBeacon(): http://foo:-80/ should throw FAIL Location's href: http://foo:-80/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://foo:-80/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://foo:-80/ should throw +PASS URL's constructor's base argument: http:/:@/www.example.com should throw FAIL URL's href: http:/:@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:/:@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:/:@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:/:@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:/:@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://user@/www.example.com should throw FAIL URL's href: http://user@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://user@/www.example.com should throw PASS sendBeacon(): http://user@/www.example.com should throw FAIL Location's href: http://user@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://user@/www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://user@/www.example.com should throw +PASS URL's constructor's base argument: http:@/www.example.com should throw FAIL URL's href: http:@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http:/@/www.example.com should throw FAIL URL's href: http:/@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:/@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:/@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:/@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:/@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://@/www.example.com should throw FAIL URL's href: http://@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://@/www.example.com should throw PASS sendBeacon(): http://@/www.example.com should throw FAIL Location's href: http://@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://@/www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://@/www.example.com should throw +PASS URL's constructor's base argument: https:@/www.example.com should throw FAIL URL's href: https:@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https:@/www.example.com should throw PASS sendBeacon(): https:@/www.example.com should throw FAIL Location's href: https:@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https:@/www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https:@/www.example.com should throw +PASS URL's constructor's base argument: http:a:b@/www.example.com should throw FAIL URL's href: http:a:b@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:a:b@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): http:a:b@/www.example.com should throw FAIL Location's href: http:a:b@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:a:b@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http:/a:b@/www.example.com should throw FAIL URL's href: http:/a:b@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:/a:b@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:/a:b@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:/a:b@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:/a:b@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://a:b@/www.example.com should throw FAIL URL's href: http://a:b@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://a:b@/www.example.com should throw PASS sendBeacon(): http://a:b@/www.example.com should throw FAIL Location's href: http://a:b@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://a:b@/www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://a:b@/www.example.com should throw +PASS URL's constructor's base argument: http::@/www.example.com should throw FAIL URL's href: http::@/www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http::@/www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http::@/www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http::@/www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http::@/www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http:@:www.example.com should throw FAIL URL's href: http:@:www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:@:www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:@:www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:@:www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:@:www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http:/@:www.example.com should throw FAIL URL's href: http:/@:www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: http:/@:www.example.com should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): http:/@:www.example.com should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: http:/@:www.example.com should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): http:/@:www.example.com should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://@:www.example.com should throw FAIL URL's href: http://@:www.example.com should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://@:www.example.com should throw PASS sendBeacon(): http://@:www.example.com should throw FAIL Location's href: http://@:www.example.com should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://@:www.example.com' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://@:www.example.com should throw +PASS URL's constructor's base argument: https://� should throw FAIL URL's href: https://� should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://� should throw PASS sendBeacon(): https://� should throw FAIL Location's href: https://� should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://�' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://� should throw +PASS URL's constructor's base argument: https://%EF%BF%BD should throw FAIL URL's href: https://%EF%BF%BD should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://%EF%BF%BD should throw PASS sendBeacon(): https://%EF%BF%BD should throw FAIL Location's href: https://%EF%BF%BD should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://%EF%BF%BD' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://%EF%BF%BD should throw +FAIL URL's constructor's base argument: https://x x:12 should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: https://x x:12 should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: https://x x:12 should throw assert_throws: function "() => client.open("GET", test.input)" did not throw FAIL sendBeacon(): https://x x:12 should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw FAIL Location's href: https://x x:12 should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): https://x x:12 should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://[www.google.com]/ should throw FAIL URL's href: http://[www.google.com]/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://[www.google.com]/ should throw PASS sendBeacon(): http://[www.google.com]/ should throw FAIL Location's href: http://[www.google.com]/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://[www.google.com]/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://[www.google.com]/ should throw +FAIL URL's constructor's base argument: sc://\0/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://\0/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://\0/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://\0/ should throw FAIL Location's href: sc://\0/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://\0/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc:// / should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc:// / should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc:// / should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc:// / should throw FAIL Location's href: sc:// / should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc:// / should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://@/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://@/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://@/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://@/ should throw FAIL Location's href: sc://@/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://@/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://te@s:t@/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://te@s:t@/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://te@s:t@/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://te@s:t@/ should throw FAIL Location's href: sc://te@s:t@/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://te@s:t@/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://:/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://:/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://:/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://:/ should throw FAIL Location's href: sc://:/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://:/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://:12/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://:12/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://:12/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://:12/ should throw FAIL Location's href: sc://:12/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://:12/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://[/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://[/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://[/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://[/ should throw FAIL Location's href: sc://[/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://[/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://\/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://\/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://\/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://\/ should throw FAIL Location's href: sc://\/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://\/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +FAIL URL's constructor's base argument: sc://]/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: sc://]/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: sc://]/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): sc://]/ should throw FAIL Location's href: sc://]/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): sc://]/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: ftp://example.com%80/ should throw FAIL URL's href: ftp://example.com%80/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: ftp://example.com%80/ should throw PASS sendBeacon(): ftp://example.com%80/ should throw FAIL Location's href: ftp://example.com%80/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'ftp://example.com%80/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): ftp://example.com%80/ should throw +PASS URL's constructor's base argument: ftp://example.com%A0/ should throw FAIL URL's href: ftp://example.com%A0/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: ftp://example.com%A0/ should throw PASS sendBeacon(): ftp://example.com%A0/ should throw FAIL Location's href: ftp://example.com%A0/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'ftp://example.com%A0/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): ftp://example.com%A0/ should throw +PASS URL's constructor's base argument: https://example.com%80/ should throw FAIL URL's href: https://example.com%80/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://example.com%80/ should throw PASS sendBeacon(): https://example.com%80/ should throw FAIL Location's href: https://example.com%80/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://example.com%80/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://example.com%80/ should throw +PASS URL's constructor's base argument: https://example.com%A0/ should throw FAIL URL's href: https://example.com%A0/ should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://example.com%A0/ should throw PASS sendBeacon(): https://example.com%A0/ should throw FAIL Location's href: https://example.com%A0/ should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://example.com%A0/' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://example.com%A0/ should throw +PASS URL's constructor's base argument: https://0x100000000/test should throw FAIL URL's href: https://0x100000000/test should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://0x100000000/test should throw PASS sendBeacon(): https://0x100000000/test should throw FAIL Location's href: https://0x100000000/test should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://0x100000000/test' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://0x100000000/test should throw +PASS URL's constructor's base argument: https://256.0.0.1/test should throw FAIL URL's href: https://256.0.0.1/test should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://256.0.0.1/test should throw PASS sendBeacon(): https://256.0.0.1/test should throw FAIL Location's href: https://256.0.0.1/test should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://256.0.0.1/test' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://256.0.0.1/test should throw +PASS URL's constructor's base argument: https://[0::0::0] should throw FAIL URL's href: https://[0::0::0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0::0::0] should throw PASS sendBeacon(): https://[0::0::0] should throw FAIL Location's href: https://[0::0::0] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0::0::0]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0::0::0] should throw +PASS URL's constructor's base argument: https://[0:.0] should throw FAIL URL's href: https://[0:.0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:.0] should throw PASS sendBeacon(): https://[0:.0] should throw FAIL Location's href: https://[0:.0] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:.0]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:.0] should throw +PASS URL's constructor's base argument: https://[0:0:] should throw FAIL URL's href: https://[0:0:] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:0:] should throw PASS sendBeacon(): https://[0:0:] should throw FAIL Location's href: https://[0:0:] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:0:]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:0:] should throw +PASS URL's constructor's base argument: https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw FAIL URL's href: https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw PASS sendBeacon(): https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw FAIL Location's href: https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:1:2:3:4:5:6:7.0.0.0.1]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:1:2:3:4:5:6:7.0.0.0.1] should throw +PASS URL's constructor's base argument: https://[0:1.00.0.0.0] should throw FAIL URL's href: https://[0:1.00.0.0.0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:1.00.0.0.0] should throw PASS sendBeacon(): https://[0:1.00.0.0.0] should throw FAIL Location's href: https://[0:1.00.0.0.0] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:1.00.0.0.0]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:1.00.0.0.0] should throw +PASS URL's constructor's base argument: https://[0:1.290.0.0.0] should throw FAIL URL's href: https://[0:1.290.0.0.0] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:1.290.0.0.0] should throw PASS sendBeacon(): https://[0:1.290.0.0.0] should throw FAIL Location's href: https://[0:1.290.0.0.0] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:1.290.0.0.0]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:1.290.0.0.0] should throw +PASS URL's constructor's base argument: https://[0:1.23.23] should throw FAIL URL's href: https://[0:1.23.23] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: https://[0:1.23.23] should throw PASS sendBeacon(): https://[0:1.23.23] should throw FAIL Location's href: https://[0:1.23.23] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'https://[0:1.23.23]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): https://[0:1.23.23] should throw +PASS URL's constructor's base argument: http://? should throw FAIL URL's href: http://? should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://? should throw PASS sendBeacon(): http://? should throw FAIL Location's href: http://? should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://?' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://? should throw +PASS URL's constructor's base argument: http://# should throw FAIL URL's href: http://# should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://# should throw PASS sendBeacon(): http://# should throw FAIL Location's href: http://# should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://#' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://# should throw +FAIL URL's constructor's base argument: non-special://[:80/ should throw assert_throws: function "() => new URL("about:blank", test.input)" did not throw FAIL URL's href: non-special://[:80/ should throw assert_throws: function "() => url.href = test.input" did not throw FAIL XHR: non-special://[:80/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw PASS sendBeacon(): non-special://[:80/ should throw FAIL Location's href: non-special://[:80/ should throw assert_throws: function "() => self[0].location = test.input" did not throw FAIL window.open(): non-special://[:80/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: http://[::127.0.0.0.1] should throw FAIL URL's href: http://[::127.0.0.0.1] should throw assert_throws: function "() => url.href = test.input" did not throw PASS XHR: http://[::127.0.0.0.1] should throw PASS sendBeacon(): http://[::127.0.0.0.1] should throw FAIL Location's href: http://[::127.0.0.0.1] should throw assert_throws: function "() => self[0].location = test.input" threw object "SyntaxError: Failed to set the 'href' property on 'Location': 'http://[::127.0.0.0.1]' is not a valid URL." ("SyntaxError") expected object "TypeError" ("TypeError") PASS window.open(): http://[::127.0.0.0.1] should throw +PASS URL's constructor's base argument: a should throw +FAIL URL's href: a should throw assert_throws: function "() => url.href = test.input" did not throw +FAIL XHR: a should throw assert_throws: function "() => client.open("GET", test.input)" did not throw +FAIL sendBeacon(): a should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw +FAIL Location's href: a should throw assert_throws: function "() => self[0].location = test.input" did not throw +FAIL window.open(): a should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: a/ should throw +FAIL URL's href: a/ should throw assert_throws: function "() => url.href = test.input" did not throw +FAIL XHR: a/ should throw assert_throws: function "() => client.open("GET", test.input)" did not throw +FAIL sendBeacon(): a/ should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw +FAIL Location's href: a/ should throw assert_throws: function "() => self[0].location = test.input" did not throw +FAIL window.open(): a/ should throw assert_throws: function "() => self.open(test.input).close()" did not throw +PASS URL's constructor's base argument: a// should throw +FAIL URL's href: a// should throw assert_throws: function "() => url.href = test.input" did not throw +FAIL XHR: a// should throw assert_throws: function "() => client.open("GET", test.input)" did not throw +FAIL sendBeacon(): a// should throw assert_throws: function "() => self.navigator.sendBeacon(test.input)" did not throw +FAIL Location's href: a// should throw assert_throws: function "() => self[0].location = test.input" did not throw +FAIL window.open(): a// should throw assert_throws: function "() => self.open(test.input).close()" did not throw Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/url-constructor-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/url-constructor-expected.txt index fb3734e..889525ee 100644 --- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/url-constructor-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/url/url-constructor-expected.txt
@@ -559,17 +559,17 @@ PASS Parsing: <http://example.org/test?%GH> against <about:blank> PASS Parsing: <http://example.org/test?a#%EF> against <about:blank> PASS Parsing: <http://example.org/test?a#%GH> against <about:blank> -PASS Parsing: <test-a.html> against <a> -PASS Parsing: <test-a-slash.html> against <a/> -PASS Parsing: <test-a-slash-slash.html> against <a//> +PASS Parsing: <a> against <about:blank> +PASS Parsing: <a/> against <about:blank> +PASS Parsing: <a//> against <about:blank> FAIL Parsing: <test-a-colon.html> against <a:> assert_throws: function "function() { bURL(expected.input, expected.base) }" did not throw +FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_throws: function "function() { + bURL(expected.input, expected.base) + }" did not throw FAIL Parsing: <test-a-colon-slash.html> against <a:/> assert_equals: href expected "a:/test-a-colon-slash.html" but got "file:///A:/test-a-colon-slash.html" FAIL Parsing: <test-a-colon-slash-slash.html> against <a://> assert_equals: href expected "a:///test-a-colon-slash-slash.html" but got "file:///A://test-a-colon-slash-slash.html" -FAIL Parsing: <test-a-colon-b.html> against <a:b> assert_throws: function "function() { - bURL(expected.input, expected.base) - }" did not throw FAIL Parsing: <test-a-colon-slash-b.html> against <a:/b> assert_equals: href expected "a:/test-a-colon-slash-b.html" but got "file:///A:/test-a-colon-slash-b.html" FAIL Parsing: <test-a-colon-slash-slash-b.html> against <a://b> assert_equals: href expected "a://b/test-a-colon-slash-slash-b.html" but got "file:///A://test-a-colon-slash-slash-b.html" PASS Parsing: <http://example.org/test?a#b\0c> against <about:blank>
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 9e62dca..1aa0a33 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -821,6 +821,7 @@ getter pushManager getter scope getter sync + getter updateViaCache getter waiting method constructor method getNotifications
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt index 787cdf3..c8aba4d 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -788,6 +788,7 @@ [Worker] getter pushManager [Worker] getter scope [Worker] getter sync +[Worker] getter updateViaCache [Worker] getter waiting [Worker] method constructor [Worker] method getNotifications
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt index 23d052d..8c758ffd 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -6067,6 +6067,7 @@ getter pushManager getter scope getter sync + getter updateViaCache getter waiting method constructor method getNotifications
diff --git a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt index 653b881..afc3a91 100644 --- a/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/stable/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -783,6 +783,7 @@ [Worker] getter pushManager [Worker] getter scope [Worker] getter sync +[Worker] getter updateViaCache [Worker] getter waiting [Worker] method constructor [Worker] method getNotifications
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 48c0839..f2aacce 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -51,11 +51,6 @@ } config("blink_headers_config") { - include_dirs = [ - "..", - "$root_gen_dir/third_party/blink", - ] - # Allow :blink_headers to include v8.h without linking to it. configs = [ "//v8:external_config" ] }
diff --git a/third_party/blink/renderer/BUILD.gn b/third_party/blink/renderer/BUILD.gn index 4b32bb2..2b61563 100644 --- a/third_party/blink/renderer/BUILD.gn +++ b/third_party/blink/renderer/BUILD.gn
@@ -77,13 +77,6 @@ # config ----------------------------------------------------------------------- config("config") { - include_dirs = [ - ".", - "..", - "$root_gen_dir/third_party/blink/renderer", - "$root_gen_dir/third_party/blink", - ] - cflags = [] defines = []
diff --git a/third_party/blink/renderer/bindings/scripts/aggregate_generated_bindings.py b/third_party/blink/renderer/bindings/scripts/aggregate_generated_bindings.py index 4065a30..c314fe6 100755 --- a/third_party/blink/renderer/bindings/scripts/aggregate_generated_bindings.py +++ b/third_party/blink/renderer/bindings/scripts/aggregate_generated_bindings.py
@@ -103,8 +103,8 @@ '#define NO_IMPLICIT_ATOMICSTRING\n\n'] basenames.sort() - output.extend('#include "bindings/%s/v8/v8_%s.cc"\n' % (component, to_snake_case(basename)) - for basename in basenames) + output.extend('#include "third_party/blink/renderer/bindings/%s/v8/v8_%s.cc"\n' % + (component, to_snake_case(basename)) for basename in basenames) return ''.join(output)
diff --git a/third_party/blink/renderer/bindings/scripts/code_generator.py b/third_party/blink/renderer/bindings/scripts/code_generator.py index 99639dea..df063fa 100644 --- a/third_party/blink/renderer/bindings/scripts/code_generator.py +++ b/third_party/blink/renderer/bindings/scripts/code_generator.py
@@ -108,14 +108,14 @@ _BLINK_RELATIVE_PATH_PREFIXES = ('bindings/', 'core/', 'modules/', 'platform/') def normalize_and_sort_includes(include_paths): - normalized_include_paths = [] + normalized_include_paths = set() for include_path in include_paths: match = re.search(r'/gen/(third_party/blink/.*)$', posixpath.abspath(include_path)) if match: include_path = match.group(1) elif include_path.startswith(_BLINK_RELATIVE_PATH_PREFIXES): include_path = 'third_party/blink/renderer/' + include_path - normalized_include_paths.append(include_path) + normalized_include_paths.add(include_path) return sorted(normalized_include_paths) @@ -150,24 +150,23 @@ IdlType.set_garbage_collected_types(interfaces_info['garbage_collected_interfaces']) set_component_dirs(interfaces_info['component_dirs']) - def render_template(self, include_paths, header_template, cpp_template, - template_context, component=None): - template_context['code_generator'] = self.generator_name + def render_templates(self, include_paths, header_template, cpp_template, + context, component=None): + context['code_generator'] = self.generator_name # Add includes for any dependencies - template_context['header_includes'] = normalize_and_sort_includes( - template_context['header_includes']) - for include_path in include_paths: if component: dependency = idl_filename_to_component(include_path) assert is_valid_component_dependency(component, dependency) includes.add(include_path) - template_context['cpp_includes'] = normalize_and_sort_includes(includes) + cpp_includes = set(context.get('cpp_includes', [])) + context['cpp_includes'] = normalize_and_sort_includes(cpp_includes | includes) + context['header_includes'] = normalize_and_sort_includes(context['header_includes']) - header_text = render_template(header_template, template_context) - cpp_text = render_template(cpp_template, template_context) + header_text = render_template(header_template, context) + cpp_text = render_template(cpp_template, context) return header_text, cpp_text def generate_code(self, definitions, definition_name):
diff --git a/third_party/blink/renderer/bindings/scripts/code_generator_v8.py b/third_party/blink/renderer/bindings/scripts/code_generator_v8.py index 434389d..5b343669 100644 --- a/third_party/blink/renderer/bindings/scripts/code_generator_v8.py +++ b/third_party/blink/renderer/bindings/scripts/code_generator_v8.py
@@ -48,7 +48,7 @@ import os import posixpath -from code_generator import CodeGeneratorBase, render_template, normalize_and_sort_includes +from code_generator import CodeGeneratorBase from idl_definitions import Visitor from idl_types import IdlType import v8_callback_function @@ -220,7 +220,7 @@ template_context['this_include_header_path'] = posixpath.basename(header_path) header_template = self.jinja_env.get_template(header_template_filename) cpp_template = self.jinja_env.get_template(cpp_template_filename) - header_text, cpp_text = self.render_template( + header_text, cpp_text = self.render_templates( include_paths, header_template, cpp_template, template_context, component) return ( @@ -245,7 +245,7 @@ template_context['exported'] = self.info_provider.specifier_for_export header_path, cpp_path = self.output_paths(dictionary_name) template_context['this_include_header_path'] = posixpath.basename(header_path) - header_text, cpp_text = self.render_template( + header_text, cpp_text = self.render_templates( include_paths, header_template, cpp_template, template_context) return ( (header_path, header_text), @@ -284,7 +284,7 @@ interface_info.get('additional_header_includes', [])) header_path, cpp_path = self.output_paths(definition_name, interface_info) template_context['this_include_header_path'] = posixpath.basename(header_path) - header_text, cpp_text = self.render_template( + header_text, cpp_text = self.render_templates( include_paths, header_template, cpp_template, template_context) return ( (header_path, header_text), @@ -310,6 +310,7 @@ self.typedefs[name] = typedef.idl_type def _generate_container_code(self, union_type): + includes.clear() union_type = union_type.resolve_typedefs(self.typedefs) header_template = self.jinja_env.get_template('union_container.h.tmpl') cpp_template = self.jinja_env.get_template('union_container.cpp.tmpl') @@ -317,18 +318,13 @@ union_type, self.info_provider) template_context['header_includes'].append( self.info_provider.include_path_for_export) - template_context['header_includes'] = normalize_and_sort_includes( - template_context['header_includes']) - template_context['cpp_includes'] = normalize_and_sort_includes( - template_context['cpp_includes']) - template_context['code_generator'] = self.generator_name template_context['exported'] = self.info_provider.specifier_for_export snake_base_name = to_snake_case(shorten_union_name(union_type)) template_context['this_include_header_path'] = snake_base_name + '.h' - header_text = render_template(header_template, template_context) - cpp_text = render_template(cpp_template, template_context) header_path = posixpath.join(self.output_dir, '%s.h' % snake_base_name) cpp_path = posixpath.join(self.output_dir, '%s.cc' % snake_base_name) + header_text, cpp_text = self.render_templates( + [], header_template, cpp_template, template_context) return ( (header_path, header_text), (cpp_path, cpp_text), @@ -385,13 +381,9 @@ template_context['header_includes'].append( self.info_provider.include_path_for_union_types(argument.idl_type)) - template_context['header_includes'] = normalize_and_sort_includes( - template_context['header_includes']) - template_context['cpp_includes'] = normalize_and_sort_includes( - template_context['cpp_includes']) template_context['code_generator'] = MODULE_PYNAME - header_text = render_template(header_template, template_context) - cpp_text = render_template(cpp_template, template_context) + header_text, cpp_text = self.render_templates( + [], header_template, cpp_template, template_context) snake_base_name = to_snake_case('V8%s' % callback_function.name) header_path = posixpath.join(self.output_dir, '%s.h' % snake_base_name) cpp_path = posixpath.join(self.output_dir, '%s.cc' % snake_base_name)
diff --git a/third_party/blink/renderer/bindings/scripts/generate_init_partial_interfaces.py b/third_party/blink/renderer/bindings/scripts/generate_init_partial_interfaces.py index d3f9f4a..dd1b8541 100755 --- a/third_party/blink/renderer/bindings/scripts/generate_init_partial_interfaces.py +++ b/third_party/blink/renderer/bindings/scripts/generate_init_partial_interfaces.py
@@ -93,7 +93,7 @@ for meta_data in meta_data_list] interface_names.sort() - includes = ['#include "bindings/modules/v8/%s.h"' % + includes = ['#include "third_party/blink/renderer/bindings/modules/v8/%s.h"' % build_basename(interface_name) for interface_name in interface_names] initialize_calls = [' %s::initialize();' % interface_name
diff --git a/third_party/blink/renderer/bindings/scripts/generate_v8_context_snapshot_external_references.py b/third_party/blink/renderer/bindings/scripts/generate_v8_context_snapshot_external_references.py index f2bbdf6..5eaa524 100644 --- a/third_party/blink/renderer/bindings/scripts/generate_v8_context_snapshot_external_references.py +++ b/third_party/blink/renderer/bindings/scripts/generate_v8_context_snapshot_external_references.py
@@ -19,14 +19,14 @@ INCLUDES = frozenset([ - 'bindings/core/v8/generated_code_helper.h', - 'bindings/core/v8/v8_html_document.h', - 'bindings/core/v8/v8_initializer.h', - 'bindings/core/v8/v8_window.h', - 'platform/bindings/dom_wrapper_world.h', - 'platform/bindings/v8_object_constructor.h', - 'platform/bindings/v8_per_isolate_data.h', - 'platform/bindings/v8_private_property.h', + 'third_party/blink/renderer/bindings/core/v8/generated_code_helper.h', + 'third_party/blink/renderer/bindings/core/v8/v8_html_document.h', + 'third_party/blink/renderer/bindings/core/v8/v8_initializer.h', + 'third_party/blink/renderer/bindings/core/v8/v8_window.h', + 'third_party/blink/renderer/platform/bindings/dom_wrapper_world.h', + 'third_party/blink/renderer/platform/bindings/v8_object_constructor.h', + 'third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h', + 'third_party/blink/renderer/platform/bindings/v8_private_property.h', 'v8/include/v8.h']) TEMPLATE_FILE = 'external_reference_table.cpp.tmpl' @@ -184,7 +184,8 @@ context = context_builder.create_interface_context(interface, interfaces) name = '%s%s' % (interface.name, 'Partial' if interface.is_partial else '') self._interface_contexts[name] = context - include_file = 'bindings/%s/v8/%s.h' % (component, utilities.to_snake_case(context['v8_name'])) + include_file = 'third_party/blink/renderer/bindings/%s/v8/%s.h' % ( + component, utilities.to_snake_case(context['v8_name'])) self._include_files.add(include_file) # Gathers all interface-dependent information and returns as a Jinja template context. @@ -192,7 +193,7 @@ interfaces = [] for name in sorted(self._interface_contexts): interfaces.append(self._interface_contexts[name]) - header_path = 'bindings/modules/v8/v8_context_snapshot_external_references.h' + header_path = 'third_party/blink/renderer/bindings/modules/v8/v8_context_snapshot_external_references.h' include_files = list(self._include_files) return { 'class': 'V8ContextSnapshotExternalReferences',
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index 13eb3dc6..ae1b1fa 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -41,10 +41,7 @@ } config("core_include_dirs") { - include_dirs = [ - "..", - "$root_gen_dir/third_party/blink/renderer", - ] + include_dirs = [] if (is_android && use_openmax_dl_fft) { include_dirs += [ "//third_party/openmax_dl" ] } @@ -1580,7 +1577,6 @@ ":core_include_dirs", "//tools/v8_context_snapshot:use_v8_context_snapshot", ] - include_dirs = [ "$root_gen_dir/third_party/blink/renderer" ] cflags = [] defines = []
diff --git a/third_party/blink/renderer/core/editing/frame_selection.h b/third_party/blink/renderer/core/editing/frame_selection.h index fd951d2..301e07e 100644 --- a/third_party/blink/renderer/core/editing/frame_selection.h +++ b/third_party/blink/renderer/core/editing/frame_selection.h
@@ -65,25 +65,33 @@ enum class HandleVisibility { kNotVisible, kVisible }; +enum class SelectLineBreak { kNotSelected, kSelected }; + // This is return type of ComputeLayoutSelectionStatus(paintfragment). // This structure represents how the fragment is selected. // |start|, |end| : Selection start/end offset. This offset is based on // the text of NGInlineNode of a parent block thus // |fragemnt.StartOffset <= start <= end <= fragment.EndOffset|. // |start| == |end| means this fragment is not selected. +// |line_break| : This value represents If this fragment is selected and +// selection wraps line break. struct LayoutSelectionStatus { STACK_ALLOCATED(); - LayoutSelectionStatus(unsigned passed_start, unsigned passed_end) - : start(passed_start), end(passed_end) { + LayoutSelectionStatus(unsigned passed_start, + unsigned passed_end, + SelectLineBreak passed_line_break) + : start(passed_start), end(passed_end), line_break(passed_line_break) { DCHECK_LE(start, end); } bool operator==(const LayoutSelectionStatus& other) const { - return start == other.start && end == other.end; + return start == other.start && end == other.end && + line_break == other.line_break; } unsigned start; unsigned end; + SelectLineBreak line_break; }; class CORE_EXPORT FrameSelection final
diff --git a/third_party/blink/renderer/core/editing/layout_selection.cc b/third_party/blink/renderer/core/editing/layout_selection.cc index e4a12e5..84892c4 100644 --- a/third_party/blink/renderer/core/editing/layout_selection.cc +++ b/third_party/blink/renderer/core/editing/layout_selection.cc
@@ -33,6 +33,7 @@ #include "third_party/blink/renderer/core/layout/layout_text_fragment.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h" +#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h" #include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" @@ -658,6 +659,26 @@ text_fragment.EndOffset()); } +static bool IsBeforeLineBreak(const NGPaintFragment& fragment) { + // TODO(yoichio): InlineBlock should not be container line box. + // See paint/selection/text-selection-inline-block.html. + const NGPaintFragment* container_line_box = fragment.ContainerLineBox(); + DCHECK(container_line_box); + const NGPhysicalLineBoxFragment& physical_line_box = + ToNGPhysicalLineBoxFragment(container_line_box->PhysicalFragment()); + const NGPhysicalFragment* last_leaf_not_linebreak = + physical_line_box.LastLogicalLeafIgnoringLineBreak(); + DCHECK(last_leaf_not_linebreak); + if (&fragment.PhysicalFragment() != last_leaf_not_linebreak) + return false; + // Even If |fragment| is before linebreak, if its direction differs to line + // direction, we don't paint line break. See + // paint/selection/text-selection-newline-mixed-ltr-rtl.html. + const ShapeResult* shape_result = + ToNGPhysicalTextFragment(fragment.PhysicalFragment()).TextShapeResult(); + return physical_line_box.BaseDirection() == shape_result->Direction(); +} + LayoutSelectionStatus LayoutSelection::ComputeSelectionStatus( const NGPaintFragment& fragment) const { const NGPhysicalTextFragment& text_fragment = @@ -670,31 +691,47 @@ switch (text_fragment.GetLayoutObject()->GetSelectionState()) { case SelectionState::kStart: { DCHECK(SelectionStart().has_value()); - unsigned start_in_block = SelectionStart().value_or(0); + const unsigned start_in_block = SelectionStart().value_or(0); + const bool is_continuous = start_in_block <= text_fragment.EndOffset(); return {ClampOffset(start_in_block, text_fragment), - text_fragment.EndOffset()}; + text_fragment.EndOffset(), + (is_continuous && IsBeforeLineBreak(fragment)) + ? SelectLineBreak::kSelected + : SelectLineBreak::kNotSelected}; } case SelectionState::kEnd: { DCHECK(SelectionEnd().has_value()); - unsigned end_in_block = + const unsigned end_in_block = SelectionEnd().value_or(text_fragment.EndOffset()); - return {text_fragment.StartOffset(), - ClampOffset(end_in_block, text_fragment)}; + const unsigned end_in_fragment = ClampOffset(end_in_block, text_fragment); + const bool is_continuous = text_fragment.EndOffset() < end_in_block; + return {text_fragment.StartOffset(), end_in_fragment, + (is_continuous && IsBeforeLineBreak(fragment)) + ? SelectLineBreak::kSelected + : SelectLineBreak::kNotSelected}; } case SelectionState::kStartAndEnd: { DCHECK(SelectionStart().has_value()); DCHECK(SelectionEnd().has_value()); - unsigned start_in_block = SelectionStart().value_or(0); - unsigned end_in_block = + const unsigned start_in_block = SelectionStart().value_or(0); + const unsigned end_in_block = SelectionEnd().value_or(text_fragment.EndOffset()); - return {ClampOffset(start_in_block, text_fragment), - ClampOffset(end_in_block, text_fragment)}; + const unsigned end_in_fragment = ClampOffset(end_in_block, text_fragment); + const bool is_continuous = start_in_block <= text_fragment.EndOffset() && + text_fragment.EndOffset() < end_in_block; + return {ClampOffset(start_in_block, text_fragment), end_in_fragment, + (is_continuous && IsBeforeLineBreak(fragment)) + ? SelectLineBreak::kSelected + : SelectLineBreak::kNotSelected}; } - case SelectionState::kInside: - return {text_fragment.StartOffset(), text_fragment.EndOffset()}; + case SelectionState::kInside: { + return {text_fragment.StartOffset(), text_fragment.EndOffset(), + IsBeforeLineBreak(fragment) ? SelectLineBreak::kSelected + : SelectLineBreak::kNotSelected}; + } default: // This block is not included in selection. - return {0, 0}; + return {0, 0, SelectLineBreak::kNotSelected}; } }
diff --git a/third_party/blink/renderer/core/editing/layout_selection_test.cc b/third_party/blink/renderer/core/editing/layout_selection_test.cc index 70e33530..b11f28d9 100644 --- a/third_party/blink/renderer/core/editing/layout_selection_test.cc +++ b/third_party/blink/renderer/core/editing/layout_selection_test.cc
@@ -686,21 +686,6 @@ TEST_NO_NEXT_LAYOUT_OBJECT(); } -class NGLayoutSelectionTest - : public LayoutSelectionTest, - private ScopedLayoutNGForTest, - private ScopedPaintUnderInvalidationCheckingForTest { - public: - NGLayoutSelectionTest() - : ScopedLayoutNGForTest(true), - ScopedPaintUnderInvalidationCheckingForTest(true) {} -}; - -std::ostream& operator<<(std::ostream& ostream, - const LayoutSelectionStatus& status) { - return ostream << status.start << ", " << status.end; -} - static const NGPaintFragment* FindNGPaintFragmentInternal( const NGPaintFragment* paint, const LayoutObject* layout_object) { @@ -727,15 +712,62 @@ return *paint_fragment; } +class NGLayoutSelectionTest + : public LayoutSelectionTest, + private ScopedLayoutNGForTest, + private ScopedPaintUnderInvalidationCheckingForTest { + public: + NGLayoutSelectionTest() + : ScopedLayoutNGForTest(true), + ScopedPaintUnderInvalidationCheckingForTest(true) {} + + const Text* GetFirstTextNode() { + for (const Node& runner : NodeTraversal::StartsAt(*GetDocument().body())) { + if (runner.IsTextNode()) + return &ToText(runner); + } + NOTREACHED(); + return nullptr; + } + + bool IsFirstTextLineBreak(const std::string& selection_text) { + SetSelectionAndUpdateLayoutSelection(selection_text); + const Text* const first_text = GetFirstTextNode(); + const NGPaintFragment& fragment = + GetNGPaintFragment(first_text->GetLayoutObject()); + const LayoutSelectionStatus& status = + Selection().ComputeLayoutSelectionStatus(fragment); + return status.line_break == SelectLineBreak::kSelected; + } + + LayoutSelectionStatus ComputeLayoutSelectionStatus(const Node& node) { + return Selection().ComputeLayoutSelectionStatus( + GetNGPaintFragment(node.GetLayoutObject())); + } + + void SetSelectionAndUpdateLayoutSelection(const std::string& selection_text) { + const SelectionInDOMTree& selection = + SetSelectionTextToBody(selection_text); + Selection().SetSelectionAndEndTyping(selection); + Selection().CommitAppearanceIfNeeded(); + } +}; + +std::ostream& operator<<(std::ostream& ostream, + const LayoutSelectionStatus& status) { + const String line_break = (status.line_break == SelectLineBreak::kSelected) + ? "kSelected" + : "kNotSelected"; + return ostream << status.start << ", " << status.end << ", " << std::boolalpha + << line_break; +} + TEST_F(NGLayoutSelectionTest, SelectOnOneText) { #ifndef NDEBUG // This line prohibits compiler optimization removing the debug function. PrintLayoutTreeForDebug(); #endif - const SelectionInDOMTree& selection = - SetSelectionTextToBody("foo<span>b^a|r</span>"); - Selection().SetSelectionAndEndTyping(selection); - Selection().CommitAppearanceIfNeeded(); + SetSelectionAndUpdateLayoutSelection("foo<span>b^a|r</span>"); TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate); TEST_NEXT("foo", kNone, NotInvalidate); TEST_NEXT(IsLayoutInline, kNone, NotInvalidate); @@ -744,7 +776,7 @@ LayoutObject* const foo = GetDocument().body()->firstChild()->GetLayoutObject(); - EXPECT_EQ(LayoutSelectionStatus(0u, 0u), + EXPECT_EQ(LayoutSelectionStatus(0u, 0u, SelectLineBreak::kNotSelected), Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo))); LayoutObject* const bar = GetDocument() .body() @@ -752,15 +784,13 @@ ->nextSibling() ->firstChild() ->GetLayoutObject(); - EXPECT_EQ(LayoutSelectionStatus(4u, 5u), + EXPECT_EQ(LayoutSelectionStatus(4u, 5u, SelectLineBreak::kNotSelected), Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(bar))); } TEST_F(NGLayoutSelectionTest, FirstLetterInAnotherBlockFlow) { - const SelectionInDOMTree& selection = SetSelectionTextToBody( + SetSelectionAndUpdateLayoutSelection( "<style>:first-letter { float: right}</style>^fo|o"); - Selection().SetSelectionAndEndTyping(selection); - Selection().CommitAppearanceIfNeeded(); TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate); TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate); TEST_NEXT(IsLayoutTextFragmentOf("f"), kStart, ShouldInvalidate); @@ -770,20 +800,17 @@ const LayoutTextFragment* const foo_f = ToLayoutTextFragment(AssociatedLayoutObjectOf(*foo, 0)); EXPECT_EQ( - LayoutSelectionStatus(0u, 1u), + LayoutSelectionStatus(0u, 1u, SelectLineBreak::kSelected), Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo_f))); const LayoutTextFragment* const foo_oo = ToLayoutTextFragment(AssociatedLayoutObjectOf(*foo, 1)); EXPECT_EQ( - LayoutSelectionStatus(1u, 2u), + LayoutSelectionStatus(1u, 2u, SelectLineBreak::kNotSelected), Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo_oo))); } TEST_F(NGLayoutSelectionTest, TwoNGBlockFlows) { - const SelectionInDOMTree& selection = - SetSelectionTextToBody("<div>f^oo</div><div>ba|r</div>"); - Selection().SetSelectionAndEndTyping(selection); - Selection().CommitAppearanceIfNeeded(); + SetSelectionAndUpdateLayoutSelection("<div>f^oo</div><div>ba|r</div>"); TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate); TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate); TEST_NEXT("foo", kStart, ShouldInvalidate); @@ -792,7 +819,7 @@ TEST_NO_NEXT_LAYOUT_OBJECT(); LayoutObject* const foo = GetDocument().body()->firstChild()->firstChild()->GetLayoutObject(); - EXPECT_EQ(LayoutSelectionStatus(1u, 3u), + EXPECT_EQ(LayoutSelectionStatus(1u, 3u, SelectLineBreak::kSelected), Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo))); LayoutObject* const bar = GetDocument() .body() @@ -800,16 +827,14 @@ ->nextSibling() ->firstChild() ->GetLayoutObject(); - EXPECT_EQ(LayoutSelectionStatus(0u, 2u), + EXPECT_EQ(LayoutSelectionStatus(0u, 2u, SelectLineBreak::kNotSelected), Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(bar))); } TEST_F(NGLayoutSelectionTest, MixedBlockFlowsAsSibling) { - const SelectionInDOMTree& selection = SetSelectionTextToBody( + SetSelectionAndUpdateLayoutSelection( "<div>f^oo</div>" "<div contenteditable>ba|r</div>"); - Selection().SetSelectionAndEndTyping(selection); - Selection().CommitAppearanceIfNeeded(); TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate); TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate); TEST_NEXT("foo", kStart, ShouldInvalidate); @@ -818,18 +843,16 @@ TEST_NO_NEXT_LAYOUT_OBJECT(); LayoutObject* const foo = GetDocument().body()->firstChild()->firstChild()->GetLayoutObject(); - EXPECT_EQ(LayoutSelectionStatus(1u, 3u), + EXPECT_EQ(LayoutSelectionStatus(1u, 3u, SelectLineBreak::kSelected), Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo))); EXPECT_EQ(2u, Selection().LayoutSelectionEnd().value()); } TEST_F(NGLayoutSelectionTest, MixedBlockFlowsAnscestor) { // Both "foo" and "bar" for DIV elements should be legacy LayoutBlock. - const SelectionInDOMTree& selection = SetSelectionTextToBody( + SetSelectionAndUpdateLayoutSelection( "<div contenteditable>f^oo" "<div contenteditable=false>ba|r</div></div>"); - Selection().SetSelectionAndEndTyping(selection); - Selection().CommitAppearanceIfNeeded(); TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate); TEST_NEXT(IsLegacyBlockFlow, kContain, NotInvalidate); TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate); @@ -841,11 +864,9 @@ } TEST_F(NGLayoutSelectionTest, MixedBlockFlowsDecendant) { - const SelectionInDOMTree& selection = SetSelectionTextToBody( + SetSelectionAndUpdateLayoutSelection( "<div contenteditable=false>f^oo" "<div contenteditable>ba|r</div></div>"); - Selection().SetSelectionAndEndTyping(selection); - Selection().CommitAppearanceIfNeeded(); TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate); TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate); TEST_NEXT(IsLayoutNGBlockFlow, kContain, NotInvalidate); @@ -855,9 +876,39 @@ TEST_NO_NEXT_LAYOUT_OBJECT(); LayoutObject* const foo = GetDocument().body()->firstChild()->firstChild()->GetLayoutObject(); - EXPECT_EQ(LayoutSelectionStatus(1u, 3u), + EXPECT_EQ(LayoutSelectionStatus(1u, 3u, SelectLineBreak::kSelected), Selection().ComputeLayoutSelectionStatus(GetNGPaintFragment(foo))); EXPECT_EQ(2u, Selection().LayoutSelectionEnd().value()); } +TEST_F(NGLayoutSelectionTest, LineBreakBasic) { + LoadAhem(); + EXPECT_TRUE(IsFirstTextLineBreak("<div>f^oo<br>ba|r</div>")); + EXPECT_TRUE(IsFirstTextLineBreak("<div>^foo<br><br>|</div>")); + EXPECT_TRUE(IsFirstTextLineBreak( + "<div style='font: Ahem; width: 2em'>f^oo ba|r</div>")); + EXPECT_TRUE(IsFirstTextLineBreak("<div>f^oo</div><div>b|ar</div>")); + EXPECT_FALSE(IsFirstTextLineBreak("<div>f^oo |</div>")); + EXPECT_FALSE(IsFirstTextLineBreak("<div>f^oo <!--|--></div>")); + EXPECT_FALSE(IsFirstTextLineBreak("<div>f^oo </div>|")); + EXPECT_FALSE(IsFirstTextLineBreak("<div>f^oo|</div>")); + EXPECT_FALSE(IsFirstTextLineBreak("<div>f^oo<!--|--></div>")); + EXPECT_FALSE(IsFirstTextLineBreak("<div>f^oo</div>|")); + // TODO(yoichio): Fix the test. See LayoutSelection::IsLineBreak. + // EXPECT_FALSE(IsFirstTextLineBreak( + // "<div style='display:inline-block'>f^oo</div>bar|")); +} + +TEST_F(NGLayoutSelectionTest, LineBreakImage) { + SetSelectionAndUpdateLayoutSelection( + "<div>^<img id=img1 width=10px height=10px>foo<br>" + "bar<img id=img2 width=10px height=10px>|</div>"); + Node* const foo = + GetDocument().body()->firstChild()->firstChild()->nextSibling(); + EXPECT_EQ(SelectLineBreak::kSelected, + ComputeLayoutSelectionStatus(*foo).line_break); + Node* const bar = foo->nextSibling()->nextSibling(); + EXPECT_EQ(SelectLineBreak::kNotSelected, + ComputeLayoutSelectionStatus(*bar).line_break); +} } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/local_caret_rect_test.cc b/third_party/blink/renderer/core/editing/local_caret_rect_test.cc index 73bd600..afaf615 100644 --- a/third_party/blink/renderer/core/editing/local_caret_rect_test.cc +++ b/third_party/blink/renderer/core/editing/local_caret_rect_test.cc
@@ -934,4 +934,24 @@ .rect); } +TEST_P(ParameterizedLocalCaretRectTest, BidiTextWithImage) { + LoadAhem(); + InsertStyleElement( + "div { font: 10px/10px Ahem; width: 30px }" + "img { width: 10px; height: 10px; vertical-align: bottom }"); + SetBodyContent("<div dir=rtl>X<img id=image>Y</div>"); + const Element& image = *GetElementById("image"); + const LayoutObject* image_layout = image.GetLayoutObject(); + const LayoutObject* text_before = image.previousSibling()->GetLayoutObject(); + // TODO(xiaochengh): Should return the same result for legacy and NG + EXPECT_EQ(LayoutNGEnabled() + ? LocalCaretRect(text_before, LayoutRect(10, 0, 1, 10)) + : LocalCaretRect(image_layout, LayoutRect(0, 0, 1, 10)), + LocalCaretRectOfPosition( + PositionWithAffinity(Position::BeforeNode(image)))); + EXPECT_EQ(LocalCaretRect(image_layout, LayoutRect(9, 0, 1, 10)), + LocalCaretRectOfPosition( + PositionWithAffinity(Position::AfterNode(image)))); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_rect.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_rect.cc index df450b93..11089b4 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_caret_rect.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_caret_rect.cc
@@ -35,7 +35,7 @@ fragment.GetLayoutObject()->GetDocument().View(); LayoutUnit caret_width = frame_view->CaretWidth(); - const bool is_ltr = fragment.Style().Direction() == TextDirection::kLtr; + const bool is_ltr = IsLtr(fragment.PhysicalFragment().ResolvedDirection()); LayoutUnit caret_left; if (is_ltr != (position_type == NGCaretPositionType::kBeforeBox)) { if (is_horizontal)
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc index 10d79eb..9e173ca 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.cc
@@ -5,10 +5,42 @@ #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_break_token.h" +#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h" +#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h" #include "third_party/blink/renderer/core/style/computed_style.h" namespace blink { +namespace { + +static const NGPhysicalFragment* LastLogicalLeafExceptLinebreakInternal( + const NGPhysicalFragment& runner, + TextDirection direction) { + if (runner.IsText()) { + if (ToNGPhysicalTextFragment(runner).IsLineBreak()) + return nullptr; + return &runner; + } + if (!runner.IsContainer() || runner.IsBlockLayoutRoot()) + return &runner; + const auto& children = ToNGPhysicalContainerFragment(runner).Children(); + for (size_t i = 0; i < children.size(); i++) { + // TODO(xiaochengh): This isn't correct for mixed Bidi. Fix it. Besides, we + // should compute and store it during layout. + // We want a logical last child in a line. + const size_t index = + direction == TextDirection::kLtr ? (children.size() - 1 - i) : i; + const NGPhysicalFragment* child = children[index].get(); + DCHECK(child); + if (const NGPhysicalFragment* candidate = + LastLogicalLeafExceptLinebreakInternal(*child, direction)) + return candidate; + } + return nullptr; +} + +} // namespace + NGPhysicalLineBoxFragment::NGPhysicalLineBoxFragment( const ComputedStyle& style, NGPhysicalSize size, @@ -80,6 +112,13 @@ return runner; } +const NGPhysicalFragment* +NGPhysicalLineBoxFragment::LastLogicalLeafIgnoringLineBreak() const { + if (Children().IsEmpty()) + return nullptr; + return LastLogicalLeafExceptLinebreakInternal(*this, this->BaseDirection()); +} + bool NGPhysicalLineBoxFragment::HasSoftWrapToNextLine() const { DCHECK(BreakToken()); DCHECK(BreakToken()->IsInlineType());
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h index 02989a09..67f8724d 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h
@@ -43,6 +43,9 @@ // nullptr if the line box is empty. const NGPhysicalFragment* FirstLogicalLeaf() const; const NGPhysicalFragment* LastLogicalLeaf() const; + // Returns the last leaf fragment in the line in logical order except line + // break. Returns nullptr if such fragment doesn't exist. + const NGPhysicalFragment* LastLogicalLeafIgnoringLineBreak() const; // Whether the content soft-wraps to the next line. bool HasSoftWrapToNextLine() const;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment_test.cc index cd44fd8..331fb87d 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment_test.cc
@@ -59,6 +59,7 @@ "</div>"); EXPECT_TEXT_FRAGMENT("foo", GetLineBox()->FirstLogicalLeaf()); EXPECT_TEXT_FRAGMENT("bar", GetLineBox()->LastLogicalLeaf()); + EXPECT_TEXT_FRAGMENT("bar", GetLineBox()->LastLogicalLeafIgnoringLineBreak()); } TEST_F(NGPhysicalLineBoxFragmentTest, FirstLastLogicalLeafInRtlText) { @@ -69,6 +70,7 @@ "</bdo>"); EXPECT_TEXT_FRAGMENT("foo", GetLineBox()->FirstLogicalLeaf()); EXPECT_TEXT_FRAGMENT("bar", GetLineBox()->LastLogicalLeaf()); + EXPECT_TEXT_FRAGMENT("bar", GetLineBox()->LastLogicalLeafIgnoringLineBreak()); } TEST_F(NGPhysicalLineBoxFragmentTest, @@ -81,6 +83,7 @@ "</div>"); EXPECT_TEXT_FRAGMENT("f", GetLineBox()->FirstLogicalLeaf()); EXPECT_TEXT_FRAGMENT("r", GetLineBox()->LastLogicalLeaf()); + EXPECT_TEXT_FRAGMENT("r", GetLineBox()->LastLogicalLeafIgnoringLineBreak()); } TEST_F(NGPhysicalLineBoxFragmentTest, FirstLastLogicalLeafWithInlineBlock) { @@ -92,12 +95,26 @@ "</div>"); EXPECT_BOX_FRAGMENT("foo", GetLineBox()->FirstLogicalLeaf()); EXPECT_BOX_FRAGMENT("baz", GetLineBox()->LastLogicalLeaf()); + EXPECT_BOX_FRAGMENT("baz", GetLineBox()->LastLogicalLeafIgnoringLineBreak()); } TEST_F(NGPhysicalLineBoxFragmentTest, FirstLastLogicalLeafWithImages) { SetBodyInnerHTML("<div id=root><img id=img1>foo<img id=img2></div>"); EXPECT_BOX_FRAGMENT("img1", GetLineBox()->FirstLogicalLeaf()); EXPECT_BOX_FRAGMENT("img2", GetLineBox()->LastLogicalLeaf()); + EXPECT_BOX_FRAGMENT("img2", GetLineBox()->LastLogicalLeafIgnoringLineBreak()); +} + +TEST_F(NGPhysicalLineBoxFragmentTest, LastLogicalLeafSoftWrap) { + SetBodyInnerHTML("<div id=root style='width: 2em'>foo bar</div>"); + EXPECT_TEXT_FRAGMENT("foo", GetLineBox()->LastLogicalLeaf()); + EXPECT_TEXT_FRAGMENT("foo", GetLineBox()->LastLogicalLeafIgnoringLineBreak()); +} + +TEST_F(NGPhysicalLineBoxFragmentTest, LastLogicalLeafHardWrap) { + SetBodyInnerHTML("<div id=root>foo<br>bar</div>"); + EXPECT_TEXT_FRAGMENT("\n", GetLineBox()->LastLogicalLeaf()); + EXPECT_TEXT_FRAGMENT("foo", GetLineBox()->LastLogicalLeafIgnoringLineBreak()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc index 0ace6d2..a92b383 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter.cc
@@ -6,6 +6,8 @@ #include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/layout/layout_block_flow.h" +#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" #include "third_party/blink/renderer/core/layout/ng/ng_text_decoration_offset.h" @@ -58,6 +60,35 @@ return color; } +NGPhysicalOffsetRect ExpandedSelectionRectForLineBreakIfNeeded( + const NGPhysicalOffsetRect& rect, + const NGPaintFragment& paint_fragment, + const LayoutSelectionStatus& selection_status) { + // Expand paint rect if selection covers multiple lines and + // this fragment is at the end of line. + if (selection_status.line_break == SelectLineBreak::kNotSelected) + return rect; + if (paint_fragment.GetLayoutObject() + ->EnclosingNGBlockFlow() + ->ShouldTruncateOverflowingText()) + return rect; + // Copy from InlineTextBoxPainter. + const NGPaintFragment* container_line_box = paint_fragment.ContainerLineBox(); + DCHECK(container_line_box); + const NGPhysicalLineBoxFragment& physical_line_box = + ToNGPhysicalLineBoxFragment(container_line_box->PhysicalFragment()); + const LayoutUnit space_width(paint_fragment.Style().GetFont().SpaceWidth()); + const NGPhysicalSize expanded_size(rect.size.width + space_width, + rect.size.height); + // TODO(yoichio): Support vertical writing mode. + // Consider sharing physical directional algorithm with ng_caret_rect.cc. + if (IsLtr(physical_line_box.BaseDirection())) + return NGPhysicalOffsetRect(rect.offset, expanded_size); + return NGPhysicalOffsetRect( + NGPhysicalOffset(rect.offset.left - space_width, rect.offset.top), + expanded_size); +} + } // namespace NGTextFragmentPainter::NGTextFragmentPainter( @@ -84,11 +115,15 @@ return; GraphicsContextStateSaver state_saver(context); - const NGPhysicalOffsetRect& ng_rect = + const NGPhysicalOffsetRect& selection_rect = text_fragment.LocalRect(selection_status.start, selection_status.end); - LayoutRect selection_rect = ng_rect.ToLayoutRect(); - selection_rect.MoveBy(box_rect.Location()); - context.FillRect(FloatRect(selection_rect), color); + const NGPhysicalOffsetRect line_break_extended_rect = + ExpandedSelectionRectForLineBreakIfNeeded(selection_rect, paint_fragment, + selection_status); + const NGPhysicalOffsetRect global_rect( + line_break_extended_rect.offset + NGPhysicalOffset(box_rect.Location()), + line_break_extended_rect.size); + context.FillRect(global_rect.ToFloatRect(), color); } // This is copied from InlineTextBoxPainter::PaintSelection() but lacks of
diff --git a/third_party/blink/renderer/core/timing/performance.cc b/third_party/blink/renderer/core/timing/performance.cc index a1032323..aa1c51c 100644 --- a/third_party/blink/renderer/core/timing/performance.cc +++ b/third_party/blink/renderer/core/timing/performance.cc
@@ -44,6 +44,7 @@ #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/timing/performance_event_timing.h" #include "third_party/blink/renderer/core/timing/performance_long_task_timing.h" +#include "third_party/blink/renderer/core/timing/performance_mark.h" #include "third_party/blink/renderer/core/timing/performance_measure.h" #include "third_party/blink/renderer/core/timing/performance_measure_options.h" #include "third_party/blink/renderer/core/timing/performance_observer.h" @@ -542,14 +543,14 @@ NotifyObserversOfEntry(*entry); } -void Performance::mark(ScriptState* script_state, - const String& mark_name, - ExceptionState& exception_state) { +PerformanceMark* Performance::mark(ScriptState* script_state, + const String& mark_name, + ExceptionState& exception_state) { DoubleOrPerformanceMarkOptions startOrOptions; - this->mark(script_state, mark_name, startOrOptions, exception_state); + return this->mark(script_state, mark_name, startOrOptions, exception_state); } -void Performance::mark( +PerformanceMark* Performance::mark( ScriptState* script_state, const String& mark_name, DoubleOrPerformanceMarkOptions& start_time_or_mark_options, @@ -579,9 +580,11 @@ } // Pass in a null ScriptValue if the mark's detail doesn't exist. - if (PerformanceEntry* entry = user_timing_->Mark( - script_state, mark_name, start, detail, exception_state)) - NotifyObserversOfEntry(*entry); + PerformanceMark* performance_mark = user_timing_->Mark( + script_state, mark_name, start, detail, exception_state); + if (performance_mark) + NotifyObserversOfEntry(*performance_mark); + return performance_mark; } void Performance::clearMarks(const String& mark_name) { @@ -759,12 +762,9 @@ PerformanceMeasure* performance_measure = user_timing_->Measure(script_state, measure_name, original_start, original_end, detail, exception_state); - if (performance_measure) { - PerformanceEntry* entry = performance_measure; - NotifyObserversOfEntry(*entry); - return performance_measure; - } - return nullptr; + if (performance_measure) + NotifyObserversOfEntry(*performance_measure); + return performance_measure; } void Performance::clearMeasures(const String& measure_name) {
diff --git a/third_party/blink/renderer/core/timing/performance.h b/third_party/blink/renderer/core/timing/performance.h index d73a129..e2bbaf83e 100644 --- a/third_party/blink/renderer/core/timing/performance.h +++ b/third_party/blink/renderer/core/timing/performance.h
@@ -57,6 +57,7 @@ class MemoryInfo; class PerformanceNavigation; class PerformanceObserver; +class PerformanceMark; class PerformanceMeasure; class PerformanceTiming; class ResourceResponse; @@ -158,12 +159,13 @@ void setEventTimingBufferMaxSize(unsigned); DEFINE_ATTRIBUTE_EVENT_LISTENER(eventtimingbufferfull); - void mark(ScriptState*, const String& mark_name, ExceptionState&); + PerformanceMark* mark(ScriptState*, const String& mark_name, ExceptionState&); - void mark(ScriptState*, - const String& mark_name, - DoubleOrPerformanceMarkOptions& start_time_or_mark_options, - ExceptionState&); + PerformanceMark* mark( + ScriptState*, + const String& mark_name, + DoubleOrPerformanceMarkOptions& start_time_or_mark_options, + ExceptionState&); void clearMarks(const String& mark_name);
diff --git a/third_party/blink/renderer/core/timing/performance.idl b/third_party/blink/renderer/core/timing/performance.idl index 4339862..d74038e 100644 --- a/third_party/blink/renderer/core/timing/performance.idl +++ b/third_party/blink/renderer/core/timing/performance.idl
@@ -65,7 +65,7 @@ // User Timing // https://w3c.github.io/user-timing/#extensions-performance-interface [MeasureAs=UserTiming, CallWith=ScriptState, RaisesException] void mark(DOMString markName); - [MeasureAs=UserTiming, CallWith=ScriptState, RuntimeEnabled=CustomUserTiming, RaisesException] void mark(DOMString markName, (DOMHighResTimeStamp or PerformanceMarkOptions) startTimeOrPerformanceMarkOptions); + [MeasureAs=UserTiming, CallWith=ScriptState, RuntimeEnabled=CustomUserTiming, RaisesException] PerformanceMark? mark(DOMString markName, (DOMHighResTimeStamp or PerformanceMarkOptions) startTimeOrPerformanceMarkOptions); [MeasureAs=UserTiming] void clearMarks(optional DOMString markName = null); // Doing either of the following requires enabling CustomUserTiming:
diff --git a/third_party/blink/renderer/core/timing/performance_user_timing.cc b/third_party/blink/renderer/core/timing/performance_user_timing.cc index 492cc64..68a478c 100644 --- a/third_party/blink/renderer/core/timing/performance_user_timing.cc +++ b/third_party/blink/renderer/core/timing/performance_user_timing.cc
@@ -99,11 +99,11 @@ performance_entry_map.erase(name); } -PerformanceEntry* UserTiming::Mark(ScriptState* script_state, - const String& mark_name, - const DOMHighResTimeStamp& start_time, - const ScriptValue& detail, - ExceptionState& exception_state) { +PerformanceMark* UserTiming::Mark(ScriptState* script_state, + const String& mark_name, + const DOMHighResTimeStamp& start_time, + const ScriptValue& detail, + ExceptionState& exception_state) { if (GetRestrictedKeyMap().Contains(mark_name)) { exception_state.ThrowDOMException( kSyntaxError, "'" + mark_name + @@ -113,14 +113,14 @@ } TRACE_EVENT_COPY_MARK("blink.user_timing", mark_name.Utf8().data()); - PerformanceEntry* entry = + PerformanceMark* mark = PerformanceMark::Create(script_state, mark_name, start_time, detail); - InsertPerformanceEntry(marks_map_, *entry); + InsertPerformanceEntry(marks_map_, *mark); DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, user_timing_mark_histogram, ("PLT.UserTiming_Mark", 0, 600000, 100)); user_timing_mark_histogram.Count(static_cast<int>(start_time)); - return entry; + return mark; } void UserTiming::ClearMarks(const String& mark_name) { @@ -202,16 +202,16 @@ WTF::StringHash::GetHash(measure_name), TraceEvent::ToTraceTimestamp(end_time_monotonic)); - PerformanceMeasure* entry = PerformanceMeasure::Create( + PerformanceMeasure* measure = PerformanceMeasure::Create( script_state, measure_name, start_time, end_time, detail); - InsertPerformanceEntry(measures_map_, *entry); + InsertPerformanceEntry(measures_map_, *measure); if (end_time >= start_time) { DEFINE_THREAD_SAFE_STATIC_LOCAL( CustomCountHistogram, measure_duration_histogram, ("PLT.UserTiming_MeasureDuration", 0, 600000, 100)); measure_duration_histogram.Count(static_cast<int>(end_time - start_time)); } - return entry; + return measure; } void UserTiming::ClearMeasures(const String& measure_name) {
diff --git a/third_party/blink/renderer/core/timing/performance_user_timing.h b/third_party/blink/renderer/core/timing/performance_user_timing.h index aed6e15..829da54 100644 --- a/third_party/blink/renderer/core/timing/performance_user_timing.h +++ b/third_party/blink/renderer/core/timing/performance_user_timing.h
@@ -47,11 +47,11 @@ return new UserTiming(performance); } - PerformanceEntry* Mark(ScriptState*, - const String& mark_name, - const DOMHighResTimeStamp& start_time, - const ScriptValue& detail, - ExceptionState&); + PerformanceMark* Mark(ScriptState*, + const String& mark_name, + const DOMHighResTimeStamp& start_time, + const ScriptValue& detail, + ExceptionState&); void ClearMarks(const String& mark_name); PerformanceMeasure* Measure(ScriptState*,
diff --git a/third_party/blink/renderer/modules/exported/BUILD.gn b/third_party/blink/renderer/modules/exported/BUILD.gn index 0e7590d5..686411e 100644 --- a/third_party/blink/renderer/modules/exported/BUILD.gn +++ b/third_party/blink/renderer/modules/exported/BUILD.gn
@@ -44,6 +44,4 @@ "//third_party/blink/renderer:config", "//third_party/blink/renderer/core:blink_core_pch", ] - - include_dirs = [ "$root_gen_dir/third_party/blink/renderer" ] }
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 4c11cc9e..185d207a 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -166,11 +166,6 @@ import("//build/config/pch.gni") config("blink_platform_config") { - include_dirs = [ - #"$angle_path/include", - "$root_gen_dir/third_party/blink/renderer", - ] - configs = [ "//third_party/blink/renderer:config", "//third_party/blink/renderer:inside_blink", @@ -1978,8 +1973,6 @@ ] defines = [ "INSIDE_BLINK" ] - - include_dirs = [ "$root_gen_dir/third_party/blink/renderer" ] } executable("image_decode_bench") {
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index 1b614e3f..f93e910 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -1554,8 +1554,7 @@ void ResourceFetcher::MoveResourceLoaderToNonBlocking(ResourceLoader* loader) { DCHECK(loader); - // TODO(yoav): Convert CHECK to DCHECK if no crash reports come in. - CHECK(loaders_.Contains(loader)); + DCHECK(loaders_.Contains(loader)); non_blocking_loaders_.insert(loader); loaders_.erase(loader); }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 021f788..42946db5 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -605,6 +605,7 @@ }, { name: "IncrementalShadowDOM", + status: "experimental", }, { name: "InertAttribute", @@ -1146,7 +1147,7 @@ }, { name: "ServiceWorkerUpdateViaCache", - status: "experimental", + status: "stable", }, { name: "SetRootScroller",
diff --git a/ui/accessibility/ax_relative_bounds.cc b/ui/accessibility/ax_relative_bounds.cc index e41cb3d6..87c3d581 100644 --- a/ui/accessibility/ax_relative_bounds.cc +++ b/ui/accessibility/ax_relative_bounds.cc
@@ -33,7 +33,7 @@ return *this; } -bool AXRelativeBounds::operator==(const AXRelativeBounds& other) { +bool AXRelativeBounds::operator==(const AXRelativeBounds& other) const { if (offset_container_id != other.offset_container_id) return false; if (bounds != other.bounds) @@ -45,7 +45,7 @@ return *transform == *other.transform; } -bool AXRelativeBounds::operator!=(const AXRelativeBounds& other) { +bool AXRelativeBounds::operator!=(const AXRelativeBounds& other) const { return !operator==(other); }
diff --git a/ui/accessibility/ax_relative_bounds.h b/ui/accessibility/ax_relative_bounds.h index bb43598..18e92b2 100644 --- a/ui/accessibility/ax_relative_bounds.h +++ b/ui/accessibility/ax_relative_bounds.h
@@ -39,8 +39,8 @@ AXRelativeBounds(const AXRelativeBounds& other); AXRelativeBounds& operator=(AXRelativeBounds other); - bool operator!=(const AXRelativeBounds& other); - bool operator==(const AXRelativeBounds& other); + bool operator!=(const AXRelativeBounds& other) const; + bool operator==(const AXRelativeBounds& other) const; std::string ToString() const; @@ -64,4 +64,4 @@ } // namespace ui -#endif // UI_ACCESSIBILITY_AX_NODE_DATA_H_ +#endif // UI_ACCESSIBILITY_AX_RELATIVE_BOUNDS_H_
diff --git a/ui/base/ime/chromeos/mock_ime_engine_handler.cc b/ui/base/ime/chromeos/mock_ime_engine_handler.cc index a8db1ae..413bb44 100644 --- a/ui/base/ime/chromeos/mock_ime_engine_handler.cc +++ b/ui/base/ime/chromeos/mock_ime_engine_handler.cc
@@ -16,7 +16,8 @@ last_text_input_context_(ui::TEXT_INPUT_TYPE_NONE, ui::TEXT_INPUT_MODE_DEFAULT, ui::TEXT_INPUT_FLAG_NONE, - ui::TextInputClient::FOCUS_REASON_NONE), + ui::TextInputClient::FOCUS_REASON_NONE, + false /* should_do_learning */), last_set_surrounding_cursor_pos_(0), last_set_surrounding_anchor_pos_(0) {}
diff --git a/ui/base/ime/dummy_input_method.cc b/ui/base/ime/dummy_input_method.cc index a73ec73..2afa00e9 100644 --- a/ui/base/ime/dummy_input_method.cc +++ b/ui/base/ime/dummy_input_method.cc
@@ -81,6 +81,10 @@ return false; } +bool DummyInputMethod::GetClientShouldDoLearning() { + return false; +} + void DummyInputMethod::ShowImeIfNeeded() { }
diff --git a/ui/base/ime/dummy_input_method.h b/ui/base/ime/dummy_input_method.h index 513213d..33743a4 100644 --- a/ui/base/ime/dummy_input_method.h +++ b/ui/base/ime/dummy_input_method.h
@@ -42,6 +42,7 @@ int GetTextInputFlags() const override; bool CanComposeInline() const override; bool IsCandidatePopupOpen() const override; + bool GetClientShouldDoLearning() override; void ShowImeIfNeeded() override; void AddObserver(InputMethodObserver* observer) override;
diff --git a/ui/base/ime/dummy_text_input_client.cc b/ui/base/ime/dummy_text_input_client.cc index 83e3a9d..2d0cb3a 100644 --- a/ui/base/ime/dummy_text_input_client.cc +++ b/ui/base/ime/dummy_text_input_client.cc
@@ -135,4 +135,8 @@ return base::EmptyString(); } +bool DummyTextInputClient::ShouldDoLearning() { + return false; +} + } // namespace ui
diff --git a/ui/base/ime/dummy_text_input_client.h b/ui/base/ime/dummy_text_input_client.h index 63b0b35..0eca8ad 100644 --- a/ui/base/ime/dummy_text_input_client.h +++ b/ui/base/ime/dummy_text_input_client.h
@@ -53,6 +53,7 @@ bool IsTextEditCommandEnabled(TextEditCommand command) const override; void SetTextEditCommandForNextKeyEvent(TextEditCommand command) override; const std::string& GetClientSourceInfo() const override; + bool ShouldDoLearning() override; int insert_char_count() const { return insert_char_count_; } base::char16 last_insert_char() const { return last_insert_char_; }
diff --git a/ui/base/ime/ime_bridge.cc b/ui/base/ime/ime_bridge.cc index c7539aa..f196d8a 100644 --- a/ui/base/ime/ime_bridge.cc +++ b/ui/base/ime/ime_bridge.cc
@@ -26,7 +26,8 @@ current_input_context_(ui::TEXT_INPUT_TYPE_NONE, ui::TEXT_INPUT_MODE_DEFAULT, 0, - ui::TextInputClient::FOCUS_REASON_NONE), + ui::TextInputClient::FOCUS_REASON_NONE, + false /* should_do_learning */), candidate_window_handler_(nullptr) {} #else IMEBridgeImpl() @@ -36,7 +37,8 @@ current_input_context_(ui::TEXT_INPUT_TYPE_NONE, ui::TEXT_INPUT_MODE_DEFAULT, 0, - ui::TextInputClient::FOCUS_REASON_NONE) {} + ui::TextInputClient::FOCUS_REASON_NONE, + false /* should_do_learning */) {} #endif ~IMEBridgeImpl() override {}
diff --git a/ui/base/ime/ime_engine_handler_interface.h b/ui/base/ime/ime_engine_handler_interface.h index 3a246117..fdca0ee 100644 --- a/ui/base/ime/ime_engine_handler_interface.h +++ b/ui/base/ime/ime_engine_handler_interface.h
@@ -38,21 +38,25 @@ InputContext(TextInputType type_, TextInputMode mode_, int flags_, - TextInputClient::FocusReason focus_reason_) + TextInputClient::FocusReason focus_reason_, + bool should_do_learning_) : type(type_), mode(mode_), flags(flags_), - focus_reason(focus_reason_) {} + focus_reason(focus_reason_), + should_do_learning(should_do_learning_) {} InputContext(int id_, TextInputType type_, TextInputMode mode_, int flags_, - TextInputClient::FocusReason focus_reason_) + TextInputClient::FocusReason focus_reason_, + bool should_do_learning_) : id(id_), type(type_), mode(mode_), flags(flags_), - focus_reason(focus_reason_) {} + focus_reason(focus_reason_), + should_do_learning(should_do_learning_) {} // An attribute of the context id which used for ChromeOS only. int id; // An attribute of the field defined at @@ -69,6 +73,9 @@ // An attribute to indicate how this input field was focused. TextInputClient::FocusReason focus_reason = TextInputClient::FOCUS_REASON_NONE; + // An attribute to indicate whether text entered in this field should be + // used to improve typing suggestions for the user. + bool should_do_learning = false; }; virtual ~IMEEngineHandlerInterface() {}
diff --git a/ui/base/ime/input_method.h b/ui/base/ime/input_method.h index eb7bb92..c1ad7f20 100644 --- a/ui/base/ime/input_method.h +++ b/ui/base/ime/input_method.h
@@ -158,6 +158,10 @@ // of IME popups is not supported. virtual bool IsCandidatePopupOpen() const = 0; + // Check whether text entered into the focused text input client should be + // used to improve typing suggestions for the user. + virtual bool GetClientShouldDoLearning() = 0; + // Displays an on screen keyboard if enabled. virtual void ShowImeIfNeeded() = 0;
diff --git a/ui/base/ime/input_method_auralinux.cc b/ui/base/ime/input_method_auralinux.cc index 696ca681..6997920 100644 --- a/ui/base/ime/input_method_auralinux.cc +++ b/ui/base/ime/input_method_auralinux.cc
@@ -250,7 +250,7 @@ ui::IMEEngineHandlerInterface::InputContext context( GetTextInputType(), GetTextInputMode(), GetTextInputFlags(), - ui::TextInputClient::FOCUS_REASON_OTHER); + ui::TextInputClient::FOCUS_REASON_OTHER, GetClientShouldDoLearning()); ui::IMEBridge::Get()->SetCurrentInputContext(context); ui::IMEEngineHandlerInterface* engine = GetEngine();
diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc index e3805d9..f01fdd1 100644 --- a/ui/base/ime/input_method_base.cc +++ b/ui/base/ime/input_method_base.cc
@@ -121,6 +121,11 @@ return client ? client->CanComposeInline() : true; } +bool InputMethodBase::GetClientShouldDoLearning() { + TextInputClient* client = GetTextInputClient(); + return client && client->ShouldDoLearning(); +} + void InputMethodBase::ShowImeIfNeeded() { for (InputMethodObserver& observer : observer_list_) observer.OnShowImeIfNeeded();
diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h index 6896502..e996e6d 100644 --- a/ui/base/ime/input_method_base.h +++ b/ui/base/ime/input_method_base.h
@@ -62,6 +62,7 @@ TextInputMode GetTextInputMode() const override; int GetTextInputFlags() const override; bool CanComposeInline() const override; + bool GetClientShouldDoLearning() override; void ShowImeIfNeeded() override; void AddObserver(InputMethodObserver* observer) override;
diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc index 01a00a0..3f894845 100644 --- a/ui/base/ime/input_method_chromeos.cc +++ b/ui/base/ime/input_method_chromeos.cc
@@ -193,7 +193,7 @@ engine->FocusOut(); ui::IMEEngineHandlerInterface::InputContext context( GetTextInputType(), GetTextInputMode(), GetTextInputFlags(), - GetClientFocusReason()); + GetClientFocusReason(), GetClientShouldDoLearning()); engine->FocusIn(context); } @@ -310,7 +310,7 @@ if (GetEngine()) { ui::IMEEngineHandlerInterface::InputContext context( GetTextInputType(), GetTextInputMode(), GetTextInputFlags(), - GetClientFocusReason()); + GetClientFocusReason(), GetClientShouldDoLearning()); GetEngine()->FocusIn(context); } } @@ -355,7 +355,7 @@ ui::IMEEngineHandlerInterface::InputContext context( GetTextInputType(), GetTextInputMode(), GetTextInputFlags(), - GetClientFocusReason()); + GetClientFocusReason(), GetClientShouldDoLearning()); ui::IMEBridge::Get()->SetCurrentInputContext(context); if (!IsTextInputTypeNone())
diff --git a/ui/base/ime/input_method_win.cc b/ui/base/ime/input_method_win.cc index 8509b095..c42abc2 100644 --- a/ui/base/ime/input_method_win.cc +++ b/ui/base/ime/input_method_win.cc
@@ -497,7 +497,7 @@ ui::IMEBridge::Get()->GetCurrentInputContext().type; ui::IMEEngineHandlerInterface::InputContext context( GetTextInputType(), GetTextInputMode(), GetTextInputFlags(), - ui::TextInputClient::FOCUS_REASON_OTHER); + ui::TextInputClient::FOCUS_REASON_OTHER, GetClientShouldDoLearning()); ui::IMEBridge::Get()->SetCurrentInputContext(context); ui::IMEEngineHandlerInterface* engine = GetEngine();
diff --git a/ui/base/ime/mock_input_method.cc b/ui/base/ime/mock_input_method.cc index d381c50..056a0a1 100644 --- a/ui/base/ime/mock_input_method.cc +++ b/ui/base/ime/mock_input_method.cc
@@ -105,6 +105,10 @@ return false; } +bool MockInputMethod::GetClientShouldDoLearning() { + return false; +} + void MockInputMethod::ShowImeIfNeeded() { for (InputMethodObserver& observer : observer_list_) observer.OnShowImeIfNeeded();
diff --git a/ui/base/ime/mock_input_method.h b/ui/base/ime/mock_input_method.h index ebc0cc01..a932271 100644 --- a/ui/base/ime/mock_input_method.h +++ b/ui/base/ime/mock_input_method.h
@@ -54,6 +54,7 @@ int GetTextInputFlags() const override; bool CanComposeInline() const override; bool IsCandidatePopupOpen() const override; + bool GetClientShouldDoLearning() override; void ShowImeIfNeeded() override; void AddObserver(InputMethodObserver* observer) override; void RemoveObserver(InputMethodObserver* observer) override;
diff --git a/ui/base/ime/text_input_client.h b/ui/base/ime/text_input_client.h index 19e3b74..2f7d4fc 100644 --- a/ui/base/ime/text_input_client.h +++ b/ui/base/ime/text_input_client.h
@@ -190,6 +190,11 @@ // Returns a string description of the view hosting the given text input // element (ie. the URL for web contents), used for recording metrics. virtual const std::string& GetClientSourceInfo() const = 0; + + // Returns whether text entered into this text client should be used to + // improve typing suggestions for the user. This should return false for text + // fields that are considered 'private' (e.g. in incognito tabs). + virtual bool ShouldDoLearning() = 0; }; } // namespace ui
diff --git a/ui/base/ime/win/tsf_text_store_unittest.cc b/ui/base/ime/win/tsf_text_store_unittest.cc index 9392429..1f4cf086 100644 --- a/ui/base/ime/win/tsf_text_store_unittest.cc +++ b/ui/base/ime/win/tsf_text_store_unittest.cc
@@ -44,6 +44,7 @@ MOCK_CONST_METHOD2(GetCompositionCharacterBounds, bool(uint32_t, gfx::Rect*)); MOCK_CONST_METHOD0(HasCompositionText, bool()); MOCK_CONST_METHOD0(GetFocusReason, ui::TextInputClient::FocusReason()); + MOCK_METHOD0(ShouldDoLearning, bool()); MOCK_CONST_METHOD1(GetTextRange, bool(gfx::Range*)); MOCK_CONST_METHOD1(GetCompositionTextRange, bool(gfx::Range*)); MOCK_CONST_METHOD1(GetSelectionRange, bool(gfx::Range*));
diff --git a/ui/views/controls/prefix_selector.cc b/ui/views/controls/prefix_selector.cc index 172dde2b..6590a8e0b 100644 --- a/ui/views/controls/prefix_selector.cc +++ b/ui/views/controls/prefix_selector.cc
@@ -151,6 +151,12 @@ return base::EmptyString(); } +bool PrefixSelector::ShouldDoLearning() { + // TODO(https://crbug.com/311180): Implement this method. + NOTIMPLEMENTED_LOG_ONCE(); + return false; +} + void PrefixSelector::OnTextInput(const base::string16& text) { // Small hack to filter out 'tab' and 'enter' input, as the expectation is // that they are control characters and will not affect the currently-active
diff --git a/ui/views/controls/prefix_selector.h b/ui/views/controls/prefix_selector.h index 937da79..e3654eeb 100644 --- a/ui/views/controls/prefix_selector.h +++ b/ui/views/controls/prefix_selector.h
@@ -61,6 +61,7 @@ bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override; void SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) override; const std::string& GetClientSourceInfo() const override; + bool ShouldDoLearning() override; private: // Invoked when text is typed. Tries to change the selection appropriately.
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index 3119ee3..469f5a75 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -1768,6 +1768,12 @@ return base::EmptyString(); } +bool Textfield::ShouldDoLearning() { + // TODO(https://crbug.com/311180): Implement this method. + NOTIMPLEMENTED_LOG_ONCE(); + return false; +} + //////////////////////////////////////////////////////////////////////////////// // Textfield, protected:
diff --git a/ui/views/controls/textfield/textfield.h b/ui/views/controls/textfield/textfield.h index 8834ac08..ee7be5c3 100644 --- a/ui/views/controls/textfield/textfield.h +++ b/ui/views/controls/textfield/textfield.h
@@ -359,6 +359,7 @@ bool IsTextEditCommandEnabled(ui::TextEditCommand command) const override; void SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) override; const std::string& GetClientSourceInfo() const override; + bool ShouldDoLearning() override; protected: // Inserts or appends a character in response to an IME operation.
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn index b87727d..664e3c3 100644 --- a/ui/webui/resources/cr_elements/BUILD.gn +++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -10,11 +10,13 @@ "chromeos/cr_picture:closure_compile", "chromeos/network:closure_compile", "cr_action_menu:closure_compile", + "cr_checkbox:closure_compile", "cr_dialog:closure_compile", "cr_drawer:closure_compile", "cr_expand_button:closure_compile", "cr_link_row:closure_compile", "cr_profile_avatar_selector:closure_compile", + "cr_radio_button:closure_compile", "cr_toast:closure_compile", "cr_toggle:closure_compile", "policy:closure_compile",
diff --git a/ui/webui/resources/cr_elements/compiled_resources2.gyp b/ui/webui/resources/cr_elements/compiled_resources2.gyp index 59c868b..fab52d7 100644 --- a/ui/webui/resources/cr_elements/compiled_resources2.gyp +++ b/ui/webui/resources/cr_elements/compiled_resources2.gyp
@@ -10,11 +10,13 @@ 'chromeos/cr_picture/compiled_resources2.gyp:*', 'chromeos/network/compiled_resources2.gyp:*', 'cr_action_menu/compiled_resources2.gyp:*', + 'cr_checkbox/compiled_resources2.gyp:*', 'cr_dialog/compiled_resources2.gyp:*', 'cr_drawer/compiled_resources2.gyp:*', 'cr_expand_button/compiled_resources2.gyp:*', 'cr_link_row/compiled_resources2.gyp:*', 'cr_profile_avatar_selector/compiled_resources2.gyp:*', + 'cr_radio_button/compiled_resources2.gyp:*', 'cr_toast/compiled_resources2.gyp:*', 'cr_toggle/compiled_resources2.gyp:*', 'policy/compiled_resources2.gyp:*',
diff --git a/ui/webui/resources/cr_elements/cr_checkbox/cr_checkbox.html b/ui/webui/resources/cr_elements/cr_checkbox/cr_checkbox.html index 6111d535..586d23a2 100644 --- a/ui/webui/resources/cr_elements/cr_checkbox/cr_checkbox.html +++ b/ui/webui/resources/cr_elements/cr_checkbox/cr_checkbox.html
@@ -1,8 +1,9 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-behaviors/paper-ripple-behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> +<link rel="import" href="../shared_vars_css.html"> + <!-- List of customizable styles: @@ -36,7 +37,7 @@ :host([disabled]) { cursor: initial; - opacity: 0.38; + opacity: var(--cr-disabled-opacity); pointer-events: none; }
diff --git a/ui/webui/resources/cr_elements/cr_radio_button/BUILD.gn b/ui/webui/resources/cr_elements/cr_radio_button/BUILD.gn new file mode 100644 index 0000000..0525dbb --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_radio_button/BUILD.gn
@@ -0,0 +1,24 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//third_party/closure_compiler/compile_js.gni") + +js_type_check("closure_compile") { + deps = [ + ":cr_radio_button", + ] +} + +js_library("cr_radio_button") { + deps = [ + ":cr_radio_button_behavior", + ] +} + +js_library("cr_radio_button_behavior") { + deps = [ + "//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted", + "//third_party/polymer/v1_0/components-chromium/paper-behaviors:paper-ripple-behavior-extracted", + ] +}
diff --git a/ui/webui/resources/cr_elements/cr_radio_button/compiled_resources2.gyp b/ui/webui/resources/cr_elements/cr_radio_button/compiled_resources2.gyp new file mode 100644 index 0000000..d9d1301e --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_radio_button/compiled_resources2.gyp
@@ -0,0 +1,22 @@ +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +{ + 'targets': [ + { + 'target_name': 'cr_radio_button', + 'dependencies': [ + 'cr_radio_button_behavior' + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { + 'target_name': 'cr_radio_button_behavior', + 'dependencies': [ + '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior/compiled_resources2.gyp:iron-a11y-keys-behavior-extracted', + '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-behaviors/compiled_resources2.gyp:paper-ripple-behavior-extracted', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + ], +}
diff --git a/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button.html b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button.html new file mode 100644 index 0000000..cedb86e --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button.html
@@ -0,0 +1,23 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> +<link rel="import" href="../shared_vars_css.html"> +<link rel="import" href="cr_radio_button_behavior.html"> +<link rel="import" href="cr_radio_button_style_css.html"> + +<dom-module id="cr-radio-button"> + <template> + <style include="cr-radio-button-style"></style> + + <div class="disc-wrapper"> + <div class="disc-border"></div> + <div class="disc"></div> + </div> + + <div id="labelWrapper"> + <span id="label" hidden$="[[!label]]">[[label]]</span> + <slot></slot> + </div> + </template> + <script src="cr_radio_button.js"></script> +</dom-module>
diff --git a/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button.js b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button.js new file mode 100644 index 0000000..3af06db4 --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button.js
@@ -0,0 +1,11 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +Polymer({ + is: 'cr-radio-button', + + behaviors: [ + CrRadioButtonBehavior, + ], +});
diff --git a/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.html b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.html new file mode 100644 index 0000000..5942b35 --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.html
@@ -0,0 +1,3 @@ +<link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-behaviors/paper-ripple-behavior.html"> +<script src="cr_radio_button_behavior.js"></script>
diff --git a/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.js b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.js new file mode 100644 index 0000000..0aca1c6e --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.js
@@ -0,0 +1,112 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview Behavior for cr-radio-button-like elements. + */ + +/** @polymerBehavior */ +var CrRadioButtonBehaviorImpl = { + properties: { + checked: { + type: Boolean, + value: false, + reflectToAttribute: true, + observer: 'checkedChanged_', + }, + + disabled: { + type: Boolean, + value: false, + reflectToAttribute: true, + observer: 'disabledChanged_', + }, + + label: { + type: String, + value: '', // Allows the hidden$= binding to run without being set. + }, + }, + + listeners: { + 'focus': 'onFocus_', + 'blur': 'cancelRipple_', + 'pointerup': 'cancelRipple_', + }, + + hostAttributes: { + 'aria-disabled': 'false', + 'aria-checked': 'false', + role: 'radio', + tabindex: 0, + }, + + keyBindings: { + // This is mainly for screenreaders, which can perform actions on things + // that aren't focused (only focused things get synthetic click/tap events). + 'enter:keyup': 'onSelectKeyUp_', + 'space:keyup': 'onSelectKeyUp_', + }, + + /** @private */ + checkedChanged_: function() { + this.setAttribute('aria-checked', this.checked ? 'true' : 'false'); + }, + + /** + * @param {boolean} current + * @param {boolean} previous + * @private + */ + disabledChanged_: function(current, previous) { + if (previous === undefined && !this.disabled) + return; + + this.setAttribute('tabindex', this.disabled ? -1 : 0); + this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false'); + }, + + /** @private */ + onFocus_: function() { + this.ensureRipple(); + this.$$('paper-ripple').holdDown = true; + }, + + /** + * @param {!{detail: {keyboardEvent: !Event}}} e + * @private + */ + onSelectKeyUp_: function(e) { + // If ripple is disabled, or focus is on a link, don't propagate to the + // parent paper-radio-group to avoid incorrect selection. + if (this.disabled || e.detail.keyboardEvent.target.tagName == 'A') + return; + + this.click(); + }, + + /** @private */ + cancelRipple_: function() { + this.ensureRipple(); + this.$$('paper-ripple').holdDown = false; + }, + + // customize the element's ripple + _createRipple: function() { + this._rippleContainer = this.$$('.disc-wrapper'); + let ripple = Polymer.PaperRippleBehavior._createRipple(); + ripple.id = 'ink'; + ripple.setAttribute('recenters', ''); + ripple.classList.add('circle', 'toggle-ink'); + return ripple; + }, +}; + + +/** @polymerBehavior */ +const CrRadioButtonBehavior = [ + Polymer.IronA11yKeysBehavior, + Polymer.PaperRippleBehavior, + CrRadioButtonBehaviorImpl, +]; \ No newline at end of file
diff --git a/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_style_css.html b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_style_css.html new file mode 100644 index 0000000..7072cc0 --- /dev/null +++ b/ui/webui/resources/cr_elements/cr_radio_button/cr_radio_button_style_css.html
@@ -0,0 +1,99 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> +<link rel="import" href="../shared_vars_css.html"> + +<!-- Common radio-button styling for Material Design WebUI. --> +<dom-module id="cr-radio-button-style"> + <template> + <style> + :host { + --cr-radio-button-ink-size: 40px; + --cr-radio-button-size: 16px; + --cr-radio-button-checked-color: var(--google-blue-600); + + --ink-to-circle: calc((var(--cr-radio-button-ink-size) - + var(--cr-radio-button-size)) / 2); + align-items: center; + display: flex; + flex-shrink: 0; + min-height: 48px; + outline: none; + } + + :host([disabled]) { + opacity: var(--cr-disabled-opacity); + /* Disable pointer events for this whole element, as outer on-tap gets + * triggered when clicking/tapping anywhere in :host. */ + pointer-events: none; + } + + :host(:not([disabled])) { + cursor: pointer; + } + + #labelWrapper { + -webkit-margin-start: var(--cr-radio-button-label-spacing, 20px); + flex: 1; + + @apply --cr-radio-button-label; + } + + #label { + color: inherit; + } + + .disc-border, + .disc, + .disc-wrapper, + paper-ripple { + border-radius: 50%; + } + + .disc-wrapper { + height: var(--cr-radio-button-ink-size); + margin: 0 calc(-1 * var(--ink-to-circle)); + position: relative; + width: var(--cr-radio-button-ink-size); + } + + .disc-border, + .disc { + box-sizing: border-box; + height: var(--cr-radio-button-size); + left: var(--ink-to-circle); + position: absolute; + top: var(--ink-to-circle); + width: var(--cr-radio-button-size); + } + + .disc-border { + border: 2px solid var(--google-grey-700); + } + + :host([checked]) .disc-border { + border-color: var(--cr-radio-button-checked-color); + } + + .disc { + background-color: transparent; + transform: scale(0); + transition: border-color 200ms, transform 200ms; + } + + :host([checked]) .disc { + background-color: var(--cr-radio-button-checked-color); + transform: scale(0.5); + } + + paper-ripple { + --paper-ripple-opacity: 0.1; + color: var(--google-grey-900); + } + + :host([checked]) paper-ripple { + color: var(--google-blue-600); + } + </style> + </template> +</dom-module>
diff --git a/ui/webui/resources/cr_elements/cr_toggle/cr_toggle.html b/ui/webui/resources/cr_elements/cr_toggle/cr_toggle.html index 4b3f0bd..7d30684 100644 --- a/ui/webui/resources/cr_elements/cr_toggle/cr_toggle.html +++ b/ui/webui/resources/cr_elements/cr_toggle/cr_toggle.html
@@ -14,7 +14,7 @@ :host([disabled]) { cursor: initial; - opacity: 0.38; + opacity: var(--cr-disabled-opacity); pointer-events: none; }
diff --git a/ui/webui/resources/cr_elements/shared_style_css.html b/ui/webui/resources/cr_elements/shared_style_css.html index 175dc75..28cabebb 100644 --- a/ui/webui/resources/cr_elements/shared_style_css.html +++ b/ui/webui/resources/cr_elements/shared_style_css.html
@@ -54,11 +54,11 @@ min-height: 1px; } - [selectable]:focus, - [selectable] > :focus { + [selectable]:not(paper-radio-group):focus, + [selectable]:not(paper-radio-group) > :focus { @apply --cr-selectable-focus; } - [selectable] > * { + [selectable]:not(paper-radio-group) > * { @apply --cr-actionable; }
diff --git a/ui/webui/resources/cr_elements/shared_vars_css.html b/ui/webui/resources/cr_elements/shared_vars_css.html index 3ffc0b3..ef0dfdb 100644 --- a/ui/webui/resources/cr_elements/shared_vars_css.html +++ b/ui/webui/resources/cr_elements/shared_vars_css.html
@@ -119,6 +119,7 @@ --cr-container-shadow-max-opacity: 1; /** MD Refresh Styles */ + --cr-disabled-opacity: 0.38; --google-blue-600: #1A73E8; --google-grey-200: #E8EAED; --google-grey-400: #BDC1C6;
diff --git a/ui/webui/resources/cr_elements_resources.grdp b/ui/webui/resources/cr_elements_resources.grdp index b3b2d42..0c8e879 100644 --- a/ui/webui/resources/cr_elements_resources.grdp +++ b/ui/webui/resources/cr_elements_resources.grdp
@@ -78,6 +78,26 @@ file="../../webui/resources/cr_elements/cr_link_row/cr_link_row.js" type="chrome_html" compress="gzip" /> + <structure name="IDR_CR_ELEMENTS_CR_RADIO_BUTTON_HTML" + file="../../webui/resources/cr_elements/cr_radio_button/cr_radio_button.html" + type="chrome_html" + compress="gzip" /> + <structure name="IDR_CR_ELEMENTS_CR_RADIO_BUTTON_JS" + file="../../webui/resources/cr_elements/cr_radio_button/cr_radio_button.js" + type="chrome_html" + compress="gzip" /> + <structure name="IDR_CR_ELEMENTS_CR_RADIO_BUTTON_BEHAVIOR_HTML" + file="../../webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.html" + type="chrome_html" + compress="gzip" /> + <structure name="IDR_CR_ELEMENTS_CR_RADIO_BUTTON_BEHAVIOR_JS" + file="../../webui/resources/cr_elements/cr_radio_button/cr_radio_button_behavior.js" + type="chrome_html" + compress="gzip" /> + <structure name="IDR_CR_ELEMENTS_CR_RADIO_BUTTON_STYLE_CSS_HTML" + file="../../webui/resources/cr_elements/cr_radio_button/cr_radio_button_style_css.html" + type="chrome_html" + compress="gzip" /> <if expr="chromeos"> <structure name="IDR_CR_ELEMENTS_CHROMEOS_CR_PICTURE_CR_CAMERA_HTML" file="../../webui/resources/cr_elements/chromeos/cr_picture/cr_camera.html"