diff --git a/DEPS b/DEPS index f2811e5..59838de6 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': '95e2b91d76d60ae69588ca700211146aabddbe5a', + 'skia_revision': '8a95244f626c2f7d4b66c8ca18266c2b0640bebb', # 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': '0cb7b82ecaab1aeb72ec695c0aaaeda26d3513b4', + 'v8_revision': '376d927a20a21470c53f62c8528ba71885ff0ec8', # 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': 'e88e454803a78a23d4578e5ac95a278dadfeea9f', + 'angle_revision': '54aafe58f5bd530eea25461edc4690a057a3638f', # 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. @@ -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': '3059fd7dba63773c249938b1b934b9c10143d684', + 'catapult_revision': 'b9ff578f32e76574afd53543708a694d08b841de', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -968,7 +968,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '7c0541da63f571512c49758cbc0767117997a270', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'e6256055e7db560da560829a3e249898f9685d1f', # commit position 21742 + Var('webrtc_git') + '/src.git' + '@' + '823f9135f858c9fc7526e29a180818ad7f0d408c', # commit position 21742 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/android_webview/browser/aw_autofill_client.cc b/android_webview/browser/aw_autofill_client.cc index ac07ebb..d72ffdf8 100644 --- a/android_webview/browser/aw_autofill_client.cc +++ b/android_webview/browser/aw_autofill_client.cc
@@ -218,6 +218,10 @@ return true; } +bool AwAutofillClient::AreServerCardsSupported() { + return true; +} + void AwAutofillClient::Dismissed(JNIEnv* env, const JavaParamRef<jobject>& obj) { anchor_view_.Reset();
diff --git a/android_webview/browser/aw_autofill_client.h b/android_webview/browser/aw_autofill_client.h index f3d0b8e..ce8597b 100644 --- a/android_webview/browser/aw_autofill_client.h +++ b/android_webview/browser/aw_autofill_client.h
@@ -103,6 +103,7 @@ bool IsContextSecure() override; bool ShouldShowSigninPromo() override; bool IsAutofillSupported() override; + bool AreServerCardsSupported() override; void ExecuteCommand(int id) override; void Dismissed(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index d1da1f06..bb2e5be 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -209,6 +209,8 @@ "events/event_rewriter_controller.h", "events/keyboard_driven_event_rewriter.cc", "events/keyboard_driven_event_rewriter.h", + "events/spoken_feedback_event_rewriter.cc", + "events/spoken_feedback_event_rewriter.h", "first_run/desktop_cleaner.cc", "first_run/desktop_cleaner.h", "first_run/first_run_helper.cc", @@ -794,6 +796,8 @@ "system/tray/system_tray_notifier.h", "system/tray/system_tray_view.cc", "system/tray/system_tray_view.h", + "system/tray/time_to_click_recorder.cc", + "system/tray/time_to_click_recorder.h", "system/tray/tray_background_view.cc", "system/tray/tray_background_view.h", "system/tray/tray_bubble_wrapper.cc", @@ -1579,6 +1583,7 @@ "drag_drop/drag_drop_tracker_unittest.cc", "drag_drop/drag_image_view_unittest.cc", "events/keyboard_driven_event_rewriter_unittest.cc", + "events/spoken_feedback_event_rewriter_unittest.cc", "extended_desktop_unittest.cc", "first_run/first_run_helper_unittest.cc", "focus_cycler_unittest.cc",
diff --git a/ash/events/OWNERS b/ash/events/OWNERS new file mode 100644 index 0000000..fbd7277 --- /dev/null +++ b/ash/events/OWNERS
@@ -0,0 +1 @@ +per-file spoken_feedback_event_rewriter*=file://ui/accessibility/OWNERS
diff --git a/ash/events/event_rewriter_controller.cc b/ash/events/event_rewriter_controller.cc index e8546e96..91871fd6 100644 --- a/ash/events/event_rewriter_controller.cc +++ b/ash/events/event_rewriter_controller.cc
@@ -9,10 +9,12 @@ #include "ash/display/mirror_window_controller.h" #include "ash/display/window_tree_host_manager.h" #include "ash/events/keyboard_driven_event_rewriter.h" +#include "ash/events/spoken_feedback_event_rewriter.h" #include "ash/shell.h" #include "ui/aura/env.h" #include "ui/aura/window_tree_host.h" #include "ui/events/event_rewriter.h" +#include "ui/events/event_sink.h" #include "ui/events/event_source.h" namespace ash { @@ -25,6 +27,11 @@ std::make_unique<KeyboardDrivenEventRewriter>(); keyboard_driven_event_rewriter_ = keyboard_driven_event_rewriter.get(); AddEventRewriter(std::move(keyboard_driven_event_rewriter)); + + std::unique_ptr<SpokenFeedbackEventRewriter> spoken_feedback_event_rewriter = + std::make_unique<SpokenFeedbackEventRewriter>(); + spoken_feedback_event_rewriter_ = spoken_feedback_event_rewriter.get(); + AddEventRewriter(std::move(spoken_feedback_event_rewriter)); } EventRewriterController::~EventRewriterController() { @@ -67,6 +74,17 @@ keyboard_driven_event_rewriter_->set_arrow_to_tab_rewriting_enabled(enabled); } +void EventRewriterController::SetSpokenFeedbackEventRewriterDelegate( + mojom::SpokenFeedbackEventRewriterDelegatePtr delegate) { + spoken_feedback_event_rewriter_->SetDelegate(std::move(delegate)); +} + +void EventRewriterController::OnUnhandledSpokenFeedbackEvent( + std::unique_ptr<ui::Event> event) { + spoken_feedback_event_rewriter_->OnUnhandledSpokenFeedbackEvent( + std::move(event)); +} + void EventRewriterController::OnHostInitialized(aura::WindowTreeHost* host) { for (const auto& rewriter : rewriters_) host->GetEventSource()->AddEventRewriter(rewriter.get());
diff --git a/ash/events/event_rewriter_controller.h b/ash/events/event_rewriter_controller.h index 05c6637..04ef56f8 100644 --- a/ash/events/event_rewriter_controller.h +++ b/ash/events/event_rewriter_controller.h
@@ -22,6 +22,7 @@ namespace ash { class KeyboardDrivenEventRewriter; +class SpokenFeedbackEventRewriter; // Owns ui::EventRewriters and ensures that they are added to each root window // EventSource, current and future, in the order that they are added to this. @@ -42,6 +43,10 @@ // mojom::EventRewriterController: void SetKeyboardDrivenEventRewriterEnabled(bool enabled) override; void SetArrowToTabRewritingEnabled(bool enabled) override; + void SetSpokenFeedbackEventRewriterDelegate( + mojom::SpokenFeedbackEventRewriterDelegatePtr delegate) override; + void OnUnhandledSpokenFeedbackEvent( + std::unique_ptr<ui::Event> event) override; // aura::EnvObserver: void OnWindowInitialized(aura::Window* window) override {} @@ -51,9 +56,12 @@ // The |EventRewriter|s managed by this controller. std::vector<std::unique_ptr<ui::EventRewriter>> rewriters_; - // A weak pointer the KeyboardDrivenEventRewriter owned in |rewriters_|. + // A weak pointer to the KeyboardDrivenEventRewriter owned in |rewriters_|. KeyboardDrivenEventRewriter* keyboard_driven_event_rewriter_; + // A weak pointer to the SpokenFeedbackEventRewriter owned in |rewriters_|. + SpokenFeedbackEventRewriter* spoken_feedback_event_rewriter_; + // Bindings for the EventRewriterController mojo interface. mojo::BindingSet<mojom::EventRewriterController> bindings_;
diff --git a/ash/events/spoken_feedback_event_rewriter.cc b/ash/events/spoken_feedback_event_rewriter.cc new file mode 100644 index 0000000..96ce99e7 --- /dev/null +++ b/ash/events/spoken_feedback_event_rewriter.cc
@@ -0,0 +1,61 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/events/spoken_feedback_event_rewriter.h" + +#include <string> +#include <utility> + +#include "ash/accessibility/accessibility_controller.h" +#include "ash/shell.h" +#include "ui/aura/window_tree_host.h" +#include "ui/events/event.h" +#include "ui/events/event_sink.h" + +namespace ash { + +SpokenFeedbackEventRewriter::SpokenFeedbackEventRewriter() = default; + +SpokenFeedbackEventRewriter::~SpokenFeedbackEventRewriter() = default; + +void SpokenFeedbackEventRewriter::SetDelegate( + mojom::SpokenFeedbackEventRewriterDelegatePtr delegate) { + delegate_ = std::move(delegate); +} + +void SpokenFeedbackEventRewriter::OnUnhandledSpokenFeedbackEvent( + std::unique_ptr<ui::Event> event) const { + DCHECK(event->IsKeyEvent()) << "Unexpected unhandled event type"; + // For now, these events are sent directly to the primary display's EventSink. + // TODO: Pass the event to the original EventSource, not the primary one. + ui::EventSource* source = + Shell::GetPrimaryRootWindow()->GetHost()->GetEventSource(); + if (SendEventToEventSource(source, event.get()).dispatcher_destroyed) { + VLOG(0) << "Undispatched key " << event->AsKeyEvent()->key_code() + << " due to destroyed dispatcher."; + } +} + +ui::EventRewriteStatus SpokenFeedbackEventRewriter::RewriteEvent( + const ui::Event& event, + std::unique_ptr<ui::Event>* new_event) { + if (!delegate_.is_bound() || !event.IsKeyEvent()) + return ui::EVENT_REWRITE_CONTINUE; + + if (!Shell::Get()->accessibility_controller()->IsSpokenFeedbackEnabled()) + return ui::EVENT_REWRITE_CONTINUE; + + // TODO: Avoid passing events that will be reposted for system-wide dispatch. + delegate_->DispatchKeyEventToChromeVox(ui::Event::Clone(event)); + return ui::EVENT_REWRITE_DISCARD; +} + +ui::EventRewriteStatus SpokenFeedbackEventRewriter::NextDispatchEvent( + const ui::Event& last_event, + std::unique_ptr<ui::Event>* new_event) { + NOTREACHED(); + return ui::EVENT_REWRITE_CONTINUE; +} + +} // namespace ash
diff --git a/ash/events/spoken_feedback_event_rewriter.h b/ash/events/spoken_feedback_event_rewriter.h new file mode 100644 index 0000000..cd3568c --- /dev/null +++ b/ash/events/spoken_feedback_event_rewriter.h
@@ -0,0 +1,50 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_EVENTS_SPOKEN_FEEDBACK_EVENT_REWRITER_H_ +#define ASH_EVENTS_SPOKEN_FEEDBACK_EVENT_REWRITER_H_ + +#include "ash/ash_export.h" +#include "ash/public/interfaces/event_rewriter_controller.mojom.h" +#include "base/macros.h" +#include "ui/events/event_rewriter.h" + +namespace ash { + +// SpokenFeedbackEventRewriter sends key events to ChromeVox (via the delegate) +// when spoken feedback is enabled. Continues dispatch of unhandled key events. +// TODO(http://crbug.com/839541): Avoid reposting unhandled events. +class ASH_EXPORT SpokenFeedbackEventRewriter : public ui::EventRewriter { + public: + SpokenFeedbackEventRewriter(); + ~SpokenFeedbackEventRewriter() override; + + // Set the delegate used to send key events to the ChromeVox extension. + void SetDelegate(mojom::SpokenFeedbackEventRewriterDelegatePtr delegate); + mojom::SpokenFeedbackEventRewriterDelegatePtr* get_delegate_for_testing() { + return &delegate_; + } + + // Continue dispatch of events that were unhandled by the ChromeVox extension. + // NOTE: These events may be delivered out-of-order from non-ChromeVox events. + void OnUnhandledSpokenFeedbackEvent(std::unique_ptr<ui::Event> event) const; + + private: + // ui::EventRewriter: + ui::EventRewriteStatus RewriteEvent( + const ui::Event& event, + std::unique_ptr<ui::Event>* new_event) override; + ui::EventRewriteStatus NextDispatchEvent( + const ui::Event& last_event, + std::unique_ptr<ui::Event>* new_event) override; + + // The delegate used to send key events to the ChromeVox extension. + mojom::SpokenFeedbackEventRewriterDelegatePtr delegate_; + + DISALLOW_COPY_AND_ASSIGN(SpokenFeedbackEventRewriter); +}; + +} // namespace ash + +#endif // ASH_EVENTS_SPOKEN_FEEDBACK_EVENT_REWRITER_H_
diff --git a/ash/events/spoken_feedback_event_rewriter_unittest.cc b/ash/events/spoken_feedback_event_rewriter_unittest.cc new file mode 100644 index 0000000..ca9aad877 --- /dev/null +++ b/ash/events/spoken_feedback_event_rewriter_unittest.cc
@@ -0,0 +1,214 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/events/spoken_feedback_event_rewriter.h" + +#include <memory> +#include <vector> + +#include "ash/accessibility/accessibility_controller.h" +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "base/macros.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "ui/aura/window.h" +#include "ui/aura/window_tree_host.h" +#include "ui/events/event.h" +#include "ui/events/event_constants.h" +#include "ui/events/event_rewriter.h" +#include "ui/events/keycodes/keyboard_codes.h" +#include "ui/events/test/event_generator.h" + +namespace ash { +namespace { + +// An event rewriter that simply records all events that it receives. +class EventRecorder : public ui::EventRewriter { + public: + EventRecorder() = default; + ~EventRecorder() override = default; + + // ui::EventRewriter: + ui::EventRewriteStatus RewriteEvent( + const ui::Event& event, + std::unique_ptr<ui::Event>* new_event) override { + recorded_event_count_++; + return ui::EVENT_REWRITE_CONTINUE; + } + ui::EventRewriteStatus NextDispatchEvent( + const ui::Event& last_event, + std::unique_ptr<ui::Event>* new_event) override { + NOTREACHED(); + return ui::EVENT_REWRITE_CONTINUE; + } + + // Count of events sent to the rewriter. + size_t recorded_event_count_ = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(EventRecorder); +}; + +// A test implementation of the spoken feedback delegate interface. +class TestDelegate : public mojom::SpokenFeedbackEventRewriterDelegate { + public: + TestDelegate() : binding_(this) {} + ~TestDelegate() override = default; + + mojom::SpokenFeedbackEventRewriterDelegatePtr BindInterface() { + mojom::SpokenFeedbackEventRewriterDelegatePtr ptr; + binding_.Bind(MakeRequest(&ptr)); + return ptr; + } + + // Count of events sent to the delegate. + size_t recorded_event_count_ = 0; + + private: + // SpokenFeedbackEventRewriterDelegate: + void DispatchKeyEventToChromeVox(std::unique_ptr<ui::Event> event) override { + recorded_event_count_++; + } + + // The binding that backs the interface pointer held by the event rewriter. + mojo::Binding<ash::mojom::SpokenFeedbackEventRewriterDelegate> binding_; + + DISALLOW_COPY_AND_ASSIGN(TestDelegate); +}; + +class SpokenFeedbackEventRewriterTest : public ash::AshTestBase { + public: + SpokenFeedbackEventRewriterTest() { + spoken_feedback_event_rewriter_.SetDelegate(delegate_.BindInterface()); + } + + void SetUp() override { + ash::AshTestBase::SetUp(); + generator_ = &AshTestBase::GetEventGenerator(); + CurrentContext()->GetHost()->GetEventSource()->AddEventRewriter( + &spoken_feedback_event_rewriter_); + CurrentContext()->GetHost()->GetEventSource()->AddEventRewriter( + &event_recorder_); + } + + void TearDown() override { + CurrentContext()->GetHost()->GetEventSource()->RemoveEventRewriter( + &event_recorder_); + CurrentContext()->GetHost()->GetEventSource()->RemoveEventRewriter( + &spoken_feedback_event_rewriter_); + generator_ = nullptr; + ash::AshTestBase::TearDown(); + } + + // Flush any messages to the test delegate and return events it has recorded. + size_t GetDelegateRecordedEventCount() { + spoken_feedback_event_rewriter_.get_delegate_for_testing() + ->FlushForTesting(); + return delegate_.recorded_event_count_; + } + + protected: + // A test spoken feedback delegate; simulates ChromeVox. + TestDelegate delegate_; + // Generates ui::Events from simulated user input. + ui::test::EventGenerator* generator_ = nullptr; + // Records events delivered to the next event rewriter after spoken feedback. + EventRecorder event_recorder_; + + SpokenFeedbackEventRewriter spoken_feedback_event_rewriter_; + + private: + DISALLOW_COPY_AND_ASSIGN(SpokenFeedbackEventRewriterTest); +}; + +// The delegate should not intercept events when spoken feedback is disabled. +TEST_F(SpokenFeedbackEventRewriterTest, EventsNotConsumedWhenDisabled) { + AccessibilityController* controller = + Shell::Get()->accessibility_controller(); + EXPECT_FALSE(controller->IsSpokenFeedbackEnabled()); + + generator_->PressKey(ui::VKEY_A, ui::EF_NONE); + EXPECT_EQ(1U, event_recorder_.recorded_event_count_); + EXPECT_EQ(0U, GetDelegateRecordedEventCount()); + generator_->ReleaseKey(ui::VKEY_A, ui::EF_NONE); + EXPECT_EQ(2U, event_recorder_.recorded_event_count_); + EXPECT_EQ(0U, GetDelegateRecordedEventCount()); + + generator_->ClickLeftButton(); + EXPECT_EQ(4U, event_recorder_.recorded_event_count_); + EXPECT_EQ(0U, GetDelegateRecordedEventCount()); + + generator_->GestureTapAt(gfx::Point()); + EXPECT_EQ(6U, event_recorder_.recorded_event_count_); + EXPECT_EQ(0U, GetDelegateRecordedEventCount()); +} + +// The delegate should intercept key events when spoken feedback is enabled. +TEST_F(SpokenFeedbackEventRewriterTest, KeyEventsConsumedWhenEnabled) { + AccessibilityController* controller = + Shell::Get()->accessibility_controller(); + controller->SetSpokenFeedbackEnabled(true, A11Y_NOTIFICATION_NONE); + EXPECT_TRUE(controller->IsSpokenFeedbackEnabled()); + + generator_->PressKey(ui::VKEY_A, ui::EF_NONE); + EXPECT_EQ(0U, event_recorder_.recorded_event_count_); + EXPECT_EQ(1U, GetDelegateRecordedEventCount()); + generator_->ReleaseKey(ui::VKEY_A, ui::EF_NONE); + EXPECT_EQ(0U, event_recorder_.recorded_event_count_); + EXPECT_EQ(2U, GetDelegateRecordedEventCount()); + + generator_->ClickLeftButton(); + EXPECT_EQ(2U, event_recorder_.recorded_event_count_); + EXPECT_EQ(2U, GetDelegateRecordedEventCount()); + + generator_->GestureTapAt(gfx::Point()); + EXPECT_EQ(4U, event_recorder_.recorded_event_count_); + EXPECT_EQ(2U, GetDelegateRecordedEventCount()); +} + +// Asynchronously unhandled events should be sent to subsequent rewriters. +TEST_F(SpokenFeedbackEventRewriterTest, UnhandledEventsSentToOtherRewriters) { + spoken_feedback_event_rewriter_.OnUnhandledSpokenFeedbackEvent( + std::make_unique<ui::KeyEvent>(ui::ET_KEY_PRESSED, ui::VKEY_A, + ui::EF_NONE)); + EXPECT_EQ(1U, event_recorder_.recorded_event_count_); + spoken_feedback_event_rewriter_.OnUnhandledSpokenFeedbackEvent( + std::make_unique<ui::KeyEvent>(ui::ET_KEY_RELEASED, ui::VKEY_A, + ui::EF_NONE)); + EXPECT_EQ(2U, event_recorder_.recorded_event_count_); +} + +TEST_F(SpokenFeedbackEventRewriterTest, KeysNotEatenWithChromeVoxDisabled) { + AccessibilityController* controller = + Shell::Get()->accessibility_controller(); + EXPECT_FALSE(controller->IsSpokenFeedbackEnabled()); + + // Send Search+Shift+Right. + generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN); + EXPECT_EQ(1U, event_recorder_.recorded_event_count_); + generator_->PressKey(ui::VKEY_SHIFT, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN); + EXPECT_EQ(2U, event_recorder_.recorded_event_count_); + + // Mock successful commands lookup and dispatch; shouldn't matter either way. + generator_->PressKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN); + EXPECT_EQ(3U, event_recorder_.recorded_event_count_); + + // Released keys shouldn't get eaten. + generator_->ReleaseKey(ui::VKEY_RIGHT, + ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN); + generator_->ReleaseKey(ui::VKEY_SHIFT, ui::EF_COMMAND_DOWN); + generator_->ReleaseKey(ui::VKEY_LWIN, 0); + EXPECT_EQ(6U, event_recorder_.recorded_event_count_); + + // Try releasing more keys. + generator_->ReleaseKey(ui::VKEY_RIGHT, 0); + generator_->ReleaseKey(ui::VKEY_SHIFT, 0); + generator_->ReleaseKey(ui::VKEY_LWIN, 0); + EXPECT_EQ(9U, event_recorder_.recorded_event_count_); + + EXPECT_EQ(0U, GetDelegateRecordedEventCount()); +} + +} // namespace +} // namespace ash
diff --git a/ash/public/interfaces/event_rewriter_controller.mojom b/ash/public/interfaces/event_rewriter_controller.mojom index 4917b6ee..b044de8 100644 --- a/ash/public/interfaces/event_rewriter_controller.mojom +++ b/ash/public/interfaces/event_rewriter_controller.mojom
@@ -4,6 +4,14 @@ module ash.mojom; +import "ui/events/mojo/event.mojom"; + +// Allows a client to implement spoken feedback features; used for ChromeVox. +interface SpokenFeedbackEventRewriterDelegate { + // Used to send key events to the ChromeVox extension. + DispatchKeyEventToChromeVox(ui.mojom.Event event); +}; + // Allows clients to toggle some event rewriting behavior. interface EventRewriterController { // Enables the KeyboardDrivenEventRewriter, which is disabled by default. @@ -13,4 +21,12 @@ // If true, Shift + Arrow keys are rewritten to Tab/Shift-Tab keys. // This only applies when the KeyboardDrivenEventRewriter is active. SetArrowToTabRewritingEnabled(bool enabled); + + // Set the delegate used by the spoken feedback event rewriter. + SetSpokenFeedbackEventRewriterDelegate( + SpokenFeedbackEventRewriterDelegate delegate); + + // Continue dispatch of key events that were unhandled by ChromeVox. + // TODO(crbug.com/839541): ChromeVox should not repost unhandled events. + OnUnhandledSpokenFeedbackEvent(ui.mojom.Event event); };
diff --git a/ash/system/status_area_widget.cc b/ash/system/status_area_widget.cc index e7fba94..40084fe 100644 --- a/ash/system/status_area_widget.cc +++ b/ash/system/status_area_widget.cc
@@ -189,6 +189,8 @@ TrayBackgroundView* StatusAreaWidget::GetSystemTrayAnchor() const { if (overview_button_tray_->visible()) return overview_button_tray_.get(); + if (unified_system_tray_) + return unified_system_tray_.get(); return system_tray_.get(); }
diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc index 0ff6ff7..ad1a282 100644 --- a/ash/system/tray/system_tray.cc +++ b/ash/system/tray/system_tray.cc
@@ -620,13 +620,13 @@ UserMetricsRecorder::RecordUserClickOnTray( LoginMetricsRecorder::TrayClickTarget::kSystemTray); - last_button_clicked_ = base::TimeTicks::Now(); - if (features::IsSystemTrayUnifiedEnabled()) { return shelf()->GetStatusAreaWidget()->unified_system_tray()->PerformAction( event); } + last_button_clicked_ = base::TimeTicks::Now(); + // If we're already showing a full system tray menu, either default or // detailed menu, hide it; otherwise, show it (and hide any popup that's // currently shown). @@ -658,6 +658,14 @@ : nullptr; } +void SystemTray::SetVisible(bool visible) { + // TODO(tetsui): Port logic in SystemTrayItems that is unrelated to SystemTray + // UI, and stop instantiating SystemTray instead of hiding it when + // UnifiedSystemTray is enabled. + TrayBackgroundView::SetVisible(!features::IsSystemTrayUnifiedEnabled() && + visible); +} + void SystemTray::BubbleViewDestroyed() { if (system_bubble_) { system_bubble_->bubble()->BubbleViewDestroyed(); @@ -747,16 +755,4 @@ } } -TimeToClickRecorder::TimeToClickRecorder(SystemTray* tray) : tray_(tray) {} - -void TimeToClickRecorder::OnEvent(ui::Event* event) { - // Ignore if the event is neither click nor tap. - if (event->type() != ui::ET_MOUSE_PRESSED && - event->type() != ui::ET_GESTURE_TAP) { - return; - } - - tray_->RecordTimeToClick(); -} - } // namespace ash
diff --git a/ash/system/tray/system_tray.h b/ash/system/tray/system_tray.h index 8529a99..8d0db51 100644 --- a/ash/system/tray/system_tray.h +++ b/ash/system/tray/system_tray.h
@@ -12,6 +12,7 @@ #include "ash/ash_export.h" #include "ash/system/tray/system_tray_bubble.h" #include "ash/system/tray/system_tray_view.h" +#include "ash/system/tray/time_to_click_recorder.h" #include "ash/system/tray/tray_background_view.h" #include "base/callback.h" #include "base/macros.h" @@ -53,7 +54,8 @@ // manages all the SystemTrayItem controllers, creates icon views that appear in // the tray, creates the bubble menu and fills the menu with items. It is also // the view that contains the icons in the tray. -class ASH_EXPORT SystemTray : public TrayBackgroundView { +class ASH_EXPORT SystemTray : public TrayBackgroundView, + public TimeToClickRecorder::Delegate { public: explicit SystemTray(Shelf* shelf); ~SystemTray() override; @@ -133,10 +135,6 @@ // Returns TrayIME object if present or null otherwise. TrayIME* GetTrayIME() const; - // Record TimeToClick metrics and reset |last_button_clicked_|. Called by - // TimeToClickRecorder which is system tray view's PreTargetHandler. - void RecordTimeToClick(); - // Determines if it's ok to switch away from the currently active user. Screen // casting may block this (or at least throw up a confirmation dialog). Calls // |callback| with the result. @@ -153,6 +151,7 @@ void CloseBubble() override; void ShowBubble(bool show_by_click) override; views::TrayBubbleView* GetBubbleView() override; + void SetVisible(bool visible) override; // views::TrayBubbleView::Delegate: void BubbleViewDestroyed() override; @@ -162,6 +161,9 @@ bool ShouldEnableExtraKeyboardAccessibility() override; void HideBubble(const views::TrayBubbleView* bubble_view) override; + // TimeToClickRecorder::Delegate: + void RecordTimeToClick() override; + ScreenTrayItem* GetScreenShareItem() { return screen_share_tray_item_; } ScreenTrayItem* GetScreenCaptureItem() { return screen_capture_tray_item_; } @@ -256,22 +258,6 @@ DISALLOW_COPY_AND_ASSIGN(SystemTray); }; -// An event handler that will be installed as system tray view PreTargetHandler -// to record TimeToClick metrics. -class TimeToClickRecorder : public ui::EventHandler { - public: - TimeToClickRecorder(SystemTray* tray); - ~TimeToClickRecorder() override = default; - - private: - // ui::EventHandler: - void OnEvent(ui::Event* event) override; - - SystemTray* const tray_; - - DISALLOW_COPY_AND_ASSIGN(TimeToClickRecorder); -}; - } // namespace ash #endif // ASH_SYSTEM_TRAY_SYSTEM_TRAY_H_
diff --git a/ash/system/tray/system_tray_view.cc b/ash/system/tray/system_tray_view.cc index daf81229..b9b34c0 100644 --- a/ash/system/tray/system_tray_view.cc +++ b/ash/system/tray/system_tray_view.cc
@@ -51,11 +51,10 @@ SystemTrayType system_tray_type, const std::vector<ash::SystemTrayItem*>& items) : time_to_click_recorder_( - std::make_unique<TimeToClickRecorder>(system_tray)), + std::make_unique<TimeToClickRecorder>(system_tray, this)), items_(items), system_tray_type_(system_tray_type) { SetLayoutManager(std::make_unique<BottomAlignedBoxLayout>()); - AddPreTargetHandler(time_to_click_recorder_.get()); } SystemTrayView::~SystemTrayView() {
diff --git a/ash/system/tray/time_to_click_recorder.cc b/ash/system/tray/time_to_click_recorder.cc new file mode 100644 index 0000000..b3509f87 --- /dev/null +++ b/ash/system/tray/time_to_click_recorder.cc
@@ -0,0 +1,28 @@ +// 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 "ash/system/tray/time_to_click_recorder.h" + +#include "ui/events/event.h" +#include "ui/views/view.h" + +namespace ash { + +TimeToClickRecorder::TimeToClickRecorder(Delegate* delegate, + views::View* target_view) + : delegate_(delegate) { + target_view->AddPreTargetHandler(this); +} + +void TimeToClickRecorder::OnEvent(ui::Event* event) { + // Ignore if the event is neither click nor tap. + if (event->type() != ui::ET_MOUSE_PRESSED && + event->type() != ui::ET_GESTURE_TAP) { + return; + } + + delegate_->RecordTimeToClick(); +} + +} // namespace ash
diff --git a/ash/system/tray/time_to_click_recorder.h b/ash/system/tray/time_to_click_recorder.h new file mode 100644 index 0000000..4e26b9d --- /dev/null +++ b/ash/system/tray/time_to_click_recorder.h
@@ -0,0 +1,43 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_SYSTEM_TRAY_TIME_TO_CLICK_RECORDER_H_ +#define ASH_SYSTEM_TRAY_TIME_TO_CLICK_RECORDER_H_ + +#include "ui/events/event_handler.h" + +namespace views { +class View; +} // namespace views + +namespace ash { + +// An event handler that will be installed as PreTargetHandler of |target_view| +// to record TimeToClick metrics. +class TimeToClickRecorder : public ui::EventHandler { + public: + class Delegate { + public: + virtual ~Delegate() {} + + // Record TimeToClick metrics. Called by TimeToClickRecorder which is a + // PreTargetHandler of |target_view|. + virtual void RecordTimeToClick() = 0; + }; + + TimeToClickRecorder(Delegate* delegate, views::View* target_view); + ~TimeToClickRecorder() override = default; + + private: + // ui::EventHandler: + void OnEvent(ui::Event* event) override; + + Delegate* const delegate_; + + DISALLOW_COPY_AND_ASSIGN(TimeToClickRecorder); +}; + +} // namespace ash + +#endif // ASH_SYSTEM_TRAY_TIME_TO_CLICK_RECORDER_H_
diff --git a/ash/system/unified/unified_system_tray.cc b/ash/system/unified/unified_system_tray.cc index 633dfa6..e4e70df 100644 --- a/ash/system/unified/unified_system_tray.cc +++ b/ash/system/unified/unified_system_tray.cc
@@ -4,8 +4,12 @@ #include "ash/system/unified/unified_system_tray.h" +#include "ash/shell.h" +#include "ash/system/date/date_view.h" +#include "ash/system/model/system_tray_model.h" #include "ash/system/status_area_widget.h" #include "ash/system/tray/system_tray.h" +#include "ash/system/tray/tray_container.h" #include "ash/system/unified/unified_system_tray_bubble.h" #include "ash/system/unified/unified_system_tray_model.h" #include "ash/system/web_notification/ash_popup_alignment_delegate.h" @@ -80,7 +84,7 @@ if (owner_->IsBubbleShown()) return false; - owner_->ShowBubbleInternal(); + owner_->ShowBubbleInternal(show_by_click); return true; } @@ -96,11 +100,11 @@ : TrayBackgroundView(shelf), ui_delegate_(std::make_unique<UiDelegate>(this)), model_(std::make_unique<UnifiedSystemTrayModel>()) { - // On the first step, features in the status area button are still provided by - // TrayViews in SystemTray. - // TODO(tetsui): Remove SystemTray from StatusAreaWidget and provide these - // features from UnifiedSystemTray. - SetVisible(false); + tray_container()->AddChildView( + new tray::TimeView(tray::TimeView::ClockLayout::HORIZONTAL_CLOCK, + Shell::Get()->system_tray_model()->clock())); + SetInkDropMode(InkDropMode::ON); + SetVisible(true); } UnifiedSystemTray::~UnifiedSystemTray() = default; @@ -138,16 +142,14 @@ void UnifiedSystemTray::ClickedOutsideBubble() {} -void UnifiedSystemTray::ShowBubbleInternal() { - bubble_ = std::make_unique<UnifiedSystemTrayBubble>(this); - // TODO(tetsui): Call its own SetIsActive. See the comment in the ctor. - shelf()->GetStatusAreaWidget()->system_tray()->SetIsActive(true); +void UnifiedSystemTray::ShowBubbleInternal(bool show_by_click) { + bubble_ = std::make_unique<UnifiedSystemTrayBubble>(this, show_by_click); + SetIsActive(true); } void UnifiedSystemTray::HideBubbleInternal() { bubble_.reset(); - // TODO(tetsui): Call its own SetIsActive. See the comment in the ctor. - shelf()->GetStatusAreaWidget()->system_tray()->SetIsActive(false); + SetIsActive(false); } } // namespace ash
diff --git a/ash/system/unified/unified_system_tray.h b/ash/system/unified/unified_system_tray.h index 0b7a958..09aeacc 100644 --- a/ash/system/unified/unified_system_tray.h +++ b/ash/system/unified/unified_system_tray.h
@@ -51,7 +51,7 @@ class UiDelegate; // Forwarded from UiDelegate. - void ShowBubbleInternal(); + void ShowBubbleInternal(bool show_by_click); void HideBubbleInternal(); std::unique_ptr<UiDelegate> ui_delegate_;
diff --git a/ash/system/unified/unified_system_tray_bubble.cc b/ash/system/unified/unified_system_tray_bubble.cc index 5d67e56..17f6948 100644 --- a/ash/system/unified/unified_system_tray_bubble.cc +++ b/ash/system/unified/unified_system_tray_bubble.cc
@@ -10,6 +10,7 @@ #include "ash/system/unified/unified_system_tray.h" #include "ash/system/unified/unified_system_tray_controller.h" #include "ash/system/unified/unified_system_tray_view.h" +#include "base/metrics/histogram_macros.h" namespace ash { @@ -19,11 +20,15 @@ } // namespace -UnifiedSystemTrayBubble::UnifiedSystemTrayBubble(UnifiedSystemTray* tray) +UnifiedSystemTrayBubble::UnifiedSystemTrayBubble(UnifiedSystemTray* tray, + bool show_by_click) : controller_(std::make_unique<UnifiedSystemTrayController>( tray->model(), tray->shelf()->GetStatusAreaWidget()->system_tray())), tray_(tray) { + if (show_by_click) + time_shown_by_click_ = base::TimeTicks::Now(); + views::TrayBubbleView::InitParams init_params; init_params.anchor_alignment = views::TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM; init_params.min_width = kTrayMenuWidth; @@ -40,6 +45,8 @@ kPaddingFromScreenTop - bubble_view->GetBorderInsets().height(); auto* unified_view = controller_->CreateView(); + time_to_click_recorder_ = + std::make_unique<TimeToClickRecorder>(this, unified_view); unified_view->SetMaxHeight(max_height); bubble_view->SetMaxHeight(max_height); bubble_view->AddChildView(unified_view); @@ -77,4 +84,15 @@ tray_->CloseBubble(); } +void UnifiedSystemTrayBubble::RecordTimeToClick() { + // Ignore if the tray bubble is not opened by click. + if (!time_shown_by_click_) + return; + + UMA_HISTOGRAM_TIMES("ChromeOS.SystemTray.TimeToClick", + base::TimeTicks::Now() - time_shown_by_click_.value()); + + time_shown_by_click_.reset(); +} + } // namespace ash
diff --git a/ash/system/unified/unified_system_tray_bubble.h b/ash/system/unified/unified_system_tray_bubble.h index 9e9a32d..82fff38 100644 --- a/ash/system/unified/unified_system_tray_bubble.h +++ b/ash/system/unified/unified_system_tray_bubble.h
@@ -7,7 +7,10 @@ #include <memory> +#include "ash/system/tray/time_to_click_recorder.h" #include "base/macros.h" +#include "base/optional.h" +#include "base/time/time.h" #include "ui/views/widget/widget_observer.h" namespace views { @@ -23,14 +26,18 @@ // Shows the bubble on the constructor, and closes the bubble on the destructor. // It is possible that the bubble widget is closed on deactivation. In such // case, this class calls UnifiedSystemTray::CloseBubble() to delete itself. -class UnifiedSystemTrayBubble : public views::WidgetObserver { +class UnifiedSystemTrayBubble : public views::WidgetObserver, + public TimeToClickRecorder::Delegate { public: - explicit UnifiedSystemTrayBubble(UnifiedSystemTray* tray); + explicit UnifiedSystemTrayBubble(UnifiedSystemTray* tray, bool show_by_click); ~UnifiedSystemTrayBubble() override; // views::WidgetObserver: void OnWidgetDestroying(views::Widget* widget) override; + // TimeToClickRecorder::Delegate: + void RecordTimeToClick() override; + private: // Controller of UnifiedSystemTrayView. As the view is owned by views // hierarchy, we have to own the controller here. @@ -46,6 +53,13 @@ // In order to do this, we observe OnWidgetDestroying(). views::Widget* bubble_widget_ = nullptr; + // PreTargetHandler of |unified_view_| to record TimeToClick metrics. Owned. + std::unique_ptr<TimeToClickRecorder> time_to_click_recorder_; + + // The time the bubble is created. If the bubble is not created by button + // click (|show_by_click| in ctor is false), it is not set. + base::Optional<base::TimeTicks> time_shown_by_click_; + DISALLOW_COPY_AND_ASSIGN(UnifiedSystemTrayBubble); };
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc index 7e3077c..78d8b61f 100644 --- a/ash/system/unified/unified_system_tray_controller.cc +++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -73,9 +73,6 @@ std::make_unique<UnifiedBrightnessSliderController>(model_); unified_view_->AddSliderView(brightness_slider_controller_->CreateView()); - time_to_click_recorder_ = std::make_unique<TimeToClickRecorder>(system_tray_); - unified_view_->AddPreTargetHandler(time_to_click_recorder_.get()); - return unified_view_; }
diff --git a/ash/system/unified/unified_system_tray_controller.h b/ash/system/unified/unified_system_tray_controller.h index eb2e97b..52e11cf 100644 --- a/ash/system/unified/unified_system_tray_controller.h +++ b/ash/system/unified/unified_system_tray_controller.h
@@ -22,7 +22,6 @@ class FeaturePodControllerBase; class SystemTray; class SystemTrayItem; -class TimeToClickRecorder; class UnifiedBrightnessSliderController; class UnifiedVolumeSliderController; class UnifiedSystemTrayModel; @@ -130,9 +129,6 @@ std::unique_ptr<UnifiedBrightnessSliderController> brightness_slider_controller_; - // PreTargetHandler of |unified_view_| to record TimeToClick metrics. Owned. - std::unique_ptr<TimeToClickRecorder> time_to_click_recorder_; - // If the previous state is expanded or not. Only valid during dragging (from // BeginDrag to EndDrag). bool was_expanded_ = true;
diff --git a/base/strings/char_traits.h b/base/strings/char_traits.h index 6cfbad5af..b193e216 100644 --- a/base/strings/char_traits.h +++ b/base/strings/char_traits.h
@@ -7,6 +7,8 @@ #include <stddef.h> +#include "base/compiler_specific.h" + namespace base { // constexpr version of http://en.cppreference.com/w/cpp/string/char_traits. @@ -61,7 +63,7 @@ constexpr int CharTraits<char>::compare(const char* s1, const char* s2, size_t n) noexcept { -#if __has_feature(cxx_constexpr_string_builtins) +#if HAS_FEATURE(cxx_constexpr_string_builtins) return __builtin_memcmp(s1, s2, n); #else for (; n; --n, ++s1, ++s2) {
diff --git a/build/android/pylib/symbols/elf_symbolizer.py b/build/android/pylib/symbols/elf_symbolizer.py index 7f256ea..1f2f918 100644 --- a/build/android/pylib/symbols/elf_symbolizer.py +++ b/build/android/pylib/symbols/elf_symbolizer.py
@@ -185,6 +185,11 @@ a2l.EnqueueRequest(addr, callback_arg) + def WaitForIdle(self): + """Waits for all the outstanding requests to complete.""" + for a2l in self._a2l_instances: + a2l.WaitForIdle() + def Join(self): """Waits for all the outstanding requests to complete and terminates.""" for a2l in self._a2l_instances:
diff --git a/build/android/pylib/symbols/elf_symbolizer_unittest.py b/build/android/pylib/symbols/elf_symbolizer_unittest.py index 1d95b15..765b5989 100755 --- a/build/android/pylib/symbols/elf_symbolizer_unittest.py +++ b/build/android/pylib/symbols/elf_symbolizer_unittest.py
@@ -117,6 +117,31 @@ symbolizer.Join() + def testWaitForIdle(self): + symbolizer = elf_symbolizer.ELFSymbolizer( + elf_file_path='/path/doesnt/matter/mock_lib1.so', + addr2line_path=_MOCK_A2L_PATH, + callback=self._callback, + max_concurrent_jobs=1) + + # Test symbols with valid name but incomplete path. + addr = _INCOMPLETE_MOCK_ADDR + exp_name = 'mock_sym_for_addr_%d' % addr + exp_source_path = None + exp_source_line = None + cb_arg = (addr, exp_name, exp_source_path, exp_source_line, False) + symbolizer.SymbolizeAsync(addr, cb_arg) + symbolizer.WaitForIdle() + + # Test symbols with no name or sym info. + addr = _UNKNOWN_MOCK_ADDR + exp_name = None + exp_source_path = None + exp_source_line = None + cb_arg = (addr, exp_name, exp_source_path, exp_source_line, False) + symbolizer.SymbolizeAsync(addr, cb_arg) + symbolizer.Join() + def _RunTest(self, max_concurrent_jobs, num_symbols): symbolizer = elf_symbolizer.ELFSymbolizer( elf_file_path='/path/doesnt/matter/mock_lib1.so',
diff --git a/chrome/VERSION b/chrome/VERSION index bc1886a..87be405d 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=68 MINOR=0 -BUILD=3423 +BUILD=3424 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java index 902f969..c51bb0e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/InterceptNavigationDelegateImpl.java
@@ -98,10 +98,6 @@ return true; } - if (navigationParams.suggestedFilename != null) { - return false; - } - TabRedirectHandler tabRedirectHandler = null; if (navigationParams.isMainFrame) { tabRedirectHandler = mTab.getTabRedirectHandler();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java index 7ea0d29..3b189acc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -522,14 +522,11 @@ mActivityTestRule.getActivity(); int initialTabCount = mActivityTestRule.getActivity().getCurrentTabModel().getCount(); - ChromeTabUtils.newTabFromMenu( - InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity()); - InstrumentationRegistry.getInstrumentation().waitForIdleSync(); - View button = mActivityTestRule.getActivity().findViewById(R.id.tab_switcher_button); - OverviewModeBehaviorWatcher overviewModeWatcher = new OverviewModeBehaviorWatcher( - mActivityTestRule.getActivity().getLayoutManager(), true, false); - TouchCommon.singleClickView(button); - overviewModeWatcher.waitForBehavior(); + ChromeTabUtils.fullyLoadUrlInNewTab(InstrumentationRegistry.getInstrumentation(), + mActivityTestRule.getActivity(), ContentUrlConstants.ABOUT_BLANK_URL, false); + ThreadUtils.runOnUiThreadBlocking( + () -> { mActivityTestRule.getActivity().getLayoutManager().showOverview(false); }); + Assert.assertTrue("Expected: " + (initialTabCount + 1) + " tab Got: " + mActivityTestRule.getActivity().getCurrentTabModel().getCount(), (initialTabCount + 1)
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index cd458bc..ed84a968 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -2207,7 +2207,7 @@ "intent://test/#Intent;scheme=test;package=com.chrome.test;end", "", false /* isPost */, true /* hasUserGesture */, PageTransition.LINK, false /* isRedirect */, true /* isExternalProtocol */, true /* isMainFrame */, - null /* suggestedFilename */, false /* hasUserGestureCarryover */); + false /* hasUserGestureCarryover */); InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { @@ -2232,12 +2232,12 @@ final NavigationParams initialNavigationParams = new NavigationParams("http://test.com", "", false /* isPost */, true /* hasUserGesture */, PageTransition.LINK, false /* isRedirect */, false /* isExternalProtocol */, true /* isMainFrame */, - null /* suggestedFilename */, false /* hasUserGestureCarryover */); + false /* hasUserGestureCarryover */); final NavigationParams redirectedNavigationParams = new NavigationParams( "intent://test/#Intent;scheme=test;package=com.chrome.test;end", "", false /* isPost */, false /* hasUserGesture */, PageTransition.LINK, true /* isRedirect */, true /* isExternalProtocol */, true /* isMainFrame */, - null /* suggestedFilename */, false /* hasUserGestureCarryover */); + false /* hasUserGestureCarryover */); InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override @@ -2266,7 +2266,7 @@ "intent://test/#Intent;scheme=test;package=com.chrome.test;end", "", false /* isPost */, false /* hasUserGesture */, PageTransition.LINK, false /* isRedirect */, true /* isExternalProtocol */, true /* isMainFrame */, - null /* suggestedFilename */, false /* hasUserGestureCarryover */); + false /* hasUserGestureCarryover */); InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() {
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 3ecb095..300d8d0 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-68.0.3422.0_rc-r1.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-68.0.3423.0_rc-r2.afdo.bz2 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index e282106..687b805 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -628,6 +628,9 @@ <message name="IDS_FILE_BROWSER_SHARE_BUTTON_LABEL" desc="Menu item's label, showing dialog to share the selected Google Drive files. This message is also used as a tooltip label and a spoken feedback label of a button which also shows the dialog to share the files. The translation should be consistent with the sharing dialog's title in Google Drive Web UI."> Share with others </message> + <message name="IDS_FILE_BROWSER_MANAGE_IN_DRIVE_BUTTON_LABEL" desc="Menu item's label, showing dialog to open the selected Google Drive files in the Drive webpage for managing sharing permissions, etc."> + Manage in Drive + </message> <message name="IDS_FILE_BROWSER_TOGGLE_HIDDEN_FILES_COMMAND_LABEL" desc="Label for menu or button with checkmark that toggles visibility of hidden files."> Show hidden files </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 74a2e57..32378e0 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -18,7 +18,6 @@ import("//components/spellcheck/spellcheck_build_features.gni") import("//device/vr/buildflags/buildflags.gni") import("//extensions/buildflags/buildflags.gni") -import("//media/media_options.gni") import("//net/features.gni") import("//ppapi/buildflags/buildflags.gni") import("//printing/buildflags/buildflags.gni") @@ -453,6 +452,30 @@ "engagement/top_sites/site_engagement_top_sites_provider.h", "experiments/memory_ablation_experiment.cc", "experiments/memory_ablation_experiment.h", + "media/webrtc/audio_debug_recordings_handler.cc", + "media/webrtc/audio_debug_recordings_handler.h", + "media/webrtc/webrtc_event_log_manager.cc", + "media/webrtc/webrtc_event_log_manager.h", + "media/webrtc/webrtc_event_log_manager_common.cc", + "media/webrtc/webrtc_event_log_manager_common.h", + "media/webrtc/webrtc_event_log_manager_local.cc", + "media/webrtc/webrtc_event_log_manager_local.h", + "media/webrtc/webrtc_event_log_manager_remote.cc", + "media/webrtc/webrtc_event_log_manager_remote.h", + "media/webrtc/webrtc_event_log_uploader.cc", + "media/webrtc/webrtc_event_log_uploader.h", + "media/webrtc/webrtc_log_uploader.cc", + "media/webrtc/webrtc_log_uploader.h", + "media/webrtc/webrtc_log_util.cc", + "media/webrtc/webrtc_log_util.h", + "media/webrtc/webrtc_logging_handler_host.cc", + "media/webrtc/webrtc_logging_handler_host.h", + "media/webrtc/webrtc_rtp_dump_handler.cc", + "media/webrtc/webrtc_rtp_dump_handler.h", + "media/webrtc/webrtc_rtp_dump_writer.cc", + "media/webrtc/webrtc_rtp_dump_writer.h", + "media/webrtc/webrtc_text_log_handler.cc", + "media/webrtc/webrtc_text_log_handler.h", # Oh hey, all the cool browser/extensions files are hanging out in # //chrome/browser/extensions/BUILD.gn @@ -1735,8 +1758,11 @@ "//components/web_resource", "//components/webdata/common", "//components/webdata_services", + "//components/webrtc_logging/browser", + "//components/webrtc_logging/common", "//content/app/resources", "//content/public/browser", + "//content/public/browser", "//content/public/common", "//content/public/common:buildflags", "//content/public/common:feature_h264_with_openh264_ffmpeg", @@ -1769,6 +1795,7 @@ "//ppapi/buildflags", "//printing/buildflags", "//rlz/buildflags", + "//services/audio/public/cpp", "//services/data_decoder/public/cpp", "//services/device/public/cpp:device_features", "//services/device/public/mojom", @@ -1805,6 +1832,8 @@ "//third_party/metrics_proto", "//third_party/re2", "//third_party/smhasher:cityhash", + "//third_party/webrtc_overrides", + "//third_party/webrtc_overrides:init_webrtc", "//third_party/widevine/cdm:headers", "//third_party/zlib", "//third_party/zlib:minizip", @@ -4112,43 +4141,6 @@ ] } - if (enable_webrtc) { - sources += [ - "media/webrtc/audio_debug_recordings_handler.cc", - "media/webrtc/audio_debug_recordings_handler.h", - "media/webrtc/webrtc_event_log_manager.cc", - "media/webrtc/webrtc_event_log_manager.h", - "media/webrtc/webrtc_event_log_manager_common.cc", - "media/webrtc/webrtc_event_log_manager_common.h", - "media/webrtc/webrtc_event_log_manager_local.cc", - "media/webrtc/webrtc_event_log_manager_local.h", - "media/webrtc/webrtc_event_log_manager_remote.cc", - "media/webrtc/webrtc_event_log_manager_remote.h", - "media/webrtc/webrtc_event_log_uploader.cc", - "media/webrtc/webrtc_event_log_uploader.h", - "media/webrtc/webrtc_log_uploader.cc", - "media/webrtc/webrtc_log_uploader.h", - "media/webrtc/webrtc_log_util.cc", - "media/webrtc/webrtc_log_util.h", - "media/webrtc/webrtc_logging_handler_host.cc", - "media/webrtc/webrtc_logging_handler_host.h", - "media/webrtc/webrtc_rtp_dump_handler.cc", - "media/webrtc/webrtc_rtp_dump_handler.h", - "media/webrtc/webrtc_rtp_dump_writer.cc", - "media/webrtc/webrtc_rtp_dump_writer.h", - "media/webrtc/webrtc_text_log_handler.cc", - "media/webrtc/webrtc_text_log_handler.h", - ] - deps += [ - "//components/webrtc_logging/browser", - "//components/webrtc_logging/common", - "//content/public/browser", - "//services/audio/public/cpp", - "//third_party/webrtc_overrides", - "//third_party/webrtc_overrides:init_webrtc", - ] - } - if (!is_chrome_branded && !is_android) { sources += [ "search/local_files_ntp_source.cc",
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.cc b/chrome/browser/autofill/android/personal_data_manager_android.cc index 9555938..735a3db 100644 --- a/chrome/browser/autofill/android/personal_data_manager_android.cc +++ b/chrome/browser/autofill/android/personal_data_manager_android.cc
@@ -474,7 +474,8 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& unused_obj) { return GetCreditCardGUIDs(env, - personal_data_manager_->GetCreditCardsToSuggest()); + personal_data_manager_->GetCreditCardsToSuggest( + /*include_server_cards=*/true)); } ScopedJavaLocalRef<jobject> PersonalDataManagerAndroid::GetCreditCardByGUID(
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index af85ebe..62a28a6c 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -240,8 +240,8 @@ "accessibility/magnification_manager.h", "accessibility/select_to_speak_event_handler.cc", "accessibility/select_to_speak_event_handler.h", - "accessibility/spoken_feedback_event_rewriter.cc", - "accessibility/spoken_feedback_event_rewriter.h", + "accessibility/spoken_feedback_event_rewriter_delegate.cc", + "accessibility/spoken_feedback_event_rewriter_delegate.h", "accessibility/switch_access_event_handler.cc", "accessibility/switch_access_event_handler.h", "app_mode/app_launch_utils.cc", @@ -1834,7 +1834,6 @@ "../policy/default_geolocation_policy_handler_unittest.cc", "../ui/browser_finder_chromeos_unittest.cc", "accessibility/select_to_speak_event_handler_unittest.cc", - "accessibility/spoken_feedback_event_rewriter_unittest.cc", "app_mode/startup_app_launcher_unittest.cc", "apps/intent_helper/apps_navigation_throttle_unittest.cc", "arc/accessibility/arc_accessibility_helper_bridge_unittest.cc",
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.cc deleted file mode 100644 index 6ac01750..0000000 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.cc +++ /dev/null
@@ -1,111 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.h" - -#include <string> -#include <utility> - -#include "ash/shell.h" -#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" -#include "chrome/browser/chromeos/accessibility/event_handler_common.h" -#include "chrome/common/extensions/extension_constants.h" -#include "content/public/browser/web_contents.h" -#include "extensions/browser/event_router.h" -#include "extensions/browser/extension_host.h" -#include "ui/aura/window_tree_host.h" -#include "ui/content_accelerators/accelerator_util.h" -#include "ui/events/event.h" -#include "ui/events/event_sink.h" - -SpokenFeedbackEventRewriterDelegate::SpokenFeedbackEventRewriterDelegate() {} - -bool SpokenFeedbackEventRewriterDelegate::IsSpokenFeedbackEnabled() const { - return chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled(); -} - -bool SpokenFeedbackEventRewriterDelegate::DispatchKeyEventToChromeVox( - const ui::KeyEvent& key_event, - bool capture) { - // Always capture the Search key. - capture |= key_event.IsCommandDown(); - - // Don't capture tab as it gets consumed by Blink so never comes back - // unhandled. In third_party/WebKit/Source/core/input/EventHandler.cpp, a - // default tab handler consumes tab even when no focusable nodes are found; it - // sets focus to Chrome and eats the event. - if (key_event.GetDomKey() == ui::DomKey::TAB) - capture = false; - - extensions::ExtensionHost* host = chromeos::GetAccessibilityExtensionHost( - extension_misc::kChromeVoxExtensionId); - if (!host) - return false; - - // Listen for any unhandled keyboard events from ChromeVox's background page - // when capturing keys to reinject. - if (capture) - host->host_contents()->SetDelegate(this); - else - host->host_contents()->SetDelegate(nullptr); - - // Forward all key events to ChromeVox's background page. - chromeos::ForwardKeyToExtension(key_event, host); - - return capture; -} - -void SpokenFeedbackEventRewriterDelegate::HandleKeyboardEvent( - content::WebContents* source, - const content::NativeWebKeyboardEvent& event) { - ui::KeyEvent key_event(*static_cast<ui::KeyEvent*>(event.os_event)); - - ui::EventSink* sink = - ash::Shell::GetPrimaryRootWindow()->GetHost()->event_sink(); - - if (sink->OnEventFromSource(&key_event).dispatcher_destroyed) { - VLOG(0) << "Undispatched key " << key_event.key_code() - << " due to destroyed dispatcher."; - } -} - -SpokenFeedbackEventRewriter::SpokenFeedbackEventRewriter() { - delegate_.reset(new SpokenFeedbackEventRewriterDelegate()); -} - -SpokenFeedbackEventRewriter::~SpokenFeedbackEventRewriter() {} - -void SpokenFeedbackEventRewriter::SetDelegateForTest( - std::unique_ptr<SpokenFeedbackEventRewriterDelegate> delegate) { - delegate_ = std::move(delegate); -} - -ui::EventRewriteStatus SpokenFeedbackEventRewriter::RewriteEvent( - const ui::Event& event, - std::unique_ptr<ui::Event>* new_event) { - if (!delegate_->IsSpokenFeedbackEnabled()) - return ui::EVENT_REWRITE_CONTINUE; - - if ((event.type() != ui::ET_KEY_PRESSED && - event.type() != ui::ET_KEY_RELEASED)) - return ui::EVENT_REWRITE_CONTINUE; - - std::string extension_id = - chromeos::AccessibilityManager::Get()->keyboard_listener_extension_id(); - if (extension_id.empty()) - return ui::EVENT_REWRITE_CONTINUE; - - bool capture = - chromeos::AccessibilityManager::Get()->keyboard_listener_capture(); - const ui::KeyEvent key_event = static_cast<const ui::KeyEvent&>(event); - if (delegate_->DispatchKeyEventToChromeVox(key_event, capture)) - return ui::EVENT_REWRITE_DISCARD; - return ui::EVENT_REWRITE_CONTINUE; -} - -ui::EventRewriteStatus SpokenFeedbackEventRewriter::NextDispatchEvent( - const ui::Event& last_event, - std::unique_ptr<ui::Event>* new_event) { - return ui::EVENT_REWRITE_CONTINUE; -}
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.h b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.h deleted file mode 100644 index 1b2a4e0..0000000 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.h +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_SPOKEN_FEEDBACK_EVENT_REWRITER_H_ -#define CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_SPOKEN_FEEDBACK_EVENT_REWRITER_H_ - -#include <vector> - -#include "base/macros.h" -#include "content/public/browser/web_contents_delegate.h" -#include "ui/events/event_rewriter.h" - -namespace ui { -class KeyEvent; -} - -// Receives requests for spoken feedback enabled state and command dispatch. -class SpokenFeedbackEventRewriterDelegate - : public content::WebContentsDelegate { - public: - SpokenFeedbackEventRewriterDelegate(); - ~SpokenFeedbackEventRewriterDelegate() override {} - - // Returns true when ChromeVox is enabled. - virtual bool IsSpokenFeedbackEnabled() const; - - // Returns true when |key_event| is dispatched to ChromeVox. - virtual bool DispatchKeyEventToChromeVox(const ui::KeyEvent& key_event, - bool capture); - - // WebContentsDelegate: - void HandleKeyboardEvent( - content::WebContents* source, - const content::NativeWebKeyboardEvent& event) override; - - private: - DISALLOW_COPY_AND_ASSIGN(SpokenFeedbackEventRewriterDelegate); -}; - -// SpokenFeedbackEventRewriter discards all keyboard events mapped by the spoken -// feedback manifest commands block. It dispatches the associated command name -// directly to spoken feedback. This only occurs whenever spoken feedback is -// enabled. -class SpokenFeedbackEventRewriter : public ui::EventRewriter { - public: - SpokenFeedbackEventRewriter(); - ~SpokenFeedbackEventRewriter() override; - - void SetDelegateForTest( - std::unique_ptr<SpokenFeedbackEventRewriterDelegate> delegate); - - private: - // EventRewriter: - ui::EventRewriteStatus RewriteEvent( - const ui::Event& event, - std::unique_ptr<ui::Event>* new_event) override; - ui::EventRewriteStatus NextDispatchEvent( - const ui::Event& last_event, - std::unique_ptr<ui::Event>* new_event) override; - - // Active delegate (used for testing). - std::unique_ptr<SpokenFeedbackEventRewriterDelegate> delegate_; - - DISALLOW_COPY_AND_ASSIGN(SpokenFeedbackEventRewriter); -}; - -#endif // CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_SPOKEN_FEEDBACK_EVENT_REWRITER_H_
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.cc new file mode 100644 index 0000000..d1d46b6 --- /dev/null +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.cc
@@ -0,0 +1,98 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.h" + +#include "ash/public/interfaces/constants.mojom.h" +#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" +#include "chrome/browser/chromeos/accessibility/event_handler_common.h" +#include "chrome/common/extensions/extension_constants.h" +#include "content/public/browser/native_web_keyboard_event.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/service_manager_connection.h" +#include "extensions/browser/extension_host.h" +#include "services/service_manager/public/cpp/connector.h" +#include "ui/events/event.h" + +SpokenFeedbackEventRewriterDelegate::SpokenFeedbackEventRewriterDelegate() + : binding_(this) { + content::ServiceManagerConnection* connection = + content::ServiceManagerConnection::GetForProcess(); + connection->GetConnector()->BindInterface(ash::mojom::kServiceName, + &event_rewriter_controller_ptr_); + // Set this object as the SpokenFeedbackEventRewriterDelegate. + ash::mojom::SpokenFeedbackEventRewriterDelegatePtr ptr; + binding_.Bind(mojo::MakeRequest(&ptr)); + event_rewriter_controller_ptr_->SetSpokenFeedbackEventRewriterDelegate( + std::move(ptr)); +} + +SpokenFeedbackEventRewriterDelegate::~SpokenFeedbackEventRewriterDelegate() {} + +void SpokenFeedbackEventRewriterDelegate::DispatchKeyEventToChromeVox( + std::unique_ptr<ui::Event> event) { + if (!ShouldDispatchKeyEventToChromeVox(event.get())) { + OnUnhandledSpokenFeedbackEvent(std::move(event)); + return; + } + + bool capture = + chromeos::AccessibilityManager::Get()->keyboard_listener_capture(); + const ui::KeyEvent* key_event = event->AsKeyEvent(); + + // Always capture the Search key. + capture |= key_event->IsCommandDown(); + + // Don't capture tab as it gets consumed by Blink so never comes back + // unhandled. In third_party/WebKit/Source/core/input/EventHandler.cpp, a + // default tab handler consumes tab even when no focusable nodes are found; it + // sets focus to Chrome and eats the event. + if (key_event->GetDomKey() == ui::DomKey::TAB) + capture = false; + + extensions::ExtensionHost* host = chromeos::GetAccessibilityExtensionHost( + extension_misc::kChromeVoxExtensionId); + // Listen for any unhandled keyboard events from ChromeVox's background page + // when capturing keys to reinject. + host->host_contents()->SetDelegate(capture ? this : nullptr); + + // Forward the event to ChromeVox's background page. + chromeos::ForwardKeyToExtension(*key_event, host); + + if (!capture) + OnUnhandledSpokenFeedbackEvent(std::move(event)); +} + +bool SpokenFeedbackEventRewriterDelegate::ShouldDispatchKeyEventToChromeVox( + const ui::Event* event) const { + chromeos::AccessibilityManager* accessibility_manager = + chromeos::AccessibilityManager::Get(); + if (!accessibility_manager->IsSpokenFeedbackEnabled() || + accessibility_manager->keyboard_listener_extension_id().empty() || + !chromeos::GetAccessibilityExtensionHost( + extension_misc::kChromeVoxExtensionId)) { + VLOG(1) << "Event sent to Spoken Feedback when disabled or unavailable"; + return false; + } + + if (!event || !event->IsKeyEvent()) { + NOTREACHED() << "Unexpected event sent to Spoken Feedback"; + return false; + } + + return true; +} + +void SpokenFeedbackEventRewriterDelegate::OnUnhandledSpokenFeedbackEvent( + std::unique_ptr<ui::Event> event) const { + event_rewriter_controller_ptr_->OnUnhandledSpokenFeedbackEvent( + std::move(event)); +} + +void SpokenFeedbackEventRewriterDelegate::HandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) { + OnUnhandledSpokenFeedbackEvent( + ui::Event::Clone(*static_cast<ui::Event*>(event.os_event))); +}
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.h b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.h new file mode 100644 index 0000000..cb3246f --- /dev/null +++ b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.h
@@ -0,0 +1,47 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_SPOKEN_FEEDBACK_EVENT_REWRITER_DELEGATE_H_ +#define CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_SPOKEN_FEEDBACK_EVENT_REWRITER_DELEGATE_H_ + +#include <memory> + +#include "ash/public/interfaces/event_rewriter_controller.mojom.h" +#include "base/macros.h" +#include "content/public/browser/web_contents_delegate.h" +#include "mojo/public/cpp/bindings/binding.h" + +// Passes key events from Ash's EventRewriter to the ChromeVox extension code. +// Reports ChromeVox's unhandled key events back to Ash for continued dispatch. +// TODO(http://crbug.com/839541): Avoid reposting unhandled events. +class SpokenFeedbackEventRewriterDelegate + : public ash::mojom::SpokenFeedbackEventRewriterDelegate, + public content::WebContentsDelegate { + public: + SpokenFeedbackEventRewriterDelegate(); + ~SpokenFeedbackEventRewriterDelegate() override; + + // ui::mojom::SpokenFeedbackEventRewriterDelegate: + void DispatchKeyEventToChromeVox(std::unique_ptr<ui::Event> event) override; + + private: + // Returns whether the event should be dispatched to the ChromeVox extension. + bool ShouldDispatchKeyEventToChromeVox(const ui::Event* event) const; + + // Reports unhandled key events to the EventRewriterController for dispatch. + void OnUnhandledSpokenFeedbackEvent(std::unique_ptr<ui::Event> event) const; + + // WebContentsDelegate: + void HandleKeyboardEvent( + content::WebContents* source, + const content::NativeWebKeyboardEvent& event) override; + + ash::mojom::EventRewriterControllerPtr event_rewriter_controller_ptr_; + + mojo::Binding<ash::mojom::SpokenFeedbackEventRewriterDelegate> binding_; + + DISALLOW_COPY_AND_ASSIGN(SpokenFeedbackEventRewriterDelegate); +}; + +#endif // CHROME_BROWSER_CHROMEOS_ACCESSIBILITY_SPOKEN_FEEDBACK_EVENT_REWRITER_DELEGATE_H_
diff --git a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_unittest.cc b/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_unittest.cc deleted file mode 100644 index dab4e61..0000000 --- a/chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_unittest.cc +++ /dev/null
@@ -1,135 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.h" - -#include <memory> -#include <vector> - -#include "ash/shell.h" -#include "ash/test/ash_test_base.h" -#include "base/macros.h" -#include "ui/aura/window.h" -#include "ui/aura/window_tree_host.h" -#include "ui/events/event.h" -#include "ui/events/event_constants.h" -#include "ui/events/keycodes/keyboard_codes.h" -#include "ui/events/test/event_generator.h" - -// Records all key events. -class EventCapturer : public ui::EventHandler { - public: - EventCapturer() {} - ~EventCapturer() override {} - - void Reset() { events_.clear(); } - - void OnEvent(ui::Event* event) override { - if (event->IsKeyEvent()) - events_.push_back(std::make_unique<ui::KeyEvent>(*event->AsKeyEvent())); - } - - const std::vector<std::unique_ptr<ui::KeyEvent>>& captured_events() const { - return events_; - } - - private: - std::vector<std::unique_ptr<ui::KeyEvent>> events_; - - DISALLOW_COPY_AND_ASSIGN(EventCapturer); -}; - -class TestDelegate : public SpokenFeedbackEventRewriterDelegate { - public: - TestDelegate() - : is_spoken_feedback_enabled_(false), dispatch_result_(false) {} - - ~TestDelegate() override {} - - void set_is_spoken_feedback_enabled(bool enabled) { - is_spoken_feedback_enabled_ = enabled; - } - - void set_dispatch_result(bool result) { dispatch_result_ = result; } - - private: - // SpokenFeedbackEventRewriterDelegate: - bool IsSpokenFeedbackEnabled() const override { - return is_spoken_feedback_enabled_; - } - - bool DispatchKeyEventToChromeVox(const ui::KeyEvent& key_event, - bool capture) override { - return dispatch_result_; - } - - bool is_spoken_feedback_enabled_; - bool dispatch_result_; - - DISALLOW_COPY_AND_ASSIGN(TestDelegate); -}; - -class SpokenFeedbackEventRewriterTest : public ash::AshTestBase { - public: - SpokenFeedbackEventRewriterTest() - : generator_(nullptr), - spoken_feedback_event_rewriter_(new SpokenFeedbackEventRewriter()) { - delegate_ = new TestDelegate(); - spoken_feedback_event_rewriter_->SetDelegateForTest( - std::unique_ptr<TestDelegate>(delegate_)); - } - - void SetUp() override { - ash::AshTestBase::SetUp(); - generator_ = &AshTestBase::GetEventGenerator(); - CurrentContext()->AddPreTargetHandler(&event_capturer_); - CurrentContext()->GetHost()->GetEventSource()->AddEventRewriter( - spoken_feedback_event_rewriter_.get()); - } - - void TearDown() override { - CurrentContext()->GetHost()->GetEventSource()->RemoveEventRewriter( - spoken_feedback_event_rewriter_.get()); - CurrentContext()->RemovePreTargetHandler(&event_capturer_); - generator_ = nullptr; - ash::AshTestBase::TearDown(); - } - - protected: - TestDelegate* delegate_; - ui::test::EventGenerator* generator_; - EventCapturer event_capturer_; - - private: - std::unique_ptr<SpokenFeedbackEventRewriter> spoken_feedback_event_rewriter_; - - DISALLOW_COPY_AND_ASSIGN(SpokenFeedbackEventRewriterTest); -}; - -TEST_F(SpokenFeedbackEventRewriterTest, KeysNotEatenWithChromeVoxDisabled) { - // Send Search+Shift+Right. - generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN); - ASSERT_EQ(1U, event_capturer_.captured_events().size()); - generator_->PressKey(ui::VKEY_SHIFT, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN); - ASSERT_EQ(2U, event_capturer_.captured_events().size()); - - // Mock successful commands lookup and dispatch; shouldn't matter either way. - delegate_->set_dispatch_result(true); - generator_->PressKey(ui::VKEY_RIGHT, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN); - ASSERT_EQ(3U, event_capturer_.captured_events().size()); - - // Released keys shouldn't get eaten. - delegate_->set_dispatch_result(false); - generator_->ReleaseKey(ui::VKEY_RIGHT, - ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN); - generator_->ReleaseKey(ui::VKEY_SHIFT, ui::EF_COMMAND_DOWN); - generator_->ReleaseKey(ui::VKEY_LWIN, 0); - ASSERT_EQ(6U, event_capturer_.captured_events().size()); - - // Try releasing more keys. - generator_->ReleaseKey(ui::VKEY_RIGHT, 0); - generator_->ReleaseKey(ui::VKEY_SHIFT, 0); - generator_->ReleaseKey(ui::VKEY_LWIN, 0); - ASSERT_EQ(9U, event_capturer_.captured_events().size()); -}
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index f62027c..3bacb389 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -37,7 +37,7 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/accessibility/magnification_manager.h" -#include "chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter.h" +#include "chrome/browser/chromeos/accessibility/spoken_feedback_event_rewriter_delegate.h" #include "chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_manager.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" @@ -1028,12 +1028,14 @@ event_rewriter_controller_ptr->SetKeyboardDrivenEventRewriterEnabled(true); } + // Construct a delegate to connect ChromeVox and SpokenFeedbackEventRewriter. + spoken_feedback_event_rewriter_delegate_ = + std::make_unique<SpokenFeedbackEventRewriterDelegate>(); + if (chromeos::GetAshConfig() != ash::Config::MASH) { // TODO(mash): Support EventRewriterController; see crbug.com/647781 ash::EventRewriterController* event_rewriter_controller = ash::Shell::Get()->event_rewriter_controller(); - event_rewriter_controller->AddEventRewriter( - std::unique_ptr<ui::EventRewriter>(new SpokenFeedbackEventRewriter())); event_rewriter_delegate_ = std::make_unique<EventRewriterDelegateImpl>(); event_rewriter_controller->AddEventRewriter( std::make_unique<ui::EventRewriterChromeOS>(
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h index 4bbb667..6860dec 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
@@ -16,6 +16,7 @@ #include "chromeos/system/version_loader.h" class NotificationPlatformBridge; +class SpokenFeedbackEventRewriterDelegate; namespace lock_screen_apps { class StateController; @@ -107,6 +108,10 @@ std::unique_ptr<EventRewriterDelegateImpl> event_rewriter_delegate_; + // Handles event dispatch to the spoken feedback extension (ChromeVox). + std::unique_ptr<SpokenFeedbackEventRewriterDelegate> + spoken_feedback_event_rewriter_delegate_; + scoped_refptr<chromeos::ExternalMetrics> external_metrics_; std::unique_ptr<arc::ArcServiceLauncher> arc_service_launcher_;
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc index a7b2aed4..1ca762b 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
@@ -156,6 +156,8 @@ properties->available_when_metered.reset( new bool(file_specific_info.cache_state().is_present() || file_specific_info.is_hosted_document())); + properties->alternate_url.reset( + new std::string(file_specific_info.alternate_url())); } // Creates entry definition list for (metadata) search result info list.
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc index 8a424bd2..018ea447 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_strings.cc
@@ -699,6 +699,8 @@ SET_STRING("TOGGLE_HIDDEN_FILES_COMMAND_LABEL", IDS_FILE_BROWSER_TOGGLE_HIDDEN_FILES_COMMAND_LABEL); SET_STRING("SHARE_BUTTON_LABEL", IDS_FILE_BROWSER_SHARE_BUTTON_LABEL); + SET_STRING("MANAGE_IN_DRIVE_BUTTON_LABEL", + IDS_FILE_BROWSER_MANAGE_IN_DRIVE_BUTTON_LABEL); SET_STRING("CHANGE_TO_LISTVIEW_BUTTON_LABEL", IDS_FILE_BROWSER_CHANGE_TO_LISTVIEW_BUTTON_LABEL); SET_STRING("CHANGE_TO_THUMBNAILVIEW_BUTTON_LABEL",
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index e4dc375..eb8694e 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -86,14 +86,8 @@ #define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) -// Fails on official build. http://crbug.com/429294 -#if defined(DISABLE_SLOW_FILESAPP_TESTS) || defined(OFFICIAL_BUILD) -#define MAYBE_FileDisplay DISABLED_FileDisplay -#else -#define MAYBE_FileDisplay FileDisplay -#endif WRAPPED_INSTANTIATE_TEST_CASE_P( - MAYBE_FileDisplay, + FileDisplay, FileManagerBrowserTest, ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "fileDisplayDownloads"), TestParameter(IN_GUEST_MODE, "fileDisplayDownloads"), @@ -177,13 +171,8 @@ TestParameter(NOT_IN_GUEST_MODE, "renameNewDirectoryDownloads"), TestParameter(NOT_IN_GUEST_MODE, "renameNewDirectoryDrive"))); -#if defined(DISABLE_SLOW_FILESAPP_TESTS) -#define MAYBE_Delete DISABLED_Delete -#else -#define MAYBE_Delete Delete -#endif WRAPPED_INSTANTIATE_TEST_CASE_P( - MAYBE_Delete, + Delete, FileManagerBrowserTest, ::testing::Values( TestParameter(NOT_IN_GUEST_MODE, @@ -259,14 +248,8 @@ "createDirectoryFromDirectoryTreeWithoutChangingCurrentDi" "rectory"))); -// Fails on official build. http://crbug.com/429294 -#if defined(DISABLE_SLOW_FILESAPP_TESTS) || defined(OFFICIAL_BUILD) -#define MAYBE_DriveSpecific DISABLED_DriveSpecific -#else -#define MAYBE_DriveSpecific DriveSpecific -#endif WRAPPED_INSTANTIATE_TEST_CASE_P( - MAYBE_DriveSpecific, + DriveSpecific, FileManagerBrowserTest, ::testing::Values( TestParameter(NOT_IN_GUEST_MODE, "openSidebarOffline"), @@ -307,13 +290,8 @@ ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "shareFile"), TestParameter(NOT_IN_GUEST_MODE, "shareDirectory"))); -#if defined(DISABLE_SLOW_FILESAPP_TESTS) -#define MAYBE_RestoreGeometry DISABLED_RestoreGeometry -#else -#define MAYBE_RestoreGeometry RestoreGeometry -#endif WRAPPED_INSTANTIATE_TEST_CASE_P( - MAYBE_RestoreGeometry, + RestoreGeometry, FileManagerBrowserTest, ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "restoreGeometry"), TestParameter(IN_GUEST_MODE, "restoreGeometry"), @@ -345,13 +323,8 @@ TestParameter(NOT_IN_GUEST_MODE, "executeDefaultTaskOnDownloads"), TestParameter(IN_GUEST_MODE, "executeDefaultTaskOnDownloads"))); -#if defined(DISABLE_SLOW_FILESAPP_TESTS) -#define MAYBE_ExecuteDefaultTaskOnDrive DISABLED_ExecuteDefaultTaskOnDrive -#else -#define MAYBE_ExecuteDefaultTaskOnDrive ExecuteDefaultTaskOnDrive -#endif WRAPPED_INSTANTIATE_TEST_CASE_P( - MAYBE_ExecuteDefaultTaskOnDrive, + ExecuteDefaultTaskOnDrive, FileManagerBrowserTest, ::testing::Values(TestParameter(NOT_IN_GUEST_MODE, "executeDefaultTaskOnDrive"))); @@ -369,13 +342,8 @@ TestParameter(IN_GUEST_MODE, "defaultTaskDialogOnDownloads"), TestParameter(NOT_IN_GUEST_MODE, "defaultTaskDialogOnDrive"))); -#if defined(DISABLE_SLOW_FILESAPP_TESTS) -#define MAYBE_GenericTask DISABLED_GenericTask -#else -#define MAYBE_GenericTask GenericTask -#endif WRAPPED_INSTANTIATE_TEST_CASE_P( - MAYBE_GenericTask, + GenericTask, FileManagerBrowserTest, ::testing::Values( TestParameter(NOT_IN_GUEST_MODE, "genericTaskIsNotExecuted"),
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc index 311a1cf5..55d82bd 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -44,23 +44,56 @@ namespace file_manager { namespace { -enum EntryType { - FILE, - DIRECTORY, +// During test, the test extensions can send a list of entries (directories +// or files) to add to a target volume using an AddEntriesMessage command. + +enum TargetVolume { LOCAL_VOLUME, DRIVE_VOLUME, USB_VOLUME }; + +struct AddEntriesMessage { + // The volume to add |entries| to. + TargetVolume volume; + + // The |entries| to be added. + std::vector<std::unique_ptr<struct TestEntryInfo>> entries; + + // Converts |value| to an AddEntriesMessage: true on success. + static bool ConvertJSONValue(const base::DictionaryValue& value, + AddEntriesMessage* message) { + base::JSONValueConverter<AddEntriesMessage> converter; + return converter.Convert(value, message); + } + + // Registers AddEntriesMessage member info to the |converter|. + static void RegisterJSONConverter( + base::JSONValueConverter<AddEntriesMessage>* converter) { + converter->RegisterCustomField("volume", &AddEntriesMessage::volume, + &MapStringToTargetVolume); + converter->RegisterRepeatedMessage<struct TestEntryInfo>( + "entries", &AddEntriesMessage::entries); + } + + // Maps |value| to TargetVolume. Returns true on success. + static bool MapStringToTargetVolume(base::StringPiece value, + TargetVolume* volume) { + if (value == "drive") + *volume = DRIVE_VOLUME; + else if (value == "local") + *volume = LOCAL_VOLUME; + else if (value == "usb") + *volume = USB_VOLUME; + else + return false; + return true; + } }; -enum TargetVolume { - LOCAL_VOLUME, - DRIVE_VOLUME, - USB_VOLUME, -}; +// The AddEntriesMessage contains a vector of TestEntryInfo: the elements of +// the vector provide the file or directory entry details. -enum SharedOption { - NONE, - SHARED, -}; +enum EntryType { FILE, DIRECTORY }; -// Test data file or directory entry info. +enum SharedOption { NONE, SHARED }; + struct TestEntryInfo { TestEntryInfo() : type(FILE), shared_option(NONE) {} @@ -130,45 +163,6 @@ } }; -// Message from JavaScript to add entries. -struct AddEntriesMessage { - // Entries to be added. - std::vector<std::unique_ptr<TestEntryInfo>> entries; - - // Target volume to add |entries| to. - TargetVolume volume; - - // Converts |value| to an AddEntriesMessage: true on success. - static bool ConvertJSONValue(const base::DictionaryValue& value, - AddEntriesMessage* message) { - base::JSONValueConverter<AddEntriesMessage> converter; - return converter.Convert(value, message); - } - - // Registers AddEntriesMessage member info to the |converter|. - static void RegisterJSONConverter( - base::JSONValueConverter<AddEntriesMessage>* converter) { - converter->RegisterCustomField("volume", &AddEntriesMessage::volume, - &MapStringToTargetVolume); - converter->RegisterRepeatedMessage<TestEntryInfo>( - "entries", &AddEntriesMessage::entries); - } - - // Maps |value| to TargetVolume. Returns true on success. - static bool MapStringToTargetVolume(base::StringPiece value, - TargetVolume* volume) { - if (value == "drive") - *volume = DRIVE_VOLUME; - else if (value == "local") - *volume = LOCAL_VOLUME; - else if (value == "usb") - *volume = USB_VOLUME; - else - return false; - return true; - } -}; - // Listens for chrome.test messages: PASS, FAIL, and SendMessage. class FileManagerTestMessageListener : public content::NotificationObserver { public: @@ -543,13 +537,13 @@ void FileManagerBrowserTestBase::SetUpCommandLine( base::CommandLine* command_line) { - if (GetGuestMode() == IN_GUEST_MODE) { + if (IsGuestModeTest()) { command_line->AppendSwitch(chromeos::switches::kGuestSession); command_line->AppendSwitchNative(chromeos::switches::kLoginUser, ""); command_line->AppendSwitch(switches::kIncognito); } - if (GetGuestMode() == IN_INCOGNITO) { + if (IsIncognitoModeTest()) { command_line->AppendSwitch(switches::kIncognito); } @@ -561,7 +555,7 @@ local_volume_.reset(new DownloadsTestVolume); - if (GetGuestMode() != IN_GUEST_MODE) { + if (!IsGuestModeTest()) { create_drive_integration_service_ = base::Bind(&FileManagerBrowserTestBase::CreateDriveIntegrationService, base::Unretained(this)); @@ -577,12 +571,12 @@ CHECK(local_volume_->Mount(profile())); - if (GetGuestMode() != IN_GUEST_MODE) { + if (!IsGuestModeTest()) { // Start the embedded test server to serve the mocked share dialog. CHECK(embedded_test_server()->Start()); const GURL share_url_base(embedded_test_server()->GetURL( "/chromeos/file_manager/share_dialog_mock/index.html")); - drive_volume_ = drive_volumes_[profile()->GetOriginalProfile()]; + drive_volume_ = std::move(drive_volumes_[profile()->GetOriginalProfile()]); drive_volume_->ConfigureShareUrlBase(share_url_base); test_util::WaitUntilDriveMountPointIsAdded(profile()); } @@ -671,29 +665,36 @@ std::string* output) { base::ScopedAllowBlockingForTesting allow_blocking; - if (name == "getTestName") { - // Obtain the test case name. - *output = GetTestCaseName(); + if (name == "isInGuestMode") { + // Obtain if the test runs in guest or incognito mode, or not. + if (IsGuestModeTest() || IsIncognitoModeTest()) { + LOG(INFO) << GetTestCaseName() << " isInGuestMode: true"; + *output = "true"; + } else { + ASSERT_EQ(NOT_IN_GUEST_MODE, GetGuestMode()); + *output = "false"; + } + return; } if (name == "getRootPaths") { // Obtain the root paths. - const auto downloads = util::GetDownloadsMountPointName(profile()); + const auto downloads_root = util::GetDownloadsMountPointName(profile()); const auto drive = drive::util::GetDriveMountPointPath(profile()); base::DictionaryValue dictionary; auto drive_root = drive.BaseName().AsUTF8Unsafe().append("/root"); dictionary.SetString("drive", "/" + drive_root); - dictionary.SetString("downloads", "/" + downloads); + dictionary.SetString("downloads", "/" + downloads_root); base::JSONWriter::Write(dictionary, output); return; } - if (name == "isInGuestMode") { - // Obtain whether the test is in guest mode or not. - *output = GetGuestMode() != NOT_IN_GUEST_MODE ? "true" : "false"; + if (name == "getTestName") { + // Obtain the test case name. + *output = GetTestCaseName(); return; } @@ -724,7 +725,7 @@ local_volume_->CreateEntry(*message.entries[i]); break; case DRIVE_VOLUME: - if (drive_volume_.get()) + if (drive_volume_) drive_volume_->CreateEntry(*message.entries[i]); break; case USB_VOLUME:
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h index 8cf21d4..3903668 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h
@@ -6,9 +6,9 @@ #define CHROME_BROWSER_CHROMEOS_FILE_MANAGER_FILE_MANAGER_BROWSERTEST_BASE_H_ #include <map> +#include <memory> #include <string> -#include "base/memory/linked_ptr.h" #include "base/values.h" #include "chrome/browser/chromeos/drive/drive_integration_service.h" #include "chrome/browser/extensions/extension_apitest.h" @@ -55,6 +55,12 @@ virtual const char* GetTestExtensionManifestName() const = 0; private: + // Returns true if the test requires incognito mode. + bool IsIncognitoModeTest() const { return GetGuestMode() == IN_INCOGNITO; } + + // Returns true if the test requires in guest mode. + bool IsGuestModeTest() const { return GetGuestMode() == IN_GUEST_MODE; } + // Called during setup if needed, to create a drive integration service for // the given |profile|. Caller owns the return result. drive::DriveIntegrationService* CreateDriveIntegrationService( @@ -77,8 +83,8 @@ std::string* output); std::unique_ptr<LocalTestVolume> local_volume_; - linked_ptr<DriveTestVolume> drive_volume_; - std::map<Profile*, linked_ptr<DriveTestVolume>> drive_volumes_; + std::unique_ptr<DriveTestVolume> drive_volume_; + std::map<Profile*, std::unique_ptr<DriveTestVolume>> drive_volumes_; std::unique_ptr<FakeTestVolume> usb_volume_; std::unique_ptr<FakeTestVolume> mtp_volume_;
diff --git a/chrome/browser/download/download_ui_controller.cc b/chrome/browser/download/download_ui_controller.cc index 28d98a2..15279d7 100644 --- a/chrome/browser/download/download_ui_controller.cc +++ b/chrome/browser/download/download_ui_controller.cc
@@ -143,8 +143,7 @@ content::WebContents* web_contents = content::DownloadItemUtils::GetWebContents(item); if (web_contents && (item->IsSavePackageDownload() || - (!web_contents->GetURL().is_empty() && - web_contents->GetURL() != item->GetOriginalUrl() && + (web_contents->GetURL() != item->GetOriginalUrl() && web_contents->GetURL() != item->GetURL()))) { auto* security_state_tab_helper = SecurityStateTabHelper::FromWebContents(web_contents);
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index d8cfe551..750f58e 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -7,7 +7,6 @@ import("//chrome/common/features.gni") import("//components/nacl/features.gni") import("//extensions/buildflags/buildflags.gni") -import("//media/media_options.gni") import("//mojo/public/tools/bindings/mojom.gni") import("//rlz/buildflags/buildflags.gni") @@ -435,6 +434,7 @@ "api/webrtc_audio_private/webrtc_audio_private_api.h", "api/webrtc_desktop_capture_private/webrtc_desktop_capture_private_api.cc", "api/webrtc_desktop_capture_private/webrtc_desktop_capture_private_api.h", + "api/webrtc_logging_private/webrtc_logging_private_api.cc", "api/webrtc_logging_private/webrtc_logging_private_api.h", "api/webstore_private/webstore_private_api.cc", "api/webstore_private/webstore_private_api.h", @@ -1139,13 +1139,6 @@ deps += [ "//rlz:rlz_lib" ] } - if (enable_webrtc) { - sources += [ "api/webrtc_logging_private/webrtc_logging_private_api.cc" ] - } else { - sources += - [ "api/webrtc_logging_private/webrtc_logging_private_api_stub.cc" ] - } - if (toolkit_views) { deps += [ "//ui/views" ] }
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc b/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc index 81874ce..7384bff 100644 --- a/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc +++ b/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc
@@ -336,6 +336,9 @@ // extension with a file browser handler that can handle the attachment's MIME // type. IN_PROC_BROWSER_TEST_F(StreamsPrivateApiTest, MAYBE_NavigateToAnAttachment) { + if (base::FeatureList::IsEnabled(network::features::kNetworkService)) + return; // Streams not used with network service. + InitializeDownloadSettings(); ASSERT_TRUE(LoadTestExtension()) << message_; @@ -381,6 +384,9 @@ // StreamsResourceThrottle, even if there is an extension with a file // browser handler that can handle the download's MIME type. IN_PROC_BROWSER_TEST_F(StreamsPrivateApiTest, MAYBE_DirectDownload) { + if (base::FeatureList::IsEnabled(network::features::kNetworkService)) + return; // Streams not used with network service. + InitializeDownloadSettings(); ASSERT_TRUE(LoadTestExtension()) << message_;
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc index 44d1375..56f2645 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc
@@ -40,6 +40,7 @@ #include "content/public/common/resource_type.h" #include "content/public/common/url_constants.h" #include "content/public/test/browser_test_utils.h" +#include "content/public/test/download_test_observer.h" #include "content/public/test/test_utils.h" #include "extensions/browser/extension_system.h" #include "extensions/common/switches.h" @@ -233,10 +234,17 @@ << message_; } -IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, Download) { +// https://crbug.com/660288 +IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, DISABLED_Download) { ASSERT_TRUE(StartEmbeddedTestServer()); - ASSERT_TRUE(RunExtensionTest("webnavigation/download")) - << message_; + content::DownloadManager* download_manager = + content::BrowserContext::GetDownloadManager(browser()->profile()); + content::DownloadTestObserverTerminal observer( + download_manager, 1, + content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); + bool result = RunExtensionTest("webnavigation/download"); + observer.WaitForFinished(); + ASSERT_TRUE(result) << message_; } IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, ServerRedirectSingleProcess) {
diff --git a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api_stub.cc b/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api_stub.cc deleted file mode 100644 index a47726a..0000000 --- a/chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api_stub.cc +++ /dev/null
@@ -1,95 +0,0 @@ -// Copyright 2013 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. -// -// Stub implementation used when WebRTC is not enabled. - -#include "chrome/browser/extensions/api/webrtc_logging_private/webrtc_logging_private_api.h" - -namespace extensions { - -namespace { - -const char kErrorNotSupported[] = "Not supported"; - -} // namespace - -bool WebrtcLoggingPrivateSetMetaDataFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -bool WebrtcLoggingPrivateStartFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -bool WebrtcLoggingPrivateSetUploadOnRenderCloseFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -bool WebrtcLoggingPrivateStopFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -bool WebrtcLoggingPrivateStoreFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -bool WebrtcLoggingPrivateUploadStoredFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -bool WebrtcLoggingPrivateUploadFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -bool WebrtcLoggingPrivateDiscardFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -bool WebrtcLoggingPrivateStartRtpDumpFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -bool WebrtcLoggingPrivateStopRtpDumpFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -bool WebrtcLoggingPrivateStartAudioDebugRecordingsFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -bool WebrtcLoggingPrivateStopAudioDebugRecordingsFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -bool WebrtcLoggingPrivateGetLogsDirectoryFunction::RunAsync() { - SetError(kErrorNotSupported); - SendResponse(false); - return false; -} - -} // namespace extensions
diff --git a/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc b/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc index fe55b30..142e791 100644 --- a/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc +++ b/chrome/browser/extensions/extension_gcm_app_handler_unittest.cc
@@ -212,6 +212,7 @@ profile->GetPrefs(), profile->GetPath(), profile->GetRequestContext(), chrome::GetChannel(), gcm::GetProductCategoryForSubtypes(profile->GetPrefs()), + SigninManagerFactory::GetForProfile(profile), std::unique_ptr<ProfileIdentityProvider>(new ProfileIdentityProvider( SigninManagerFactory::GetForProfile(profile), ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
diff --git a/chrome/browser/extensions/extension_view_host.cc b/chrome/browser/extensions/extension_view_host.cc index d4c7aa6..d4dc62958 100644 --- a/chrome/browser/extensions/extension_view_host.cc +++ b/chrome/browser/extensions/extension_view_host.cc
@@ -161,21 +161,6 @@ Browser* browser = view_->GetBrowser(); return browser ? browser->OpenURL(params) : nullptr; } - case WindowOpenDisposition::CURRENT_TAB: { - // Only allow these from hosts that are bound to a browser (e.g. popups). - // Otherwise they are not driven by a user gesture. - Browser* browser = view_->GetBrowser(); - if (!browser) - return nullptr; - - // Only allow navigations that will surely result in a download. - if (!params.suggested_filename.has_value() || - !(params.url.SchemeIsBlob() || params.url.SchemeIsFileSystem() || - params.url.SchemeIs(url::kDataScheme))) { - return nullptr; - } - return browser->OpenURL(params); - } default: return nullptr; }
diff --git a/chrome/browser/gcm/gcm_profile_service_factory.cc b/chrome/browser/gcm/gcm_profile_service_factory.cc index ac7c59f..3834f7c 100644 --- a/chrome/browser/gcm/gcm_profile_service_factory.cc +++ b/chrome/browser/gcm/gcm_profile_service_factory.cc
@@ -87,6 +87,7 @@ profile->GetPrefs(), profile->GetPath(), profile->GetRequestContext(), chrome::GetChannel(), gcm::GetProductCategoryForSubtypes(profile->GetPrefs()), + SigninManagerFactory::GetForProfile(profile), std::unique_ptr<ProfileIdentityProvider>(new ProfileIdentityProvider( SigninManagerFactory::GetForProfile(profile), ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
diff --git a/chrome/browser/gcm/gcm_profile_service_unittest.cc b/chrome/browser/gcm/gcm_profile_service_unittest.cc index fe93807..8a39cf87 100644 --- a/chrome/browser/gcm/gcm_profile_service_unittest.cc +++ b/chrome/browser/gcm/gcm_profile_service_unittest.cc
@@ -54,6 +54,7 @@ profile->GetPrefs(), profile->GetPath(), profile->GetRequestContext(), chrome::GetChannel(), gcm::GetProductCategoryForSubtypes(profile->GetPrefs()), + SigninManagerFactory::GetForProfile(profile), std::unique_ptr<ProfileIdentityProvider>(new ProfileIdentityProvider( SigninManagerFactory::GetForProfile(profile), ProfileOAuth2TokenServiceFactory::GetForProfile(profile),
diff --git a/chrome/browser/profile_resetter/reset_report_uploader.cc b/chrome/browser/profile_resetter/reset_report_uploader.cc index 4c7b445e..696cd4a6 100644 --- a/chrome/browser/profile_resetter/reset_report_uploader.cc +++ b/chrome/browser/profile_resetter/reset_report_uploader.cc
@@ -13,8 +13,9 @@ #include "net/base/escape.h" #include "net/base/load_flags.h" #include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/url_fetcher.h" -#include "net/url_request/url_request_context_getter.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "services/network/public/mojom/url_loader_factory.mojom.h" namespace { const char kResetReportUrl[] = @@ -31,10 +32,9 @@ } // namespace -ResetReportUploader::ResetReportUploader(content::BrowserContext* context) - : url_request_context_getter_( - content::BrowserContext::GetDefaultStoragePartition(context)-> - GetURLRequestContext()) {} +ResetReportUploader::ResetReportUploader( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + : url_loader_factory_(std::move(url_loader_factory)) {} ResetReportUploader::~ResetReportUploader() {} @@ -43,6 +43,11 @@ std::string request_data; CHECK(report.SerializeToString(&request_data)); + DispatchReportInternal(request_data); +} + +void ResetReportUploader::DispatchReportInternal( + const std::string& request_data) { // Create traffic annotation tag. net::NetworkTrafficAnnotationTag traffic_annotation = net::DefineNetworkTrafficAnnotation("profile_resetter_upload", R"( @@ -72,19 +77,31 @@ "send the data." })"); - // Note fetcher will be deleted by OnURLFetchComplete. - net::URLFetcher* fetcher = - net::URLFetcher::Create(GetClientReportUrl(kResetReportUrl), - net::URLFetcher::POST, this, traffic_annotation) - .release(); - fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | - net::LOAD_DO_NOT_SAVE_COOKIES | - net::LOAD_DISABLE_CACHE); - fetcher->SetRequestContext(url_request_context_getter_.get()); - fetcher->SetUploadData("application/octet-stream", request_data); - fetcher->Start(); + auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->url = GetClientReportUrl(kResetReportUrl); + resource_request->load_flags = net::LOAD_DO_NOT_SEND_COOKIES | + net::LOAD_DO_NOT_SAVE_COOKIES | + net::LOAD_DISABLE_CACHE; + resource_request->method = "POST"; + std::unique_ptr<network::SimpleURLLoader> simple_url_loader = + network::SimpleURLLoader::Create(std::move(resource_request), + traffic_annotation); + simple_url_loader->AttachStringForUpload(request_data, + "application/octet-stream"); + auto it = simple_url_loaders_.insert(simple_url_loaders_.begin(), + std::move(simple_url_loader)); + it->get()->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + url_loader_factory_.get(), + base::BindOnce(&ResetReportUploader::OnSimpleLoaderComplete, + base::Unretained(this), std::move(it))); } -void ResetReportUploader::OnURLFetchComplete(const net::URLFetcher* source) { - delete source; +void ResetReportUploader::OnSimpleLoaderComplete( + SimpleURLLoaderList::iterator it, + std::unique_ptr<std::string> response_body) { + simple_url_loaders_.erase(it); +} + +GURL ResetReportUploader::GetClientReportUrlForTesting() { + return GetClientReportUrl(kResetReportUrl); }
diff --git a/chrome/browser/profile_resetter/reset_report_uploader.h b/chrome/browser/profile_resetter/reset_report_uploader.h index a710c101..7b05ef0 100644 --- a/chrome/browser/profile_resetter/reset_report_uploader.h +++ b/chrome/browser/profile_resetter/reset_report_uploader.h
@@ -5,18 +5,16 @@ #ifndef CHROME_BROWSER_PROFILE_RESETTER_RESET_REPORT_UPLOADER_H_ #define CHROME_BROWSER_PROFILE_RESETTER_RESET_REPORT_UPLOADER_H_ +#include <list> + #include "base/macros.h" #include "base/memory/ref_counted.h" #include "components/keyed_service/core/keyed_service.h" -#include "net/url_request/url_fetcher_delegate.h" +#include "url/gurl.h" -namespace content { -class BrowserContext; -} - -namespace net { -class URLFetcher; -class URLRequestContextGetter; +namespace network { +class SimpleURLLoader; +class SharedURLLoaderFactory; } namespace reset_report { @@ -24,18 +22,27 @@ } // Service whose job is up upload ChromeResetReports. -class ResetReportUploader : public KeyedService, - private net::URLFetcherDelegate { +class ResetReportUploader : public KeyedService { public: - explicit ResetReportUploader(content::BrowserContext* context); + explicit ResetReportUploader( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); ~ResetReportUploader() override; void DispatchReport(const reset_report::ChromeResetReport& report); - private: - void OnURLFetchComplete(const net::URLFetcher* source) override; + // Visible for testing: + void DispatchReportInternal(const std::string& request_data); + static GURL GetClientReportUrlForTesting(); - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; + private: + using SimpleURLLoaderList = + std::list<std::unique_ptr<network::SimpleURLLoader>>; + + void OnSimpleLoaderComplete(SimpleURLLoaderList::iterator it, + std::unique_ptr<std::string> response_body); + + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; + SimpleURLLoaderList simple_url_loaders_; DISALLOW_COPY_AND_ASSIGN(ResetReportUploader); };
diff --git a/chrome/browser/profile_resetter/reset_report_uploader_factory.cc b/chrome/browser/profile_resetter/reset_report_uploader_factory.cc index 7b567c4..d5572e08 100644 --- a/chrome/browser/profile_resetter/reset_report_uploader_factory.cc +++ b/chrome/browser/profile_resetter/reset_report_uploader_factory.cc
@@ -7,6 +7,8 @@ #include "base/memory/singleton.h" #include "chrome/browser/profile_resetter/reset_report_uploader.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/storage_partition.h" // static ResetReportUploaderFactory* ResetReportUploaderFactory::GetInstance() { @@ -29,5 +31,7 @@ KeyedService* ResetReportUploaderFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - return new ResetReportUploader(context); + return new ResetReportUploader( + content::BrowserContext::GetDefaultStoragePartition(context) + ->GetURLLoaderFactoryForBrowserProcess()); }
diff --git a/chrome/browser/profile_resetter/reset_report_uploader_unittest.cc b/chrome/browser/profile_resetter/reset_report_uploader_unittest.cc new file mode 100644 index 0000000..8e9d376 --- /dev/null +++ b/chrome/browser/profile_resetter/reset_report_uploader_unittest.cc
@@ -0,0 +1,48 @@ +// 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/profile_resetter/reset_report_uploader.h" + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" +#include "content/public/common/weak_wrapper_shared_url_loader_factory.h" +#include "content/public/test/test_utils.h" +#include "net/http/http_status_code.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +class ResetReportUploaderTest : public testing::Test { + public: + ResetReportUploaderTest() + : test_shared_loader_factory_( + base::MakeRefCounted<content::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_)) {} + + protected: + scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory() { + return test_shared_loader_factory_; + } + network::TestURLLoaderFactory* test_url_loader_factory() { + return &test_url_loader_factory_; + } + + private: + base::test::ScopedTaskEnvironment scoped_task_environment_; + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; +}; + +TEST_F(ResetReportUploaderTest, NoCrash) { + test_url_loader_factory()->AddResponse( + ResetReportUploader::GetClientReportUrlForTesting().spec(), ""); + ResetReportUploader* uploader = + new ResetReportUploader(shared_url_loader_factory()); + uploader->DispatchReportInternal(""); +}
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index 1dd092b..1dbacd3 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -84,6 +84,12 @@ file="site_settings/all_sites.js" type="chrome_html" preprocess="true" /> + <structure name="IDR_SETTINGS_SITE_ENTRY_HTML" + file="site_settings/site_entry.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_SITE_ENTRY_JS" + file="site_settings/site_entry.js" + type="chrome_html" /> <structure name="IDR_SETTINGS_CATEGORY_DEFAULT_SETTING_HTML" file="site_settings/category_default_setting.html" type="chrome_html" />
diff --git a/chrome/browser/resources/settings/site_settings/all_sites.html b/chrome/browser/resources/settings/site_settings/all_sites.html index 49e8860b..d91cf76 100644 --- a/chrome/browser/resources/settings/site_settings/all_sites.html +++ b/chrome/browser/resources/settings/site_settings/all_sites.html
@@ -1,10 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> <link rel="import" href="../settings_shared_css.html"> -<link rel="import" href="constants.html"> -<link rel="import" href="site_list.html"> -<link rel="import" href="site_settings_behavior.html"> +<link rel="import" href="site_entry.html"> <dom-module id="all-sites"> <template> @@ -12,28 +9,19 @@ :host { display: block; } + + /* There is only one top-level heading for All Sites, so remove the + * additional leading padding used for lists. */ + .list-frame.without-heading { + -webkit-padding-start: var(--settings-box-row-padding); + } </style> <div class="list-frame" hidden$="[[sites.length]]"> <div class="list-item secondary">$i18n{noSitesAdded}</div> </div> - <div class="list-frame menu-content vertical-list" id="listContainer"> + <div class="list-frame without-heading" id="listContainer"> <template is="dom-repeat" items="[[sites]]"> - <div class="list-item"> - <div class="layout horizontal center flex" on-click="onOriginTap_" - actionable> - <div class="favicon-image" - style$="[[computeSiteIcon(item.origin)]]"> - </div> - <div class="middle no-min-width text-elide" - id="displayName"> - [[item.displayName]] - </div> - <paper-icon-button-light class="subpage-arrow"> - <button aria-label$="[[item.displayName]]" - aria-describedby="displayName"></button> - </paper-icon-button-light> - </div> - </div> + <site-entry site="{{item}}" label="[[item.displayName]]"> </template> </div> </template>
diff --git a/chrome/browser/resources/settings/site_settings/all_sites.js b/chrome/browser/resources/settings/site_settings/all_sites.js index 8edec70..81c9e55 100644 --- a/chrome/browser/resources/settings/site_settings/all_sites.js +++ b/chrome/browser/resources/settings/site_settings/all_sites.js
@@ -62,17 +62,6 @@ return Promise.all(promiseList); }, - /** - * A handler for selecting a site (by clicking on the origin). - * @param {!{model: !{item: !SiteException}}} event - * @private - */ - onOriginTap_: function(event) { - settings.navigateTo( - settings.routes.SITE_SETTINGS_SITE_DETAILS, - new URLSearchParams('site=' + event.model.item.origin)); - }, - /** @private */ populateList_: function() { this.getAllSitesList_().then(this.processExceptions_.bind(this));
diff --git a/chrome/browser/resources/settings/site_settings/site_entry.html b/chrome/browser/resources/settings/site_settings/site_entry.html new file mode 100644 index 0000000..8e0e8d5 --- /dev/null +++ b/chrome/browser/resources/settings/site_settings/site_entry.html
@@ -0,0 +1,24 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> +<link rel="import" href="../settings_shared_css.html"> +<link rel="import" href="site_settings_behavior.html"> + +<dom-module id="site-entry"> + <template> + <style include="settings-shared"></style> + <div class="settings-box list-item" on-click="onOriginTap_" + actionable> + <div class="favicon-image" style$="[[computeSiteIcon(site.origin)]]"> + </div> + <div class="middle text-elide" id="displayName"> + [[site.displayName]] + </div> + <paper-icon-button-light class="subpage-arrow"> + <button aria-label$="[[site.displayName]]" + aria-describedby="displayName"></button> + </paper-icon-button-light> + </div> + </template> + <script src="site_entry.js"></script> +</dom-module>
diff --git a/chrome/browser/resources/settings/site_settings/site_entry.js b/chrome/browser/resources/settings/site_settings/site_entry.js new file mode 100644 index 0000000..b424b21 --- /dev/null +++ b/chrome/browser/resources/settings/site_settings/site_entry.js
@@ -0,0 +1,37 @@ +// 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 + * 'site-entry' is an element representing a single ETLD+1 site entity. + */ + +Polymer({ + is: 'site-entry', + + behaviors: [SiteSettingsBehavior], + + properties: { + /** + * TODO(https://crbug.com/835712): This should be an object representing a + * ETLD+1 site. + */ + site: Object, + }, + + /** @override */ + ready: function() {}, + + /** + * A handler for selecting a site (by clicking on the origin). + * @param {!{model: !{item: !SiteException}}} event + * @private + */ + onOriginTap_: function(event) { + settings.navigateTo( + settings.routes.SITE_SETTINGS_SITE_DETAILS, + new URLSearchParams('site=' + this.site.origin)); + }, + +});
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service.cc b/chrome/browser/supervised_user/child_accounts/child_account_service.cc index bfe688c..ff084e0b 100644 --- a/chrome/browser/supervised_user/child_accounts/child_account_service.cc +++ b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
@@ -32,6 +32,8 @@ #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_pref_names.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/storage_partition.h" #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -328,7 +330,8 @@ SigninManagerFactory::GetForProfile(profile_) ->GetAuthenticatedAccountId(), ProfileOAuth2TokenServiceFactory::GetForProfile(profile_), - profile_->GetRequestContext())); + content::BrowserContext::GetDefaultStoragePartition(profile_) + ->GetURLLoaderFactoryForBrowserProcess())); family_fetcher_->StartGetFamilyMembers(); }
diff --git a/chrome/browser/supervised_user/child_accounts/family_info_fetcher.cc b/chrome/browser/supervised_user/child_accounts/family_info_fetcher.cc index 7c6cdd9b..9939e91 100644 --- a/chrome/browser/supervised_user/child_accounts/family_info_fetcher.cc +++ b/chrome/browser/supervised_user/child_accounts/family_info_fetcher.cc
@@ -16,7 +16,9 @@ #include "net/base/load_flags.h" #include "net/http/http_status_code.h" #include "net/traffic_annotation/network_traffic_annotation.h" -#include "net/url_request/url_request_status.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/simple_url_loader.h" #include "url/gurl.h" const char kGetFamilyProfileApiPath[] = "families/mine?alt=json"; @@ -80,14 +82,13 @@ Consumer* consumer, const std::string& account_id, OAuth2TokenService* token_service, - net::URLRequestContextGetter* request_context) + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) : OAuth2TokenService::Consumer("family_info_fetcher"), consumer_(consumer), account_id_(account_id), token_service_(token_service), - request_context_(request_context), - access_token_expired_(false) { -} + url_loader_factory_(std::move(url_loader_factory)), + access_token_expired_(false) {} FamilyInfoFetcher::~FamilyInfoFetcher() { // Ensures O2TS observation is cleared when FamilyInfoFetcher is destructed @@ -167,7 +168,7 @@ access_token_ = access_token; GURL url = kids_management_api::GetURL(request_path_); - const int id = 0; + net::NetworkTrafficAnnotationTag traffic_annotation = net::DefineNetworkTrafficAnnotation("family_info", R"( semantics { @@ -195,21 +196,24 @@ } } })"); - url_fetcher_ = net::URLFetcher::Create(id, url, net::URLFetcher::GET, this, - traffic_annotation); - data_use_measurement::DataUseUserData::AttachToFetcher( - url_fetcher_.get(), - data_use_measurement::DataUseUserData::SUPERVISED_USER); - url_fetcher_->SetRequestContext(request_context_); - url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | - net::LOAD_DO_NOT_SAVE_COOKIES); - url_fetcher_->SetAutomaticallyRetryOnNetworkChanges( - kNumFamilyInfoFetcherRetries); - url_fetcher_->AddExtraRequestHeader(base::StringPrintf( + auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->url = url; + resource_request->load_flags = + net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES; + resource_request->headers.AddHeaderFromString(base::StringPrintf( supervised_users::kAuthorizationHeaderFormat, access_token.c_str())); - - url_fetcher_->Start(); + simple_url_loader_ = network::SimpleURLLoader::Create( + std::move(resource_request), traffic_annotation); + simple_url_loader_->SetRetryOptions( + kNumFamilyInfoFetcherRetries, + network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE); + // TODO re-add data use measurement once SimpleURLLoader supports it + // data_use_measurement::DataUseUserData::SUPERVISED_USER + simple_url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + url_loader_factory_.get(), + base::BindOnce(&FamilyInfoFetcher::OnSimpleLoaderComplete, + base::Unretained(this))); } void FamilyInfoFetcher::OnGetTokenFailure( @@ -220,16 +224,25 @@ consumer_->OnFailure(TOKEN_ERROR); } -void FamilyInfoFetcher::OnURLFetchComplete( - const net::URLFetcher* source) { - const net::URLRequestStatus& status = source->GetStatus(); - if (!status.is_success()) { - DLOG(WARNING) << "URLRequestStatus error " << status.error(); - consumer_->OnFailure(NETWORK_ERROR); - return; +void FamilyInfoFetcher::OnSimpleLoaderComplete( + std::unique_ptr<std::string> response_body) { + int response_code = -1; + if (simple_url_loader_->ResponseInfo() && + simple_url_loader_->ResponseInfo()->headers) { + response_code = + simple_url_loader_->ResponseInfo()->headers->response_code(); } + std::string body; + if (response_body) + body = std::move(*response_body); + OnSimpleLoaderCompleteInternal(simple_url_loader_->NetError(), response_code, + body); +} - int response_code = source->GetResponseCode(); +void FamilyInfoFetcher::OnSimpleLoaderCompleteInternal( + int net_error, + int response_code, + const std::string& response_body) { if (response_code == net::HTTP_UNAUTHORIZED && !access_token_expired_) { DVLOG(1) << "Access token expired, retrying"; access_token_expired_ = true; @@ -246,8 +259,11 @@ return; } - std::string response_body; - source->GetResponseAsString(&response_body); + if (net_error != net::OK) { + DLOG(WARNING) << "NetError " << net_error; + consumer_->OnFailure(NETWORK_ERROR); + return; + } if (request_path_ == kGetFamilyProfileApiPath) { FamilyProfileFetched(response_body);
diff --git a/chrome/browser/supervised_user/child_accounts/family_info_fetcher.h b/chrome/browser/supervised_user/child_accounts/family_info_fetcher.h index 2adb0b06..88275a2 100644 --- a/chrome/browser/supervised_user/child_accounts/family_info_fetcher.h +++ b/chrome/browser/supervised_user/child_accounts/family_info_fetcher.h
@@ -11,9 +11,8 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/scoped_refptr.h" #include "google_apis/gaia/oauth2_token_service.h" -#include "net/url_request/url_fetcher.h" -#include "net/url_request/url_fetcher_delegate.h" namespace base { class DictionaryValue; @@ -21,16 +20,16 @@ class Time; } -namespace net { -class URLRequestContextGetter; -} +namespace network { +class SimpleURLLoader; +class SharedURLLoaderFactory; +} // namespace network // Fetches information about the family of the signed-in user. It can get // information about the family itself (e.g. a name), as well as a list of // family members and their properties. class FamilyInfoFetcher : public OAuth2TokenService::Observer, - public OAuth2TokenService::Consumer, - public net::URLFetcherDelegate { + public OAuth2TokenService::Consumer { public: enum ErrorCode { TOKEN_ERROR, // Failed to get OAuth2 token. @@ -81,10 +80,11 @@ // Instantiates a fetcher, but doesn't start a fetch - use the StartGet* // methods below. |consumer| must outlive us. - FamilyInfoFetcher(Consumer* consumer, - const std::string& account_id, - OAuth2TokenService* token_service, - net::URLRequestContextGetter* request_context); + FamilyInfoFetcher( + Consumer* consumer, + const std::string& account_id, + OAuth2TokenService* token_service, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); ~FamilyInfoFetcher() override; // Public so tests can use them. @@ -96,6 +96,11 @@ void StartGetFamilyProfile(); void StartGetFamilyMembers(); + // Public so tests can use it. + void OnSimpleLoaderCompleteInternal(int net_error, + int response_code, + const std::string& response_body); + private: // OAuth2TokenService::Observer implementation: void OnRefreshTokenAvailable(const std::string& account_id) override; @@ -108,8 +113,7 @@ void OnGetTokenFailure(const OAuth2TokenService::Request* request, const GoogleServiceAuthError& error) override; - // net::URLFetcherDelegate implementation. - void OnURLFetchComplete(const net::URLFetcher* source) override; + void OnSimpleLoaderComplete(std::unique_ptr<std::string> response_body); static bool ParseMembers(const base::ListValue* list, std::vector<FamilyMember>* members); @@ -126,13 +130,13 @@ Consumer* consumer_; const std::string account_id_; OAuth2TokenService* token_service_; - net::URLRequestContextGetter* request_context_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; std::string request_path_; std::unique_ptr<OAuth2TokenService::Request> access_token_request_; std::string access_token_; bool access_token_expired_; - std::unique_ptr<net::URLFetcher> url_fetcher_; + std::unique_ptr<network::SimpleURLLoader> simple_url_loader_; DISALLOW_COPY_AND_ASSIGN(FamilyInfoFetcher); };
diff --git a/chrome/browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc b/chrome/browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc index 6ef5fc0c6..1785e354 100644 --- a/chrome/browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc +++ b/chrome/browser/supervised_user/child_accounts/family_info_fetcher_unittest.cc
@@ -16,15 +16,17 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" +#include "content/public/common/weak_wrapper_shared_url_loader_factory.h" #include "net/base/net_errors.h" -#include "net/url_request/test_url_fetcher_factory.h" +#include "net/http/http_status_code.h" #include "net/url_request/url_request_test_util.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" const char kAccountId[] = "user@gmail.com"; const char kDifferentAccountId[] = "some_other_user@gmail.com"; -const int kFamilyInfoFetcherURLFetcherID = 0; bool operator==(const FamilyInfoFetcher::FamilyProfile& family1, const FamilyInfoFetcher::FamilyProfile& family2) { @@ -110,9 +112,12 @@ public FamilyInfoFetcher::Consumer { public: FamilyInfoFetcherTest() - : request_context_(new net::TestURLRequestContextGetter( - base::ThreadTaskRunnerHandle::Get())), - fetcher_(this, kAccountId, &token_service_, request_context_.get()) {} + : fetcher_( + this, + kAccountId, + &token_service_, + base::MakeRefCounted<content::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_)) {} MOCK_METHOD1(OnGetFamilyProfileSuccess, void(const FamilyInfoFetcher::FamilyProfile& family)); @@ -137,20 +142,8 @@ base::Time::Now() + base::TimeDelta::FromHours(1)); } - net::TestURLFetcher* GetURLFetcher() { - net::TestURLFetcher* url_fetcher = - url_fetcher_factory_.GetFetcherByID( - kFamilyInfoFetcherURLFetcherID); - EXPECT_TRUE(url_fetcher); - return url_fetcher; - } - void SendResponse(net::Error error, const std::string& response) { - net::TestURLFetcher* url_fetcher = GetURLFetcher(); - url_fetcher->set_status(net::URLRequestStatus::FromError(error)); - url_fetcher->set_response_code(net::HTTP_OK); - url_fetcher->SetResponseString(response); - url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); + fetcher_.OnSimpleLoaderCompleteInternal(error, net::HTTP_OK, response); } void SendValidGetFamilyProfileResponse( @@ -173,8 +166,7 @@ base::MessageLoop message_loop_; FakeProfileOAuth2TokenService token_service_; - scoped_refptr<net::TestURLRequestContextGetter> request_context_; - net::TestURLFetcherFactory url_fetcher_factory_; + network::TestURLLoaderFactory test_url_loader_factory_; FamilyInfoFetcher fetcher_; };
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 38caa0b..d174083 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -12,7 +12,6 @@ import("//components/offline_pages/buildflags/features.gni") import("//components/signin/features.gni") import("//extensions/buildflags/buildflags.gni") -import("//media/media_options.gni") import("//ppapi/buildflags/buildflags.gni") import("//printing/buildflags/buildflags.gni") import("//rlz/buildflags/buildflags.gni") @@ -784,6 +783,8 @@ "webui/log_web_ui_url.h", "webui/media/media_engagement_ui.cc", "webui/media/media_engagement_ui.h", + "webui/media/webrtc_logs_ui.cc", + "webui/media/webrtc_logs_ui.h", "webui/memory_internals_ui.cc", "webui/memory_internals_ui.h", "webui/metrics_handler.cc", @@ -1015,6 +1016,7 @@ "//components/version_ui", "//components/web_cache/browser", "//components/web_resource", + "//components/webrtc_logging/browser", "//content/app/resources", "//content/public/common", "//crypto", @@ -3850,14 +3852,6 @@ } } - if (enable_webrtc) { - sources += [ - "webui/media/webrtc_logs_ui.cc", - "webui/media/webrtc_logs_ui.h", - ] - deps += [ "//components/webrtc_logging/browser" ] - } - if (safe_browsing_mode == 1) { deps += [ "//chrome/browser/safe_browsing:chunk_proto",
diff --git a/chrome/browser/ui/android/external_protocol_dialog_android.cc b/chrome/browser/ui/android/external_protocol_dialog_android.cc index c84db6c..000fcc6d 100644 --- a/chrome/browser/ui/android/external_protocol_dialog_android.cc +++ b/chrome/browser/ui/android/external_protocol_dialog_android.cc
@@ -36,10 +36,9 @@ has_user_gesture, // has_user_gesture false, // is_post, doesn't matter here. page_transition, - false, // is_redirect, doesn't matter here. - true, // is_external_protocol - false, // is_main_frame - GURL(), // base_url_for_data_url, not applicable. - base::nullopt); // suggested_filename + false, // is_redirect, doesn't matter here. + true, // is_external_protocol + false, // is_main_frame + GURL()); // base_url_for_data_url, not applicable. delegate->ShouldIgnoreNavigation(navigation_params); }
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index b5b3763..c46297a 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -290,6 +290,11 @@ return GetPrefs()->GetBoolean(prefs::kAutofillEnabled); } +bool ChromeAutofillClient::AreServerCardsSupported() { + // When in VR, server side cards are not supported. + return !vr::VrTabHelper::IsInVr(web_contents()); +} + void ChromeAutofillClient::MainFrameWasResized(bool width_changed) { #if defined(OS_ANDROID) // Ignore virtual keyboard showing and hiding a strip of suggestions.
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index 04f5124..6918d996 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -90,6 +90,7 @@ bool IsContextSecure() override; bool ShouldShowSigninPromo() override; bool IsAutofillSupported() override; + bool AreServerCardsSupported() override; void ExecuteCommand(int id) override; // content::WebContentsObserver implementation.
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc index 3bcf193c..f235d9fc 100644 --- a/chrome/browser/ui/browser_navigator.cc +++ b/chrome/browser/ui/browser_navigator.cc
@@ -322,7 +322,6 @@ params->should_replace_current_entry; load_url_params.is_renderer_initiated = params->is_renderer_initiated; load_url_params.started_from_context_menu = params->started_from_context_menu; - load_url_params.suggested_filename = params->suggested_filename; load_url_params.has_user_gesture = params->user_gesture; // |frame_tree_node_id| is kNoFrameTreeNodeId for main frame navigations.
diff --git a/chrome/browser/ui/browser_navigator_params.cc b/chrome/browser/ui/browser_navigator_params.cc index 0f5171b..50fe09ab 100644 --- a/chrome/browser/ui/browser_navigator_params.cc +++ b/chrome/browser/ui/browser_navigator_params.cc
@@ -58,6 +58,5 @@ this->uses_post = params.uses_post; this->post_data = params.post_data; this->started_from_context_menu = params.started_from_context_menu; - this->suggested_filename = params.suggested_filename; this->open_pwa_window_if_possible = params.open_app_window_if_possible; }
diff --git a/chrome/browser/ui/browser_navigator_params.h b/chrome/browser/ui/browser_navigator_params.h index bfb2276..24b7099 100644 --- a/chrome/browser/ui/browser_navigator_params.h +++ b/chrome/browser/ui/browser_navigator_params.h
@@ -9,7 +9,6 @@ #include <vector> #include "base/memory/ref_counted.h" -#include "base/optional.h" #include "build/build_config.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "content/public/browser/global_request_id.h" @@ -246,11 +245,6 @@ // an about:blank or a data url navigation. scoped_refptr<content::SiteInstance> source_site_instance; - // If this event was triggered by an anchor element with a download - // attribute, |suggested_filename| will contain the (possibly empty) value of - // that attribute. - base::Optional<std::string> suggested_filename; - // Indicates that the navigation should happen in an pwa window if // possible, i.e. if the is a PWA installed for the target URL. bool open_pwa_window_if_possible = false;
diff --git a/chrome/browser/ui/search/local_ntp_browsertest.cc b/chrome/browser/ui/search/local_ntp_browsertest.cc index a6bfb74..49f1f88 100644 --- a/chrome/browser/ui/search/local_ntp_browsertest.cc +++ b/chrome/browser/ui/search/local_ntp_browsertest.cc
@@ -329,9 +329,8 @@ ui_test_utils::NavigateToURL(browser(), download_url); download_observer.WaitForFinished(); - // This should neither have changed the visible URL, nor the last committed - // one. - ASSERT_EQ(GURL(chrome::kChromeUINewTabURL), active_tab->GetVisibleURL()); + // This should have changed the visible URL, but not the last committed one. + ASSERT_EQ(download_url, active_tab->GetVisibleURL()); ASSERT_EQ(GURL(chrome::kChromeUINewTabURL), active_tab->GetLastCommittedURL());
diff --git a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h index b978b700..cdeecc21 100644 --- a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h +++ b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h
@@ -41,7 +41,6 @@ namespace syncer { class SyncService; -class SyncServiceBase; } // namespace syncer namespace ui { @@ -198,8 +197,7 @@ ScopedObserver<sessions::TabRestoreService, RecentTabsSubMenuModel> tab_restore_service_observer_; - ScopedObserver<syncer::SyncServiceBase, RecentTabsSubMenuModel> - sync_observer_; + ScopedObserver<syncer::SyncService, RecentTabsSubMenuModel> sync_observer_; #endif base::WeakPtrFactory<RecentTabsSubMenuModel> weak_ptr_factory_;
diff --git a/chrome/browser/ui/views/device_chooser_content_view.cc b/chrome/browser/ui/views/device_chooser_content_view.cc index f5358a0..d555fa4 100644 --- a/chrome/browser/ui/views/device_chooser_content_view.cc +++ b/chrome/browser/ui/views/device_chooser_content_view.cc
@@ -220,7 +220,7 @@ if (chooser_controller_->IsConnected(row)) return gfx::CreateVectorIcon(vector_icons::kBluetoothConnectedIcon, - gfx::kChromeIconGrey); + TableModel::kIconSize, gfx::kChromeIconGrey); int level = chooser_controller_->GetSignalStrengthLevel(row);
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc index 1d2c74c9..dab1059f 100644 --- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
@@ -22,11 +22,13 @@ #include "content/public/browser/web_contents.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/color_utils.h" +#include "ui/gfx/image/image_skia.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/views/background.h" #include "ui/views/controls/button/button.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/button/image_button_factory.h" +#include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/controls/webview/webview.h" #include "ui/views/layout/fill_layout.h" @@ -47,6 +49,7 @@ public: ReadOnlyOriginView(const base::string16& page_title, const GURL& origin, + const gfx::ImageSkia* icon_image_skia, SkColor background_color, views::ButtonListener* site_settings_listener) { std::unique_ptr<views::View> title_origin_container = @@ -86,6 +89,17 @@ views::GridLayout* top_level_layout = SetLayoutManager(std::make_unique<views::GridLayout>(this)); views::ColumnSet* top_level_columns = top_level_layout->AddColumnSet(0); + // Payment handler icon comes from Web Manifest, which are square. + constexpr int kPaymentHandlerIconSize = 32; + bool has_icon = icon_image_skia && icon_image_skia->width(); + if (has_icon) { + // A column for the instrument icon. + top_level_columns->AddColumn( + views::GridLayout::LEADING, views::GridLayout::FILL, 0, + views::GridLayout::FIXED, kPaymentHandlerIconSize, + kPaymentHandlerIconSize); + top_level_columns->AddPaddingColumn(0, 8); + } top_level_columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1, views::GridLayout::USE_PREF, 0, 0); @@ -95,6 +109,14 @@ views::GridLayout::FIXED, kSiteSettingsSize, kSiteSettingsSize); top_level_layout->StartRow(0, 0); + if (has_icon) { + std::unique_ptr<views::ImageView> instrument_icon_view = + CreateInstrumentIconView(/*icon_id=*/0, icon_image_skia, + /*label=*/page_title); + instrument_icon_view->SetImageSize( + gfx::Size(kPaymentHandlerIconSize, kPaymentHandlerIconSize)); + top_level_layout->AddView(instrument_icon_view.release()); + } top_level_layout->AddView(title_origin_container.release()); views::ImageButton* site_settings_button = @@ -175,8 +197,10 @@ const GURL origin = web_contents() ? web_contents()->GetVisibleURL().GetOrigin() : GURL(); std::unique_ptr<views::Background> background = GetHeaderBackground(); - return std::make_unique<ReadOnlyOriginView>(GetSheetTitle(), origin, - background->get_color(), this); + return std::make_unique<ReadOnlyOriginView>( + GetSheetTitle(), origin, + state()->selected_instrument()->icon_image_skia(), + background->get_color(), this); } std::unique_ptr<views::Background>
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc index 9ab17b84..d325dbd4 100644 --- a/chrome/browser/ui/views/payments/payment_request_views_util.cc +++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -203,7 +203,7 @@ columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); - constexpr int kPaddingBetweenArrowAndTitle = 16; + constexpr int kPaddingBetweenArrowAndTitle = 8; if (show_back_arrow) columns->AddPaddingColumn(0, kPaddingBetweenArrowAndTitle);
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index b609302..0c7c6abe 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -479,9 +479,6 @@ "pepper_permission_util.h", ] } - if (!enable_webrtc) { - sources -= [ "media/webrtc_logging_messages.h" ] - } if (safe_browsing_mode != 0) { public_deps += [ "//chrome/common/safe_browsing" ]
diff --git a/chrome/common/extensions/api/BUILD.gn b/chrome/common/extensions/api/BUILD.gn index 288a413..8cdf32f 100644 --- a/chrome/common/extensions/api/BUILD.gn +++ b/chrome/common/extensions/api/BUILD.gn
@@ -6,7 +6,6 @@ import("//build/config/ui.gni") import("//chrome/common/features.gni") import("//extensions/buildflags/buildflags.gni") -import("//media/media_options.gni") import("//tools/json_schema_compiler/json_features.gni") import("//tools/json_schema_compiler/json_schema_api.gni") @@ -16,6 +15,10 @@ "accessibility_features.json", "accessibility_private.json", "activity_log_private.json", + "cast_streaming_receiver_session.idl", + "cast_streaming_rtp_stream.idl", + "cast_streaming_session.idl", + "cast_streaming_udp_transport.idl", "autofill_private.idl", "automation.idl", "automation_internal.idl", @@ -131,15 +134,6 @@ schema_sources += [ "mdns.idl" ] } -if (enable_webrtc) { - schema_sources += [ - "cast_streaming_receiver_session.idl", - "cast_streaming_rtp_stream.idl", - "cast_streaming_session.idl", - "cast_streaming_udp_transport.idl", - ] -} - extensions_api_root_namespace = "extensions::api::%(namespace)s" extensions_api_uncompiled_sources = [
diff --git a/chrome/common/extensions/api/file_manager_private.idl b/chrome/common/extensions/api/file_manager_private.idl index 5027bbf..d7b7507 100644 --- a/chrome/common/extensions/api/file_manager_private.idl +++ b/chrome/common/extensions/api/file_manager_private.idl
@@ -175,7 +175,8 @@ sharedWithMe, shared, starred, - externalFileUrl + externalFileUrl, + alternateUrl }; // Entry property visibility for setEntryTag(); @@ -301,8 +302,11 @@ // True if the entry is starred by the user. boolean? starred; - // External file URL to open the file in browser. + // externalfile:// URL to open the file in browser. DOMString? externalFileUrl; + + // https:// URL to open the file in the Drive website. + DOMString? alternateUrl; }; // Information about total and remaining size on the mount point.
diff --git a/chrome/common/features.gni b/chrome/common/features.gni index a949d72..a8d49da 100644 --- a/chrome/common/features.gni +++ b/chrome/common/features.gni
@@ -80,8 +80,10 @@ "enable_print_preview=$enable_print_preview", "enable_printing=$enable_basic_printing", "enable_service_discovery=$enable_service_discovery", - "enable_webrtc=$enable_webrtc", "enable_vr=$enable_vr", + + # TODO(phoglund): Remove this. + "enable_webrtc=true", "mac_views_browser=$mac_views_browser", "safe_browsing_mode=$safe_browsing_mode", "optimize_webui=$optimize_webui",
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn index 6fd923e..0b312fc 100644 --- a/chrome/renderer/BUILD.gn +++ b/chrome/renderer/BUILD.gn
@@ -8,7 +8,6 @@ import("//components/offline_pages/buildflags/features.gni") import("//components/spellcheck/spellcheck_build_features.gni") import("//extensions/buildflags/buildflags.gni") -import("//media/media_options.gni") import("//ppapi/buildflags/buildflags.gni") import("//tools/grit/grit_rule.gni") @@ -60,6 +59,10 @@ "media/chrome_key_systems.h", "media/chrome_key_systems_provider.cc", "media/chrome_key_systems_provider.h", + "media/chrome_webrtc_log_message_delegate.cc", + "media/chrome_webrtc_log_message_delegate.h", + "media/webrtc_logging_message_filter.cc", + "media/webrtc_logging_message_filter.h", "net/net_error_helper.cc", "net/net_error_helper.h", "net/net_error_helper_core.cc", @@ -346,24 +349,8 @@ public_deps = [ "//ipc", ] - if (!enable_webrtc) { - sources -= [ - "media/cast_receiver_session.cc", - "media/cast_receiver_session.h", - "media/cast_rtp_stream.cc", - "media/cast_rtp_stream.h", - ] - } } - if (enable_webrtc) { - sources += [ - "media/chrome_webrtc_log_message_delegate.cc", - "media/chrome_webrtc_log_message_delegate.h", - "media/webrtc_logging_message_filter.cc", - "media/webrtc_logging_message_filter.h", - ] - } - if (enable_extensions && enable_webrtc) { + if (enable_extensions) { sources += [ "extensions/cast_streaming_native_handler.cc", "extensions/cast_streaming_native_handler.h", @@ -428,6 +415,8 @@ sources = [ "chrome_mock_render_thread.cc", "chrome_mock_render_thread.h", + "media/mock_webrtc_logging_message_filter.cc", + "media/mock_webrtc_logging_message_filter.h", "safe_browsing/mock_feature_extractor_clock.cc", "safe_browsing/mock_feature_extractor_clock.h", "safe_browsing/test_utils.cc", @@ -443,13 +432,6 @@ "//testing/gtest", ] - if (enable_webrtc) { - sources += [ - "media/mock_webrtc_logging_message_filter.cc", - "media/mock_webrtc_logging_message_filter.h", - ] - } - if (is_android) { sources -= [ "safe_browsing/mock_feature_extractor_clock.cc",
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc index ce598cc..9def392 100644 --- a/chrome/renderer/autofill/form_autofill_browsertest.cc +++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -2530,30 +2530,31 @@ } TEST_F(FormAutofillTest, WebFormElementToFormData) { - LoadHTML("<FORM name='TestForm' action='http://cnn.com' method='post'>" - " <LABEL for='firstname'>First name:</LABEL>" - " <INPUT type='text' id='firstname' value='John'/>" - " <LABEL for='lastname'>Last name:</LABEL>" - " <INPUT type='text' id='lastname' value='Smith'/>" - " <LABEL for='street-address'>Address:</LABEL>" - " <TEXTAREA id='street-address'>" - "123 Fantasy Ln. " - "Apt. 42" - "</TEXTAREA>" - " <LABEL for='state'>State:</LABEL>" - " <SELECT id='state'/>" - " <OPTION value='CA'>California</OPTION>" - " <OPTION value='TX'>Texas</OPTION>" - " </SELECT>" - " <LABEL for='password'>Password:</LABEL>" - " <INPUT type='password' id='password' value='secret'/>" - " <LABEL for='month'>Card expiration:</LABEL>" - " <INPUT type='month' id='month' value='2011-12'/>" - " <INPUT type='submit' name='reply-send' value='Send'/>" - // The below inputs should be ignored - " <LABEL for='notvisible'>Hidden:</LABEL>" - " <INPUT type='hidden' id='notvisible' value='apple'/>" - "</FORM>"); + LoadHTML( + "<FORM name='TestForm' action='http://cnn.com/submit/?a=1' method='post'>" + " <LABEL for='firstname'>First name:</LABEL>" + " <INPUT type='text' id='firstname' value='John'/>" + " <LABEL for='lastname'>Last name:</LABEL>" + " <INPUT type='text' id='lastname' value='Smith'/>" + " <LABEL for='street-address'>Address:</LABEL>" + " <TEXTAREA id='street-address'>" + "123 Fantasy Ln. " + "Apt. 42" + "</TEXTAREA>" + " <LABEL for='state'>State:</LABEL>" + " <SELECT id='state'/>" + " <OPTION value='CA'>California</OPTION>" + " <OPTION value='TX'>Texas</OPTION>" + " </SELECT>" + " <LABEL for='password'>Password:</LABEL>" + " <INPUT type='password' id='password' value='secret'/>" + " <LABEL for='month'>Card expiration:</LABEL>" + " <INPUT type='month' id='month' value='2011-12'/>" + " <INPUT type='submit' name='reply-send' value='Send'/>" + // The below inputs should be ignored + " <LABEL for='notvisible'>Hidden:</LABEL>" + " <INPUT type='hidden' id='notvisible' value='apple'/>" + "</FORM>"); WebLocalFrame* frame = GetMainFrame(); ASSERT_NE(nullptr, frame); @@ -2571,7 +2572,7 @@ EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name); EXPECT_EQ(GetCanonicalOriginForDocument(frame->GetDocument()), form.origin); EXPECT_FALSE(form.origin.is_empty()); - EXPECT_EQ(GURL("http://cnn.com"), form.action); + EXPECT_EQ(GURL("http://cnn.com/submit/"), form.action); const std::vector<FormFieldData>& fields = form.fields; ASSERT_EQ(6U, fields.size());
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 78bdbc1..deb01ac4 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -16,7 +16,6 @@ import("//components/signin/features.gni") import("//components/spellcheck/spellcheck_build_features.gni") import("//extensions/buildflags/buildflags.gni") -import("//media/media_options.gni") import("//mojo/public/tools/bindings/mojom.gni") import("//ppapi/buildflags/buildflags.gni") import("//remoting/remoting_enable.gni") @@ -1742,6 +1741,7 @@ "//components/exo:test_support", "//components/prefs", "//components/user_manager:test_support", + "//content/public/common:feature_h264_with_openh264_ffmpeg", "//services/audio/public/cpp:test_support", "//services/network/public/mojom", "//services/preferences/public/cpp", @@ -1805,31 +1805,7 @@ if (enable_captive_portal_detection) { sources += [ "../browser/captive_portal/captive_portal_browsertest.cc" ] } - if (enable_webrtc) { - deps += [ "//content/public/common:feature_h264_with_openh264_ffmpeg" ] - } else { - sources -= [ - "../browser/media/webrtc/webrtc_apprtc_browsertest.cc", - "../browser/media/webrtc/webrtc_audio_quality_browsertest.cc", - "../browser/media/webrtc/webrtc_browsertest.cc", - "../browser/media/webrtc/webrtc_disable_encryption_flag_browsertest.cc", - "../browser/media/webrtc/webrtc_getmediadevices_browsertest.cc", - "../browser/media/webrtc/webrtc_internals_integration_browsertest.cc", - "../browser/media/webrtc/webrtc_internals_perf_browsertest.cc", - "../browser/media/webrtc/webrtc_rtp_browsertest.cc", - "../browser/media/webrtc/webrtc_simulcast_browsertest.cc", - "../browser/media/webrtc/webrtc_stats_perf_browsertest.cc", - "../browser/media/webrtc/webrtc_video_display_perf_browsertest.cc", - "../browser/media/webrtc/webrtc_video_quality_browsertest.cc", - "../browser/media/webrtc/webrtc_webcam_browsertest.cc", - ] - if (enable_extensions) { - sources -= [ - "../browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc", - "../browser/extensions/api/webrtc_logging_private/webrtc_logging_private_apitest.cc", - ] - } - } + if (is_mac) { # Other platforms only need .pak files, and can build this target # standalone much faster. @@ -2958,6 +2934,7 @@ "../browser/platform_util_unittest.cc", "../browser/policy/policy_path_parser_unittest.cc", "../browser/profile_resetter/profile_resetter_unittest.cc", + "../browser/profile_resetter/reset_report_uploader_unittest.cc", "../browser/profile_resetter/triggered_profile_resetter_win_unittest.cc", "../browser/renderer_context_menu/render_view_context_menu_unittest.cc", "../browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win_unittest.cc", @@ -3148,6 +3125,9 @@ "../browser/media/router/providers/dial/dial_media_route_provider_unittest.cc", "../browser/media/router/providers/extension/extension_media_route_provider_proxy_unittest.cc", "../browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc", + "../browser/media/webrtc/webrtc_log_uploader_unittest.cc", + "../browser/media/webrtc/webrtc_rtp_dump_handler_unittest.cc", + "../browser/media/webrtc/webrtc_rtp_dump_writer_unittest.cc", "../browser/policy/local_sync_policy_handler_unittest.cc", "../browser/renderer_context_menu/render_view_context_menu_test_util.cc", "../browser/renderer_context_menu/render_view_context_menu_test_util.h", @@ -3174,6 +3154,7 @@ "../common/media_router/discovery/media_sink_service_base_unittest.cc", "../common/media_router/mojo/media_router_struct_traits_unittest.cc", "../common/media_router/providers/cast/cast_media_source_unittest.cc", + "../renderer/media/chrome_webrtc_log_message_delegate_unittest.cc", ] deps += [ "//components/bubble:test_support", @@ -3902,14 +3883,6 @@ ] } } - if (enable_webrtc) { - sources += [ - "../browser/media/webrtc/webrtc_log_uploader_unittest.cc", - "../browser/media/webrtc/webrtc_rtp_dump_handler_unittest.cc", - "../browser/media/webrtc/webrtc_rtp_dump_writer_unittest.cc", - "../renderer/media/chrome_webrtc_log_message_delegate_unittest.cc", - ] - } if (is_chromeos) { deps += [ "//chrome/browser/chromeos:unit_tests",
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index 0e2e92f..a525fef0 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -1702,28 +1702,18 @@ self.assertTrue(frame_url.endswith('#two')) -def log(message): - # Log a message with timestamp, in a format similar to ChromeDriver log - print '[%.3f] %s' % (time.time(), message) - class ChromeDriverPageLoadTimeoutTest(ChromeDriverBaseTestWithWebServer): class _RequestHandler(object): def __init__(self): self.request_received_event = threading.Event() self.send_response_event = threading.Event() - print - log('Created _RequestHandler') def handle(self, request): - log('Request received') self.request_received_event.set() - log('After request_received_event.set()') # Don't hang infinitely, 10 seconds are enough. self.send_response_event.wait(10) - log('After send_response_event.wait(10)') self.send_response_event.clear() - log('After send_response_event.clear()') return {'Cache-Control': 'no-store'}, 'Hi!' def setUp(self): @@ -1740,16 +1730,13 @@ # on Mac. So we use longer timeout on Mac, 0.5 second on others. timeout = 3000 if util.GetPlatformName() == 'mac' else 500 self._driver.SetTimeout('page load', timeout) - log('setUp complete') def tearDown(self): super(ChromeDriverPageLoadTimeoutTest, self).tearDown() self._http_server.SetCallbackForPath('/hang', None) def _LoadHangingUrl(self, host=None): - log('Entering _LoadHangingUrl') self._driver.Load(self._http_server.GetUrl(host) + '/hang') - log('Leaving _LoadHangingUrl') def _CheckPageLoadTimeout(self, action): self._handler.request_received_event.clear() @@ -1779,30 +1766,21 @@ def testHistoryNavigationWithPageLoadTimeout(self): # Allow the page to load for the first time. - log('Entering testHistoryNavigationWithPageLoadTimeout') self._handler.send_response_event.set() - log('After self._handler.send_response_event.set()') self._LoadHangingUrl() self.assertTrue(self._handler.request_received_event.wait(1)) - log('Before GoBack') self._driver.GoBack() - log('Before GoForward') self._CheckPageLoadTimeout(self._driver.GoForward) - log('After GoForward') self.assertEquals(self._initial_url, self._driver.GetCurrentUrl()) def testRefreshWithPageLoadTimeout(self): # Allow the page to load for the first time. - log('Entering testRefreshWithPageLoadTimeout') self._handler.send_response_event.set() - log('After self._handler.send_response_event.set()') self._LoadHangingUrl() self.assertTrue(self._handler.request_received_event.wait(1)) - log('Before Refresh') self._CheckPageLoadTimeout(self._driver.Refresh) - log('After Refresh') class ChromeDriverAndroidTest(ChromeDriverBaseTest):
diff --git a/chrome/test/data/extensions/api_test/webnavigation/download/test_download.js b/chrome/test/data/extensions/api_test/webnavigation/download/test_download.js index 126add5..6791a0e 100644 --- a/chrome/test/data/extensions/api_test/webnavigation/download/test_download.js +++ b/chrome/test/data/extensions/api_test/webnavigation/download/test_download.js
@@ -3,7 +3,8 @@ // found in the LICENSE file. onload = function() { - var getURL = chrome.extension.getURL; + var URL_START = + 'http://127.0.0.1:PORT/extensions/api_test/webnavigation/download/a.html'; var URL_LOAD_REDIRECT = "http://127.0.0.1:PORT/server-redirect"; var URL_NOT_FOUND = "http://127.0.0.1:PORT/not-found"; chrome.tabs.create({"url": "about:blank"}, function(tab) { @@ -12,11 +13,12 @@ var fixPort = function(url) { return url.replace(/PORT/g, config.testServer.port); }; + URL_START = fixPort(URL_START); URL_LOAD_REDIRECT = fixPort(URL_LOAD_REDIRECT); URL_NOT_FOUND = fixPort(URL_NOT_FOUND); chrome.test.runTests([ // Navigates to a page that redirects (on the server side) to a.html. - function serverRedirect() { + function download() { expect([ { label: "a-onBeforeNavigate", event: "onBeforeNavigate", @@ -25,7 +27,7 @@ processId: -1, tabId: 0, timeStamp: 0, - url: getURL('a.html') }}, + url: URL_START }}, { label: "a-onCommitted", event: "onCommitted", details: { frameId: 0, @@ -34,41 +36,24 @@ timeStamp: 0, transitionQualifiers: [], transitionType: "link", - url: getURL('a.html') }}, + url: URL_START }}, { label: "a-onDOMContentLoaded", event: "onDOMContentLoaded", details: { frameId: 0, processId: 0, tabId: 0, timeStamp: 0, - url: getURL('a.html') }}, + url: URL_START }}, { label: "a-onCompleted", event: "onCompleted", details: { frameId: 0, processId: 0, tabId: 0, timeStamp: 0, - url: getURL('a.html') }}, - { label: "b-onBeforeNavigate", - event: "onBeforeNavigate", - details: { frameId: 0, - parentFrameId: -1, - processId: -1, - tabId: 0, - timeStamp: 0, - url: URL_LOAD_REDIRECT }}, - { label: "b-onErrorOccurred", - event: "onErrorOccurred", - details: { error: "net::ERR_INVALID_RESPONSE", - frameId: 0, - processId: -1, - tabId: 0, - timeStamp: 0, - url: URL_NOT_FOUND }}], - [ navigationOrder("a-"), - [ "b-onBeforeNavigate", "b-onErrorOccurred"] ]); + url: URL_START }}], + [ navigationOrder("a-") ]); chrome.tabs.update( - tabId, { url: getURL('a.html?' + config.testServer.port) }); + tabId, { url: URL_START + "?" + config.testServer.port }); }, ]); });
diff --git a/chrome/test/data/webui/settings/all_sites_tests.js b/chrome/test/data/webui/settings/all_sites_tests.js index 237a2b10..72e1d23 100644 --- a/chrome/test/data/webui/settings/all_sites_tests.js +++ b/chrome/test/data/webui/settings/all_sites_tests.js
@@ -129,7 +129,8 @@ testElement.async(resolver.resolve); return resolver.promise.then(function() { const item = testElement.$.listContainer.children[0]; - const name = item.querySelector('#displayName'); + assertEquals('SITE-ENTRY', item.tagName); + const name = item.root.querySelector('#displayName'); assertTrue(!!name); }); }); @@ -177,7 +178,7 @@ // Validate that the sites are shown in UI and can be selected. const firstItem = testElement.$.listContainer.children[1]; - const clickable = firstItem.querySelector('.middle'); + const clickable = firstItem.root.querySelector('.middle'); assertNotEquals(undefined, clickable); MockInteractions.tap(clickable); assertEquals( @@ -226,7 +227,7 @@ assertEquals(undefined, testElement.selectedOrigin); // Validate that the sites are shown in UI and can be selected. const firstItem = testElement.$.listContainer.children[0]; - const clickable = firstItem.querySelector('.middle'); + const clickable = firstItem.root.querySelector('.middle'); assertNotEquals(undefined, clickable); MockInteractions.tap(clickable); if (testElement.sites.length == 1) {
diff --git a/chrome/test/media_router/media_router_integration_browsertest.cc b/chrome/test/media_router/media_router_integration_browsertest.cc index 7b0bba42..2882717 100644 --- a/chrome/test/media_router/media_router_integration_browsertest.cc +++ b/chrome/test/media_router/media_router_integration_browsertest.cc
@@ -15,6 +15,7 @@ #include "base/strings/stringprintf.h" #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" +#include "build/build_config.h" #include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_finder.h" @@ -839,8 +840,14 @@ RunReconnectSessionTest(); } +// Flaky on Linux MSAN. https://crbug.com/840165 +#if defined(OS_LINUX) && defined(MEMORY_SANITIZER) +#define MAYBE_Fail_ReconnectSession DISABLED_Fail_ReconnectSession +#else +#define MAYBE_Fail_ReconnectSession Fail_ReconnectSession +#endif IN_PROC_BROWSER_TEST_F(MediaRouterIntegrationBrowserTest, - Fail_ReconnectSession) { + MAYBE_Fail_ReconnectSession) { WebContents* web_contents = StartSessionWithTestPageAndChooseSink(); CheckSessionValidity(web_contents); std::string session_id(GetStartedConnectionId(web_contents));
diff --git a/chrome/tools/service_discovery_sniffer/BUILD.gn b/chrome/tools/service_discovery_sniffer/BUILD.gn index 65f8279..5c3ba63 100644 --- a/chrome/tools/service_discovery_sniffer/BUILD.gn +++ b/chrome/tools/service_discovery_sniffer/BUILD.gn
@@ -3,7 +3,6 @@ # found in the LICENSE file. import("//build/config/features.gni") -import("//media/media_options.gni") executable("service_discovery_sniffer") { testonly = true @@ -18,9 +17,6 @@ "//build/config:exe_and_shlib_deps", "//chrome/browser", "//net", + "//third_party/webrtc_overrides:init_webrtc", ] - - if (enable_webrtc) { - deps += [ "//third_party/webrtc_overrides:init_webrtc" ] - } }
diff --git a/chromecast/graphics/cast_system_gesture_event_handler.cc b/chromecast/graphics/cast_system_gesture_event_handler.cc index d6b27d1..2513a47 100644 --- a/chromecast/graphics/cast_system_gesture_event_handler.cc +++ b/chromecast/graphics/cast_system_gesture_event_handler.cc
@@ -66,65 +66,79 @@ return CastSideSwipeOrigin::NONE; } -void CastSystemGestureEventHandler::OnEvent(ui::Event* event) { - if (current_swipe_ != CastSideSwipeOrigin::NONE && - (event->IsTouchEvent() || event->IsGestureEvent())) { - // If we're in the process of handling a swipe, prevent the underlying touch - // or gesture event from being propagated out to other users. - event->StopPropagation(); - } - - // From here-on in, we're only interested in gestures. - if (!event->IsGestureEvent()) { +void CastSystemGestureEventHandler::OnTouchEvent(ui::TouchEvent* event) { + if (swipe_gesture_handlers_.empty()) { return; } - ui::GestureEvent* gesture_event = event->AsGestureEvent(); - gfx::Point gesture_location(gesture_event->location()); - aura::Window* target = static_cast<aura::Window*>(event->target()); + gfx::Point touch_location(event->location()); + aura::Window* target = static_cast<aura::Window*>(event->target()); // Convert the event's point to the point on the physical screen. // For cast on root window this is likely going to be identical, but put it // through the ScreenPositionClient just to be sure. - ::wm::ConvertPointToScreen(target, &gesture_location); + ::wm::ConvertPointToScreen(target, &touch_location); gfx::Rect screen_bounds = display::Screen::GetScreen() - ->GetDisplayNearestPoint(gesture_location) + ->GetDisplayNearestPoint(touch_location) .bounds(); CastSideSwipeOrigin side_swipe_origin = - GetDragPosition(gesture_location, screen_bounds); + GetDragPosition(touch_location, screen_bounds); - // Detect the beginning of a system gesture swipe. - if (side_swipe_origin != CastSideSwipeOrigin::NONE && - (event->type() == ui::ET_SCROLL_FLING_START || - event->type() == ui::ET_GESTURE_BEGIN)) { + // A located event has occurred inside the margin. It might be the start of + // our gesture, or a touch that we need to squash. + if (current_swipe_ == CastSideSwipeOrigin::NONE && + side_swipe_origin != CastSideSwipeOrigin::NONE) { + // Check to see if we have any potential consumers of events on this side. + // If not, we can continue on without consuming it. + bool have_swipe_consumer = false; for (auto* side_swipe_handler : swipe_gesture_handlers_) { - // Let the subscriber know about the swipe. If it is actually consumed by - // them, it will be marked as handled. - side_swipe_handler->OnSideSwipeBegin(side_swipe_origin, gesture_event); - - // If handled, remember the origin and then stop the further propagation - // of the event. - if (event->handled()) { - // Record the swipe origin to properly fire OnSideSwipeEnd when the - // swipe gesture finishes. - current_swipe_ = side_swipe_origin; - event->StopPropagation(); - + if (side_swipe_handler->CanHandleSwipe(side_swipe_origin)) { + have_swipe_consumer = true; break; } } + if (!have_swipe_consumer) { + return; + } + + // All touch or gesture events inside the margins have to be consumed, or we + // risk a state issue later when the touch ends (b/78461207) + event->StopPropagation(); + + // Detect the beginning of a system gesture swipe. + if (event->type() == ui::ET_TOUCH_PRESSED) { + current_swipe_ = side_swipe_origin; + for (auto* side_swipe_handler : swipe_gesture_handlers_) { + // Let the subscriber know about the gesture begin. + side_swipe_handler->HandleSideSwipeBegin(side_swipe_origin, + touch_location); + } + } + return; } - // Detect the end of a system gesture swipe. - if (current_swipe_ != CastSideSwipeOrigin::NONE && - event->type() == ui::ET_GESTURE_END) { + if (current_swipe_ == CastSideSwipeOrigin::NONE) { + return; + } + + // A swipe is in progress, or has completed, so stop propagation of underlying + // gesture/touch events. + event->StopPropagation(); + + // The system gesture has ended. + if (event->type() == ui::ET_TOUCH_RELEASED) { for (auto* side_swipe_handler : swipe_gesture_handlers_) { - side_swipe_handler->OnSideSwipeEnd(current_swipe_, gesture_event); + side_swipe_handler->HandleSideSwipeEnd(current_swipe_, touch_location); } current_swipe_ = CastSideSwipeOrigin::NONE; - // Prevent the gesture from being used for other gesture uses. - target->CleanupGestureState(); + return; + } + + // The system gesture is ongoing... + for (auto* side_swipe_handler : swipe_gesture_handlers_) { + // Let the subscriber know about the gesture begin. + side_swipe_handler->HandleSideSwipeContinue(current_swipe_, touch_location); } }
diff --git a/chromecast/graphics/cast_system_gesture_event_handler.h b/chromecast/graphics/cast_system_gesture_event_handler.h index 9c04044..d968815 100644 --- a/chromecast/graphics/cast_system_gesture_event_handler.h +++ b/chromecast/graphics/cast_system_gesture_event_handler.h
@@ -41,7 +41,7 @@ CastSideSwipeOrigin GetDragPosition(const gfx::Point& point, const gfx::Rect& screen_bounds) const; - void OnEvent(ui::Event* event) override; + void OnTouchEvent(ui::TouchEvent* event) override; private: const int gesture_start_width_;
diff --git a/chromecast/graphics/cast_system_gesture_event_handler_test.cc b/chromecast/graphics/cast_system_gesture_event_handler_test.cc index 8612974..d4d21f5a 100644 --- a/chromecast/graphics/cast_system_gesture_event_handler_test.cc +++ b/chromecast/graphics/cast_system_gesture_event_handler_test.cc
@@ -21,6 +21,7 @@ constexpr base::TimeDelta kTimeDelay = base::TimeDelta::FromMilliseconds(100); constexpr int kSwipeDistance = 50; constexpr int kNumSteps = 5; +constexpr gfx::Point kZeroPoint{0, 0}; } // namespace @@ -50,56 +51,61 @@ class TestSideSwipeGestureHandler : public CastSideSwipeGestureHandlerInterface { public: + TestSideSwipeGestureHandler() + : begin_swipe_point_(kZeroPoint), end_swipe_point_(kZeroPoint) {} + ~TestSideSwipeGestureHandler() override = default; - void OnSideSwipeBegin(CastSideSwipeOrigin swipe_origin, - ui::GestureEvent* gesture_event) override { + bool CanHandleSwipe(CastSideSwipeOrigin swipe_origin) override { + return handle_swipe_; + } + + void HandleSideSwipeBegin(CastSideSwipeOrigin swipe_origin, + const gfx::Point& touch_location) override { if (handle_swipe_) { begin_swipe_origin_ = swipe_origin; - begin_gesture_event_ = gesture_event; - - gesture_event->SetHandled(); + begin_swipe_point_ = touch_location; } } - void OnSideSwipeEnd(CastSideSwipeOrigin swipe_origin, - ui::GestureEvent* gesture_event) override { + void HandleSideSwipeEnd(CastSideSwipeOrigin swipe_origin, + const gfx::Point& gesture_event) override { end_swipe_origin_ = swipe_origin; - end_gesture_event_ = gesture_event; + end_swipe_point_ = gesture_event; } void SetHandleSwipe(bool handle_swipe) { handle_swipe_ = handle_swipe; } CastSideSwipeOrigin begin_swipe_origin() const { return begin_swipe_origin_; } - ui::GestureEvent* begin_gesture_event() const { return begin_gesture_event_; } + gfx::Point begin_swipe_point() const { return begin_swipe_point_; } CastSideSwipeOrigin end_swipe_origin() const { return end_swipe_origin_; } - ui::GestureEvent* end_gesture_event() const { return end_gesture_event_; } + gfx::Point end_swipe_point() const { return end_swipe_point_; } private: bool handle_swipe_ = true; CastSideSwipeOrigin begin_swipe_origin_ = CastSideSwipeOrigin::NONE; - ui::GestureEvent* begin_gesture_event_ = nullptr; + gfx::Point begin_swipe_point_; CastSideSwipeOrigin end_swipe_origin_ = CastSideSwipeOrigin::NONE; - ui::GestureEvent* end_gesture_event_ = nullptr; + gfx::Point end_swipe_point_; }; // Event sink to check for events that get through (or don't get through) after // the system gesture handler handles them. class TestEventHandler : public ui::EventHandler { public: - TestEventHandler() : EventHandler(), num_gesture_events_received_(0) {} + TestEventHandler() : EventHandler(), num_touch_events_received_(0) {} - void OnGestureEvent(ui::GestureEvent* event) override { - num_gesture_events_received_++; + void OnTouchEvent(ui::TouchEvent* event) override { + num_touch_events_received_++; } - int NumGestureEventsReceived() const { return num_gesture_events_received_; } + int NumTouchEventsReceived() const { return num_touch_events_received_; } private: - int num_gesture_events_received_; + int num_touch_events_received_; }; class CastSystemGestureEventHandlerTest : public aura::test::AuraTestBase { @@ -157,11 +163,11 @@ TEST_F(CastSystemGestureEventHandlerTest, Initialization) { EXPECT_EQ(CastSideSwipeOrigin::NONE, test_gesture_handler().begin_swipe_origin()); - EXPECT_EQ(nullptr, test_gesture_handler().begin_gesture_event()); + EXPECT_EQ(kZeroPoint, test_gesture_handler().begin_swipe_point()); EXPECT_EQ(CastSideSwipeOrigin::NONE, test_gesture_handler().end_swipe_origin()); - EXPECT_EQ(nullptr, test_gesture_handler().end_gesture_event()); - EXPECT_EQ(0, test_event_handler().NumGestureEventsReceived()); + EXPECT_EQ(kZeroPoint, test_gesture_handler().end_swipe_point()); + EXPECT_EQ(0, test_event_handler().NumTouchEventsReceived()); } // A swipe in the middle of the screen should produce no system gesture. @@ -176,11 +182,11 @@ EXPECT_EQ(CastSideSwipeOrigin::NONE, test_gesture_handler().begin_swipe_origin()); - EXPECT_EQ(nullptr, test_gesture_handler().begin_gesture_event()); + EXPECT_EQ(kZeroPoint, test_gesture_handler().begin_swipe_point()); EXPECT_EQ(CastSideSwipeOrigin::NONE, test_gesture_handler().end_swipe_origin()); - EXPECT_EQ(nullptr, test_gesture_handler().end_gesture_event()); - EXPECT_NE(0, test_event_handler().NumGestureEventsReceived()); + EXPECT_EQ(kZeroPoint, test_gesture_handler().end_swipe_point()); + EXPECT_NE(0, test_event_handler().NumTouchEventsReceived()); } TEST_F(CastSystemGestureEventHandlerTest, SwipeFromLeft) { @@ -193,11 +199,11 @@ EXPECT_EQ(CastSideSwipeOrigin::LEFT, test_gesture_handler().begin_swipe_origin()); - EXPECT_NE(nullptr, test_gesture_handler().begin_gesture_event()); + EXPECT_NE(kZeroPoint, test_gesture_handler().begin_swipe_point()); EXPECT_EQ(CastSideSwipeOrigin::LEFT, test_gesture_handler().end_swipe_origin()); - EXPECT_NE(nullptr, test_gesture_handler().end_gesture_event()); - EXPECT_EQ(0, test_event_handler().NumGestureEventsReceived()); + EXPECT_NE(kZeroPoint, test_gesture_handler().end_swipe_point()); + EXPECT_EQ(0, test_event_handler().NumTouchEventsReceived()); } TEST_F(CastSystemGestureEventHandlerTest, SwipeFromRight) { @@ -211,11 +217,11 @@ EXPECT_EQ(CastSideSwipeOrigin::RIGHT, test_gesture_handler().begin_swipe_origin()); - EXPECT_NE(nullptr, test_gesture_handler().begin_gesture_event()); + EXPECT_NE(kZeroPoint, test_gesture_handler().begin_swipe_point()); EXPECT_EQ(CastSideSwipeOrigin::RIGHT, test_gesture_handler().end_swipe_origin()); - EXPECT_NE(nullptr, test_gesture_handler().end_gesture_event()); - EXPECT_EQ(0, test_event_handler().NumGestureEventsReceived()); + EXPECT_NE(kZeroPoint, test_gesture_handler().end_swipe_point()); + EXPECT_EQ(0, test_event_handler().NumTouchEventsReceived()); } TEST_F(CastSystemGestureEventHandlerTest, SwipeFromTop) { @@ -228,11 +234,11 @@ EXPECT_EQ(CastSideSwipeOrigin::TOP, test_gesture_handler().begin_swipe_origin()); - EXPECT_NE(nullptr, test_gesture_handler().begin_gesture_event()); + EXPECT_NE(kZeroPoint, test_gesture_handler().begin_swipe_point()); EXPECT_EQ(CastSideSwipeOrigin::TOP, test_gesture_handler().end_swipe_origin()); - EXPECT_NE(nullptr, test_gesture_handler().end_gesture_event()); - EXPECT_EQ(0, test_event_handler().NumGestureEventsReceived()); + EXPECT_NE(kZeroPoint, test_gesture_handler().end_swipe_point()); + EXPECT_EQ(0, test_event_handler().NumTouchEventsReceived()); } TEST_F(CastSystemGestureEventHandlerTest, SwipeFromBottom) { @@ -246,11 +252,11 @@ EXPECT_EQ(CastSideSwipeOrigin::BOTTOM, test_gesture_handler().begin_swipe_origin()); - EXPECT_NE(nullptr, test_gesture_handler().begin_gesture_event()); + EXPECT_NE(kZeroPoint, test_gesture_handler().begin_swipe_point()); EXPECT_EQ(CastSideSwipeOrigin::BOTTOM, test_gesture_handler().end_swipe_origin()); - EXPECT_NE(nullptr, test_gesture_handler().end_gesture_event()); - EXPECT_EQ(0, test_event_handler().NumGestureEventsReceived()); + EXPECT_NE(kZeroPoint, test_gesture_handler().end_swipe_point()); + EXPECT_EQ(0, test_event_handler().NumTouchEventsReceived()); } // Test that ignoring the gesture at its beginning will make it so the swipe @@ -268,11 +274,11 @@ EXPECT_EQ(CastSideSwipeOrigin::NONE, test_gesture_handler().begin_swipe_origin()); - EXPECT_EQ(nullptr, test_gesture_handler().begin_gesture_event()); + EXPECT_EQ(kZeroPoint, test_gesture_handler().begin_swipe_point()); EXPECT_EQ(CastSideSwipeOrigin::NONE, test_gesture_handler().end_swipe_origin()); - EXPECT_EQ(nullptr, test_gesture_handler().end_gesture_event()); - EXPECT_NE(0, test_event_handler().NumGestureEventsReceived()); + EXPECT_EQ(kZeroPoint, test_gesture_handler().end_swipe_point()); + EXPECT_NE(0, test_event_handler().NumTouchEventsReceived()); } } // namespace test
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index ea66bbc5..0ac2dad 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -10651.0.0 \ No newline at end of file +10654.0.0 \ No newline at end of file
diff --git a/chromeos/components/BUILD.gn b/chromeos/components/BUILD.gn index 07becfd3..17af193 100644 --- a/chromeos/components/BUILD.gn +++ b/chromeos/components/BUILD.gn
@@ -16,7 +16,9 @@ deps = [ "//base", "//base/test:test_support", + "//chromeos/components/drivefs:unit_tests", "//chromeos/components/proximity_auth:unit_tests", "//chromeos/components/tether:unit_tests", + "//mojo/edk", ] }
diff --git a/chromeos/components/drivefs/BUILD.gn b/chromeos/components/drivefs/BUILD.gn new file mode 100644 index 0000000..6b24f78 --- /dev/null +++ b/chromeos/components/drivefs/BUILD.gn
@@ -0,0 +1,42 @@ +# 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. + +assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos") + +component("drivefs") { + sources = [ + "drivefs_host.cc", + "drivefs_host.h", + "pending_connection_manager.cc", + "pending_connection_manager.h", + ] + deps = [ + "//base", + "//chromeos", + "//chromeos/components/drivefs/mojom", + "//components/account_id", + "//mojo/edk", + "//mojo/public/cpp/bindings", + ] + defines = [ "IS_DRIVEFS_IMPL" ] +} + +source_set("unit_tests") { + testonly = true + sources = [ + "drivefs_host_unittest.cc", + "pending_connection_manager_unittest.cc", + ] + + deps = [ + ":drivefs", + "//base", + "//base/test:test_support", + "//chromeos:test_support", + "//chromeos/components/drivefs/mojom", + "//mojo/public/cpp/bindings", + "//testing/gmock", + "//testing/gtest", + ] +}
diff --git a/chromeos/components/drivefs/DEPS b/chromeos/components/drivefs/DEPS new file mode 100644 index 0000000..348fd9f --- /dev/null +++ b/chromeos/components/drivefs/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+mojo/edk/embedder", + "+mojo/public", +]
diff --git a/chromeos/components/drivefs/OWNERS b/chromeos/components/drivefs/OWNERS new file mode 100644 index 0000000..0930c405 --- /dev/null +++ b/chromeos/components/drivefs/OWNERS
@@ -0,0 +1,3 @@ +dats@chromium.org +sammc@chromium.org +slangley@chromium.org
diff --git a/chromeos/components/drivefs/drivefs_host.cc b/chromeos/components/drivefs/drivefs_host.cc new file mode 100644 index 0000000..3a9fcfc --- /dev/null +++ b/chromeos/components/drivefs/drivefs_host.cc
@@ -0,0 +1,210 @@ +// 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 "chromeos/components/drivefs/drivefs_host.h" + +#include <utility> + +#include "base/strings/strcat.h" +#include "base/unguessable_token.h" +#include "chromeos/components/drivefs/pending_connection_manager.h" +#include "mojo/edk/embedder/connection_params.h" +#include "mojo/edk/embedder/embedder.h" +#include "mojo/edk/embedder/outgoing_broker_client_invitation.h" +#include "mojo/edk/embedder/scoped_platform_handle.h" +#include "mojo/edk/embedder/transport_protocol.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace drivefs { + +namespace { + +constexpr char kMountScheme[] = "drivefs://"; +constexpr char kDataPath[] = "GCache/v2"; + +class MojoConnectionDelegateImpl : public DriveFsHost::MojoConnectionDelegate { + public: + MojoConnectionDelegateImpl() = default; + + static std::unique_ptr<DriveFsHost::MojoConnectionDelegate> Create() { + return std::make_unique<MojoConnectionDelegateImpl>(); + } + + mojom::DriveFsBootstrapPtrInfo InitializeMojoConnection() override { + return mojom::DriveFsBootstrapPtrInfo( + invitation_.AttachMessagePipe("drivefs-bootstrap"), + mojom::DriveFsBootstrap::Version_); + } + + void AcceptMojoConnection(base::ScopedFD handle) override { + invitation_.Send(base::kNullProcessHandle, + {mojo::edk::TransportProtocol::kLegacy, + mojo::edk::ScopedPlatformHandle( + mojo::edk::PlatformHandle(handle.release()))}); + } + + private: + // The underlying mojo connection. + mojo::edk::OutgoingBrokerClientInvitation invitation_; + + DISALLOW_COPY_AND_ASSIGN(MojoConnectionDelegateImpl); +}; + +base::RepeatingCallback<std::unique_ptr<DriveFsHost::MojoConnectionDelegate>()> +GetMojoConnectionDelegateFactoryOrDefault( + base::RepeatingCallback< + std::unique_ptr<DriveFsHost::MojoConnectionDelegate>()> factory) { + return factory ? factory + : base::BindRepeating(&MojoConnectionDelegateImpl::Create); +} + +} // namespace + +// A container of state tied to a particular mounting of DriveFS. None of this +// should be shared between mounts. +class DriveFsHost::MountState { + public: + explicit MountState(DriveFsHost* host) + : host_(host), + mojo_connection_delegate_( + host_->mojo_connection_delegate_factory_.Run()), + pending_token_(base::UnguessableToken::Create()), + binding_(host_) { + source_path_ = base::StrCat({kMountScheme, pending_token_.ToString(), "@", + host_->profile_path_.Append(kDataPath) + .Append(host_->account_id_.GetGaiaId()) + .value()}); + + // TODO(sammc): Switch the mount type once a more appropriate mount type + // exists. + chromeos::disks::DiskMountManager::GetInstance()->MountPath( + source_path_, "", "", chromeos::MOUNT_TYPE_ARCHIVE, + chromeos::MOUNT_ACCESS_MODE_READ_WRITE); + + auto bootstrap = + mojo::MakeProxy(mojo_connection_delegate_->InitializeMojoConnection()); + mojom::DriveFsDelegatePtr delegate; + binding_.Bind(mojo::MakeRequest(&delegate)); + bootstrap->Init({base::in_place, host_->account_id_.GetUserEmail()}, + mojo::MakeRequest(&drivefs_), std::move(delegate)); + + // If unconsumed, the registration is cleaned up when |this| is destructed. + PendingConnectionManager::Get().ExpectOpenIpcChannel( + pending_token_, + base::BindOnce(&DriveFsHost::MountState::AcceptMojoConnection, + base::Unretained(this))); + } + + ~MountState() { + if (pending_token_) { + PendingConnectionManager::Get().CancelExpectedOpenIpcChannel( + pending_token_); + } + if (!mount_path_.empty()) { + chromeos::disks::DiskMountManager::GetInstance()->UnmountPath( + mount_path_, chromeos::UNMOUNT_OPTIONS_NONE, {}); + } + } + + // Accepts the mojo connection over |handle|, delegating to + // |mojo_connection_delegate_|. + void AcceptMojoConnection(base::ScopedFD handle) { + DCHECK(pending_token_); + pending_token_ = {}; + mojo_connection_delegate_->AcceptMojoConnection(std::move(handle)); + } + + // Returns false if there was an error for |source_path_| and thus if |this| + // should be deleted. + bool OnMountEvent( + chromeos::disks::DiskMountManager::MountEvent event, + chromeos::MountError error_code, + const chromeos::disks::DiskMountManager::MountPointInfo& mount_info) { + if (mount_info.source_path != source_path_ || + event != chromeos::disks::DiskMountManager::MOUNTING) { + return true; + } + if (error_code != chromeos::MOUNT_ERROR_NONE) { + return false; + } + mount_path_ = mount_info.mount_path; + return true; + } + + private: + // Owns this. + DriveFsHost* const host_; + + const std::unique_ptr<DriveFsHost::MojoConnectionDelegate> + mojo_connection_delegate_; + + // The token passed to DriveFS as part of |source_path_| used to match it to + // this DriveFsHost instance. + base::UnguessableToken pending_token_; + + // The path passed to cros-disks to mount. + std::string source_path_; + + // The path where DriveFS is mounted. + std::string mount_path_; + + // Mojo connections to the DriveFS process. + mojom::DriveFsPtr drivefs_; + mojo::Binding<mojom::DriveFsDelegate> binding_; + + private: + DISALLOW_COPY_AND_ASSIGN(MountState); +}; + +DriveFsHost::DriveFsHost( + const base::FilePath& profile_path, + const AccountId& account_id, + base::RepeatingCallback< + std::unique_ptr<DriveFsHost::MojoConnectionDelegate>()> + mojo_connection_delegate_factory) + : profile_path_(profile_path), + account_id_(account_id), + mojo_connection_delegate_factory_( + GetMojoConnectionDelegateFactoryOrDefault( + std::move(mojo_connection_delegate_factory))) { + chromeos::disks::DiskMountManager::GetInstance()->AddObserver(this); +} + +DriveFsHost::~DriveFsHost() { + chromeos::disks::DiskMountManager::GetInstance()->RemoveObserver(this); +} + +bool DriveFsHost::Mount() { + if (mount_state_ || account_id_.GetAccountType() != AccountType::GOOGLE) { + return false; + } + mount_state_ = std::make_unique<MountState>(this); + return true; +} + +void DriveFsHost::Unmount() { + mount_state_.reset(); +} + +void DriveFsHost::GetAccessToken(const std::string& client_id, + const std::string& app_id, + const std::vector<std::string>& scopes, + GetAccessTokenCallback callback) { + // TODO(crbug.com/823956): Implement this. + std::move(callback).Run(mojom::AccessTokenStatus::kAuthError, ""); +} + +void DriveFsHost::OnMountEvent( + chromeos::disks::DiskMountManager::MountEvent event, + chromeos::MountError error_code, + const chromeos::disks::DiskMountManager::MountPointInfo& mount_info) { + if (!mount_state_) { + return; + } + if (!mount_state_->OnMountEvent(event, error_code, mount_info)) { + Unmount(); + } +} + +} // namespace drivefs
diff --git a/chromeos/components/drivefs/drivefs_host.h b/chromeos/components/drivefs/drivefs_host.h new file mode 100644 index 0000000..2fe2450 --- /dev/null +++ b/chromeos/components/drivefs/drivefs_host.h
@@ -0,0 +1,86 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_DRIVEFS_DRIVEFS_HOST_H_ +#define CHROMEOS_COMPONENTS_DRIVEFS_DRIVEFS_HOST_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/component_export.h" +#include "base/files/file_path.h" +#include "base/files/scoped_file.h" +#include "base/macros.h" +#include "chromeos/components/drivefs/mojom/drivefs.mojom.h" +#include "chromeos/disks/disk_mount_manager.h" +#include "components/account_id/account_id.h" + +namespace drivefs { + +// A host for a DriveFS process. In addition to managing its lifetime via +// mounting and unmounting, it also bridges between the DriveFS process and the +// file manager. +class COMPONENT_EXPORT(DRIVEFS) DriveFsHost + : public mojom::DriveFsDelegate, + public chromeos::disks::DiskMountManager::Observer { + public: + class MojoConnectionDelegate { + public: + virtual ~MojoConnectionDelegate() = default; + + // Prepare the mojo connection to be used to communicate with the DriveFS + // process. Returns the mojo handle to use for bootstrapping. + virtual mojom::DriveFsBootstrapPtrInfo InitializeMojoConnection() = 0; + + // Accepts the mojo connection over |handle|. + virtual void AcceptMojoConnection(base::ScopedFD handle) = 0; + }; + + DriveFsHost(const base::FilePath& profile_path, + const AccountId& account, + base::RepeatingCallback<std::unique_ptr<MojoConnectionDelegate>()> + mojo_connection_delegate_factory = {}); + ~DriveFsHost() override; + + // Mount DriveFS. + bool Mount(); + + // Unmount DriveFS. + void Unmount(); + + private: + class MountState; + + // mojom::DriveFsDelegate: + void GetAccessToken(const std::string& client_id, + const std::string& app_id, + const std::vector<std::string>& scopes, + GetAccessTokenCallback callback) override; + + // DiskMountManager::Observer: + void OnMountEvent(chromeos::disks::DiskMountManager::MountEvent event, + chromeos::MountError error_code, + const chromeos::disks::DiskMountManager::MountPointInfo& + mount_info) override; + + // The path to the user's profile. + const base::FilePath profile_path_; + + // The user whose DriveFS instance |this| is host to. + const AccountId account_id_; + + // A callback used to create mojo connection delegates. + const base::RepeatingCallback<std::unique_ptr<MojoConnectionDelegate>()> + mojo_connection_delegate_factory_; + + // State specific to the current mount, or null if not mounted. + std::unique_ptr<MountState> mount_state_; + + DISALLOW_COPY_AND_ASSIGN(DriveFsHost); +}; + +} // namespace drivefs + +#endif // CHROMEOS_COMPONENTS_DRIVEFS_DRIVEFS_HOST_H_
diff --git a/chromeos/components/drivefs/drivefs_host_unittest.cc b/chromeos/components/drivefs/drivefs_host_unittest.cc new file mode 100644 index 0000000..0f860f9 --- /dev/null +++ b/chromeos/components/drivefs/drivefs_host_unittest.cc
@@ -0,0 +1,264 @@ +// 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 "chromeos/components/drivefs/drivefs_host.h" + +#include <utility> + +#include "base/logging.h" +#include "base/run_loop.h" +#include "base/strings/strcat.h" +#include "base/strings/string_split.h" +#include "base/test/bind_test_util.h" +#include "base/test/scoped_task_environment.h" +#include "chromeos/components/drivefs/pending_connection_manager.h" +#include "chromeos/disks/mock_disk_mount_manager.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace drivefs { +namespace { + +using testing::_; + +class TestingMojoConnectionDelegate + : public DriveFsHost::MojoConnectionDelegate { + public: + TestingMojoConnectionDelegate( + mojom::DriveFsBootstrapPtrInfo pending_bootstrap) + : pending_bootstrap_(std::move(pending_bootstrap)) {} + + mojom::DriveFsBootstrapPtrInfo InitializeMojoConnection() override { + return std::move(pending_bootstrap_); + } + + void AcceptMojoConnection(base::ScopedFD handle) override {} + + private: + mojom::DriveFsBootstrapPtrInfo pending_bootstrap_; + + DISALLOW_COPY_AND_ASSIGN(TestingMojoConnectionDelegate); +}; + +class DriveFsHostTest : public ::testing::Test, + public mojom::DriveFsBootstrap, + public mojom::DriveFs { + public: + DriveFsHostTest() : bootstrap_binding_(this), binding_(this) {} + + protected: + void SetUp() override { + testing::Test::SetUp(); + profile_path_ = base::FilePath(FILE_PATH_LITERAL("/path/to/profile")); + account_id_ = AccountId::FromUserEmailGaiaId("test@example.com", "ID"); + + disk_manager_ = new chromeos::disks::MockDiskMountManager; + // Takes ownership of |disk_manager_|. + chromeos::disks::DiskMountManager::InitializeForTesting(disk_manager_); + + host_ = std::make_unique<DriveFsHost>( + profile_path_, account_id_, + base::BindRepeating(&DriveFsHostTest::CreateMojoConnectionDelegate, + base::Unretained(this))); + } + + void TearDown() override { + host_.reset(); + disk_manager_ = nullptr; + chromeos::disks::DiskMountManager::Shutdown(); + } + + std::unique_ptr<DriveFsHost::MojoConnectionDelegate> + CreateMojoConnectionDelegate() { + DCHECK(pending_bootstrap_); + return std::make_unique<TestingMojoConnectionDelegate>( + std::move(pending_bootstrap_)); + } + + void DispatchMountEvent( + chromeos::disks::DiskMountManager::MountEvent event, + chromeos::MountError error_code, + const chromeos::disks::DiskMountManager::MountPointInfo& mount_info) { + static_cast<chromeos::disks::DiskMountManager::Observer&>(*host_) + .OnMountEvent(event, error_code, mount_info); + } + + std::string StartMount() { + std::string source; + EXPECT_CALL( + *disk_manager_, + MountPath( + testing::AllOf(testing::StartsWith("drivefs://"), + testing::EndsWith("@/path/to/profile/GCache/v2/ID")), + "", "", _, chromeos::MOUNT_ACCESS_MODE_READ_WRITE)) + .WillOnce(testing::SaveArg<0>(&source)); + + mojom::DriveFsBootstrapPtrInfo bootstrap; + bootstrap_binding_.Bind(mojo::MakeRequest(&bootstrap)); + pending_bootstrap_ = std::move(bootstrap); + + EXPECT_TRUE(host_->Mount()); + testing::Mock::VerifyAndClear(&disk_manager_); + + return base::SplitStringPiece( + base::StringPiece(source).substr(strlen("drivefs://")), "@", + base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)[0] + .as_string(); + } + + void DispatchMountSuccessEvent(const std::string& token) { + DispatchMountEvent( + chromeos::disks::DiskMountManager::MOUNTING, chromeos::MOUNT_ERROR_NONE, + {base::StrCat({"drivefs://", token, "@/path/to/profile/GCache/v2/ID"}), + "/media/drivefsroot/ID", + chromeos::MOUNT_TYPE_ARCHIVE, + {}}); + } + + void DoMount() { + auto token = StartMount(); + DispatchMountSuccessEvent(token); + + base::RunLoop run_loop; + bootstrap_binding_.set_connection_error_handler(run_loop.QuitClosure()); + ASSERT_TRUE(PendingConnectionManager::Get().OpenIpcChannel(token, {})); + run_loop.Run(); + } + + void Init(mojom::DriveFsConfigurationPtr config, + mojom::DriveFsRequest drive_fs, + mojom::DriveFsDelegatePtr delegate) override { + EXPECT_EQ("test@example.com", config->user_email); + binding_.Bind(std::move(drive_fs)); + delegate_ptr_ = std::move(delegate); + } + + base::FilePath profile_path_; + base::test::ScopedTaskEnvironment task_environment_; + AccountId account_id_; + chromeos::disks::MockDiskMountManager* disk_manager_; + std::unique_ptr<DriveFsHost> host_; + + mojo::Binding<mojom::DriveFsBootstrap> bootstrap_binding_; + mojo::Binding<mojom::DriveFs> binding_; + mojom::DriveFsDelegatePtr delegate_ptr_; + + mojom::DriveFsBootstrapPtrInfo pending_bootstrap_; + + private: + DISALLOW_COPY_AND_ASSIGN(DriveFsHostTest); +}; + +TEST_F(DriveFsHostTest, Basic) { + ASSERT_NO_FATAL_FAILURE(DoMount()); +} + +TEST_F(DriveFsHostTest, UnmountAfterMountComplete) { + ASSERT_NO_FATAL_FAILURE(DoMount()); + + EXPECT_CALL(*disk_manager_, UnmountPath("/media/drivefsroot/ID", + chromeos::UNMOUNT_OPTIONS_NONE, _)); + base::RunLoop run_loop; + binding_.set_connection_error_handler(run_loop.QuitClosure()); + host_->Unmount(); + run_loop.Run(); +} + +TEST_F(DriveFsHostTest, UnmountBeforeMountEvent) { + auto token = StartMount(); + host_->Unmount(); + EXPECT_FALSE(PendingConnectionManager::Get().OpenIpcChannel(token, {})); +} + +TEST_F(DriveFsHostTest, UnmountBeforeMojoConnection) { + auto token = StartMount(); + DispatchMountSuccessEvent(token); + EXPECT_CALL(*disk_manager_, UnmountPath("/media/drivefsroot/ID", + chromeos::UNMOUNT_OPTIONS_NONE, _)); + + host_->Unmount(); + EXPECT_FALSE(PendingConnectionManager::Get().OpenIpcChannel(token, {})); +} + +TEST_F(DriveFsHostTest, DestroyBeforeMountEvent) { + auto token = StartMount(); + EXPECT_CALL(*disk_manager_, UnmountPath(_, _, _)).Times(0); + + host_.reset(); + EXPECT_FALSE(PendingConnectionManager::Get().OpenIpcChannel(token, {})); +} + +TEST_F(DriveFsHostTest, DestroyBeforeMojoConnection) { + auto token = StartMount(); + DispatchMountSuccessEvent(token); + EXPECT_CALL(*disk_manager_, UnmountPath("/media/drivefsroot/ID", + chromeos::UNMOUNT_OPTIONS_NONE, _)); + + host_.reset(); + EXPECT_FALSE(PendingConnectionManager::Get().OpenIpcChannel(token, {})); +} + +TEST_F(DriveFsHostTest, ObserveOtherMount) { + auto token = StartMount(); + EXPECT_CALL(*disk_manager_, UnmountPath(_, _, _)).Times(0); + + DispatchMountEvent(chromeos::disks::DiskMountManager::MOUNTING, + chromeos::MOUNT_ERROR_DIRECTORY_CREATION_FAILED, + {"some/other/mount/event", + "/some/other/mount/point", + chromeos::MOUNT_TYPE_DEVICE, + {}}); + DispatchMountEvent( + chromeos::disks::DiskMountManager::UNMOUNTING, chromeos::MOUNT_ERROR_NONE, + {base::StrCat({"drivefs://", token, "@/path/to/profile/GCache/v2/ID"}), + "/media/drivefsroot/ID", + chromeos::MOUNT_TYPE_ARCHIVE, + {}}); + host_->Unmount(); +} + +TEST_F(DriveFsHostTest, MountError) { + auto token = StartMount(); + EXPECT_CALL(*disk_manager_, UnmountPath(_, _, _)).Times(0); + + DispatchMountEvent( + chromeos::disks::DiskMountManager::MOUNTING, + chromeos::MOUNT_ERROR_DIRECTORY_CREATION_FAILED, + {base::StrCat({"drivefs://", token, "@/path/to/profile/GCache/v2/ID"}), + "/media/drivefsroot/ID", + chromeos::MOUNT_TYPE_ARCHIVE, + {}}); + EXPECT_FALSE(PendingConnectionManager::Get().OpenIpcChannel(token, {})); +} + +TEST_F(DriveFsHostTest, MountWhileAlreadyMounted) { + DoMount(); + EXPECT_FALSE(host_->Mount()); +} + +TEST_F(DriveFsHostTest, NonGaiaAccount) { + EXPECT_CALL(*disk_manager_, MountPath(_, _, _, _, _)).Times(0); + AccountId non_gaia_account = AccountId::FromUserEmail("test2@example.com"); + host_ = std::make_unique<DriveFsHost>(profile_path_, non_gaia_account); + EXPECT_FALSE(host_->Mount()); +} + +TEST_F(DriveFsHostTest, GetAccessToken) { + ASSERT_NO_FATAL_FAILURE(DoMount()); + + base::RunLoop run_loop; + auto quit_closure = run_loop.QuitClosure(); + delegate_ptr_->GetAccessToken( + "client ID", "app ID", {"scope1", "scope2"}, + base::BindLambdaForTesting( + [&](mojom::AccessTokenStatus status, const std::string& token) { + EXPECT_EQ(mojom::AccessTokenStatus::kAuthError, status); + EXPECT_TRUE(token.empty()); + std::move(quit_closure).Run(); + })); + run_loop.Run(); +} + +} // namespace +} // namespace drivefs
diff --git a/chromeos/components/drivefs/mojom/BUILD.gn b/chromeos/components/drivefs/mojom/BUILD.gn new file mode 100644 index 0000000..2ebf047 --- /dev/null +++ b/chromeos/components/drivefs/mojom/BUILD.gn
@@ -0,0 +1,18 @@ +# 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("//mojo/public/tools/bindings/mojom.gni") + +mojom_component("mojom") { + sources = [ + "drivefs.mojom", + ] + + public_deps = [ + "//mojo/public/mojom/base", + ] + + output_prefix = "drivefs_mojom" + macro_prefix = "DRIVEFS_MOJOM" +}
diff --git a/chromeos/components/drivefs/mojom/OWNERS b/chromeos/components/drivefs/mojom/OWNERS new file mode 100644 index 0000000..08850f4 --- /dev/null +++ b/chromeos/components/drivefs/mojom/OWNERS
@@ -0,0 +1,2 @@ +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/components/drivefs/mojom/drivefs.mojom b/chromeos/components/drivefs/mojom/drivefs.mojom new file mode 100644 index 0000000..4f2190a6 --- /dev/null +++ b/chromeos/components/drivefs/mojom/drivefs.mojom
@@ -0,0 +1,44 @@ +// 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. + +module drivefs.mojom; + +// This file tracks platform/drivefs/mojom/drivefs.mojom. Changes should be made +// there first and then replicated here. + +// Implemented by DriveFS, used from Chrome. +interface DriveFsBootstrap { + // Initialize a DriveFS instance with its configuration and mojo connections + // to the browser. + Init(DriveFsConfiguration config, DriveFs& drive_fs, + DriveFsDelegate delegate); +}; + +// Implemented by DriveFS, used from Chrome. +interface DriveFs { +}; + +// Implemented by Chrome, used from DriveFS. +interface DriveFsDelegate { + // Get an access token for |client_id| and |app_id| with access to |scopes|. + // |access_token| is only valid if |status| is kSuccess. + GetAccessToken(string client_id, string app_id, array<string> scopes) => ( + AccessTokenStatus status, string access_token); +}; + +struct DriveFsConfiguration { + string user_email; +}; + +enum AccessTokenStatus { + // Getting an access token succeeded. + kSuccess, + + // Getting an access token failed due to a transient error (e.g. network + // access is unavailable). + kTransientError, + + // Getting an access token failed due to an auth error. + kAuthError, +};
diff --git a/chromeos/components/drivefs/pending_connection_manager.cc b/chromeos/components/drivefs/pending_connection_manager.cc new file mode 100644 index 0000000..75a9ae9 --- /dev/null +++ b/chromeos/components/drivefs/pending_connection_manager.cc
@@ -0,0 +1,47 @@ +// 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 "chromeos/components/drivefs/pending_connection_manager.h" + +#include <utility> + +#include "base/logging.h" + +namespace drivefs { + +// static +PendingConnectionManager& PendingConnectionManager::Get() { + static base::NoDestructor<PendingConnectionManager> connection_manager; + return *connection_manager; +} + +bool PendingConnectionManager::OpenIpcChannel(const std::string& identity, + base::ScopedFD ipc_channel) { + auto it = open_ipc_channel_callbacks_.find(identity); + if (it == open_ipc_channel_callbacks_.end()) { + return false; + } + OpenIpcChannelCallback callback = std::move(it->second); + open_ipc_channel_callbacks_.erase(it); + std::move(callback).Run(std::move(ipc_channel)); + return true; +} + +void PendingConnectionManager::ExpectOpenIpcChannel( + base::UnguessableToken token, + OpenIpcChannelCallback handler) { + DCHECK(token); + open_ipc_channel_callbacks_.emplace(token.ToString(), std::move(handler)); +} + +void PendingConnectionManager::CancelExpectedOpenIpcChannel( + base::UnguessableToken token) { + bool erased = open_ipc_channel_callbacks_.erase(token.ToString()); + DCHECK_EQ(1u, erased); +} + +PendingConnectionManager::PendingConnectionManager() = default; +PendingConnectionManager::~PendingConnectionManager() = default; + +} // namespace drivefs
diff --git a/chromeos/components/drivefs/pending_connection_manager.h b/chromeos/components/drivefs/pending_connection_manager.h new file mode 100644 index 0000000..b223829 --- /dev/null +++ b/chromeos/components/drivefs/pending_connection_manager.h
@@ -0,0 +1,51 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_COMPONENTS_DRIVEFS_PENDING_CONNECTION_MANAGER_H_ +#define CHROMEOS_COMPONENTS_DRIVEFS_PENDING_CONNECTION_MANAGER_H_ + +#include <string> + +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "base/component_export.h" +#include "base/containers/flat_map.h" +#include "base/files/scoped_file.h" +#include "base/macros.h" +#include "base/no_destructor.h" +#include "base/unguessable_token.h" +#include "chromeos/chromeos_export.h" + +namespace drivefs { + +class PendingConnectionManagerTest; + +class COMPONENT_EXPORT(DRIVEFS) PendingConnectionManager { + public: + using OpenIpcChannelCallback = base::OnceCallback<void(base::ScopedFD)>; + + static PendingConnectionManager& Get(); + + bool OpenIpcChannel(const std::string& identity, base::ScopedFD ipc_channel); + + void ExpectOpenIpcChannel(base::UnguessableToken token, + OpenIpcChannelCallback handler); + void CancelExpectedOpenIpcChannel(base::UnguessableToken token); + + private: + friend class base::NoDestructor<PendingConnectionManager>; + friend class PendingConnectionManagerTest; + + PendingConnectionManager(); + ~PendingConnectionManager(); + + base::flat_map<std::string, OpenIpcChannelCallback> + open_ipc_channel_callbacks_; + + DISALLOW_COPY_AND_ASSIGN(PendingConnectionManager); +}; + +} // namespace drivefs + +#endif // CHROMEOS_COMPONENTS_DRIVEFS_PENDING_CONNECTION_MANAGER_H_
diff --git a/chromeos/components/drivefs/pending_connection_manager_unittest.cc b/chromeos/components/drivefs/pending_connection_manager_unittest.cc new file mode 100644 index 0000000..9fd1defb --- /dev/null +++ b/chromeos/components/drivefs/pending_connection_manager_unittest.cc
@@ -0,0 +1,44 @@ +// 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 "chromeos/components/drivefs/pending_connection_manager.h" + +#include "base/test/bind_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace drivefs { + +class PendingConnectionManagerTest : public testing::Test { + protected: + PendingConnectionManager connection_manager_; +}; + +namespace { + +TEST_F(PendingConnectionManagerTest, Basic) { + auto token = base::UnguessableToken::Create(); + int callback_calls = 0; + connection_manager_.ExpectOpenIpcChannel( + token, + base::BindLambdaForTesting([&](base::ScopedFD fd) { callback_calls++; })); + EXPECT_TRUE(connection_manager_.OpenIpcChannel(token.ToString(), {})); + EXPECT_FALSE(connection_manager_.OpenIpcChannel(token.ToString(), {})); + EXPECT_EQ(1, callback_calls); +} + +TEST_F(PendingConnectionManagerTest, Cancel) { + auto token = base::UnguessableToken::Create(); + connection_manager_.ExpectOpenIpcChannel( + token, base::BindLambdaForTesting( + [&](base::ScopedFD fd) { FAIL() << "Unexpected call"; })); + connection_manager_.CancelExpectedOpenIpcChannel(token); + EXPECT_FALSE(connection_manager_.OpenIpcChannel(token.ToString(), {})); +} + +TEST_F(PendingConnectionManagerTest, UnexpectedConnection) { + EXPECT_FALSE(connection_manager_.OpenIpcChannel("invalid", {})); +} + +} // namespace +} // namespace drivefs
diff --git a/chromeos/components/run_all_unittests.cc b/chromeos/components/run_all_unittests.cc index a223cf77..660ab97 100644 --- a/chromeos/components/run_all_unittests.cc +++ b/chromeos/components/run_all_unittests.cc
@@ -5,8 +5,12 @@ #include "base/bind.h" #include "base/test/launcher/unit_test_launcher.h" #include "base/test/test_suite.h" +#include "mojo/edk/embedder/embedder.h" int main(int argc, char** argv) { + // Some unit tests make Mojo calls. + mojo::edk::Init(); + base::TestSuite test_suite(argc, argv); return base::LaunchUnitTests( argc, argv,
diff --git a/chromeos/disks/disk_mount_manager.h b/chromeos/disks/disk_mount_manager.h index f45eb463..f8be5ed 100644 --- a/chromeos/disks/disk_mount_manager.h +++ b/chromeos/disks/disk_mount_manager.h
@@ -250,32 +250,29 @@ typedef base::Callback<void(bool success)> EnsureMountInfoRefreshedCallback; // Implement this interface to be notified about disk/mount related events. - // TODO(agawronska): Make observer methods non-pure virtual, because - // subclasses only use small subset of them. class Observer { public: virtual ~Observer() {} // Called when auto-mountable disk mount status is changed. - virtual void OnAutoMountableDiskEvent(DiskEvent event, - const Disk& disk) = 0; + virtual void OnAutoMountableDiskEvent(DiskEvent event, const Disk& disk) {} // Called when fixed storage disk status is changed. - virtual void OnBootDeviceDiskEvent(DiskEvent event, const Disk& disk) = 0; + virtual void OnBootDeviceDiskEvent(DiskEvent event, const Disk& disk) {} // Called when device status is changed. virtual void OnDeviceEvent(DeviceEvent event, - const std::string& device_path) = 0; + const std::string& device_path) {} // Called after a mount point has been mounted or unmounted. virtual void OnMountEvent(MountEvent event, MountError error_code, - const MountPointInfo& mount_info) = 0; + const MountPointInfo& mount_info) {} // Called on format process events. virtual void OnFormatEvent(FormatEvent event, FormatError error_code, - const std::string& device_path) = 0; + const std::string& device_path) {} // Called on rename process events. virtual void OnRenameEvent(RenameEvent event, RenameError error_code, - const std::string& device_path) = 0; + const std::string& device_path) {} }; virtual ~DiskMountManager() {}
diff --git a/components/BUILD.gn b/components/BUILD.gn index 23bf42e..a58e5743 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -337,7 +337,7 @@ deps += [ "//components/safe_browsing/android:unit_tests_mobile" ] } - if (enable_webrtc && !is_ios) { + if (!is_ios) { deps += [ "//components/webrtc_logging/browser:unit_tests", "//components/webrtc_logging/common:unit_tests",
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc index 8f5157ab..b5cab99 100644 --- a/components/autofill/content/renderer/form_autofill_util.cc +++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -1594,7 +1594,7 @@ form->name = GetFormIdentifier(form_element); form->origin = GetCanonicalOriginForDocument(frame->GetDocument()); - form->action = frame->GetDocument().CompleteURL(form_element.Action()); + form->action = GetCanonicalActionForForm(form_element); if (frame->Top()) { form->main_frame_origin = frame->Top()->GetSecurityOrigin(); } else {
diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h index 85fef365..77f5dd83 100644 --- a/components/autofill/core/browser/autofill_client.h +++ b/components/autofill/core/browser/autofill_client.h
@@ -194,6 +194,10 @@ // features of Autofill are disabled, including Autocomplete. virtual bool IsAutofillSupported() = 0; + // Whether server side cards are supported by the client. If false, only + // local cards will be shown. + virtual bool AreServerCardsSupported() = 0; + // Handles simple actions for the autofill popups. virtual void ExecuteCommand(int id) = 0; };
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index f50eccd1..529efe2 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc
@@ -1590,9 +1590,11 @@ // data. std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( - type, SanitizeCreditCardFieldValue(field.value)); + type, SanitizeCreditCardFieldValue(field.value), + client_->AreServerCardsSupported()); const std::vector<CreditCard*> cards_to_suggest = - personal_data_->GetCreditCardsToSuggest(); + personal_data_->GetCreditCardsToSuggest( + client_->AreServerCardsSupported()); for (const CreditCard* credit_card : cards_to_suggest) { if (!credit_card->bank_name().empty()) { credit_card_form_event_logger_->SetBankNameAvailable(); @@ -1687,7 +1689,8 @@ // class' FillCreditCardForm(). if (autofill_assistant_.CanShowCreditCardAssist(form_structures_)) { const std::vector<CreditCard*> cards = - personal_data_->GetCreditCardsToSuggest(); + personal_data_->GetCreditCardsToSuggest( + client_->AreServerCardsSupported()); // Expired cards are last in the sorted order, so if the first one is // expired, they all are. if (!cards.empty() && !cards.front()->IsExpired(AutofillClock::Now()))
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index f6f95ddd..23c69b4 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1095,10 +1095,10 @@ // TODO(crbug.com/613187): Investigate if it would be more efficient to dedupe // with a vector instead of a list. -const std::vector<CreditCard*> PersonalDataManager::GetCreditCardsToSuggest() - const { +const std::vector<CreditCard*> PersonalDataManager::GetCreditCardsToSuggest( + bool include_server_cards) const { std::vector<CreditCard*> credit_cards; - if (ShouldSuggestServerCards()) { + if (include_server_cards && ShouldSuggestServerCards()) { credit_cards = GetCreditCards(); } else { credit_cards = GetLocalCreditCards(); @@ -1150,10 +1150,12 @@ std::vector<Suggestion> PersonalDataManager::GetCreditCardSuggestions( const AutofillType& type, - const base::string16& field_contents) { + const base::string16& field_contents, + bool include_server_cards) { if (IsInAutofillSuggestionsDisabledExperiment()) return std::vector<Suggestion>(); - std::vector<CreditCard*> cards = GetCreditCardsToSuggest(); + std::vector<CreditCard*> cards = + GetCreditCardsToSuggest(include_server_cards); // If enabled, suppress disused address profiles when triggered from an empty // field. if (field_contents.empty() &&
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h index 038c3a3..6eb722b0 100644 --- a/components/autofill/core/browser/personal_data_manager.h +++ b/components/autofill/core/browser/personal_data_manager.h
@@ -231,8 +231,10 @@ // Returns the credit cards to suggest to the user. Those have been deduped // and ordered by frecency with the expired cards put at the end of the - // vector. - const std::vector<CreditCard*> GetCreditCardsToSuggest() const; + // vector. If |include_server_cards| is false, server side cards should not + // be included. + const std::vector<CreditCard*> GetCreditCardsToSuggest( + bool include_server_cards) const; // Remove credit cards that are expired at |comparison_time| and not used // since |min_last_used| from |cards|. The relative ordering of |cards| is @@ -244,10 +246,12 @@ // Gets credit cards that can suggest data for |type|. See // GetProfileSuggestions for argument descriptions. The variant in each - // GUID pair should be ignored. + // GUID pair should be ignored. If |include_server_cards| is false, server + // side cards should not be included. std::vector<Suggestion> GetCreditCardSuggestions( const AutofillType& type, - const base::string16& field_contents); + const base::string16& field_contents, + bool include_server_cards); // Tries to delete disused credit cards once per major version if the // feature is enabled.
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index acce1f30..1f3b0ff 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -2043,7 +2043,8 @@ std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions(AutofillType(CREDIT_CARD_NUMBER), - base::ASCIIToUTF16("12345678")); + base::ASCIIToUTF16("12345678"), + /*include_server_cards=*/true); // There should be no suggestions. ASSERT_EQ(0U, suggestions.size()); @@ -2058,7 +2059,8 @@ std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( AutofillType(CREDIT_CARD_NAME_FULL), - /* field_contents= */ base::string16()); + /* field_contents= */ base::string16(), + /*include_server_cards=*/true); ASSERT_EQ(3U, suggestions.size()); // Ordered as expected. @@ -2106,7 +2108,8 @@ std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( AutofillType(CREDIT_CARD_NAME_FULL), - /* field_contents= */ base::string16()); + /* field_contents= */ base::string16(), + /*include_server_cards=*/true); ASSERT_EQ(5U, suggestions.size()); // All cards should be ordered as expected. @@ -2155,7 +2158,8 @@ std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( AutofillType(CREDIT_CARD_NAME_FULL), - /* field_contents= */ base::string16()); + /* field_contents= */ base::string16(), + /*include_server_cards=*/true); ASSERT_EQ(0U, suggestions.size()); } @@ -2203,7 +2207,8 @@ std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( AutofillType(CREDIT_CARD_NAME_FULL), - /* field_contents= */ base::string16()); + /* field_contents= */ base::string16(), + /*include_server_cards=*/true); ASSERT_EQ(0U, suggestions.size()); } @@ -2248,7 +2253,8 @@ std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( AutofillType(CREDIT_CARD_NAME_FULL), - /* field_contents= */ base::string16()); + /* field_contents= */ base::string16(), + /* include_server_cards= */ true); ASSERT_EQ(3U, suggestions.size()); // The never used non expired card should be suggested first. @@ -2316,7 +2322,8 @@ std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( - AutofillType(CREDIT_CARD_NAME_FULL), base::string16()); + AutofillType(CREDIT_CARD_NAME_FULL), base::string16(), + /*include_server_cards=*/true); EXPECT_EQ(4U, suggestions.size()); EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[0].value); EXPECT_EQ(base::ASCIIToUTF16("Clyde Barrow"), suggestions[1].value); @@ -2332,7 +2339,8 @@ { std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( - AutofillType(CREDIT_CARD_NAME_FULL), base::string16()); + AutofillType(CREDIT_CARD_NAME_FULL), base::string16(), + /*include_server_cards=*/true); EXPECT_EQ(2U, suggestions.size()); EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[0].value); EXPECT_EQ(base::ASCIIToUTF16("Clyde Barrow"), suggestions[1].value); @@ -2342,7 +2350,8 @@ { std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( - AutofillType(CREDIT_CARD_NAME_FULL), base::ASCIIToUTF16("B")); + AutofillType(CREDIT_CARD_NAME_FULL), base::ASCIIToUTF16("B"), + /*include_server_cards=*/true); ASSERT_EQ(1U, suggestions.size()); EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[0].value); @@ -2352,7 +2361,8 @@ { std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( - AutofillType(CREDIT_CARD_NAME_FULL), base::ASCIIToUTF16("Cl")); + AutofillType(CREDIT_CARD_NAME_FULL), base::ASCIIToUTF16("Cl"), + /*include_server_cards=*/true); ASSERT_EQ(1U, suggestions.size()); EXPECT_EQ(base::ASCIIToUTF16("Clyde Barrow"), suggestions[0].value); @@ -2362,7 +2372,8 @@ { std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( - AutofillType(CREDIT_CARD_NAME_FULL), base::ASCIIToUTF16("Jo")); + AutofillType(CREDIT_CARD_NAME_FULL), base::ASCIIToUTF16("Jo"), + /*include_server_cards=*/true); ASSERT_EQ(1U, suggestions.size()); EXPECT_EQ(base::ASCIIToUTF16("John Dillinger"), suggestions[0].value); @@ -2374,7 +2385,8 @@ { std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( - AutofillType(CREDIT_CARD_NUMBER), base::ASCIIToUTF16("4234")); + AutofillType(CREDIT_CARD_NUMBER), base::ASCIIToUTF16("4234"), + /*include_server_cards=*/true); ASSERT_EQ(2U, suggestions.size()); EXPECT_EQ( @@ -2420,7 +2432,8 @@ std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( AutofillType(CREDIT_CARD_NUMBER), - /* field_contents= */ base::string16()); + /* field_contents= */ base::string16(), + /*include_server_cards=*/true); ASSERT_EQ(1U, suggestions.size()); EXPECT_EQ( base::UTF8ToUTF16(std::string("Amex") + kUTF8MidlineEllipsis + "0005"), @@ -2478,7 +2491,8 @@ std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( AutofillType(CREDIT_CARD_NAME_FULL), - /* field_contents= */ base::string16()); + /* field_contents= */ base::string16(), + /*include_server_cards=*/true); ASSERT_EQ(4U, suggestions.size()); EXPECT_EQ(base::ASCIIToUTF16("John Dillinger"), suggestions[0].value); EXPECT_EQ(base::ASCIIToUTF16("Clyde Barrow"), suggestions[1].value); @@ -2486,7 +2500,8 @@ EXPECT_EQ(base::ASCIIToUTF16("Bonnie Parker"), suggestions[3].value); suggestions = personal_data_->GetCreditCardSuggestions( - AutofillType(CREDIT_CARD_NUMBER), /* field_contents= */ base::string16()); + AutofillType(CREDIT_CARD_NUMBER), /* field_contents= */ base::string16(), + /*include_server_cards=*/true); ASSERT_EQ(4U, suggestions.size()); EXPECT_EQ( base::UTF8ToUTF16(std::string("Visa") + kUTF8MidlineEllipsis + "3456"), @@ -2527,7 +2542,8 @@ std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( AutofillType(CREDIT_CARD_NAME_FULL), - /* field_contents= */ base::string16()); + /* field_contents= */ base::string16(), + /*include_server_cards=*/true); ASSERT_EQ(3U, suggestions.size()); // Add a second dupe local card to make sure a full server card can be a dupe @@ -2541,7 +2557,7 @@ suggestions = personal_data_->GetCreditCardSuggestions( AutofillType(CREDIT_CARD_NAME_FULL), - /* field_contents= */ base::string16()); + /* field_contents= */ base::string16(), /*include_server_cards=*/true); ASSERT_EQ(3U, suggestions.size()); } @@ -2597,7 +2613,8 @@ std::vector<Suggestion> suggestions = personal_data_->GetCreditCardSuggestions( AutofillType(CREDIT_CARD_NUMBER), - /* field_contents= */ base::string16()); + /* field_contents= */ base::string16(), + /*include_server_cards=*/true); ASSERT_EQ(3U, suggestions.size()); // Local cards will show network. @@ -3759,7 +3776,7 @@ std::vector<AutofillProfile*> profiles = personal_data_->GetProfilesToSuggest(); std::vector<CreditCard*> credit_cards = - personal_data_->GetCreditCardsToSuggest(); + personal_data_->GetCreditCardsToSuggest(/*include_server_cards=*/true); // |profile1| should have been merged into |profile2| which should then have // been merged into |profile3|. |profile4| should have been merged into @@ -5735,7 +5752,7 @@ // Check that no server cards are available for suggestion, but that the other // calls to get the credit cards are unaffected. EXPECT_EQ(3U, personal_data_->GetCreditCards().size()); - EXPECT_EQ(1U, personal_data_->GetCreditCardsToSuggest().size()); + EXPECT_EQ(1U, personal_data_->GetCreditCardsToSuggest(true).size()); EXPECT_EQ(1U, personal_data_->GetLocalCreditCards().size()); EXPECT_EQ(2U, personal_data_->GetServerCreditCards().size()); @@ -5744,7 +5761,21 @@ // Check that all cards are available. EXPECT_EQ(3U, personal_data_->GetCreditCards().size()); - EXPECT_EQ(3U, personal_data_->GetCreditCardsToSuggest().size()); + EXPECT_EQ(3U, personal_data_->GetCreditCardsToSuggest(true).size()); + EXPECT_EQ(1U, personal_data_->GetLocalCreditCards().size()); + EXPECT_EQ(2U, personal_data_->GetServerCreditCards().size()); +} + +TEST_F(PersonalDataManagerTest, ExcludeServerSideCards) { + SetUpThreeCardTypes(); + + // include_server_cards is set to false, therefore no server cards should be + // available for suggestion, but that the other calls to get the credit cards + // are unaffected. + EXPECT_EQ(3U, personal_data_->GetCreditCards().size()); + EXPECT_EQ(1U, personal_data_ + ->GetCreditCardsToSuggest(/*include_server_cards=*/false) + .size()); EXPECT_EQ(1U, personal_data_->GetLocalCreditCards().size()); EXPECT_EQ(2U, personal_data_->GetServerCreditCards().size()); }
diff --git a/components/autofill/core/browser/test_autofill_client.cc b/components/autofill/core/browser/test_autofill_client.cc index 9cc6166..7bff6dfa 100644 --- a/components/autofill/core/browser/test_autofill_client.cc +++ b/components/autofill/core/browser/test_autofill_client.cc
@@ -132,4 +132,8 @@ return true; } +bool TestAutofillClient::AreServerCardsSupported() { + return true; +} + } // namespace autofill
diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h index 4ad768b..6475c1c 100644 --- a/components/autofill/core/browser/test_autofill_client.h +++ b/components/autofill/core/browser/test_autofill_client.h
@@ -73,6 +73,7 @@ bool IsContextSecure() override; bool ShouldShowSigninPromo() override; bool IsAutofillSupported() override; + bool AreServerCardsSupported() override; void ExecuteCommand(int id) override; void SetPrefs(std::unique_ptr<PrefService> prefs) {
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc index e9ef1f0..f7bf4c7 100644 --- a/components/browser_sync/profile_sync_service.cc +++ b/components/browser_sync/profile_sync_service.cc
@@ -23,6 +23,7 @@ #include "components/invalidation/public/invalidation_service.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/reading_list/features/reading_list_buildflags.h" +#include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_metrics.h" @@ -46,8 +47,10 @@ #include "components/sync/driver/user_selectable_sync_type.h" #include "components/sync/engine/configure_reason.h" #include "components/sync/engine/cycle/type_debug_info_observer.h" +#include "components/sync/engine/engine_components_factory_impl.h" #include "components/sync/engine/net/http_bridge_network_resources.h" #include "components/sync/engine/net/network_resources.h" +#include "components/sync/engine/polling_constants.h" #include "components/sync/engine/sync_encryption_handler.h" #include "components/sync/engine/sync_string_conversions.h" #include "components/sync/js/js_event_details.h" @@ -66,6 +69,7 @@ #include "components/version_info/version_info_values.h" #include "google_apis/gaia/gaia_constants.h" #include "net/url_request/url_request_context_getter.h" +#include "services/identity/public/cpp/identity_manager.h" #include "services/identity/public/cpp/primary_account_access_token_fetcher.h" using sync_sessions::SessionsSyncManager; @@ -75,6 +79,8 @@ using syncer::DataTypeManager; using syncer::DataTypeStatusTable; using syncer::DeviceInfoSyncBridge; +using syncer::EngineComponentsFactory; +using syncer::EngineComponentsFactoryImpl; using syncer::JsBackend; using syncer::JsController; using syncer::JsEventHandler; @@ -83,8 +89,11 @@ using syncer::ModelTypeSet; using syncer::ModelTypeStore; using syncer::ProtocolEventObserver; -using syncer::SyncEngine; +using syncer::SyncBackendRegistrar; +using syncer::SyncClient; using syncer::SyncCredentials; +using syncer::SyncEngine; +using syncer::SyncManagerFactory; using syncer::SyncProtocolError; using syncer::WeakHandle; @@ -92,11 +101,11 @@ namespace { -const char kSyncOAuthConsumerName[] = "sync"; +constexpr char kSyncOAuthConsumerName[] = "sync"; -const char kSyncUnrecoverableErrorHistogram[] = "Sync.UnrecoverableErrors"; +constexpr char kSyncUnrecoverableErrorHistogram[] = "Sync.UnrecoverableErrors"; -const net::BackoffEntry::Policy kRequestAccessTokenBackoffPolicy = { +constexpr net::BackoffEntry::Policy kRequestAccessTokenBackoffPolicy = { // Number of initial errors (in sequence) to ignore before applying // exponential back-off rules. 0, @@ -124,6 +133,43 @@ false, }; +constexpr base::FilePath::CharType kSyncDataFolderName[] = + FILE_PATH_LITERAL("Sync Data"); + +constexpr base::FilePath::CharType kLevelDBFolderName[] = + FILE_PATH_LITERAL("LevelDB"); + +base::FilePath FormatSyncDataPath(const base::FilePath& base_directory) { + return base_directory.Append(base::FilePath(kSyncDataFolderName)); +} + +base::FilePath FormatSharedModelTypeStorePath( + const base::FilePath& base_directory) { + return FormatSyncDataPath(base_directory) + .Append(base::FilePath(kLevelDBFolderName)); +} + +EngineComponentsFactory::Switches EngineSwitchesFromCommandLine() { + EngineComponentsFactory::Switches factory_switches = { + EngineComponentsFactory::ENCRYPTION_KEYSTORE, + EngineComponentsFactory::BACKOFF_NORMAL}; + + base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); + if (cl->HasSwitch(switches::kSyncShortInitialRetryOverride)) { + factory_switches.backoff_override = + EngineComponentsFactory::BACKOFF_SHORT_INITIAL_RETRY_OVERRIDE; + } + if (cl->HasSwitch(switches::kSyncEnableGetUpdateAvoidance)) { + factory_switches.pre_commit_updates_policy = + EngineComponentsFactory::FORCE_ENABLE_PRE_COMMIT_UPDATE_AVOIDANCE; + } + if (cl->HasSwitch(switches::kSyncShortNudgeDelayForTest)) { + factory_switches.nudge_delay = + EngineComponentsFactory::NudgeDelay::SHORT_NUDGE_DELAY; + } + return factory_switches; +} + } // namespace ProfileSyncService::InitParams::InitParams() = default; @@ -131,11 +177,12 @@ ProfileSyncService::InitParams::~InitParams() = default; ProfileSyncService::ProfileSyncService(InitParams init_params) - : SyncServiceBase(std::move(init_params.sync_client), - std::move(init_params.signin_wrapper), - init_params.channel, - init_params.base_directory, - init_params.debug_identifier), + : sync_client_(std::move(init_params.sync_client)), + signin_(std::move(init_params.signin_wrapper)), + channel_(init_params.channel), + base_directory_(init_params.base_directory), + debug_identifier_(init_params.debug_identifier), + sync_prefs_(sync_client_->GetPrefService()), signin_scoped_device_id_callback_( init_params.signin_scoped_device_id_callback), last_auth_error_(GoogleServiceAuthError::AuthErrorNone()), @@ -151,7 +198,6 @@ is_auth_in_progress_(false), unrecoverable_error_reason_(ERROR_REASON_UNSET), expect_sync_configuration_aborted_(false), - configure_status_(DataTypeManager::UNKNOWN), oauth2_token_service_(init_params.oauth2_token_service), request_access_token_backoff_(&kRequestAccessTokenBackoffPolicy), gaia_cookie_manager_service_(init_params.gaia_cookie_manager_service), @@ -161,9 +207,12 @@ passphrase_prompt_triggered_by_version_(false), sync_enabled_weak_factory_(this), weak_factory_(this) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(signin_scoped_device_id_callback_); DCHECK(sync_client_); + + ResetCryptoState(); + std::string last_version = sync_prefs_.GetLastRunVersion(); std::string current_version = PRODUCT_VERSION; sync_prefs_.SetLastRunVersion(current_version); @@ -183,7 +232,7 @@ } ProfileSyncService::~ProfileSyncService() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (gaia_cookie_manager_service_) gaia_cookie_manager_service_->RemoveObserver(this); sync_prefs_.RemoveSyncPrefObserver(this); @@ -192,13 +241,13 @@ } bool ProfileSyncService::CanSyncStart() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return (IsSyncAllowed() && IsSyncRequested() && (IsLocalSyncEnabled() || IsSignedIn())); } void ProfileSyncService::Initialize() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); sync_client_->Initialize(); // We don't pass StartupController an Unretained reference to future-proof @@ -342,14 +391,14 @@ } void ProfileSyncService::RegisterAuthNotifications() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); oauth2_token_service_->AddObserver(this); if (signin_) signin_->GetIdentityManager()->AddObserver(this); } void ProfileSyncService::UnregisterAuthNotifications() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (signin_) signin_->GetIdentityManager()->RemoveObserver(this); if (oauth2_token_service_) @@ -358,7 +407,7 @@ void ProfileSyncService::RegisterDataTypeController( std::unique_ptr<DataTypeController> data_type_controller) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_EQ(data_type_controllers_.count(data_type_controller->type()), 0U); data_type_controllers_[data_type_controller->type()] = std::move(data_type_controller); @@ -366,7 +415,7 @@ bool ProfileSyncService::IsDataTypeControllerRunning( syncer::ModelType type) const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DataTypeController::TypeMap::const_iterator iter = data_type_controllers_.find(type); if (iter == data_type_controllers_.end()) { @@ -376,7 +425,7 @@ } sync_sessions::OpenTabsUIDelegate* ProfileSyncService::GetOpenTabsUIDelegate() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Although the backing data actually is of type |SESSIONS|, the desire to use // open tabs functionality is tracked by the state of the |PROXY_TABS| type. if (!IsDataTypeControllerRunning(syncer::PROXY_TABS)) { @@ -388,24 +437,24 @@ } sync_sessions::FaviconCache* ProfileSyncService::GetFaviconCache() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return sessions_sync_manager_->GetFaviconCache(); } syncer::DeviceInfoTracker* ProfileSyncService::GetDeviceInfoTracker() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return device_info_sync_bridge_.get(); } syncer::LocalDeviceInfoProvider* ProfileSyncService::GetLocalDeviceInfoProvider() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return local_device_.get(); } void ProfileSyncService::GetDataTypeControllerStates( DataTypeController::StateMap* state_map) const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); for (const auto& item : data_type_controllers_) { const syncer::ModelType type = item.first; const std::unique_ptr<DataTypeController>& controller = item.second; @@ -414,7 +463,7 @@ } void ProfileSyncService::OnSessionRestoreComplete() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DataTypeController::TypeMap::const_iterator iter = data_type_controllers_.find(syncer::SESSIONS); if (iter == data_type_controllers_.end()) { @@ -437,9 +486,10 @@ if (IsLocalSyncEnabled()) return credentials; - credentials.account_id = signin_->GetAccountIdToUse(); + const AccountInfo account_info = GetAuthenticatedAccountInfo(); + credentials.account_id = account_info.account_id; DCHECK(!credentials.account_id.empty()); - credentials.email = signin_->GetEffectiveUsername(); + credentials.email = account_info.email; credentials.sync_token = access_token_; if (credentials.sync_token.empty()) @@ -468,6 +518,15 @@ return syncer::MakeWeakHandle(sync_enabled_weak_factory_.GetWeakPtr()); } +void ProfileSyncService::ResetCryptoState() { + crypto_ = std::make_unique<syncer::SyncServiceCrypto>( + base::BindRepeating(&ProfileSyncService::NotifyObservers, + base::Unretained(this)), + base::BindRepeating(&ProfileSyncService::GetPreferredDataTypes, + base::Unretained(this)), + &sync_prefs_); +} + bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { if (encryption_pending()) return true; @@ -478,7 +537,7 @@ } void ProfileSyncService::OnProtocolEvent(const syncer::ProtocolEvent& event) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); for (auto& observer : protocol_event_observers_) observer.OnProtocolEvent(event); } @@ -486,7 +545,7 @@ void ProfileSyncService::OnDirectoryTypeCommitCounterUpdated( syncer::ModelType type, const syncer::CommitCounters& counters) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); for (auto& observer : type_debug_info_observers_) observer.OnCommitCountersUpdated(type, counters); } @@ -494,7 +553,7 @@ void ProfileSyncService::OnDirectoryTypeUpdateCounterUpdated( syncer::ModelType type, const syncer::UpdateCounters& counters) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); for (auto& observer : type_debug_info_observers_) observer.OnUpdateCountersUpdated(type, counters); } @@ -502,13 +561,13 @@ void ProfileSyncService::OnDatatypeStatusCounterUpdated( syncer::ModelType type, const syncer::StatusCounters& counters) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); for (auto& observer : type_debug_info_observers_) observer.OnStatusCountersUpdated(type, counters); } void ProfileSyncService::OnDataTypeRequestsSyncStartup(syncer::ModelType type) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(syncer::UserTypes().Has(type)); if (!GetPreferredDataTypes().Has(type)) { @@ -557,9 +616,70 @@ ReportPreviousSessionMemoryWarningCount(); } +void ProfileSyncService::InitializeEngine() { + DCHECK(engine_); + + if (!sync_thread_) { + sync_thread_ = std::make_unique<base::Thread>("Chrome_SyncThread"); + base::Thread::Options options; + options.timer_slack = base::TIMER_SLACK_MAXIMUM; + bool success = sync_thread_->StartWithOptions(options); + DCHECK(success); + } + + SyncEngine::InitParams params; + params.sync_task_runner = sync_thread_->task_runner(); + params.host = this; + params.registrar = std::make_unique<SyncBackendRegistrar>( + debug_identifier_, + base::BindRepeating(&SyncClient::CreateModelWorkerForGroup, + base::Unretained(sync_client_.get()))); + params.encryption_observer_proxy = crypto_->GetEncryptionObserverProxy(); + params.extensions_activity = sync_client_->GetExtensionsActivity(); + params.event_handler = GetJsEventHandler(); + params.service_url = sync_service_url(); + params.sync_user_agent = GetLocalDeviceInfoProvider()->GetSyncUserAgent(); + params.http_factory_getter = MakeHttpPostProviderFactoryGetter(); + params.credentials = GetCredentials(); + invalidation::InvalidationService* invalidator = + sync_client_->GetInvalidationService(); + params.invalidator_client_id = + invalidator ? invalidator->GetInvalidatorClientId() : "", + params.sync_manager_factory = std::make_unique<SyncManagerFactory>(); + // The first time we start up the engine we want to ensure we have a clean + // directory, so delete any old one that might be there. + params.delete_sync_data_folder = !IsFirstSetupComplete(); + params.enable_local_sync_backend = sync_prefs_.IsLocalSyncEnabled(); + params.local_sync_backend_folder = sync_client_->GetLocalSyncBackendFolder(); + params.restored_key_for_bootstrapping = + sync_prefs_.GetEncryptionBootstrapToken(); + params.restored_keystore_key_for_bootstrapping = + sync_prefs_.GetKeystoreEncryptionBootstrapToken(); + params.engine_components_factory = + std::make_unique<EngineComponentsFactoryImpl>( + EngineSwitchesFromCommandLine()); + params.unrecoverable_error_handler = GetUnrecoverableErrorHandler(); + params.report_unrecoverable_error_function = + base::BindRepeating(syncer::ReportUnrecoverableError, channel_); + params.saved_nigori_state = crypto_->TakeSavedNigoriState(); + sync_prefs_.GetInvalidationVersions(¶ms.invalidation_versions); + params.short_poll_interval = sync_prefs_.GetShortPollInterval(); + if (params.short_poll_interval.is_zero()) { + params.short_poll_interval = + base::TimeDelta::FromSeconds(syncer::kDefaultShortPollIntervalSeconds); + } + params.long_poll_interval = sync_prefs_.GetLongPollInterval(); + if (params.long_poll_interval.is_zero()) { + params.long_poll_interval = + base::TimeDelta::FromSeconds(syncer::kDefaultLongPollIntervalSeconds); + } + + engine_->Initialize(std::move(params)); +} + void ProfileSyncService::AccessTokenFetched(const GoogleServiceAuthError& error, const std::string& access_token) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(ongoing_access_token_fetch_); std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher> fetcher_deleter( @@ -615,14 +735,14 @@ void ProfileSyncService::OnRefreshTokenAvailable( const std::string& account_id) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (account_id == signin_->GetAccountIdToUse()) + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + if (account_id == GetAuthenticatedAccountInfo().account_id) OnRefreshTokensLoaded(); } void ProfileSyncService::OnRefreshTokenRevoked(const std::string& account_id) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (account_id == signin_->GetAccountIdToUse()) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + if (account_id == GetAuthenticatedAccountInfo().account_id) { access_token_.clear(); UpdateAuthErrorState( GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED)); @@ -630,10 +750,10 @@ } void ProfileSyncService::OnRefreshTokensLoaded() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - GoogleServiceAuthError token_error = - oauth2_token_service_->GetAuthError(signin_->GetAccountIdToUse()); + GoogleServiceAuthError token_error = oauth2_token_service_->GetAuthError( + GetAuthenticatedAccountInfo().account_id); if (token_error == GoogleServiceAuthError::FromInvalidGaiaCredentialsReason( GoogleServiceAuthError::InvalidGaiaCredentialsReason:: CREDENTIALS_REJECTED_BY_CLIENT)) { @@ -668,7 +788,7 @@ } void ProfileSyncService::Shutdown() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); UnregisterAuthNotifications(); ShutdownImpl(syncer::BROWSER_SHUTDOWN); @@ -778,12 +898,12 @@ } bool ProfileSyncService::IsFirstSetupComplete() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return sync_prefs_.IsFirstSetupComplete(); } void ProfileSyncService::SetFirstSetupComplete() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); sync_prefs_.SetFirstSetupComplete(); if (IsEngineInitialized()) { ReconfigureDatatypeManager(); @@ -791,7 +911,7 @@ } bool ProfileSyncService::IsSyncConfirmationNeeded() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return (!IsLocalSyncEnabled() && IsSignedIn()) && !IsFirstSetupInProgress() && !IsFirstSetupComplete() && IsSyncRequested(); } @@ -800,6 +920,12 @@ sync_prefs_.SetLastSyncedTime(base::Time::Now()); } +void ProfileSyncService::NotifyObservers() { + for (auto& observer : observers_) { + observer.OnStateChanged(this); + } +} + void ProfileSyncService::NotifySyncCycleCompleted() { for (auto& observer : observers_) observer.OnSyncCycleCompleted(this); @@ -833,7 +959,7 @@ // to do as little work as possible, to avoid further corruption or crashes. void ProfileSyncService::OnUnrecoverableError(const base::Location& from_here, const std::string& message) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Unrecoverable errors that arrive via the syncer::UnrecoverableErrorHandler // interface are assumed to originate within the syncer. unrecoverable_error_reason_ = ERROR_REASON_SYNCER; @@ -862,7 +988,7 @@ } void ProfileSyncService::ReenableDatatype(syncer::ModelType type) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!engine_initialized_ || !data_type_manager_) return; data_type_manager_->ReenableType(type); @@ -894,7 +1020,7 @@ debug_info_listener, const std::string& cache_guid, bool success) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); UpdateEngineInitUMA(success); if (!success) { @@ -918,7 +1044,6 @@ engine_initialized_ = true; sync_js_controller_.AttachJsBackend(js_backend); - debug_info_listener_ = debug_info_listener; // Initialize local device info. local_device_->Initialize(cache_guid, @@ -941,7 +1066,7 @@ data_type_manager_.reset( sync_client_->GetSyncApiComponentFactory()->CreateDataTypeManager( - initial_types, debug_info_listener_, &data_type_controllers_, this, + initial_types, debug_info_listener, &data_type_controllers_, this, engine_.get(), this)); crypto_->SetSyncEngine(engine_.get()); @@ -974,7 +1099,7 @@ void ProfileSyncService::OnSyncCycleCompleted( const syncer::SyncCycleSnapshot& snapshot) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); last_snapshot_ = snapshot; @@ -1001,7 +1126,7 @@ void ProfileSyncService::OnExperimentsChanged( const syncer::Experiments& experiments) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (current_experiments_.Matches(experiments)) return; @@ -1046,7 +1171,7 @@ void ProfileSyncService::OnConnectionStatusChange( syncer::ConnectionStatus status) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); token_status_.connection_status_update_time = base::Time::Now(); token_status_.connection_status = status; if (status == syncer::CONNECTION_AUTH_ERROR) { @@ -1107,7 +1232,7 @@ } void ProfileSyncService::OnMigrationNeededForTypes(syncer::ModelTypeSet types) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(engine_initialized_); DCHECK(data_type_manager_); @@ -1117,7 +1242,7 @@ } void ProfileSyncService::OnActionableError(const SyncProtocolError& error) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); last_actionable_error_ = error; DCHECK_NE(last_actionable_error_.action, syncer::UNKNOWN_ACTION); switch (error.action) { @@ -1174,7 +1299,7 @@ } void ProfileSyncService::ClearAndRestartSyncForPassphraseEncryption() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); engine_->ClearServerData( base::BindRepeating(&ProfileSyncService::OnClearServerDataDone, sync_enabled_weak_factory_.GetWeakPtr())); @@ -1198,7 +1323,7 @@ } void ProfileSyncService::ClearServerDataForTest(const base::Closure& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Sync has a restriction that the engine must be in configuration mode // in order to run clear server data. engine_->StartConfiguration(); @@ -1207,12 +1332,11 @@ void ProfileSyncService::OnConfigureDone( const DataTypeManager::ConfigureResult& result) { - DCHECK(thread_checker_.CalledOnValidThread()); - configure_status_ = result.status; + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); data_type_status_table_ = result.data_type_status_table; if (!sync_configure_start_time_.is_null()) { - if (configure_status_ == DataTypeManager::OK) { + if (result.status == DataTypeManager::OK) { base::Time sync_configure_stop_time = base::Time::Now(); base::TimeDelta delta = sync_configure_stop_time - sync_configure_start_time_; @@ -1229,7 +1353,7 @@ for (auto& observer : observers_) observer.OnSyncConfigurationCompleted(this); - DVLOG(1) << "PSS OnConfigureDone called with status: " << configure_status_; + DVLOG(1) << "PSS OnConfigureDone called with status: " << result.status; // The possible status values: // ABORT - Configuration was aborted. This is not an error, if // initiated by user. @@ -1237,7 +1361,7 @@ // Everything else is an UnrecoverableError. So treat it as such. // First handle the abort case. - if (configure_status_ == DataTypeManager::ABORTED && + if (result.status == DataTypeManager::ABORTED && expect_sync_configuration_aborted_) { DVLOG(0) << "ProfileSyncService::Observe Sync Configure aborted"; expect_sync_configuration_aborted_ = false; @@ -1245,7 +1369,7 @@ } // Handle unrecoverable error. - if (configure_status_ != DataTypeManager::OK) { + if (result.status != DataTypeManager::OK) { if (result.was_catch_up_configure) { // Record catchup configuration failure. UMA_HISTOGRAM_ENUMERATION("Sync.ClearServerDataEvents", @@ -1258,7 +1382,7 @@ DCHECK(error.IsSet()); std::string message = "Sync configuration failed with status " + - DataTypeManager::ConfigureStatusToString(configure_status_) + + DataTypeManager::ConfigureStatusToString(result.status) + " caused by " + syncer::ModelTypeSetToString( data_type_status_table_.GetUnrecoverableErrorTypes()) + @@ -1269,7 +1393,7 @@ return; } - DCHECK_EQ(DataTypeManager::OK, configure_status_); + DCHECK_EQ(DataTypeManager::OK, result.status); // We should never get in a state where we have no encrypted datatypes // enabled, and yet we still think we require a passphrase for decryption. @@ -1301,7 +1425,7 @@ } void ProfileSyncService::OnConfigureStart() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); sync_configure_start_time_ = base::Time::Now(); engine_->StartConfiguration(); NotifyObservers(); @@ -1309,7 +1433,7 @@ ProfileSyncService::SyncStatusSummary ProfileSyncService::QuerySyncStatusSummary() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (HasUnrecoverableError()) return UNRECOVERABLE_ERROR; if (!engine_) @@ -1326,15 +1450,9 @@ } std::string ProfileSyncService::QuerySyncStatusSummaryString() { - DCHECK(thread_checker_.CalledOnValidThread()); - SyncStatusSummary status = QuerySyncStatusSummary(); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - std::string config_status_str = - configure_status_ != DataTypeManager::UNKNOWN - ? DataTypeManager::ConfigureStatusToString(configure_status_) - : ""; - - switch (status) { + switch (QuerySyncStatusSummary()) { case UNRECOVERABLE_ERROR: return "Unrecoverable error detected"; case NOT_ENABLED: @@ -1351,17 +1469,17 @@ } std::string ProfileSyncService::GetEngineInitializationStateString() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return startup_controller_->GetEngineInitializationStateString(); } bool ProfileSyncService::IsSetupInProgress() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return startup_controller_->IsSetupInProgress(); } bool ProfileSyncService::QueryDetailedSyncStatus(SyncEngine::Status* result) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (engine_ && engine_initialized_) { *result = engine_->GetDetailedStatus(); return true; @@ -1373,7 +1491,7 @@ } const GoogleServiceAuthError& ProfileSyncService::GetAuthError() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return last_auth_error_; } @@ -1382,13 +1500,13 @@ } bool ProfileSyncService::IsFirstSetupInProgress() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return !IsFirstSetupComplete() && startup_controller_->IsSetupInProgress(); } std::unique_ptr<syncer::SyncSetupInProgressHandle> ProfileSyncService::GetSetupInProgressHandle() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (++outstanding_setup_in_progress_handles_ == 1) { DCHECK(!startup_controller_->IsSetupInProgress()); @@ -1403,31 +1521,31 @@ } bool ProfileSyncService::IsSyncAllowed() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return IsSyncAllowedByFlag() && !IsManaged() && IsSyncAllowedByPlatform(); } bool ProfileSyncService::IsSyncActive() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return engine_initialized_ && data_type_manager_ && data_type_manager_->state() != DataTypeManager::STOPPED; } bool ProfileSyncService::IsLocalSyncEnabled() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return sync_prefs_.IsLocalSyncEnabled(); } // TODO(tschumann): This is only called for tests. Add ForTesting name suffix. void ProfileSyncService::TriggerRefresh(const syncer::ModelTypeSet& types) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (engine_initialized_) engine_->TriggerRefresh(types); } bool ProfileSyncService::IsSignedIn() const { - // Sync is logged in if there is a non-empty effective account id. - return !signin_->GetAccountIdToUse().empty(); + // Sync is logged in if there is a non-empty account id. + return !GetAuthenticatedAccountInfo().account_id.empty(); } bool ProfileSyncService::CanEngineStart() const { @@ -1435,38 +1553,38 @@ return true; return CanSyncStart() && oauth2_token_service_ && oauth2_token_service_->RefreshTokenIsAvailable( - signin_->GetAccountIdToUse()); + GetAuthenticatedAccountInfo().account_id); } bool ProfileSyncService::IsEngineInitialized() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return engine_initialized_; } bool ProfileSyncService::ConfigurationDone() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return data_type_manager_ && data_type_manager_->state() == DataTypeManager::CONFIGURED; } bool ProfileSyncService::waiting_for_auth() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return is_auth_in_progress_; } bool ProfileSyncService::HasUnrecoverableError() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return unrecoverable_error_reason_ != ERROR_REASON_UNSET; } bool ProfileSyncService::IsPassphraseRequired() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return crypto_->passphrase_required_reason() != syncer::REASON_PASSPHRASE_NOT_REQUIRED; } bool ProfileSyncService::IsPassphraseRequiredForDecryption() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // If there is an encrypted datatype enabled and we don't have the proper // passphrase, we must prompt the user for a passphrase. The only way for the // user to avoid entering their passphrase is to disable the encrypted types. @@ -1534,7 +1652,7 @@ void ProfileSyncService::OnUserChoseDatatypes( bool sync_everything, syncer::ModelTypeSet chosen_types) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(syncer::UserSelectableTypes().HasAll(chosen_types)); if (!engine_ && !HasUnrecoverableError()) { @@ -1551,7 +1669,7 @@ } void ProfileSyncService::OnUserChangedSyncEverythingOnly(bool sync_everything) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!engine_ && !HasUnrecoverableError()) { NOTREACHED(); return; @@ -1566,7 +1684,7 @@ void ProfileSyncService::ChangePreferredDataTypes( syncer::ModelTypeSet preferred_types) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DVLOG(1) << "ChangePreferredDataTypes invoked"; const syncer::ModelTypeSet registered_types = GetRegisteredDataTypes(); // Will only enable those types that are registered and preferred. @@ -1577,19 +1695,35 @@ } syncer::ModelTypeSet ProfileSyncService::GetActiveDataTypes() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!data_type_manager_) return syncer::ModelTypeSet(); return data_type_manager_->GetActiveDataTypes(); } syncer::SyncClient* ProfileSyncService::GetSyncClient() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return sync_client_.get(); } +void ProfileSyncService::AddObserver(syncer::SyncServiceObserver* observer) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + observers_.AddObserver(observer); +} + +void ProfileSyncService::RemoveObserver(syncer::SyncServiceObserver* observer) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + observers_.RemoveObserver(observer); +} + +bool ProfileSyncService::HasObserver( + const syncer::SyncServiceObserver* observer) const { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + return observers_.HasObserver(observer); +} + syncer::ModelTypeSet ProfileSyncService::GetPreferredDataTypes() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); const syncer::ModelTypeSet registered_types = GetRegisteredDataTypes(); const syncer::ModelTypeSet preferred_types = Union(sync_prefs_.GetPreferredDataTypes(registered_types), @@ -1600,7 +1734,7 @@ } syncer::ModelTypeSet ProfileSyncService::GetForcedDataTypes() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // TODO(treib,zea): When SyncPrefs also implements SyncTypePreferenceProvider, // we'll need another way to distinguish user-choosable types from // programmatically-enabled types. @@ -1608,7 +1742,7 @@ } syncer::ModelTypeSet ProfileSyncService::GetRegisteredDataTypes() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); syncer::ModelTypeSet registered_types; // The data_type_controllers_ are determined by command-line flags; // that's effectively what controls the values returned here. @@ -1621,12 +1755,12 @@ } bool ProfileSyncService::IsUsingSecondaryPassphrase() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return crypto_->IsUsingSecondaryPassphrase(); } std::string ProfileSyncService::GetCustomPassphraseKey() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); syncer::SystemEncryptor encryptor; syncer::Cryptographer cryptographer(&encryptor); cryptographer.Bootstrap(sync_prefs_.GetEncryptionBootstrapToken()); @@ -1634,24 +1768,24 @@ } syncer::PassphraseType ProfileSyncService::GetPassphraseType() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return crypto_->GetPassphraseType(); } base::Time ProfileSyncService::GetExplicitPassphraseTime() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return crypto_->GetExplicitPassphraseTime(); } bool ProfileSyncService::IsCryptographerReady( const syncer::BaseTransaction* trans) const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return engine_ && engine_->IsCryptographerReady(trans); } void ProfileSyncService::SetPlatformSyncAllowedProvider( const PlatformSyncAllowedProvider& platform_sync_allowed_provider) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); platform_sync_allowed_provider_ = platform_sync_allowed_provider; } @@ -1708,7 +1842,7 @@ } syncer::UserShare* ProfileSyncService::GetUserShare() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (engine_ && engine_initialized_) { return engine_->GetUserShare(); } @@ -1717,35 +1851,25 @@ } syncer::SyncCycleSnapshot ProfileSyncService::GetLastCycleSnapshot() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return last_snapshot_; } void ProfileSyncService::HasUnsyncedItemsForTest( base::OnceCallback<void(bool)> cb) const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(HasSyncingEngine()); DCHECK(engine_initialized_); engine_->HasUnsyncedItemsForTest(std::move(cb)); } BackendMigrator* ProfileSyncService::GetBackendMigratorForTest() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return migrator_.get(); } -void ProfileSyncService::GetModelSafeRoutingInfo( - syncer::ModelSafeRoutingInfo* out) const { - DCHECK(thread_checker_.CalledOnValidThread()); - if (engine_ && engine_initialized_) { - engine_->GetModelSafeRoutingInfo(out); - } else { - NOTREACHED(); - } -} - std::unique_ptr<base::Value> ProfileSyncService::GetTypeStatusMap() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); auto result = std::make_unique<base::ListValue>(); if (!engine_ || !engine_initialized_) { @@ -1838,10 +1962,9 @@ // Invalidate previous token, otherwise token service will return the same // token again. - const std::string& account_id = signin_->GetAccountIdToUse(); if (!access_token_.empty()) { - oauth2_token_service_->InvalidateAccessToken(account_id, oauth2_scopes, - access_token_); + signin_->GetIdentityManager()->RemoveAccessTokenFromCache( + GetAuthenticatedAccountInfo(), oauth2_scopes, access_token_); } access_token_.clear(); @@ -1850,9 +1973,8 @@ token_status_.token_receive_time = base::Time(); token_status_.next_token_request_time = base::Time(); ongoing_access_token_fetch_ = - std::make_unique<identity::PrimaryAccountAccessTokenFetcher>( - kSyncOAuthConsumerName, signin_->GetSigninManager(), - oauth2_token_service_, oauth2_scopes, + signin_->GetIdentityManager()->CreateAccessTokenFetcherForPrimaryAccount( + kSyncOAuthConsumerName, oauth2_scopes, base::BindOnce(&ProfileSyncService::AccessTokenFetched, base::Unretained(this)), identity::PrimaryAccountAccessTokenFetcher::Mode::kImmediate); @@ -1860,13 +1982,13 @@ void ProfileSyncService::SetEncryptionPassphrase(const std::string& passphrase, PassphraseType type) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); crypto_->SetEncryptionPassphrase(passphrase, type == EXPLICIT); } bool ProfileSyncService::SetDecryptionPassphrase( const std::string& passphrase) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (IsPassphraseRequired()) { DVLOG(1) << "Setting passphrase for decryption."; bool result = crypto_->SetDecryptionPassphrase(passphrase); @@ -1879,22 +2001,22 @@ } bool ProfileSyncService::IsEncryptEverythingAllowed() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return crypto_->IsEncryptEverythingAllowed(); } void ProfileSyncService::SetEncryptEverythingAllowed(bool allowed) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); crypto_->SetEncryptEverythingAllowed(allowed); } void ProfileSyncService::EnableEncryptEverything() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); crypto_->EnableEncryptEverything(); } bool ProfileSyncService::encryption_pending() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // We may be called during the setup process before we're // initialized (via IsEncryptedDatatypeEnabled and // IsPassphraseRequiredForDecryption). @@ -1902,17 +2024,17 @@ } bool ProfileSyncService::IsEncryptEverythingEnabled() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return crypto_->IsEncryptEverythingEnabled(); } syncer::ModelTypeSet ProfileSyncService::GetEncryptedDataTypes() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return crypto_->GetEncryptedDataTypes(); } void ProfileSyncService::OnSyncManagedPrefChange(bool is_sync_managed) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (is_sync_managed) { StopImpl(CLEAR_DATA); } else { @@ -1923,7 +2045,7 @@ void ProfileSyncService::OnPrimaryAccountSet( const AccountInfo& primary_account_info) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!IsEngineInitialized() || GetAuthError().state() != GoogleServiceAuthError::NONE) { // Track the fact that we're still waiting for auth to complete. @@ -1938,7 +2060,7 @@ void ProfileSyncService::OnPrimaryAccountCleared( const AccountInfo& previous_primary_account_info) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); sync_disabled_by_admin_ = false; UMA_HISTOGRAM_ENUMERATION("Sync.StopSource", syncer::SIGN_OUT, syncer::STOP_SOURCE_LIMIT); @@ -1955,7 +2077,7 @@ void ProfileSyncService::OnGaiaAccountsInCookieUpdatedWithCallback( const std::vector<gaia::ListedAccount>& accounts, const base::Closure& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!IsEngineInitialized()) return; @@ -1969,7 +2091,7 @@ bool ProfileSyncService::HasCookieJarMismatch( const std::vector<gaia::ListedAccount>& cookie_jar_accounts) { - std::string account_id = signin_->GetAccountIdToUse(); + std::string account_id = GetAuthenticatedAccountInfo().account_id; // Iterate through list of accounts, looking for current sync account. for (const auto& account : cookie_jar_accounts) { if (account.id == account_id) @@ -1980,7 +2102,7 @@ void ProfileSyncService::AddProtocolEventObserver( ProtocolEventObserver* observer) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); protocol_event_observers_.AddObserver(observer); if (HasSyncingEngine()) { engine_->RequestBufferedProtocolEventsAndEnableForwarding(); @@ -1989,7 +2111,7 @@ void ProfileSyncService::RemoveProtocolEventObserver( ProtocolEventObserver* observer) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); protocol_event_observers_.RemoveObserver(observer); if (HasSyncingEngine() && !protocol_event_observers_.might_have_observers()) { engine_->DisableProtocolEventForwarding(); @@ -1998,7 +2120,7 @@ void ProfileSyncService::AddTypeDebugInfoObserver( syncer::TypeDebugInfoObserver* type_debug_info_observer) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); type_debug_info_observers_.AddObserver(type_debug_info_observer); if (type_debug_info_observers_.might_have_observers() && engine_initialized_) { @@ -2008,7 +2130,7 @@ void ProfileSyncService::RemoveTypeDebugInfoObserver( syncer::TypeDebugInfoObserver* type_debug_info_observer) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); type_debug_info_observers_.RemoveObserver(type_debug_info_observer); if (!type_debug_info_observers_.might_have_observers() && engine_initialized_) { @@ -2018,7 +2140,7 @@ void ProfileSyncService::AddPreferenceProvider( syncer::SyncTypePreferenceProvider* provider) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(!HasPreferenceProvider(provider)) << "Providers may only be added once!"; preference_providers_.insert(provider); @@ -2026,7 +2148,7 @@ void ProfileSyncService::RemovePreferenceProvider( syncer::SyncTypePreferenceProvider* provider) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(HasPreferenceProvider(provider)) << "Only providers that have been added before can be removed!"; preference_providers_.erase(provider); @@ -2034,7 +2156,7 @@ bool ProfileSyncService::HasPreferenceProvider( syncer::SyncTypePreferenceProvider* provider) const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return preference_providers_.count(provider) > 0; } @@ -2082,7 +2204,7 @@ void GetAllNodesRequestHelper::OnReceivedNodesForType( const syncer::ModelType type, std::unique_ptr<base::ListValue> node_list) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Add these results to our list. std::unique_ptr<base::DictionaryValue> type_dict(new base::DictionaryValue()); @@ -2103,7 +2225,7 @@ void ProfileSyncService::GetAllNodes( const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); ModelTypeSet all_types = GetActiveDataTypes(); all_types.PutAll(syncer::ControlTypes()); scoped_refptr<GetAllNodesRequestHelper> helper = @@ -2133,12 +2255,18 @@ } } +AccountInfo ProfileSyncService::GetAuthenticatedAccountInfo() const { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + return signin_ ? signin_->GetIdentityManager()->GetPrimaryAccountInfo() + : AccountInfo(); +} + syncer::GlobalIdMapper* ProfileSyncService::GetGlobalIdMapper() const { return sessions_sync_manager_->GetGlobalIdMapper(); } base::WeakPtr<syncer::JsController> ProfileSyncService::GetJsController() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return sync_js_controller_.AsWeakPtr(); } @@ -2154,31 +2282,31 @@ } bool ProfileSyncService::IsSyncAllowedByPlatform() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return platform_sync_allowed_provider_.is_null() || platform_sync_allowed_provider_.Run(); } bool ProfileSyncService::IsManaged() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return sync_prefs_.IsManaged() || sync_disabled_by_admin_; } void ProfileSyncService::RequestStop(SyncStopDataFate data_fate) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); sync_prefs_.SetSyncRequested(false); StopImpl(data_fate); } bool ProfileSyncService::IsSyncRequested() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // When local sync is on sync should be considered requsted or otherwise it // will not resume after the policy or the flag has been removed. return sync_prefs_.IsSyncRequested() || sync_prefs_.IsLocalSyncEnabled(); } void ProfileSyncService::RequestStart() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!IsSyncAllowed()) { // Sync cannot be requested if it's not allowed. return; @@ -2192,7 +2320,7 @@ } void ProfileSyncService::ReconfigureDatatypeManager() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // If we haven't initialized yet, don't configure the DTM as it could cause // association to start before a Directory has even been created. if (engine_initialized_) { @@ -2221,7 +2349,7 @@ } const DataTypeStatusTable& ProfileSyncService::data_type_status_table() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return data_type_status_table_; } @@ -2236,37 +2364,37 @@ } bool ProfileSyncService::IsRetryingAccessTokenFetchForTest() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return request_access_token_retry_timer_.IsRunning(); } std::string ProfileSyncService::GetAccessTokenForTest() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return access_token_; } syncer::SyncableService* ProfileSyncService::GetSessionsSyncableService() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!sessions_sync_manager_) return nullptr; return sessions_sync_manager_->GetSyncableService(); } syncer::ModelTypeSyncBridge* ProfileSyncService::GetSessionSyncBridge() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (!sessions_sync_manager_) return nullptr; return sessions_sync_manager_->GetModelTypeSyncBridge(); } syncer::ModelTypeSyncBridge* ProfileSyncService::GetDeviceInfoSyncBridge() { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return device_info_sync_bridge_.get(); } syncer::SyncService::SyncTokenStatus ProfileSyncService::GetSyncTokenStatus() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); SyncTokenStatus status = token_status_; if (!request_access_token_retry_timer_.IsRunning()) status.next_token_request_time = base::Time(); @@ -2275,7 +2403,7 @@ void ProfileSyncService::OverrideNetworkResourcesForTest( std::unique_ptr<syncer::NetworkResources> network_resources) { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); network_resources_ = std::move(network_resources); } @@ -2293,7 +2421,7 @@ } void ProfileSyncService::FlushDirectory() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // engine_initialized_ implies engine_ isn't null and the manager exists. // If sync is not initialized yet, we fail silently. if (engine_initialized_) @@ -2301,12 +2429,12 @@ } base::FilePath ProfileSyncService::GetDirectoryPathForTest() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return FormatSyncDataPath(base_directory_); } base::MessageLoop* ProfileSyncService::GetSyncLoopForTest() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return sync_thread_ ? sync_thread_->message_loop() : nullptr; } @@ -2369,17 +2497,17 @@ } const GURL& ProfileSyncService::sync_service_url() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return sync_service_url_; } std::string ProfileSyncService::unrecoverable_error_message() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return unrecoverable_error_message_; } base::Location ProfileSyncService::unrecoverable_error_location() const { - DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return unrecoverable_error_location_; }
diff --git a/components/browser_sync/profile_sync_service.h b/components/browser_sync/profile_sync_service.h index 6d08362..9e836d574 100644 --- a/components/browser_sync/profile_sync_service.h +++ b/components/browser_sync/profile_sync_service.h
@@ -16,6 +16,8 @@ #include "base/memory/memory_pressure_listener.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "base/threading/thread.h" +#include "base/threading/thread_checker.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "build/build_config.h" @@ -29,7 +31,9 @@ #include "components/sync/driver/data_type_manager_observer.h" #include "components/sync/driver/data_type_status_table.h" #include "components/sync/driver/startup_controller.h" -#include "components/sync/driver/sync_service_base.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_service.h" +#include "components/sync/driver/sync_service_crypto.h" #include "components/sync/driver/sync_stopped_reporter.h" #include "components/sync/engine/events/protocol_event_observer.h" #include "components/sync/engine/model_safe_worker.h" @@ -69,8 +73,9 @@ class DeviceInfoSyncBridge; class DeviceInfoTracker; class LocalDeviceInfoProvider; +class ModelTypeSyncBridge; class NetworkResources; -class SyncClient; +class SyncableService; class SyncErrorController; class SyncTypePreferenceProvider; class TypeDebugInfoObserver; @@ -163,7 +168,8 @@ // Once first setup has completed and there are no outstanding // setup-in-progress handles, CanConfigureDataTypes() will return true and // datatype configuration can begin. -class ProfileSyncService : public syncer::SyncServiceBase, +class ProfileSyncService : public syncer::SyncService, + public syncer::SyncEngineHost, public syncer::SyncPrefObserver, public syncer::DataTypeManagerObserver, public syncer::UnrecoverableErrorHandler, @@ -260,6 +266,9 @@ void RequestStart() override; syncer::ModelTypeSet GetActiveDataTypes() const override; syncer::SyncClient* GetSyncClient() const override; + void AddObserver(syncer::SyncServiceObserver* observer) override; + void RemoveObserver(syncer::SyncServiceObserver* observer) override; + bool HasObserver(const syncer::SyncServiceObserver* observer) const override; syncer::ModelTypeSet GetPreferredDataTypes() const override; void OnUserChoseDatatypes(bool sync_everything, syncer::ModelTypeSet chosen_types) override; @@ -310,6 +319,7 @@ base::WeakPtr<syncer::JsController> GetJsController() override; void GetAllNodes(const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) override; + AccountInfo GetAuthenticatedAccountInfo() const override; syncer::GlobalIdMapper* GetGlobalIdMapper() const override; // Changes only the KeepEverythingSynced value. @@ -466,9 +476,6 @@ // Used by tests to inspect the OAuth2 access tokens used by PSS. std::string GetAccessTokenForTest() const; - // TODO(sync): This is only used in tests. Can we remove it? - void GetModelSafeRoutingInfo(syncer::ModelSafeRoutingInfo* out) const; - // SyncPrefObserver implementation. void OnSyncManagedPrefChange(bool is_sync_managed) override; @@ -503,10 +510,6 @@ // TODO(sync): This is only used in tests. Can we remove it? const syncer::DataTypeStatusTable& data_type_status_table() const; - syncer::DataTypeManager::ConfigureStatus configure_status() { - return configure_status_; - } - // If true, the ProfileSyncService has detected that a new GAIA signin has // succeeded, and is waiting for initialization to complete. This is used by // the UI to differentiate between a new auth error (encountered as part of @@ -563,16 +566,17 @@ // to start accounts with a clean slate when performing end to end testing. void ClearServerDataForTest(const base::Closure& callback); - protected: - // SyncServiceBase implementation. - syncer::SyncCredentials GetCredentials() override; - syncer::WeakHandle<syncer::JsEventHandler> GetJsEventHandler() override; - syncer::SyncEngine::HttpPostProviderFactoryGetter - MakeHttpPostProviderFactoryGetter() override; - syncer::WeakHandle<syncer::UnrecoverableErrorHandler> - GetUnrecoverableErrorHandler() override; - private: + syncer::SyncCredentials GetCredentials(); + virtual syncer::WeakHandle<syncer::JsEventHandler> GetJsEventHandler(); + syncer::SyncEngine::HttpPostProviderFactoryGetter + MakeHttpPostProviderFactoryGetter(); + syncer::WeakHandle<syncer::UnrecoverableErrorHandler> + GetUnrecoverableErrorHandler(); + + // Destroys the |crypto_| object and creates a new one with fresh state. + void ResetCryptoState(); + enum UnrecoverableErrorReason { ERROR_REASON_UNSET, ERROR_REASON_SYNCER, @@ -644,6 +648,9 @@ // Sets the last synced time to the current time. void UpdateLastSyncedTime(); + // Notify all observers that a change has occurred. + void NotifyObservers(); + void NotifySyncCycleCompleted(); void NotifyForeignSessionUpdated(); void NotifyShutdown(); @@ -655,6 +662,9 @@ // Starts up the engine sync components. virtual void StartUpSlowEngineComponents(); + // Kicks off asynchronous initialization of the SyncEngine. + void InitializeEngine(); + // Collects preferred sync data types from |preference_providers_|. syncer::ModelTypeSet GetDataTypesFromPreferenceProviders() const; @@ -725,6 +735,45 @@ // Called when a SetupInProgressHandle issued by this instance is destroyed. virtual void OnSetupInProgressHandleDestroyed(); + // This profile's SyncClient, which abstracts away non-Sync dependencies and + // the Sync API component factory. + const std::unique_ptr<syncer::SyncClient> sync_client_; + + // Encapsulates user signin - used to set/get the user's authenticated + // email address. + const std::unique_ptr<SigninManagerWrapper> signin_; + + // The product channel of the embedder. + const version_info::Channel channel_; + + // The path to the base directory under which sync should store its + // information. + const base::FilePath base_directory_; + + // An identifier representing this instance for debugging purposes. + const std::string debug_identifier_; + + // The class that handles getting, setting, and persisting sync preferences. + syncer::SyncPrefs sync_prefs_; + + // A utility object containing logic and state relating to encryption. It is + // never null. + std::unique_ptr<syncer::SyncServiceCrypto> crypto_; + + // The thread where all the sync operations happen. This thread is kept alive + // until browser shutdown and reused if sync is turned off and on again. It is + // joined during the shutdown process, but there is an abort mechanism in + // place to prevent slow HTTP requests from blocking browser shutdown. + std::unique_ptr<base::Thread> sync_thread_; + + // Our asynchronous engine to communicate with sync components living on + // other threads. + std::unique_ptr<syncer::SyncEngine> engine_; + + // Used to ensure that certain operations are performed on the thread that + // this object was created on. + THREAD_CHECKER(thread_checker_); + SigninScopedDeviceIdCallback signin_scoped_device_id_callback_; // This is a cache of the last authentication response we received from the @@ -781,6 +830,7 @@ // Manages the start and stop of the data types. std::unique_ptr<syncer::DataTypeManager> data_type_manager_; + base::ObserverList<syncer::SyncServiceObserver> observers_; base::ObserverList<syncer::ProtocolEventObserver> protocol_event_observers_; base::ObserverList<syncer::TypeDebugInfoObserver> type_debug_info_observers_; @@ -806,15 +856,9 @@ // or must delay loading for some reason). syncer::DataTypeStatusTable data_type_status_table_; - syncer::DataTypeManager::ConfigureStatus configure_status_; - // The set of currently enabled sync experiments. syncer::Experiments current_experiments_; - // Sync's internal debug info listener. Used to record datatype configuration - // and association information. - syncer::WeakHandle<syncer::DataTypeDebugInfoListener> debug_info_listener_; - // ProfileSyncService uses this service to get access tokens. ProfileOAuth2TokenService* const oauth2_token_service_; @@ -879,8 +923,6 @@ DISALLOW_COPY_AND_ASSIGN(ProfileSyncService); }; -bool ShouldShowActionOnUI(const syncer::SyncProtocolError& error); - } // namespace browser_sync #endif // COMPONENTS_BROWSER_SYNC_PROFILE_SYNC_SERVICE_H_
diff --git a/components/browser_sync/profile_sync_service_unittest.cc b/components/browser_sync/profile_sync_service_unittest.cc index 22eacc3..3fe3948 100644 --- a/components/browser_sync/profile_sync_service_unittest.cc +++ b/components/browser_sync/profile_sync_service_unittest.cc
@@ -20,6 +20,7 @@ #include "components/sync/base/pref_names.h" #include "components/sync/device_info/local_device_info_provider.h" #include "components/sync/driver/fake_data_type_controller.h" +#include "components/sync/driver/signin_manager_wrapper.h" #include "components/sync/driver/sync_api_component_factory_mock.h" #include "components/sync/driver/sync_driver_switches.h" #include "components/sync/driver/sync_service_observer.h"
diff --git a/components/cronet/tools/combine_maven_modules.py b/components/cronet/tools/combine_maven_modules.py new file mode 100755 index 0000000..30ba3260 --- /dev/null +++ b/components/cronet/tools/combine_maven_modules.py
@@ -0,0 +1,200 @@ +#!/usr/bin/python +# 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. + +"""combine_maven_modules.py - Combine Cronet maven modules together.""" + +import fileinput +import optparse +import os +import shutil +import sys +import tempfile +import zipfile + +REPOSITORY_ROOT = os.path.abspath(os.path.join( + os.path.dirname(__file__), '..', '..', '..')) +ANDROID_MANIFEST = os.path.join(REPOSITORY_ROOT, 'build', 'android', + 'AndroidManifest.xml') +VERSION_SCRIPT = os.path.join(REPOSITORY_ROOT, 'build', 'util', 'version.py') +KEEP_RESOURCE = os.path.join(REPOSITORY_ROOT, 'components', 'cronet', 'android', + 'api', 'res', 'raw', 'keep_cronet_api.xml') + +def zipdir(path, zip_file): + ziph = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED) + for root, _, files in os.walk(path): + for file_to_zip in files: + filename = os.path.join(root, file_to_zip) + ziph.write(filename, filename[len(path):]) + ziph.close() + + +class ModuleBuilder(object): + + def __init__(self, work_dir, version, suffix): + """ModuleBuilder builds Maven modules. + + Args: + work_dir: Working directory to build Maven modules. + version: Chromium version (e.g. 66.0.3359.126). + suffix: Maven module version suffix (e.g. -alpha). + """ + self._build_dir = os.path.join(work_dir, 'Release', 'cronet') + self._version_file = os.path.join(work_dir, 'Release', 'VERSION') + self._modules_dir = os.path.join(work_dir, 'org', 'chromium', 'net') + + # Convert from Chromium's four number version (e.g. 66.0.3359.126) to a + # three number version more compatible with Maven version comparing. + # Remove the second number from Chromium's which is always 0. + version = version.split('.') + del version[1] + version = '.'.join(version) + + self._version_without_suffix = version + self._version = '%s%s' % (version, suffix) + self._suffix = suffix + + def make_module(self, module_name, aar_jar, include_javadocs=False, + include_keep_resource=False, aar_proguard_config=None, + aar_native_lib=None): + """Make a Maven module. + + Args: + module_name: Maven module name (e.g. cronet-api). + aar_jar: Name of jar to include in aar. + include_javadocs: Boolean indicating if javadocs should be put in aar. + include_keep_resource: Boolean indicating if keep_cronet_api.xml + resource should be included in aar. + aar_proguard_config: Proguard config file to include in aar. + aar_native_lib: Native library name to include in aar. + """ + aar_jar = os.path.join(self._build_dir, aar_jar) + + module_dir = os.path.join(self._modules_dir, module_name, self._version) + os.makedirs(module_dir) + module_prefix = '%s-%s' % (module_name, self._version) + + aar_dir = tempfile.mkdtemp() + shutil.copyfile(aar_jar, os.path.join(aar_dir, 'classes.jar')) + open(os.path.join(aar_dir, 'public.txt'), 'a').close() + shutil.copy(ANDROID_MANIFEST, aar_dir) + manifest = fileinput.FileInput(os.path.join(aar_dir, 'AndroidManifest.xml'), + inplace=True) + for line in manifest: + print line.replace('org.dummy', 'org.chromium.net'), + + if aar_proguard_config: + aar_proguard_config = os.path.join(self._build_dir, aar_proguard_config) + shutil.copyfile(aar_proguard_config, os.path.join(aar_dir, + 'proguard.txt')) + if aar_native_lib: + for arch in ['arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']: + lib_dir = os.path.join(aar_dir, 'jni', arch) + os.makedirs(lib_dir) + shutil.copyfile(os.path.join(self._build_dir, 'libs', arch, + aar_native_lib), + os.path.join(lib_dir, aar_native_lib)) + with open(os.path.join(aar_dir, 'R.txt'), 'a') as r_file: + if include_keep_resource: + r_file.write('int raw keep_cronet_api 0x7f020000\n') + res_dir = os.path.join(aar_dir, 'res', 'raw') + os.makedirs(res_dir) + shutil.copy(KEEP_RESOURCE, res_dir) + + zipdir(aar_dir, os.path.join(module_dir, '%s.aar' % module_prefix)) + shutil.rmtree(aar_dir) + + shutil.copyfile(aar_jar.replace('.jar', '-src.jar'), + os.path.join(module_dir, '%s-sources.jar' % module_prefix)) + + pom_template = os.path.join(REPOSITORY_ROOT, 'components', 'cronet', + 'android', 'maven', + '%s.pom.template' % module_name) + pom_file = os.path.join(module_dir, '%s.pom' % module_prefix) + if os.system('%s -f %s -i %s -o %s' % (VERSION_SCRIPT, self._version_file, + pom_template, pom_file)): + sys.stderr.write('version.py failed.') + exit(1) + if self._suffix != '': + pom_file = fileinput.FileInput(pom_file, inplace=True) + for line in pom_file: + print line.replace('%s</version>' % self._version_without_suffix, + '%s</version>' % self._version), + + if include_javadocs: + javadoc_dir = os.path.join(self._build_dir, 'javadoc') + + # Create an index.html file at the root as this is the accepted format. + # Do this by copying reference/index.html and adjusting the path. + with open(os.path.join(javadoc_dir, 'reference', 'index.html'), 'r') as \ + old_index, open(os.path.join(javadoc_dir, 'index.html'), 'w') as \ + new_index: + for line in old_index: + new_index.write(line.replace('classes.html', + 'reference/classes.html')) + + zipdir(javadoc_dir, os.path.join(module_dir, + '%s-javadoc.jar' % module_prefix)) + +def main(): + parser = optparse.OptionParser() + parser.add_option('--version', + help='Version of Cronet to download (e.g. 66.0.3359.126).') + parser.add_option('--suffix', + help='The suffix to add. Must be alpha or beta.') + options, _ = parser.parse_args() + + if not options.version: + parser.error('Version not provided.') + + suffix = options.suffix + if suffix: + if suffix != 'alpha' and suffix != 'beta': + parser.error('Suffix must be alpha or beta') + suffix = '-%s' % suffix + else: + suffix = '' + + work_dir = tempfile.mkdtemp() + + if os.system( + 'cd %s && gsutil -m cp -R gs://chromium-cronet/android/%s/Release .' + % (work_dir, options.version)): + sys.stderr.write('Google cloud storage download failed.') + exit(1) + + module_builder = ModuleBuilder(work_dir, options.version, suffix) + + module_builder.make_module( + module_name="cronet-api", + aar_jar="cronet_api.jar", + include_javadocs=True, + include_keep_resource=True, + ) + + module_builder.make_module( + module_name="cronet-common", + aar_jar="cronet_impl_common_java.jar", + aar_proguard_config="cronet_impl_common_proguard.cfg", + ) + + module_builder.make_module( + module_name="cronet-embedded", + aar_jar="cronet_impl_native_java.jar", + aar_proguard_config="cronet_impl_native_proguard.cfg", + aar_native_lib="libcronet.%s.so" % options.version + ) + + module_builder.make_module( + module_name="cronet-fallback", + aar_jar="cronet_impl_platform_java.jar", + aar_proguard_config="cronet_impl_platform_proguard.cfg" + ) + + shutil.rmtree(os.path.join(work_dir, 'Release')) + + print 'Maven modules in: %s' % work_dir + +if __name__ == '__main__': + main()
diff --git a/components/download/internal/common/in_progress_download_manager.cc b/components/download/internal/common/in_progress_download_manager.cc index 30d6684..7ad88f9 100644 --- a/components/download/internal/common/in_progress_download_manager.cc +++ b/components/download/internal/common/in_progress_download_manager.cc
@@ -66,7 +66,6 @@ const GURL& tab_url, const GURL& tab_referrer_url, std::vector<GURL> url_chain, - const base::Optional<std::string>& suggested_filename, scoped_refptr<network::ResourceResponse> response, net::CertStatus cert_status, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, @@ -77,8 +76,8 @@ ResourceDownloader::InterceptNavigationResponse( download_manager, std::move(resource_request), render_process_id, render_frame_id, site_url, tab_url, tab_referrer_url, - std::move(url_chain), suggested_filename, std::move(response), - std::move(cert_status), std::move(url_loader_client_endpoints), + std::move(url_chain), std::move(response), std::move(cert_status), + std::move(url_loader_client_endpoints), std::move(url_loader_factory_getter), main_task_runner) .release(), base::OnTaskRunnerDeleter(base::ThreadTaskRunnerHandle::Get())); @@ -219,7 +218,6 @@ const GURL& tab_url, const GURL& tab_referrer_url, std::vector<GURL> url_chain, - const base::Optional<std::string>& suggested_filename, scoped_refptr<network::ResourceResponse> response, net::CertStatus cert_status, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, @@ -229,7 +227,7 @@ base::BindOnce(&CreateDownloadHandlerForNavigation, weak_factory_.GetWeakPtr(), std::move(resource_request), render_process_id, render_frame_id, site_url, tab_url, - tab_referrer_url, std::move(url_chain), suggested_filename, + tab_referrer_url, std::move(url_chain), std::move(response), std::move(cert_status), std::move(url_loader_client_endpoints), std::move(url_loader_factory_getter),
diff --git a/components/download/internal/common/resource_downloader.cc b/components/download/internal/common/resource_downloader.cc index 6d687263..acd5147b 100644 --- a/components/download/internal/common/resource_downloader.cc +++ b/components/download/internal/common/resource_downloader.cc
@@ -6,7 +6,6 @@ #include <memory> -#include "base/strings/utf_string_conversions.h" #include "components/download/public/common/download_url_loader_factory_getter.h" #include "components/download/public/common/stream_handle_input_stream.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -90,7 +89,6 @@ const GURL& tab_url, const GURL& tab_referrer_url, std::vector<GURL> url_chain, - const base::Optional<std::string>& suggested_filename, const scoped_refptr<network::ResourceResponse>& response, net::CertStatus cert_status, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, @@ -102,7 +100,7 @@ site_url, tab_url, tab_referrer_url, download::DownloadItem::kInvalidId, task_runner, std::move(url_loader_factory_getter)); downloader->InterceptResponse(std::move(response), std::move(url_chain), - suggested_filename, cert_status, + cert_status, std::move(url_loader_client_endpoints)); return downloader; } @@ -173,18 +171,14 @@ void ResourceDownloader::InterceptResponse( const scoped_refptr<network::ResourceResponse>& response, std::vector<GURL> url_chain, - const base::Optional<std::string>& suggested_filename, net::CertStatus cert_status, network::mojom::URLLoaderClientEndpointsPtr endpoints) { // Set the URLLoader. url_loader_.Bind(std::move(endpoints->url_loader)); // Create the new URLLoaderClient that will intercept the navigation. - auto save_info = std::make_unique<DownloadSaveInfo>(); - if (suggested_filename.has_value()) - save_info->suggested_name = base::UTF8ToUTF16(suggested_filename.value()); url_loader_client_ = std::make_unique<DownloadResponseHandler>( - resource_request_.get(), this, std::move(save_info), + resource_request_.get(), this, std::make_unique<DownloadSaveInfo>(), false, /* is_parallel_request */ false, /* is_transient */ false, /* fetch_error_body */
diff --git a/components/download/internal/common/resource_downloader.h b/components/download/internal/common/resource_downloader.h index 171748d..ce6eef6 100644 --- a/components/download/internal/common/resource_downloader.h +++ b/components/download/internal/common/resource_downloader.h
@@ -47,7 +47,6 @@ const GURL& tab_url, const GURL& tab_referrer_url, std::vector<GURL> url_chain, - const base::Optional<std::string>& suggested_filename, const scoped_refptr<network::ResourceResponse>& response, net::CertStatus cert_status, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, @@ -85,7 +84,6 @@ void InterceptResponse( const scoped_refptr<network::ResourceResponse>& response, std::vector<GURL> url_chain, - const base::Optional<std::string>& suggested_filename, net::CertStatus cert_status, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints);
diff --git a/components/download/public/common/in_progress_download_manager.h b/components/download/public/common/in_progress_download_manager.h index 3659cd2..9dba8c6 100644 --- a/components/download/public/common/in_progress_download_manager.h +++ b/components/download/public/common/in_progress_download_manager.h
@@ -92,7 +92,6 @@ const GURL& tab_url, const GURL& tab_referrer_url, std::vector<GURL> url_chain, - const base::Optional<std::string>& suggested_filename, scoped_refptr<network::ResourceResponse> response, net::CertStatus cert_status, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
diff --git a/components/gcm_driver/gcm_profile_service.cc b/components/gcm_driver/gcm_profile_service.cc index a27e9dae..b44d2083 100644 --- a/components/gcm_driver/gcm_profile_service.cc +++ b/components/gcm_driver/gcm_profile_service.cc
@@ -28,7 +28,6 @@ #include "components/gcm_driver/gcm_client_factory.h" #include "components/gcm_driver/gcm_desktop_utils.h" #include "components/gcm_driver/gcm_driver_desktop.h" -#include "components/signin/core/browser/signin_manager.h" #include "google_apis/gaia/identity_provider.h" #include "net/url_request/url_request_context_getter.h" #endif @@ -38,21 +37,25 @@ #if !BUILDFLAG(USE_GCM_FROM_PLATFORM) // Identity observer only has actual work to do when the user is actually signed // in. It ensures that account tracker is taking -class GCMProfileService::IdentityObserver : public IdentityProvider::Observer { +class GCMProfileService::IdentityObserver : public SigninManagerBase::Observer { public: - IdentityObserver(ProfileIdentityProvider* identity_provider, + IdentityObserver(SigninManagerBase* signin_manager, + ProfileIdentityProvider* identity_provider, net::URLRequestContextGetter* request_context, GCMDriver* driver); ~IdentityObserver() override; - // IdentityProvider::Observer: - void OnActiveAccountLogin() override; - void OnActiveAccountLogout() override; + // SigninManagerBase::Observer: + void GoogleSigninSucceeded(const std::string& account_id, + const std::string& username) override; + void GoogleSignedOut(const std::string& account_id, + const std::string& username) override; private: void StartAccountTracker(net::URLRequestContextGetter* request_context); GCMDriver* driver_; + SigninManagerBase* signin_manager_; IdentityProvider* identity_provider_; std::unique_ptr<GCMAccountTracker> gcm_account_tracker_; @@ -66,27 +69,31 @@ }; GCMProfileService::IdentityObserver::IdentityObserver( + SigninManagerBase* signin_manager, ProfileIdentityProvider* identity_provider, net::URLRequestContextGetter* request_context, GCMDriver* driver) : driver_(driver), + signin_manager_(signin_manager), identity_provider_(identity_provider), weak_ptr_factory_(this) { - identity_provider_->AddObserver(this); + signin_manager_->AddObserver(this); - OnActiveAccountLogin(); + GoogleSigninSucceeded(signin_manager_->GetAuthenticatedAccountId(), + signin_manager_->GetAuthenticatedAccountInfo().email); StartAccountTracker(request_context); } GCMProfileService::IdentityObserver::~IdentityObserver() { if (gcm_account_tracker_) gcm_account_tracker_->Shutdown(); - identity_provider_->RemoveObserver(this); + signin_manager_->RemoveObserver(this); } -void GCMProfileService::IdentityObserver::OnActiveAccountLogin() { +void GCMProfileService::IdentityObserver::GoogleSigninSucceeded( + const std::string& account_id, + const std::string& username) { // This might be called multiple times when the password changes. - const std::string account_id = identity_provider_->GetActiveAccountId(); if (account_id == account_id_) return; account_id_ = account_id; @@ -95,7 +102,9 @@ driver_->OnSignedIn(); } -void GCMProfileService::IdentityObserver::OnActiveAccountLogout() { +void GCMProfileService::IdentityObserver::GoogleSignedOut( + const std::string& account_id, + const std::string& username) { account_id_.clear(); // Still need to notify GCMDriver for UMA purpose. @@ -141,12 +150,14 @@ net::URLRequestContextGetter* request_context, version_info::Channel channel, const std::string& product_category_for_subtypes, + SigninManagerBase* signin_manager, std::unique_ptr<ProfileIdentityProvider> identity_provider, std::unique_ptr<GCMClientFactory> gcm_client_factory, const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner, const scoped_refptr<base::SequencedTaskRunner>& io_task_runner, scoped_refptr<base::SequencedTaskRunner>& blocking_task_runner) : profile_identity_provider_(std::move(identity_provider)), + signin_manager_(signin_manager), request_context_(request_context) { driver_ = CreateGCMDriverDesktop( std::move(gcm_client_factory), prefs, @@ -154,8 +165,9 @@ product_category_for_subtypes, ui_task_runner, io_task_runner, blocking_task_runner); - identity_observer_.reset(new IdentityObserver( - profile_identity_provider_.get(), request_context_, driver_.get())); + identity_observer_.reset( + new IdentityObserver(signin_manager_, profile_identity_provider_.get(), + request_context_, driver_.get())); } #endif // BUILDFLAG(USE_GCM_FROM_PLATFORM) @@ -179,7 +191,8 @@ #if !BUILDFLAG(USE_GCM_FROM_PLATFORM) if (identity_observer_) { identity_observer_ = std::make_unique<IdentityObserver>( - profile_identity_provider_.get(), request_context_, driver_.get()); + signin_manager_, profile_identity_provider_.get(), request_context_, + driver.get()); } #endif // !BUILDFLAG(USE_GCM_FROM_PLATFORM) }
diff --git a/components/gcm_driver/gcm_profile_service.h b/components/gcm_driver/gcm_profile_service.h index 5e1bbe3..13275d6 100644 --- a/components/gcm_driver/gcm_profile_service.h +++ b/components/gcm_driver/gcm_profile_service.h
@@ -17,6 +17,7 @@ #include "components/gcm_driver/gcm_buildflags.h" #include "components/keyed_service/core/keyed_service.h" #include "components/signin/core/browser/profile_identity_provider.h" +#include "components/signin/core/browser/signin_manager.h" #include "components/version_info/version_info.h" class PrefService; @@ -48,6 +49,7 @@ net::URLRequestContextGetter* request_context, version_info::Channel channel, const std::string& product_category_for_subtypes, + SigninManagerBase* signin_manager, std::unique_ptr<ProfileIdentityProvider> identity_provider, std::unique_ptr<GCMClientFactory> gcm_client_factory, const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner, @@ -76,6 +78,7 @@ std::unique_ptr<GCMDriver> driver_; #if !BUILDFLAG(USE_GCM_FROM_PLATFORM) + SigninManagerBase* signin_manager_; net::URLRequestContextGetter* request_context_ = nullptr; // Used for both account tracker and GCM.UserSignedIn UMA.
diff --git a/components/navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java b/components/navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java index 457c2a84..d6e14f9a 100644 --- a/components/navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java +++ b/components/navigation_interception/android/java/src/org/chromium/components/navigation_interception/NavigationParams.java
@@ -34,12 +34,6 @@ public final boolean isExternalProtocol; /** - * If this navigation was triggered by an anchor with a download - * attribute, this is the (possibly empty) value of that attribute. - * */ - public final String suggestedFilename; - - /** * True if the navigation was originated from a navigation which had been * initiated by the user. */ @@ -50,7 +44,7 @@ public NavigationParams(String url, String referrer, boolean isPost, boolean hasUserGesture, int pageTransitionType, boolean isRedirect, boolean isExternalProtocol, - boolean isMainFrame, String suggestedFilename, boolean hasUserGestureCarryover) { + boolean isMainFrame, boolean hasUserGestureCarryover) { this.url = url; this.referrer = TextUtils.isEmpty(referrer) ? null : referrer; this.isPost = isPost; @@ -59,17 +53,14 @@ this.isRedirect = isRedirect; this.isExternalProtocol = isExternalProtocol; this.isMainFrame = isMainFrame; - this.suggestedFilename = suggestedFilename; this.hasUserGestureCarryover = hasUserGestureCarryover; } @CalledByNative public static NavigationParams create(String url, String referrer, boolean isPost, boolean hasUserGesture, int pageTransitionType, boolean isRedirect, - boolean isExternalProtocol, boolean isMainFrame, String suggestedFilename, - boolean hasUserGestureCarryover) { + boolean isExternalProtocol, boolean isMainFrame, boolean hasUserGestureCarryover) { return new NavigationParams(url, referrer, isPost, hasUserGesture, pageTransitionType, - isRedirect, isExternalProtocol, isMainFrame, suggestedFilename, - hasUserGestureCarryover); + isRedirect, isExternalProtocol, isMainFrame, hasUserGestureCarryover); } }
diff --git a/components/navigation_interception/intercept_navigation_throttle.cc b/components/navigation_interception/intercept_navigation_throttle.cc index b126c38..81acec4 100644 --- a/components/navigation_interception/intercept_navigation_throttle.cc +++ b/components/navigation_interception/intercept_navigation_throttle.cc
@@ -52,8 +52,7 @@ navigation_handle()->HasUserGesture(), navigation_handle()->IsPost(), navigation_handle()->GetPageTransition(), is_redirect, navigation_handle()->IsExternalProtocol(), true, - navigation_handle()->GetBaseURLForDataURL(), - navigation_handle()->GetSuggestedFilename()); + navigation_handle()->GetBaseURLForDataURL()); bool should_ignore_navigation = should_ignore_callback_.Run( navigation_handle()->GetWebContents(), navigation_params); return should_ignore_navigation
diff --git a/components/navigation_interception/navigation_params.cc b/components/navigation_interception/navigation_params.cc index 2a60e7c..02d8755 100644 --- a/components/navigation_interception/navigation_params.cc +++ b/components/navigation_interception/navigation_params.cc
@@ -6,17 +6,15 @@ namespace navigation_interception { -NavigationParams::NavigationParams( - const GURL& url, - const content::Referrer& referrer, - bool has_user_gesture, - bool is_post, - ui::PageTransition transition_type, - bool is_redirect, - bool is_external_protocol, - bool is_main_frame, - const GURL& base_url_for_data_url, - const base::Optional<std::string>& suggested_filename) +NavigationParams::NavigationParams(const GURL& url, + const content::Referrer& referrer, + bool has_user_gesture, + bool is_post, + ui::PageTransition transition_type, + bool is_redirect, + bool is_external_protocol, + bool is_main_frame, + const GURL& base_url_for_data_url) : url_(url), referrer_(referrer), has_user_gesture_(has_user_gesture), @@ -25,8 +23,7 @@ is_redirect_(is_redirect), is_external_protocol_(is_external_protocol), is_main_frame_(is_main_frame), - base_url_for_data_url_(base_url_for_data_url), - suggested_filename_(suggested_filename) {} + base_url_for_data_url_(base_url_for_data_url) {} NavigationParams::~NavigationParams() = default;
diff --git a/components/navigation_interception/navigation_params.h b/components/navigation_interception/navigation_params.h index 1630235..d14e88f 100644 --- a/components/navigation_interception/navigation_params.h +++ b/components/navigation_interception/navigation_params.h
@@ -5,7 +5,6 @@ #ifndef COMPONENTS_NAVIGATION_INTERCEPTION_NAVIGATION_PARAMS_H_ #define COMPONENTS_NAVIGATION_INTERCEPTION_NAVIGATION_PARAMS_H_ -#include "base/optional.h" #include "content/public/common/referrer.h" #include "ui/base/page_transition_types.h" #include "url/gurl.h" @@ -22,8 +21,7 @@ bool is_redirect, bool is_external_protocol, bool is_main_frame, - const GURL& base_url_for_data_url, - const base::Optional<std::string>& suggested_filename); + const GURL& base_url_for_data_url); ~NavigationParams(); NavigationParams(const NavigationParams&); NavigationParams& operator=(const NavigationParams&) = delete; @@ -38,9 +36,6 @@ bool is_external_protocol() const { return is_external_protocol_; } bool is_main_frame() const { return is_main_frame_; } const GURL& base_url_for_data_url() const { return base_url_for_data_url_; } - const base::Optional<std::string>& suggested_filename() const { - return suggested_filename_; - } private: @@ -53,7 +48,6 @@ bool is_external_protocol_; bool is_main_frame_; GURL base_url_for_data_url_; - base::Optional<std::string> suggested_filename_; }; } // namespace navigation_interception
diff --git a/components/navigation_interception/navigation_params_android.cc b/components/navigation_interception/navigation_params_android.cc index cc449e49..a5d6dcf 100644 --- a/components/navigation_interception/navigation_params_android.cc +++ b/components/navigation_interception/navigation_params_android.cc
@@ -25,17 +25,11 @@ ScopedJavaLocalRef<jstring> jstring_referrer = ConvertUTF8ToJavaString(env, params.referrer().url.spec()); - ScopedJavaLocalRef<jstring> jstring_suggested_filename = nullptr; - if (params.suggested_filename().has_value()) { - jstring_suggested_filename = - ConvertUTF8ToJavaString(env, params.suggested_filename().value()); - } - return Java_NavigationParams_create( env, jstring_url, jstring_referrer, params.is_post(), params.has_user_gesture(), params.transition_type(), params.is_redirect(), params.is_external_protocol(), params.is_main_frame(), - jstring_suggested_filename, has_user_gesture_carryover); + has_user_gesture_carryover); } } // namespace navigation_interception
diff --git a/components/password_manager/core/browser/password_manager.h b/components/password_manager/core/browser/password_manager.h index 777554cf..ee030a8 100644 --- a/components/password_manager/core/browser/password_manager.h +++ b/components/password_manager/core/browser/password_manager.h
@@ -56,32 +56,6 @@ explicit PasswordManager(PasswordManagerClient* client); ~PasswordManager() override; - // Called by a PasswordFormManager when it decides a form can be autofilled - // on the page. - void Autofill( - password_manager::PasswordManagerDriver* driver, - const autofill::PasswordForm& form_for_autofill, - const std::map<base::string16, const autofill::PasswordForm*>& - best_matches, - const std::vector<const autofill::PasswordForm*>& federated_matches, - const autofill::PasswordForm& preferred_match, - bool wait_for_username) const; - - // Called by a PasswordFormManager when a page initially loads and it decides - // that a form can be autofilled on the page, but a menu of account options - // should be shown instead. Similar to Autofill() above, but does not fill; it - // only shows a selection of accounts. - // - // Currently used by the fill-on-account-select experiment only. See - // https://crbug.com/568713. - void ShowInitialPasswordAccountSuggestions( - password_manager::PasswordManagerDriver* driver, - const autofill::PasswordForm& form_for_autofill, - const std::map<base::string16, const autofill::PasswordForm*>& - best_matches, - const autofill::PasswordForm& preferred_match, - bool wait_for_username) const; - // Called by a PasswordFormManager when it decides a HTTP auth dialog can be // autofilled. void AutofillHttpAuth(
diff --git a/components/payments/content/payment_request_state.cc b/components/payments/content/payment_request_state.cc index f38dab9..6377d67 100644 --- a/components/payments/content/payment_request_state.cc +++ b/components/payments/content/payment_request_state.cc
@@ -414,7 +414,8 @@ // Create the list of available instruments. A copy of each card will be made // by their respective AutofillPaymentInstrument. const std::vector<autofill::CreditCard*>& cards = - personal_data_manager_->GetCreditCardsToSuggest(); + personal_data_manager_->GetCreditCardsToSuggest( + /*include_server_cards=*/true); for (autofill::CreditCard* card : cards) AddAutofillPaymentInstrument(/*selected=*/false, *card); }
diff --git a/components/safe_browsing/features.cc b/components/safe_browsing/features.cc index c645946..61977125 100644 --- a/components/safe_browsing/features.cc +++ b/components/safe_browsing/features.cc
@@ -48,6 +48,10 @@ const base::Feature kThreatDomDetailsTagAndAttributeFeature{ "ThreatDomDetailsTagAttributes", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSuspiciousSiteTriggerQuotaFeature{ + "SafeBrowsingSuspiciousSiteTriggerQuota", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kTriggerThrottlerDailyQuotaFeature{ "SafeBrowsingTriggerThrottlerDailyQuota", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/safe_browsing/features.h b/components/safe_browsing/features.h index e0fc05a..2d08f8c 100644 --- a/components/safe_browsing/features.h +++ b/components/safe_browsing/features.h
@@ -34,10 +34,17 @@ // be lower case. extern const base::Feature kThreatDomDetailsTagAndAttributeFeature; +// Controls the daily quota for the suspicious site trigger. +extern const base::Feature kSuspiciousSiteTriggerQuotaFeature; + // Controls the daily quota for data collection triggers. It's a single param // containing a comma-separated list of pairs. The format of the param is // "T1,Q1,T2,Q2,...Tn,Qn", where Tx is a TriggerType and Qx is how many reports // that trigger is allowed to send per day. +// TODO(crbug.com/744869): This param should be deprecated after ad sampler +// launch in favour of having a unique quota feature and param per trigger. +// Having a single shared feature makes it impossible to run multiple trigger +// trials simultaneously. extern const base::Feature kTriggerThrottlerDailyQuotaFeature; // Controls whether to dispatch the SafetyNet check on a worker thread. Android
diff --git a/components/safe_browsing/triggers/trigger_throttler.cc b/components/safe_browsing/triggers/trigger_throttler.cc index 335f91d30..ed95d3d 100644 --- a/components/safe_browsing/triggers/trigger_throttler.cc +++ b/components/safe_browsing/triggers/trigger_throttler.cc
@@ -13,8 +13,9 @@ #include "components/safe_browsing/features.h" namespace safe_browsing { -const char kTriggerTypeAndQuotaParam[] = "trigger_type_and_quota_csv"; const size_t kAdSamplerTriggerDefaultQuota = 10; +const char kSuspiciousSiteTriggerQuotaParam[] = "suspicious_site_trigger_quota"; +const char kTriggerTypeAndQuotaParam[] = "trigger_type_and_quota_csv"; namespace { const size_t kUnlimitedTriggerQuota = std::numeric_limits<size_t>::max(); @@ -35,13 +36,20 @@ void ParseTriggerTypeAndQuotaParam( std::vector<TriggerTypeAndQuotaItem>* trigger_type_and_quota_list) { DCHECK(trigger_type_and_quota_list); + trigger_type_and_quota_list->clear(); + + // First, handle the trigger-specific features. + trigger_type_and_quota_list->push_back(std::make_pair( + TriggerType::SUSPICIOUS_SITE, base::GetFieldTrialParamByFeatureAsInt( + kSuspiciousSiteTriggerQuotaFeature, + kSuspiciousSiteTriggerQuotaParam, 0))); + // If the feature is disabled we just use the default list. Otherwise the list // from the Finch param will be the one used. if (!base::FeatureList::IsEnabled(kTriggerThrottlerDailyQuotaFeature)) { return; } - trigger_type_and_quota_list->clear(); const std::string& trigger_and_quota_csv_param = base::GetFieldTrialParamValueByFeature(kTriggerThrottlerDailyQuotaFeature, kTriggerTypeAndQuotaParam);
diff --git a/components/safe_browsing/triggers/trigger_throttler.h b/components/safe_browsing/triggers/trigger_throttler.h index 6de4d53..0d1fedd9 100644 --- a/components/safe_browsing/triggers/trigger_throttler.h +++ b/components/safe_browsing/triggers/trigger_throttler.h
@@ -14,14 +14,21 @@ #include "base/time/clock.h" namespace safe_browsing { +// Default quota for ad sampler trigger. +extern const size_t kAdSamplerTriggerDefaultQuota; + +// Param name of the finch param containing the quota for the suspicious site +// trigger. +extern const char kSuspiciousSiteTriggerQuotaParam[]; // Param name of the finch param containing the comma-separated list of trigger // types and daily quotas. +// TODO(crbug.com/744869): This param should be deprecated after ad sampler +// launch in favour of having a unique quota feature and param per trigger. +// Having a single shared feature makes it impossible to run multiple trigger +// trials simultaneously. extern const char kTriggerTypeAndQuotaParam[]; -// Default quota for ad sampler trigger. -extern const size_t kAdSamplerTriggerDefaultQuota; - enum class TriggerType { SECURITY_INTERSTITIAL = 1, AD_SAMPLE = 2,
diff --git a/components/safe_browsing/triggers/trigger_throttler_unittest.cc b/components/safe_browsing/triggers/trigger_throttler_unittest.cc index e0288d76..386d1836 100644 --- a/components/safe_browsing/triggers/trigger_throttler_unittest.cc +++ b/components/safe_browsing/triggers/trigger_throttler_unittest.cc
@@ -144,20 +144,20 @@ const TriggerType trigger_type, const std::string& group_name, int quota) { - base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial( - safe_browsing::kTriggerThrottlerDailyQuotaFeature.name, group_name); + std::string feature_name = ""; + std::string param_name = ""; + GetFeatureAndParamForTrigger(trigger_type, &feature_name, ¶m_name); + + base::FieldTrial* trial = + base::FieldTrialList::CreateFieldTrial(feature_name, group_name); std::map<std::string, std::string> feature_params; - feature_params[std::string(safe_browsing::kTriggerTypeAndQuotaParam)] = - base::StringPrintf("%d,%d", trigger_type, quota); - base::AssociateFieldTrialParams( - safe_browsing::kTriggerThrottlerDailyQuotaFeature.name, group_name, - feature_params); + feature_params[param_name] = + GetQuotaParamValueForTrigger(trigger_type, quota); + base::AssociateFieldTrialParams(feature_name, group_name, feature_params); std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); - feature_list->InitializeFromCommandLine( - safe_browsing::kTriggerThrottlerDailyQuotaFeature.name, std::string()); + feature_list->InitializeFromCommandLine(feature_name, std::string()); feature_list->AssociateReportingFieldTrial( - safe_browsing::kTriggerThrottlerDailyQuotaFeature.name, - base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial); + feature_name, base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial); return feature_list; } @@ -165,6 +165,35 @@ const TriggerType trigger_type) { return throttler.GetDailyQuotaForTrigger(trigger_type); } + + private: + void GetFeatureAndParamForTrigger(const TriggerType trigger_type, + std::string* out_feature, + std::string* out_param) { + switch (trigger_type) { + case TriggerType::AD_SAMPLE: + *out_feature = safe_browsing::kTriggerThrottlerDailyQuotaFeature.name; + *out_param = safe_browsing::kTriggerTypeAndQuotaParam; + break; + + case TriggerType::SUSPICIOUS_SITE: + *out_feature = safe_browsing::kSuspiciousSiteTriggerQuotaFeature.name; + *out_param = safe_browsing::kSuspiciousSiteTriggerQuotaParam; + break; + + default: + NOTREACHED() << "Unhandled trigger type: " + << static_cast<int>(trigger_type); + } + } + + std::string GetQuotaParamValueForTrigger(const TriggerType trigger_type, + int quota) { + if (trigger_type == TriggerType::AD_SAMPLE) + return base::StringPrintf("%d,%d", trigger_type, quota); + else + return base::StringPrintf("%d", quota); + } }; TEST_F(TriggerThrottlerTestFinch, ConfigureQuotaViaFinch) {
diff --git a/components/spellcheck/renderer/spellcheck.cc b/components/spellcheck/renderer/spellcheck.cc index 097917cb..c7028f62 100644 --- a/components/spellcheck/renderer/spellcheck.cc +++ b/components/spellcheck/renderer/spellcheck.cc
@@ -65,29 +65,12 @@ return true; } -class DocumentMarkersRemover : public content::RenderFrameVisitor { - public: - explicit DocumentMarkersRemover(const std::set<std::string>& words); - ~DocumentMarkersRemover() override {} - bool Visit(content::RenderFrame* render_frame) override; - - private: - WebVector<WebString> words_; - DISALLOW_COPY_AND_ASSIGN(DocumentMarkersRemover); -}; - -DocumentMarkersRemover::DocumentMarkersRemover( - const std::set<std::string>& words) - : words_(words.size()) { - std::transform(words.begin(), words.end(), words_.begin(), +WebVector<WebString> ConvertToWebStringFromUtf8( + const std::set<std::string>& words) { + WebVector<WebString> result(words.size()); + std::transform(words.begin(), words.end(), result.begin(), [](const std::string& w) { return WebString::FromUTF8(w); }); -} - -bool DocumentMarkersRemover::Visit(content::RenderFrame* render_frame) { - // TODO(xiaochengh): Both nullptr checks seem unnecessary. - if (render_frame && render_frame->GetWebFrame()) - render_frame->GetWebFrame()->RemoveSpellingMarkersUnderWords(words_); - return true; + return result; } bool IsApostrophe(base::char16 c) { @@ -245,14 +228,9 @@ const std::vector<std::string>& words_added, const std::vector<std::string>& words_removed) { const std::set<std::string> added(words_added.begin(), words_added.end()); - + NotifyDictionaryObservers(ConvertToWebStringFromUtf8(added)); custom_dictionary_.OnCustomDictionaryChanged( added, std::set<std::string>(words_removed.begin(), words_removed.end())); - if (added.empty()) - return; - - DocumentMarkersRemover markersRemover(added); - content::RenderFrame::ForEach(&markersRemover); } // TODO(groby): Make sure we always have a spelling engine, even before @@ -533,3 +511,20 @@ #endif return spellcheck_enabled_; } + +void SpellCheck::AddDictionaryUpdateObserver( + DictionaryUpdateObserver* observer) { + return dictionary_update_observers_.AddObserver(observer); +} + +void SpellCheck::RemoveDictionaryUpdateObserver( + DictionaryUpdateObserver* observer) { + return dictionary_update_observers_.RemoveObserver(observer); +} + +void SpellCheck::NotifyDictionaryObservers( + const WebVector<WebString>& words_added) { + for (auto& observer : dictionary_update_observers_) { + observer.OnDictionaryUpdated(words_added); + } +}
diff --git a/components/spellcheck/renderer/spellcheck.h b/components/spellcheck/renderer/spellcheck.h index f5617c68..58debac 100644 --- a/components/spellcheck/renderer/spellcheck.h +++ b/components/spellcheck/renderer/spellcheck.h
@@ -14,6 +14,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/observer_list.h" #include "base/strings/string16.h" #include "components/spellcheck/common/spellcheck.mojom.h" #include "components/spellcheck/renderer/custom_dictionary_engine.h" @@ -28,12 +29,22 @@ class WebTextCheckingCompletion; struct WebTextCheckingResult; template <typename T> class WebVector; +class WebString; } namespace service_manager { class LocalInterfaceProvider; } +class DictionaryUpdateObserver { + public: + virtual ~DictionaryUpdateObserver() = default; + // |words_added| is newly added words to dictionary as correct words. + // OnDictionaryUpdated should be called even if |words_added| empty. + virtual void OnDictionaryUpdated( + const blink::WebVector<blink::WebString>& words_added) = 0; +}; + // TODO(morrita): Needs reorg with SpellCheckProvider. // See http://crbug.com/73699. // Shared spellchecking logic/data for a RenderProcess. All RenderViews use @@ -109,6 +120,11 @@ bool IsSpellcheckEnabled(); + // Add observer on dictionary update event. + void AddDictionaryUpdateObserver(DictionaryUpdateObserver* observer); + // Remove observer on dictionary update event. + void RemoveDictionaryUpdateObserver(DictionaryUpdateObserver* observer); + private: friend class SpellCheckTest; FRIEND_TEST_ALL_PREFIXES(SpellCheckTest, GetAutoCorrectionWord_EN_US); @@ -135,6 +151,10 @@ const std::vector<std::string>& words_added, const std::vector<std::string>& words_removed) override; + // Performs dictionary update notification. + void NotifyDictionaryObservers( + const blink::WebVector<blink::WebString>& words_added); + #if !BUILDFLAG(USE_BROWSER_SPELLCHECKER) // Posts delayed spellcheck task and clear it if any. // Takes ownership of |request|. @@ -166,6 +186,9 @@ // Remember state for spellchecking. bool spellcheck_enabled_; + // Observers of update dictionary events. + base::ObserverList<DictionaryUpdateObserver> dictionary_update_observers_; + base::WeakPtrFactory<SpellCheck> weak_factory_; DISALLOW_COPY_AND_ASSIGN(SpellCheck);
diff --git a/components/spellcheck/renderer/spellcheck_provider.cc b/components/spellcheck/renderer/spellcheck_provider.cc index 8bf21f6..1e255d2 100644 --- a/components/spellcheck/renderer/spellcheck_provider.cc +++ b/components/spellcheck/renderer/spellcheck_provider.cc
@@ -38,6 +38,44 @@ int(SpellCheckResult::GRAMMAR), "mismatching enums"); +class SpellCheckProvider::DictionaryUpdateObserverImpl + : public DictionaryUpdateObserver { + public: + explicit DictionaryUpdateObserverImpl(SpellCheckProvider* owner); + ~DictionaryUpdateObserverImpl() override; + + // DictionaryUpdateObserver: + void OnDictionaryUpdated(const WebVector<WebString>& words_added) override; + + private: + SpellCheckProvider* owner_; +}; + +SpellCheckProvider::DictionaryUpdateObserverImpl::DictionaryUpdateObserverImpl( + SpellCheckProvider* owner) + : owner_(owner) { + owner_->spellcheck_->AddDictionaryUpdateObserver(this); +} + +SpellCheckProvider::DictionaryUpdateObserverImpl:: + ~DictionaryUpdateObserverImpl() { + owner_->spellcheck_->RemoveDictionaryUpdateObserver(this); +} + +void SpellCheckProvider::DictionaryUpdateObserverImpl::OnDictionaryUpdated( + const WebVector<WebString>& words_added) { + // Clear only cache. Current pending requests should continue as they are. + owner_->last_request_.clear(); + owner_->last_results_.Assign( + blink::WebVector<blink::WebTextCheckingResult>()); + + // owner_->render_frame() is nullptr in unit tests. + if (auto* render_frame = owner_->render_frame()) { + DCHECK(render_frame->GetWebFrame()); + render_frame->GetWebFrame()->RemoveSpellingMarkersUnderWords(words_added); + } +} + SpellCheckProvider::SpellCheckProvider( content::RenderFrame* render_frame, SpellCheck* spellcheck, @@ -51,11 +89,18 @@ DCHECK(embedder_provider); if (render_frame) // NULL in unit tests. render_frame->GetWebFrame()->SetTextCheckClient(this); + + dictionary_update_observer_ = + std::make_unique<DictionaryUpdateObserverImpl>(this); } SpellCheckProvider::~SpellCheckProvider() { } +void SpellCheckProvider::ResetDictionaryUpdateObserverForTesting() { + dictionary_update_observer_.reset(); +} + spellcheck::mojom::SpellCheckHost& SpellCheckProvider::GetSpellCheckHost() { if (spell_check_host_) return *spell_check_host_;
diff --git a/components/spellcheck/renderer/spellcheck_provider.h b/components/spellcheck/renderer/spellcheck_provider.h index 79b55aa..d142707 100644 --- a/components/spellcheck/renderer/spellcheck_provider.h +++ b/components/spellcheck/renderer/spellcheck_provider.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_PROVIDER_H_ #define COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_PROVIDER_H_ +#include <memory> #include <vector> #include "base/containers/id_map.h" @@ -63,12 +64,16 @@ private: friend class TestingSpellCheckProvider; + class DictionaryUpdateObserverImpl; // Sets the SpellCheckHost (for unit tests). void SetSpellCheckHostForTesting(spellcheck::mojom::SpellCheckHostPtr host) { spell_check_host_ = std::move(host); } + // Reset dictionary_update_observer_ in TestingSpellCheckProvider dtor. + void ResetDictionaryUpdateObserverForTesting(); + // Returns the SpellCheckHost. spellcheck::mojom::SpellCheckHost& GetSpellCheckHost(); @@ -129,6 +134,9 @@ // Interface to the SpellCheckHost. spellcheck::mojom::SpellCheckHostPtr spell_check_host_; + // Dictionary updated observer. + std::unique_ptr<DictionaryUpdateObserverImpl> dictionary_update_observer_; + base::WeakPtrFactory<SpellCheckProvider> weak_factory_; DISALLOW_COPY_AND_ASSIGN(SpellCheckProvider);
diff --git a/components/spellcheck/renderer/spellcheck_provider_test.cc b/components/spellcheck/renderer/spellcheck_provider_test.cc index 9c1b6a33..94fb1eb 100644 --- a/components/spellcheck/renderer/spellcheck_provider_test.cc +++ b/components/spellcheck/renderer/spellcheck_provider_test.cc
@@ -44,6 +44,8 @@ TestingSpellCheckProvider::~TestingSpellCheckProvider() { binding_.Close(); + // dictionary_update_observer_ must be released before deleting spellcheck_. + ResetDictionaryUpdateObserverForTesting(); delete spellcheck_; }
diff --git a/components/spellcheck/renderer/spellcheck_provider_test.h b/components/spellcheck/renderer/spellcheck_provider_test.h index 5e0cfbf0..9e8534e 100644 --- a/components/spellcheck/renderer/spellcheck_provider_test.h +++ b/components/spellcheck/renderer/spellcheck_provider_test.h
@@ -70,6 +70,9 @@ std::vector<RequestTextCheckParams> text_check_requests_; #endif + // Returns |spellcheck|. + SpellCheck* spellcheck() { return spellcheck_; } + private: // spellcheck::mojom::SpellCheckHost: void RequestDictionary() override;
diff --git a/components/spellcheck/renderer/spellcheck_provider_unittest.cc b/components/spellcheck/renderer/spellcheck_provider_unittest.cc index 555e718..64d9f3c 100644 --- a/components/spellcheck/renderer/spellcheck_provider_unittest.cc +++ b/components/spellcheck/renderer/spellcheck_provider_unittest.cc
@@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/strings/utf_string_conversions.h" #include "components/spellcheck/renderer/spellcheck_provider_test.h" + +#include "base/strings/utf_string_conversions.h" +#include "components/spellcheck/renderer/spellcheck.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_vector.h" @@ -12,7 +14,17 @@ namespace { -class SpellCheckProviderCacheTest : public SpellCheckProviderTest {}; +class SpellCheckProviderCacheTest : public SpellCheckProviderTest { + protected: + void UpdateCustomDictionary() { + SpellCheck* spellcheck = provider_.spellcheck(); + EXPECT_NE(spellcheck, nullptr); + // Skip adding friend class - use public CustomDictionaryChanged from + // |spellcheck::mojom::SpellChecker| + static_cast<spellcheck::mojom::SpellChecker*>(spellcheck) + ->CustomDictionaryChanged({}, {}); + } +}; TEST_F(SpellCheckProviderCacheTest, SubstringWithoutMisspellings) { FakeTextCheckingCompletion completion; @@ -49,4 +61,17 @@ EXPECT_EQ(completion.completion_count_, 0U); } +TEST_F(SpellCheckProviderCacheTest, ResetCacheOnCustomDictionaryUpdate) { + FakeTextCheckingCompletion completion; + + blink::WebVector<blink::WebTextCheckingResult> last_results; + provider_.SetLastResults(base::ASCIIToUTF16("This is a test"), last_results); + + UpdateCustomDictionary(); + + EXPECT_FALSE(provider_.SatisfyRequestFromCache( + base::ASCIIToUTF16("This is a"), &completion)); + EXPECT_EQ(completion.completion_count_, 0U); +} + } // namespace
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index f83e796..280f6a10 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -141,8 +141,6 @@ "driver/sync_error_controller.h", "driver/sync_service.cc", "driver/sync_service.h", - "driver/sync_service_base.cc", - "driver/sync_service_base.h", "driver/sync_service_crypto.cc", "driver/sync_service_crypto.h", "driver/sync_service_observer.cc",
diff --git a/components/sync/driver/signin_manager_wrapper.cc b/components/sync/driver/signin_manager_wrapper.cc index 7862741..2dddca8 100644 --- a/components/sync/driver/signin_manager_wrapper.cc +++ b/components/sync/driver/signin_manager_wrapper.cc
@@ -20,11 +20,3 @@ SigninManagerBase* SigninManagerWrapper::GetSigninManager() { return signin_manager_; } - -std::string SigninManagerWrapper::GetEffectiveUsername() const { - return identity_manager_->GetPrimaryAccountInfo().email; -} - -std::string SigninManagerWrapper::GetAccountIdToUse() const { - return identity_manager_->GetPrimaryAccountInfo().account_id; -}
diff --git a/components/sync/driver/signin_manager_wrapper.h b/components/sync/driver/signin_manager_wrapper.h index 8058d04..c4f750b 100644 --- a/components/sync/driver/signin_manager_wrapper.h +++ b/components/sync/driver/signin_manager_wrapper.h
@@ -5,8 +5,6 @@ #ifndef COMPONENTS_SYNC_DRIVER_SIGNIN_MANAGER_WRAPPER_H_ #define COMPONENTS_SYNC_DRIVER_SIGNIN_MANAGER_WRAPPER_H_ -#include <string> - #include "base/macros.h" class SigninManagerBase; @@ -23,12 +21,6 @@ SigninManagerBase* signin_manager); ~SigninManagerWrapper(); - // Get the email address to use for this account. - std::string GetEffectiveUsername() const; - - // Get the unique ID used to represent this account. - std::string GetAccountIdToUse() const; - // Return the original IdentityManager object that was passed in. identity::IdentityManager* GetIdentityManager();
diff --git a/components/sync/driver/sync_service_base.cc b/components/sync/driver/sync_service_base.cc deleted file mode 100644 index f31158d3..0000000 --- a/components/sync/driver/sync_service_base.cc +++ /dev/null
@@ -1,181 +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. - -#include "components/sync/driver/sync_service_base.h" - -#include <utility> - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/metrics/histogram_macros.h" -#include "base/path_service.h" -#include "base/syslog_logging.h" -#include "components/invalidation/public/invalidation_service.h" -#include "components/signin/core/browser/account_info.h" -#include "components/sync/base/report_unrecoverable_error.h" -#include "components/sync/device_info/local_device_info_provider.h" -#include "components/sync/driver/sync_driver_switches.h" -#include "components/sync/engine/engine_components_factory_impl.h" -#include "components/sync/engine/polling_constants.h" -#include "services/identity/public/cpp/identity_manager.h" - -namespace syncer { - -namespace { - -const base::FilePath::CharType kSyncDataFolderName[] = - FILE_PATH_LITERAL("Sync Data"); - -const base::FilePath::CharType kLevelDBFolderName[] = - FILE_PATH_LITERAL("LevelDB"); - -EngineComponentsFactory::Switches EngineSwitchesFromCommandLine() { - EngineComponentsFactory::Switches factory_switches = { - EngineComponentsFactory::ENCRYPTION_KEYSTORE, - EngineComponentsFactory::BACKOFF_NORMAL}; - - base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); - if (cl->HasSwitch(switches::kSyncShortInitialRetryOverride)) { - factory_switches.backoff_override = - EngineComponentsFactory::BACKOFF_SHORT_INITIAL_RETRY_OVERRIDE; - } - if (cl->HasSwitch(switches::kSyncEnableGetUpdateAvoidance)) { - factory_switches.pre_commit_updates_policy = - EngineComponentsFactory::FORCE_ENABLE_PRE_COMMIT_UPDATE_AVOIDANCE; - } - if (cl->HasSwitch(switches::kSyncShortNudgeDelayForTest)) { - factory_switches.nudge_delay = - EngineComponentsFactory::NudgeDelay::SHORT_NUDGE_DELAY; - } - return factory_switches; -} - -} // namespace - -SyncServiceBase::SyncServiceBase(std::unique_ptr<SyncClient> sync_client, - std::unique_ptr<SigninManagerWrapper> signin, - const version_info::Channel& channel, - const base::FilePath& base_directory, - const std::string& debug_identifier) - : sync_client_(std::move(sync_client)), - signin_(std::move(signin)), - channel_(channel), - base_directory_(base_directory), - debug_identifier_(debug_identifier), - sync_prefs_(sync_client_->GetPrefService()) { - ResetCryptoState(); -} - -SyncServiceBase::~SyncServiceBase() = default; - -void SyncServiceBase::AddObserver(SyncServiceObserver* observer) { - DCHECK(thread_checker_.CalledOnValidThread()); - observers_.AddObserver(observer); -} - -void SyncServiceBase::RemoveObserver(SyncServiceObserver* observer) { - DCHECK(thread_checker_.CalledOnValidThread()); - observers_.RemoveObserver(observer); -} - -bool SyncServiceBase::HasObserver(const SyncServiceObserver* observer) const { - DCHECK(thread_checker_.CalledOnValidThread()); - return observers_.HasObserver(observer); -} - -AccountInfo SyncServiceBase::GetAuthenticatedAccountInfo() const { - DCHECK(thread_checker_.CalledOnValidThread()); - return signin_ ? signin_->GetIdentityManager()->GetPrimaryAccountInfo() - : AccountInfo(); -} - -// static -base::FilePath SyncServiceBase::FormatSyncDataPath( - const base::FilePath& base_directory) { - return base_directory.Append(base::FilePath(kSyncDataFolderName)); -} - -// static -base::FilePath SyncServiceBase::FormatSharedModelTypeStorePath( - const base::FilePath& base_directory) { - return FormatSyncDataPath(base_directory) - .Append(base::FilePath(kLevelDBFolderName)); -} - -void SyncServiceBase::NotifyObservers() { - for (auto& observer : observers_) { - observer.OnStateChanged(this); - } -} - -void SyncServiceBase::InitializeEngine() { - DCHECK(engine_); - - if (!sync_thread_) { - sync_thread_ = std::make_unique<base::Thread>("Chrome_SyncThread"); - base::Thread::Options options; - options.timer_slack = base::TIMER_SLACK_MAXIMUM; - bool success = sync_thread_->StartWithOptions(options); - DCHECK(success); - } - - SyncEngine::InitParams params; - params.sync_task_runner = sync_thread_->task_runner(); - params.host = this; - params.registrar = std::make_unique<SyncBackendRegistrar>( - debug_identifier_, base::Bind(&SyncClient::CreateModelWorkerForGroup, - base::Unretained(sync_client_.get()))); - params.encryption_observer_proxy = crypto_->GetEncryptionObserverProxy(); - params.extensions_activity = sync_client_->GetExtensionsActivity(); - params.event_handler = GetJsEventHandler(); - params.service_url = sync_service_url(); - params.sync_user_agent = GetLocalDeviceInfoProvider()->GetSyncUserAgent(); - params.http_factory_getter = MakeHttpPostProviderFactoryGetter(); - params.credentials = GetCredentials(); - invalidation::InvalidationService* invalidator = - sync_client_->GetInvalidationService(); - params.invalidator_client_id = - invalidator ? invalidator->GetInvalidatorClientId() : "", - params.sync_manager_factory = std::make_unique<SyncManagerFactory>(); - // The first time we start up the engine we want to ensure we have a clean - // directory, so delete any old one that might be there. - params.delete_sync_data_folder = !IsFirstSetupComplete(); - params.enable_local_sync_backend = sync_prefs_.IsLocalSyncEnabled(); - params.local_sync_backend_folder = sync_client_->GetLocalSyncBackendFolder(); - params.restored_key_for_bootstrapping = - sync_prefs_.GetEncryptionBootstrapToken(); - params.restored_keystore_key_for_bootstrapping = - sync_prefs_.GetKeystoreEncryptionBootstrapToken(); - params.engine_components_factory = - std::make_unique<EngineComponentsFactoryImpl>( - EngineSwitchesFromCommandLine()); - params.unrecoverable_error_handler = GetUnrecoverableErrorHandler(); - params.report_unrecoverable_error_function = - base::Bind(ReportUnrecoverableError, channel_); - params.saved_nigori_state = crypto_->TakeSavedNigoriState(); - sync_prefs_.GetInvalidationVersions(¶ms.invalidation_versions); - params.short_poll_interval = sync_prefs_.GetShortPollInterval(); - if (params.short_poll_interval.is_zero()) { - params.short_poll_interval = - base::TimeDelta::FromSeconds(kDefaultShortPollIntervalSeconds); - } - params.long_poll_interval = sync_prefs_.GetLongPollInterval(); - if (params.long_poll_interval.is_zero()) { - params.long_poll_interval = - base::TimeDelta::FromSeconds(kDefaultLongPollIntervalSeconds); - } - - engine_->Initialize(std::move(params)); -} - -void SyncServiceBase::ResetCryptoState() { - crypto_ = std::make_unique<SyncServiceCrypto>( - base::BindRepeating(&SyncServiceBase::NotifyObservers, - base::Unretained(this)), - base::BindRepeating(&SyncService::GetPreferredDataTypes, - base::Unretained(this)), - &sync_prefs_); -} - -} // namespace syncer
diff --git a/components/sync/driver/sync_service_base.h b/components/sync/driver/sync_service_base.h deleted file mode 100644 index 1f97abf4..0000000 --- a/components/sync/driver/sync_service_base.h +++ /dev/null
@@ -1,135 +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_SYNC_DRIVER_SYNC_SERVICE_BASE_H_ -#define COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_BASE_H_ - -#include <memory> -#include <string> - -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/observer_list.h" -#include "base/threading/thread.h" -#include "base/threading/thread_checker.h" -#include "components/sync/base/sync_prefs.h" -#include "components/sync/base/unrecoverable_error_handler.h" -#include "components/sync/base/weak_handle.h" -#include "components/sync/driver/signin_manager_wrapper.h" -#include "components/sync/driver/sync_client.h" -#include "components/sync/driver/sync_service.h" -#include "components/sync/driver/sync_service_crypto.h" -#include "components/sync/engine/sync_engine.h" -#include "components/sync/engine/sync_engine_host.h" -#include "components/sync/engine/sync_manager.h" -#include "components/sync/js/sync_js_controller.h" -#include "components/version_info/version_info.h" - -namespace syncer { - -// This is a base class for implementations of SyncService that contains some -// common functionality and member variables. Anything that can live inside the -// sync component should eventually live here instead of a concrete -// implementation. This is set up as a base class so things can be transferred -// piece by piece as easily as possible. -class SyncServiceBase : public SyncService, public SyncEngineHost { - public: - SyncServiceBase(std::unique_ptr<SyncClient> sync_client, - std::unique_ptr<SigninManagerWrapper> signin, - const version_info::Channel& channel, - const base::FilePath& base_directory, - const std::string& debug_identifier); - ~SyncServiceBase() override; - - // SyncService partial implementation. - void AddObserver(SyncServiceObserver* observer) override; - void RemoveObserver(SyncServiceObserver* observer) override; - bool HasObserver(const SyncServiceObserver* observer) const override; - AccountInfo GetAuthenticatedAccountInfo() const override; - - // Given base path (path to profile) formats path to "Sync Data" folder where - // sync engine stores directory database. - static base::FilePath FormatSyncDataPath( - const base::FilePath& base_directory); - - // Given base path (path to profile) formats path to a folder containing - // ModelTypeStore's leveldb database. - static base::FilePath FormatSharedModelTypeStorePath( - const base::FilePath& base_directory); - - protected: - // Notify all observers that a change has occurred. - void NotifyObservers(); - - // Kicks off asynchronous initialization of the SyncEngine. - void InitializeEngine(); - - // Destroys the |crypto_| object and creates a new one with fresh state. - void ResetCryptoState(); - - // Returns SyncCredentials from the OAuth2TokenService. - virtual SyncCredentials GetCredentials() = 0; - - // Returns a weak handle to the JsEventHandler. - virtual WeakHandle<JsEventHandler> GetJsEventHandler() = 0; - - // Returns a callback that makes an HttpPostProviderFactory. - virtual SyncEngine::HttpPostProviderFactoryGetter - MakeHttpPostProviderFactoryGetter() = 0; - - // Returns a weak handle to an UnrecoverableErrorHandler (may be |this|). - virtual WeakHandle<UnrecoverableErrorHandler> - GetUnrecoverableErrorHandler() = 0; - - // This profile's SyncClient, which abstracts away non-Sync dependencies and - // the Sync API component factory. - const std::unique_ptr<SyncClient> sync_client_; - - // Encapsulates user signin - used to set/get the user's authenticated - // email address. - const std::unique_ptr<SigninManagerWrapper> signin_; - - // The product channel of the embedder. - const version_info::Channel channel_; - - // The path to the base directory under which sync should store its - // information. - const base::FilePath base_directory_; - - // An identifier representing this instance for debugging purposes. - const std::string debug_identifier_; - - // The class that handles getting, setting, and persisting sync - // preferences. - SyncPrefs sync_prefs_; - - // A utility object containing logic and state relating to encryption. It is - // never null. - std::unique_ptr<SyncServiceCrypto> crypto_; - - // The thread where all the sync operations happen. This thread is kept alive - // until browser shutdown and reused if sync is turned off and on again. It is - // joined during the shutdown process, but there is an abort mechanism in - // place to prevent slow HTTP requests from blocking browser shutdown. - std::unique_ptr<base::Thread> sync_thread_; - - // Our asynchronous engine to communicate with sync components living on - // other threads. - std::unique_ptr<SyncEngine> engine_; - - // The list of observers of the SyncService state. - base::ObserverList<SyncServiceObserver> observers_; - - // Used to ensure that certain operations are performed on the thread that - // this object was created on. - base::ThreadChecker thread_checker_; - - private: - DISALLOW_COPY_AND_ASSIGN(SyncServiceBase); -}; - -} // namespace syncer - -#endif // COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_BASE_H_
diff --git a/components/sync_preferences/BUILD.gn b/components/sync_preferences/BUILD.gn index a3ae9d25..49ca951 100644 --- a/components/sync_preferences/BUILD.gn +++ b/components/sync_preferences/BUILD.gn
@@ -63,6 +63,7 @@ ":test_support", "//components/pref_registry", "//components/prefs", + "//components/prefs:test_support", "//components/sync", "//components/sync:test_support_model", "//testing/gtest",
diff --git a/components/sync_preferences/pref_model_associator.cc b/components/sync_preferences/pref_model_associator.cc index 401d614..2aeff8db 100644 --- a/components/sync_preferences/pref_model_associator.cc +++ b/components/sync_preferences/pref_model_associator.cc
@@ -375,7 +375,7 @@ // Windows client, the Windows client does not support // kConfirmToQuitEnabled. Ignore updates from these preferences. std::string pref_name = pref_specifics.name(); - if (!IsPrefRegistered(pref_name.c_str())) + if (!IsPrefRegistered(pref_name)) continue; if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { @@ -406,6 +406,7 @@ return syncer::SyncError(); } +// static base::Value* PrefModelAssociator::ReadPreferenceSpecifics( const sync_pb::PreferenceSpecifics& preference) { base::JSONReader reader; @@ -425,10 +426,10 @@ void PrefModelAssociator::AddSyncedPrefObserver(const std::string& name, SyncedPrefObserver* observer) { - std::unique_ptr<SyncedPrefObserverList>& observers = + std::unique_ptr<base::ObserverList<SyncedPrefObserver>>& observers = synced_pref_observers_[name]; if (!observers) - observers = std::make_unique<SyncedPrefObserverList>(); + observers = std::make_unique<base::ObserverList<SyncedPrefObserver>>(); observers->AddObserver(observer); } @@ -439,18 +440,7 @@ auto observer_iter = synced_pref_observers_.find(name); if (observer_iter == synced_pref_observers_.end()) return; - SyncedPrefObserverList* observers = observer_iter->second.get(); - observers->RemoveObserver(observer); -} - -void PrefModelAssociator::SetPrefModelAssociatorClientForTesting( - const PrefModelAssociatorClient* client) { - DCHECK(!client_); - client_ = client; -} - -std::set<std::string> PrefModelAssociator::registered_preferences() const { - return registered_preferences_; + observer_iter->second->RemoveObserver(observer); } void PrefModelAssociator::RegisterPref(const char* name) { @@ -458,7 +448,7 @@ registered_preferences_.insert(name); } -bool PrefModelAssociator::IsPrefRegistered(const char* name) { +bool PrefModelAssociator::IsPrefRegistered(const std::string& name) const { return registered_preferences_.count(name) > 0; } @@ -475,7 +465,7 @@ if (!preference) return; - if (!IsPrefRegistered(name.c_str())) + if (!IsPrefRegistered(name)) return; // We are not syncing this preference. syncer::SyncChangeList changes; @@ -522,8 +512,7 @@ auto observer_iter = synced_pref_observers_.find(path); if (observer_iter == synced_pref_observers_.end()) return; - SyncedPrefObserverList* observers = observer_iter->second.get(); - for (auto& observer : *observers) + for (auto& observer : *observer_iter->second) observer.OnSyncedPrefChanged(path, from_sync); }
diff --git a/components/sync_preferences/pref_model_associator.h b/components/sync_preferences/pref_model_associator.h index 8832be19..d47a36b4 100644 --- a/components/sync_preferences/pref_model_associator.h +++ b/components/sync_preferences/pref_model_associator.h
@@ -61,10 +61,6 @@ std::unique_ptr<syncer::SyncErrorFactory> sync_error_factory) override; void StopSyncing(syncer::ModelType type) override; - // Returns the list of preference names that are registered as syncable, and - // hence should be monitored for changes. - std::set<std::string> registered_preferences() const; - // Register a preference with the specified name for syncing. We do not care // about the type at registration time, but when changes arrive from the // syncer, we check if they can be applied and if not drop them. @@ -72,9 +68,6 @@ // begins). virtual void RegisterPref(const char* name); - // Returns true if the specified preference is registered for syncing. - virtual bool IsPrefRegistered(const char* name); - // Process a local preference change. This can trigger new SyncChanges being // sent to the syncer. virtual void ProcessPrefChange(const std::string& name); @@ -95,15 +88,13 @@ bool CreatePrefSyncData(const std::string& name, const base::Value& value, syncer::SyncData* sync_data) const; - - // Extract preference value from sync specifics. - base::Value* ReadPreferenceSpecifics( - const sync_pb::PreferenceSpecifics& specifics); - // Returns true if the pref under the given name is pulled down from sync. // Note this does not refer to SYNCABLE_PREF. bool IsPrefSynced(const std::string& name) const; + // Returns true if the specified preference is registered for syncing. + bool IsPrefRegistered(const std::string& name) const; + // Adds a SyncedPrefObserver to watch for changes to a specific pref. void AddSyncedPrefObserver(const std::string& name, SyncedPrefObserver* observer); @@ -115,19 +106,13 @@ // Returns the PrefModelAssociatorClient for this object. const PrefModelAssociatorClient* client() const { return client_; } - // Set the PrefModelAssociatorClient to use for that object during tests. - void SetPrefModelAssociatorClientForTesting( - const PrefModelAssociatorClient* client); - // Register callback method which will get called at the end of // PrefModelAssociator::MergeDataAndStartSyncing(). void RegisterMergeDataFinishedCallback(const base::Closure& callback); - protected: + private: friend class PrefServiceSyncableTest; - typedef std::map<std::string, syncer::SyncData> SyncDataMap; - // Create an association for a given preference. If |sync_pref| is valid, // signifying that sync has data for this preference, we reconcile their data // with ours and append a new UPDATE SyncChange to |sync_changes|. If @@ -143,9 +128,14 @@ static std::unique_ptr<base::Value> MergeListValues( const base::Value& from_value, const base::Value& to_value); + static base::Value MergeDictionaryValues(const base::Value& from_value, const base::Value& to_value); + // Extract preference value from sync specifics. + static base::Value* ReadPreferenceSpecifics( + const sync_pb::PreferenceSpecifics& specifics); + // Do we have an active association between the preferences and sync models? // Set when start syncing, reset in StopSyncing. While this is not set, we // ignore any local preference changes (when we start syncing we will look @@ -184,17 +174,14 @@ // PRIORITY_PREFERENCES. syncer::ModelType type_; - private: + void NotifySyncedPrefObservers(const std::string& path, bool from_sync) const; + // Map prefs to lists of observers. Observers will receive notification when // a pref changes, including the detail of whether or not the change came // from sync. - using SyncedPrefObserverList = base::ObserverList<SyncedPrefObserver>; - using SyncedPrefObserverMap = - base::hash_map<std::string, std::unique_ptr<SyncedPrefObserverList>>; - - void NotifySyncedPrefObservers(const std::string& path, bool from_sync) const; - - SyncedPrefObserverMap synced_pref_observers_; + base::hash_map<std::string, + std::unique_ptr<base::ObserverList<SyncedPrefObserver>>> + synced_pref_observers_; const PrefModelAssociatorClient* client_; // Weak. std::vector<base::Closure> callback_list_;
diff --git a/components/sync_preferences/pref_service_syncable.cc b/components/sync_preferences/pref_service_syncable.cc index 96e192db..478d278a 100644 --- a/components/sync_preferences/pref_service_syncable.cc +++ b/components/sync_preferences/pref_service_syncable.cc
@@ -174,15 +174,6 @@ pref_sync_associator_.RegisterMergeDataFinishedCallback(callback); } -// Set the PrefModelAssociatorClient to use for that object during tests. -void PrefServiceSyncable::SetPrefModelAssociatorClientForTesting( - const PrefModelAssociatorClient* pref_model_associator_client) { - pref_sync_associator_.SetPrefModelAssociatorClientForTesting( - pref_model_associator_client); - priority_pref_sync_associator_.SetPrefModelAssociatorClientForTesting( - pref_model_associator_client); -} - void PrefServiceSyncable::AddRegisteredSyncablePreference( const std::string& path, uint32_t flags) {
diff --git a/components/sync_preferences/pref_service_syncable.h b/components/sync_preferences/pref_service_syncable.h index f425965..656b10e8 100644 --- a/components/sync_preferences/pref_service_syncable.h +++ b/components/sync_preferences/pref_service_syncable.h
@@ -40,7 +40,7 @@ std::unique_ptr<PrefValueStore> pref_value_store, scoped_refptr<PersistentPrefStore> user_prefs, scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry, - const PrefModelAssociatorClient* pref_model_associato_client, + const PrefModelAssociatorClient* pref_model_associator_client, base::RepeatingCallback<void(PersistentPrefStore::PrefReadError)> read_error_callback, bool async); @@ -91,11 +91,6 @@ void RemoveSyncedPrefObserver(const std::string& name, SyncedPrefObserver* observer); - protected: - // Set the PrefModelAssociatorClient to use for that object during tests. - void SetPrefModelAssociatorClientForTesting( - const PrefModelAssociatorClient* pref_model_associator_client); - private: friend class PrefModelAssociator;
diff --git a/components/sync_preferences/pref_service_syncable_unittest.cc b/components/sync_preferences/pref_service_syncable_unittest.cc index bc0d19b..1129b29 100644 --- a/components/sync_preferences/pref_service_syncable_unittest.cc +++ b/components/sync_preferences/pref_service_syncable_unittest.cc
@@ -15,7 +15,9 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "components/pref_registry/pref_registry_syncable.h" +#include "components/prefs/pref_notifier_impl.h" #include "components/prefs/scoped_user_pref_update.h" +#include "components/prefs/testing_pref_store.h" #include "components/sync/model/sync_change.h" #include "components/sync/model/sync_data.h" #include "components/sync/model/sync_error_factory_mock.h" @@ -29,6 +31,7 @@ using syncer::SyncChange; using syncer::SyncData; +using testing::NotNull; namespace sync_preferences { @@ -39,6 +42,7 @@ const char kExampleUrl2[] = "http://example.com/2"; const char kStringPrefName[] = "string_pref_name"; const char kListPrefName[] = "list_pref_name"; +const char kDictPrefName[] = "dict_pref_name"; const char kUnsyncedPreferenceName[] = "nonsense_pref_name"; const char kUnsyncedPreferenceDefaultValue[] = "default"; const char kDefaultCharsetPrefName[] = "default_charset"; @@ -49,25 +53,6 @@ (*num)++; } -class TestPrefModelAssociatorClient : public PrefModelAssociatorClient { - public: - TestPrefModelAssociatorClient() {} - ~TestPrefModelAssociatorClient() override {} - - // PrefModelAssociatorClient implementation. - bool IsMergeableListPreference(const std::string& pref_name) const override { - return pref_name == kListPrefName; - } - - bool IsMergeableDictionaryPreference( - const std::string& pref_name) const override { - return false; - } - - private: - DISALLOW_COPY_AND_ASSIGN(TestPrefModelAssociatorClient); -}; - class TestSyncProcessorStub : public syncer::SyncChangeProcessor { public: explicit TestSyncProcessorStub(syncer::SyncChangeList* output) @@ -100,11 +85,9 @@ public: PrefServiceSyncableTest() : pref_sync_service_(nullptr), - test_processor_(nullptr), next_pref_remote_sync_node_id_(0) {} void SetUp() override { - prefs_.SetPrefModelAssociatorClientForTesting(&client_); prefs_.registry()->RegisterStringPref(kUnsyncedPreferenceName, kUnsyncedPreferenceDefaultValue); prefs_.registry()->RegisterStringPref( @@ -116,7 +99,7 @@ kDefaultCharsetPrefName, kDefaultCharsetValue, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); - pref_sync_service_ = reinterpret_cast<PrefModelAssociator*>( + pref_sync_service_ = static_cast<PrefModelAssociator*>( prefs_.GetSyncableService(syncer::PREFERENCES)); ASSERT_TRUE(pref_sync_service_); } @@ -154,9 +137,9 @@ void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data, syncer::SyncChangeList* output) { - test_processor_ = new TestSyncProcessorStub(output); syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing( - syncer::PREFERENCES, initial_data, base::WrapUnique(test_processor_), + syncer::PREFERENCES, initial_data, + std::make_unique<TestSyncProcessorStub>(output), std::make_unique<syncer::SyncErrorFactoryMock>()); EXPECT_FALSE(r.error().IsSet()); } @@ -184,22 +167,20 @@ } bool IsSynced(const std::string& pref_name) { - return pref_sync_service_->registered_preferences().count(pref_name) > 0; + return pref_sync_service_->IsPrefSynced(pref_name); } - bool HasSyncData(const std::string& pref_name) { - return pref_sync_service_->IsPrefSynced(pref_name); + bool IsRegistered(const std::string& pref_name) { + return pref_sync_service_->IsPrefRegistered(pref_name.c_str()); } PrefService* GetPrefs() { return &prefs_; } TestingPrefServiceSyncable* GetTestingPrefService() { return &prefs_; } protected: - TestPrefModelAssociatorClient client_; TestingPrefServiceSyncable prefs_; PrefModelAssociator* pref_sync_service_; - TestSyncProcessorStub* test_processor_; int next_pref_remote_sync_node_id_; }; @@ -228,7 +209,7 @@ syncer::SyncChangeList out; InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); - EXPECT_TRUE(IsSynced(kStringPrefName)); + EXPECT_TRUE(IsRegistered(kStringPrefName)); EXPECT_TRUE(pref->IsDefaultValue()); EXPECT_FALSE(FindValue(kStringPrefName, out).get()); } @@ -258,7 +239,6 @@ ListPrefUpdate update(GetPrefs(), kListPrefName); base::ListValue* url_list = update.Get(); url_list->AppendString(kExampleUrl0); - url_list->AppendString(kExampleUrl1); } syncer::SyncDataList in; @@ -266,7 +246,6 @@ AddToRemoteDataList(kStringPrefName, base::Value(kExampleUrl1), &in); base::ListValue urls_to_restore; urls_to_restore.AppendString(kExampleUrl1); - urls_to_restore.AppendString(kExampleUrl2); AddToRemoteDataList(kListPrefName, urls_to_restore, &in); AddToRemoteDataList(kDefaultCharsetPrefName, base::Value(kNonDefaultCharsetValue), &in); @@ -277,15 +256,259 @@ EXPECT_EQ(kExampleUrl1, prefs_.GetString(kStringPrefName)); + // No associator client is registered, so lists and dictionaries should not + // get merged (remote write wins). + auto expected_urls = std::make_unique<base::ListValue>(); + expected_urls->AppendString(kExampleUrl1); + EXPECT_FALSE(FindValue(kListPrefName, out)); + EXPECT_TRUE(GetPreferenceValue(kListPrefName).Equals(expected_urls.get())); + EXPECT_EQ(kNonDefaultCharsetValue, prefs_.GetString(kDefaultCharsetPrefName)); +} + +class TestPrefModelAssociatorClient : public PrefModelAssociatorClient { + public: + TestPrefModelAssociatorClient() {} + ~TestPrefModelAssociatorClient() override {} + + // PrefModelAssociatorClient implementation. + bool IsMergeableListPreference(const std::string& pref_name) const override { + return pref_name == kListPrefName; + } + + bool IsMergeableDictionaryPreference( + const std::string& pref_name) const override { + return true; + } + + private: + DISALLOW_COPY_AND_ASSIGN(TestPrefModelAssociatorClient); +}; + +class PrefServiceSyncableMergeTest : public testing::Test { + public: + PrefServiceSyncableMergeTest() + : pref_registry_( + base::MakeRefCounted<user_prefs::PrefRegistrySyncable>()), + pref_notifier_(new PrefNotifierImpl), + managed_prefs_(base::MakeRefCounted<TestingPrefStore>()), + user_prefs_(base::MakeRefCounted<TestingPrefStore>()), + prefs_( + std::unique_ptr<PrefNotifierImpl>(pref_notifier_), + std::make_unique<PrefValueStore>(managed_prefs_.get(), + new TestingPrefStore, + new TestingPrefStore, + new TestingPrefStore, + user_prefs_.get(), + new TestingPrefStore, + pref_registry_->defaults().get(), + pref_notifier_), + user_prefs_, + pref_registry_, + &client_, + base::BindRepeating(&PrefServiceSyncableMergeTest::HandleReadError), + /*async=*/false), + pref_sync_service_(nullptr), + next_pref_remote_sync_node_id_(0) {} + + void SetUp() override { + pref_registry_->RegisterStringPref(kUnsyncedPreferenceName, + kUnsyncedPreferenceDefaultValue); + pref_registry_->RegisterStringPref( + kStringPrefName, std::string(), + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + pref_registry_->RegisterListPref( + kListPrefName, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + pref_registry_->RegisterDictionaryPref( + kDictPrefName, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + pref_registry_->RegisterStringPref( + kDefaultCharsetPrefName, kDefaultCharsetValue, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + + // Downcast to PrefModelAssociator so that tests can access its' specific + // behavior. This is a smell. The roles between PrefServiceSyncable and + // PrefModelAssociator are not clearly separated (and this test should only + // test against the SyncableService interface). + pref_sync_service_ = // static_cast<PrefModelAssociator*>( + prefs_.GetSyncableService(syncer::PREFERENCES); //); + ASSERT_THAT(pref_sync_service_, NotNull()); + } + + /// Empty stub for prefs_ error handling. + static void HandleReadError(PersistentPrefStore::PrefReadError error) {} + + syncer::SyncChange MakeRemoteChange(int64_t id, + const std::string& name, + const base::Value& value, + SyncChange::SyncChangeType type) { + std::string serialized; + JSONStringValueSerializer json(&serialized); + CHECK(json.Serialize(value)); + sync_pb::EntitySpecifics entity; + sync_pb::PreferenceSpecifics* pref_one = entity.mutable_preference(); + pref_one->set_name(name); + pref_one->set_value(serialized); + return syncer::SyncChange( + FROM_HERE, type, + syncer::SyncData::CreateRemoteData(id, entity, base::Time())); + } + + void AddToRemoteDataList(const std::string& name, + const base::Value& value, + syncer::SyncDataList* out) { + std::string serialized; + JSONStringValueSerializer json(&serialized); + ASSERT_TRUE(json.Serialize(value)); + sync_pb::EntitySpecifics one; + sync_pb::PreferenceSpecifics* pref_one = one.mutable_preference(); + pref_one->set_name(name); + pref_one->set_value(serialized); + out->push_back(SyncData::CreateRemoteData(++next_pref_remote_sync_node_id_, + one, base::Time())); + } + + void InitWithSyncDataTakeOutput(const syncer::SyncDataList& initial_data, + syncer::SyncChangeList* output) { + syncer::SyncMergeResult r = pref_sync_service_->MergeDataAndStartSyncing( + syncer::PREFERENCES, initial_data, + std::make_unique<TestSyncProcessorStub>(output), + std::make_unique<syncer::SyncErrorFactoryMock>()); + EXPECT_FALSE(r.error().IsSet()); + } + + const base::Value& GetPreferenceValue(const std::string& name) { + const PrefService::Preference* preference = + prefs_.FindPreference(name.c_str()); + return *preference->GetValue(); + } + + std::unique_ptr<base::Value> FindValue(const std::string& name, + const syncer::SyncChangeList& list) { + syncer::SyncChangeList::const_iterator it = list.begin(); + for (; it != list.end(); ++it) { + if (syncer::SyncDataLocal(it->sync_data()).GetTag() == name) { + return base::JSONReader::Read( + it->sync_data().GetSpecifics().preference().value()); + } + } + return nullptr; + } + + protected: + scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry_; + // Owned by prefs_; + PrefNotifierImpl* pref_notifier_; + scoped_refptr<TestingPrefStore> managed_prefs_; + scoped_refptr<TestingPrefStore> user_prefs_; + TestPrefModelAssociatorClient client_; + PrefServiceSyncable prefs_; + syncer::SyncableService* pref_sync_service_; + int next_pref_remote_sync_node_id_; +}; + +TEST_F(PrefServiceSyncableMergeTest, ShouldMergeSelectedListValues) { + { + ListPrefUpdate update(&prefs_, kListPrefName); + base::ListValue* url_list = update.Get(); + url_list->AppendString(kExampleUrl0); + url_list->AppendString(kExampleUrl1); + } + + base::ListValue urls_to_restore; + urls_to_restore.AppendString(kExampleUrl1); + urls_to_restore.AppendString(kExampleUrl2); + syncer::SyncDataList in; + AddToRemoteDataList(kListPrefName, urls_to_restore, &in); + + syncer::SyncChangeList out; + InitWithSyncDataTakeOutput(in, &out); + std::unique_ptr<base::ListValue> expected_urls(new base::ListValue); expected_urls->AppendString(kExampleUrl1); expected_urls->AppendString(kExampleUrl2); expected_urls->AppendString(kExampleUrl0); std::unique_ptr<base::Value> value(FindValue(kListPrefName, out)); ASSERT_TRUE(value.get()); - EXPECT_TRUE(value->Equals(expected_urls.get())); + EXPECT_TRUE(value->Equals(expected_urls.get())) << *value; EXPECT_TRUE(GetPreferenceValue(kListPrefName).Equals(expected_urls.get())); - EXPECT_EQ(kNonDefaultCharsetValue, prefs_.GetString(kDefaultCharsetPrefName)); +} + +// List preferences have special handling at association time due to our ability +// to merge the local and sync value. Make sure the merge logic doesn't merge +// managed preferences. +TEST_F(PrefServiceSyncableMergeTest, ManagedListPreferences) { + // Make the list of urls to restore on startup managed. + base::ListValue managed_value; + managed_value.AppendString(kExampleUrl0); + managed_value.AppendString(kExampleUrl1); + managed_prefs_->SetValue(kListPrefName, managed_value.CreateDeepCopy(), + WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); + + // Set a cloud version. + syncer::SyncDataList in; + base::ListValue urls_to_restore; + urls_to_restore.AppendString(kExampleUrl1); + urls_to_restore.AppendString(kExampleUrl2); + AddToRemoteDataList(kListPrefName, urls_to_restore, &in); + + // Start sync and verify the synced value didn't get merged. + { + syncer::SyncChangeList out; + InitWithSyncDataTakeOutput(in, &out); + EXPECT_FALSE(FindValue(kListPrefName, out).get()); + } + + // Changing the user's urls to restore on startup pref should not sync + // anything. + { + syncer::SyncChangeList out; + base::ListValue user_value; + user_value.AppendString("http://chromium.org"); + prefs_.Set(kListPrefName, user_value); + EXPECT_FALSE(FindValue(kListPrefName, out).get()); + } + + // An incoming sync transaction should change the user value, not the managed + // value. + base::ListValue sync_value; + sync_value.AppendString("http://crbug.com"); + syncer::SyncChangeList list; + list.push_back(MakeRemoteChange(1, kListPrefName, sync_value, + SyncChange::ACTION_UPDATE)); + pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); + + const base::Value* managed_prefs_result; + ASSERT_TRUE(managed_prefs_->GetValue(kListPrefName, &managed_prefs_result)); + EXPECT_TRUE(managed_value.Equals(managed_prefs_result)); + // Get should return the managed value, too. + EXPECT_TRUE(managed_value.Equals(prefs_.Get(kListPrefName))); + // Verify the user pref value has the change. + EXPECT_TRUE(sync_value.Equals(prefs_.GetUserPrefValue(kListPrefName))); +} + +TEST_F(PrefServiceSyncableMergeTest, ShouldMergeSelectedDictionaryValues) { + { + DictionaryPrefUpdate update(&prefs_, kDictPrefName); + base::DictionaryValue* dict_value = update.Get(); + dict_value->Set("my_key1", std::make_unique<base::Value>("my_value1")); + dict_value->Set("my_key3", std::make_unique<base::Value>("my_value3")); + } + + base::DictionaryValue remote_update; + remote_update.Set("my_key2", std::make_unique<base::Value>("my_value2")); + syncer::SyncDataList in; + AddToRemoteDataList(kDictPrefName, remote_update, &in); + + syncer::SyncChangeList out; + InitWithSyncDataTakeOutput(in, &out); + + base::DictionaryValue expected_dict; + expected_dict.Set("my_key1", std::make_unique<base::Value>("my_value1")); + expected_dict.Set("my_key2", std::make_unique<base::Value>("my_value2")); + expected_dict.Set("my_key3", std::make_unique<base::Value>("my_value3")); + std::unique_ptr<base::Value> value(FindValue(kDictPrefName, out)); + ASSERT_TRUE(value.get()); + EXPECT_TRUE(value->Equals(&expected_dict)); + EXPECT_TRUE(GetPreferenceValue(kDictPrefName).Equals(&expected_dict)); } TEST_F(PrefServiceSyncableTest, FailModelAssociation) { @@ -353,8 +576,7 @@ const base::Value& actual = GetPreferenceValue(kStringPrefName); EXPECT_TRUE(expected.Equals(&actual)); - EXPECT_EQ( - 1U, pref_sync_service_->registered_preferences().count(kStringPrefName)); + EXPECT_TRUE(pref_sync_service_->IsPrefSynced(kStringPrefName)); } TEST_F(PrefServiceSyncableTest, UpdatedSyncNodeUnknownPreference) { @@ -394,49 +616,6 @@ EXPECT_TRUE(sync_value.Equals(prefs_.GetUserPref(kStringPrefName))); } -// List preferences have special handling at association time due to our ability -// to merge the local and sync value. Make sure the merge logic doesn't merge -// managed preferences. -TEST_F(PrefServiceSyncableTest, ManagedListPreferences) { - // Make the list of urls to restore on startup managed. - base::ListValue managed_value; - managed_value.AppendString(kExampleUrl0); - managed_value.AppendString(kExampleUrl1); - prefs_.SetManagedPref(kListPrefName, managed_value.CreateDeepCopy()); - - // Set a cloud version. - syncer::SyncDataList in; - syncer::SyncChangeList out; - base::ListValue urls_to_restore; - urls_to_restore.AppendString(kExampleUrl1); - urls_to_restore.AppendString(kExampleUrl2); - AddToRemoteDataList(kListPrefName, urls_to_restore, &in); - - // Start sync and verify the synced value didn't get merged. - InitWithSyncDataTakeOutput(in, &out); - EXPECT_FALSE(FindValue(kListPrefName, out).get()); - out.clear(); - - // Changing the user's urls to restore on startup pref should not sync - // anything. - base::ListValue user_value; - user_value.AppendString("http://chromium.org"); - prefs_.SetUserPref(kListPrefName, user_value.CreateDeepCopy()); - EXPECT_FALSE(FindValue(kListPrefName, out).get()); - - // An incoming sync transaction should change the user value, not the managed - // value. - base::ListValue sync_value; - sync_value.AppendString("http://crbug.com"); - syncer::SyncChangeList list; - list.push_back(MakeRemoteChange(1, kListPrefName, sync_value, - SyncChange::ACTION_UPDATE)); - pref_sync_service_->ProcessSyncChanges(FROM_HERE, list); - - EXPECT_TRUE(managed_value.Equals(prefs_.GetManagedPref(kListPrefName))); - EXPECT_TRUE(sync_value.Equals(prefs_.GetUserPref(kListPrefName))); -} - TEST_F(PrefServiceSyncableTest, DynamicManagedPreferences) { syncer::SyncChangeList out; InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); @@ -500,7 +679,7 @@ syncer::SyncChangeList out; InitWithSyncDataTakeOutput(syncer::SyncDataList(), &out); - EXPECT_TRUE(IsSynced(kStringPrefName)); + EXPECT_TRUE(IsRegistered(kStringPrefName)); EXPECT_TRUE(pref->IsDefaultValue()); EXPECT_FALSE(FindValue(kStringPrefName, out).get()); out.clear();
diff --git a/components/sync_preferences/testing_pref_service_syncable.cc b/components/sync_preferences/testing_pref_service_syncable.cc index 92fa102..e42f5020 100644 --- a/components/sync_preferences/testing_pref_service_syncable.cc +++ b/components/sync_preferences/testing_pref_service_syncable.cc
@@ -4,6 +4,8 @@ #include "components/sync_preferences/testing_pref_service_syncable.h" +#include <memory> + #include "base/bind.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_notifier_impl.h" @@ -31,7 +33,7 @@ pref_notifier), user_prefs, pref_registry, - nullptr, // pref_model_associator_client + /*pref_model_associator_client=*/nullptr, base::Bind(&TestingPrefServiceBase< PrefServiceSyncable, user_prefs::PrefRegistrySyncable>::HandleReadError),
diff --git a/components/sync_preferences/testing_pref_service_syncable.h b/components/sync_preferences/testing_pref_service_syncable.h index cf83573f..ee59cc1 100644 --- a/components/sync_preferences/testing_pref_service_syncable.h +++ b/components/sync_preferences/testing_pref_service_syncable.h
@@ -16,6 +16,18 @@ namespace sync_preferences { // Test version of PrefServiceSyncable. +// This class hierarchy has a flaw: TestingPrefServiceBase is inheriting from +// the first template parameter (PrefServiceSyncable in this case). This means, +// all of the supported parameter types must support the same constructor +// signatures -- which they don't. Hence, it's not possible to properly inject +// a PrefModelAssociatorClient. +// TODO(tschumann) The whole purpose of TestingPrefServiceBase is questionable +// and I'd be in favor of removing it completely: +// -- it hides the dependency injetion of the different stores +// -- just to later offer ways to manipulate speficic stores. +// -- if tests just dependency injects the individual stores directly, they +// already have full control and won't need that indirection at all. +// See PrefServiceSyncableMergeTest as an example of a cleaner way. class TestingPrefServiceSyncable : public TestingPrefServiceBase<PrefServiceSyncable, user_prefs::PrefRegistrySyncable> { @@ -34,8 +46,6 @@ // a PrefRegistry via its constructor (or via e.g. PrefServiceFactory). user_prefs::PrefRegistrySyncable* registry(); - using PrefServiceSyncable::SetPrefModelAssociatorClientForTesting; - private: DISALLOW_COPY_AND_ASSIGN(TestingPrefServiceSyncable); };
diff --git a/components/translate/core/browser/translate_infobar_delegate.h b/components/translate/core/browser/translate_infobar_delegate.h index 7d19064..a30bf284 100644 --- a/components/translate/core/browser/translate_infobar_delegate.h +++ b/components/translate/core/browser/translate_infobar_delegate.h
@@ -205,6 +205,12 @@ // Set a observer. void SetObserver(Observer* observer); + // InfoBarDelegate: + infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override; + int GetIconId() const override; + void InfoBarDismissed() override; + TranslateInfoBarDelegate* AsTranslateInfoBarDelegate() override; + protected: TranslateInfoBarDelegate( const base::WeakPtr<TranslateManager>& translate_manager, @@ -219,12 +225,6 @@ friend class TranslationInfoBarTest; typedef std::pair<std::string, base::string16> LanguageNamePair; - // InfoBarDelegate: - infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override; - int GetIconId() const override; - void InfoBarDismissed() override; - TranslateInfoBarDelegate* AsTranslateInfoBarDelegate() override; - bool is_off_the_record_; translate::TranslateStep step_;
diff --git a/components/webrtc_logging/browser/BUILD.gn b/components/webrtc_logging/browser/BUILD.gn index b1f22936..ddc7597 100644 --- a/components/webrtc_logging/browser/BUILD.gn +++ b/components/webrtc_logging/browser/BUILD.gn
@@ -2,10 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//media/media_options.gni") - -assert(enable_webrtc) - source_set("browser") { sources = [ "log_cleanup.cc",
diff --git a/components/webrtc_logging/common/BUILD.gn b/components/webrtc_logging/common/BUILD.gn index 9df6f3b6..34ff3156 100644 --- a/components/webrtc_logging/common/BUILD.gn +++ b/components/webrtc_logging/common/BUILD.gn
@@ -2,10 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//media/media_options.gni") - -assert(enable_webrtc) - source_set("common") { sources = [ "partial_circular_buffer.cc",
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 75952c7..dbc59a9 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -97,6 +97,7 @@ "//gpu/ipc/common:gpu_preferences_util", "//gpu/ipc/host", "//gpu/vulkan:buildflags", + "//jingle:jingle_glue", "//media", "//media:media_buildflags", "//media/capture", @@ -170,6 +171,9 @@ "//third_party/icu", "//third_party/libyuv", "//third_party/re2", + "//third_party/webrtc/media:rtc_media_base", + "//third_party/webrtc/modules/desktop_capture:primitives", + "//third_party/webrtc/rtc_base:rtc_base", "//third_party/zlib", "//third_party/zlib/google:compression_utils", "//third_party/zlib/google:zip", @@ -1054,6 +1058,8 @@ "media/android/media_web_contents_observer_android.h", "media/audible_metrics.cc", "media/audible_metrics.h", + "media/audio_input_stream_broker.cc", + "media/audio_input_stream_broker.h", "media/audio_output_stream_broker.cc", "media/audio_output_stream_broker.h", "media/audio_stream_broker.cc", @@ -1356,6 +1362,8 @@ "renderer_host/media/media_stream_track_metrics_host.h", "renderer_host/media/media_stream_ui_proxy.cc", "renderer_host/media/media_stream_ui_proxy.h", + "renderer_host/media/peer_connection_tracker_host.cc", + "renderer_host/media/peer_connection_tracker_host.h", "renderer_host/media/render_frame_audio_input_stream_factory.cc", "renderer_host/media/render_frame_audio_input_stream_factory.h", "renderer_host/media/render_frame_audio_output_stream_factory.cc", @@ -1372,11 +1380,11 @@ "renderer_host/media/video_capture_controller.cc", "renderer_host/media/video_capture_controller.h", "renderer_host/media/video_capture_controller_event_handler.h", - "renderer_host/media/video_capture_dependencies.cc", - "renderer_host/media/video_capture_dependencies.h", "renderer_host/media/video_capture_device_launch_observer.h", "renderer_host/media/video_capture_factory_delegate.cc", "renderer_host/media/video_capture_factory_delegate.h", + "renderer_host/media/video_capture_gpu_jpeg_decoder.cc", + "renderer_host/media/video_capture_gpu_jpeg_decoder.h", "renderer_host/media/video_capture_host.cc", "renderer_host/media/video_capture_host.h", "renderer_host/media/video_capture_manager.cc", @@ -1390,6 +1398,18 @@ "renderer_host/overscroll_controller.cc", "renderer_host/overscroll_controller.h", "renderer_host/overscroll_controller_delegate.h", + "renderer_host/p2p/socket_dispatcher_host.cc", + "renderer_host/p2p/socket_dispatcher_host.h", + "renderer_host/p2p/socket_host.cc", + "renderer_host/p2p/socket_host.h", + "renderer_host/p2p/socket_host_tcp.cc", + "renderer_host/p2p/socket_host_tcp.h", + "renderer_host/p2p/socket_host_tcp_server.cc", + "renderer_host/p2p/socket_host_tcp_server.h", + "renderer_host/p2p/socket_host_throttler.cc", + "renderer_host/p2p/socket_host_throttler.h", + "renderer_host/p2p/socket_host_udp.cc", + "renderer_host/p2p/socket_host_udp.h", "renderer_host/render_frame_metadata_provider_impl.cc", "renderer_host/render_frame_metadata_provider_impl.h", "renderer_host/render_message_filter.cc", @@ -1699,6 +1719,13 @@ "web_package/web_package_prefetch_handler.h", "web_package/web_package_request_handler.cc", "web_package/web_package_request_handler.h", + "webrtc/webrtc_internals.cc", + "webrtc/webrtc_internals.h", + "webrtc/webrtc_internals_message_handler.cc", + "webrtc/webrtc_internals_message_handler.h", + "webrtc/webrtc_internals_ui.cc", + "webrtc/webrtc_internals_ui.h", + "webrtc/webrtc_internals_ui_observer.h", "websockets/websocket_handshake_request_info_impl.cc", "websockets/websocket_handshake_request_info_impl.h", "websockets/websocket_manager.cc", @@ -1739,6 +1766,8 @@ # ChromeOS also defines linux but their memory-monitors conflict. if (is_chromeos) { sources += [ + "media/keyboard_mic_registration.cc", + "media/keyboard_mic_registration.h", "memory/memory_monitor_chromeos.cc", "memory/memory_monitor_chromeos.h", "tracing/cros_tracing_agent.cc", @@ -1797,39 +1826,6 @@ ] } - if (enable_webrtc) { - sources += [ - "renderer_host/media/peer_connection_tracker_host.cc", - "renderer_host/media/peer_connection_tracker_host.h", - "renderer_host/p2p/socket_dispatcher_host.cc", - "renderer_host/p2p/socket_dispatcher_host.h", - "renderer_host/p2p/socket_host.cc", - "renderer_host/p2p/socket_host.h", - "renderer_host/p2p/socket_host_tcp.cc", - "renderer_host/p2p/socket_host_tcp.h", - "renderer_host/p2p/socket_host_tcp_server.cc", - "renderer_host/p2p/socket_host_tcp_server.h", - "renderer_host/p2p/socket_host_throttler.cc", - "renderer_host/p2p/socket_host_throttler.h", - "renderer_host/p2p/socket_host_udp.cc", - "renderer_host/p2p/socket_host_udp.h", - "webrtc/webrtc_internals.cc", - "webrtc/webrtc_internals.h", - "webrtc/webrtc_internals_message_handler.cc", - "webrtc/webrtc_internals_message_handler.h", - "webrtc/webrtc_internals_ui.cc", - "webrtc/webrtc_internals_ui.h", - "webrtc/webrtc_internals_ui_observer.h", - ] - - deps += [ - "//jingle:jingle_glue", - "//third_party/webrtc/media:rtc_media_base", - "//third_party/webrtc/modules/desktop_capture:primitives", - "//third_party/webrtc/rtc_base:rtc_base", - ] - } - # Desktop/Window/WebContents screen capture implementations, conditionally # built depending on the available implementations for each platform. if (is_linux || is_mac || is_win) { @@ -1837,6 +1833,8 @@ sources += [ "media/capture/cursor_renderer.cc", "media/capture/cursor_renderer.h", + "media/capture/desktop_capture_device.cc", + "media/capture/desktop_capture_device.h", "media/capture/fake_webcontent_capture_machine.cc", "media/capture/fake_webcontent_capture_machine.h", "media/capture/frame_sink_video_capture_device.cc", @@ -1844,6 +1842,8 @@ "media/capture/web_contents_video_capture_device.cc", "media/capture/web_contents_video_capture_device.h", ] + public_deps += [ "//third_party/webrtc_overrides:init_webrtc" ] + deps += [ "//third_party/webrtc/modules/desktop_capture" ] if (use_aura) { sources += [ "media/capture/aura_window_capture_machine.cc", @@ -1864,14 +1864,6 @@ "//sandbox/mac:seatbelt_extension", ] } - if (enable_webrtc) { - sources += [ - "media/capture/desktop_capture_device.cc", - "media/capture/desktop_capture_device.h", - ] - deps += [ "//third_party/webrtc/modules/desktop_capture" ] - public_deps += [ "//third_party/webrtc_overrides:init_webrtc" ] - } } if (is_win) {
diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index 9c7c35f..b25ed2a 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h
@@ -19,6 +19,10 @@ #include "services/viz/public/interfaces/compositing/compositing_mode_watcher.mojom.h" #include "ui/base/ui_features.h" +#if defined(OS_CHROMEOS) +#include "content/browser/media/keyboard_mic_registration.h" +#endif + #if defined(USE_AURA) namespace aura { class Env; @@ -166,6 +170,13 @@ media::UserInputMonitor* user_input_monitor() const { return user_input_monitor_.get(); } + +#if defined(OS_CHROMEOS) + KeyboardMicRegistration* keyboard_mic_registration() { + return &keyboard_mic_registration_; + } +#endif + discardable_memory::DiscardableSharedMemoryManager* discardable_shared_memory_manager() const { return discardable_shared_memory_manager_.get(); @@ -344,6 +355,10 @@ scoped_refptr<base::DeferredSequencedTaskRunner> audio_service_runner_; std::unique_ptr<media::AudioSystem> audio_system_; +#if defined(OS_CHROMEOS) + KeyboardMicRegistration keyboard_mic_registration_; +#endif + std::unique_ptr<midi::MidiService> midi_service_; // Must be deleted on the IO thread.
diff --git a/content/browser/browser_side_navigation_browsertest.cc b/content/browser/browser_side_navigation_browsertest.cc index f5b07b2..1931019 100644 --- a/content/browser/browser_side_navigation_browsertest.cc +++ b/content/browser/browser_side_navigation_browsertest.cc
@@ -482,7 +482,7 @@ base::TimeTicks::Now() /* navigation_start */, "GET", nullptr /* post_data */, base::Optional<SourceLocation>(), CSPDisposition::CHECK, false /* started_from_context_menu */, - false /* has_user_gesture */, base::nullopt /* suggested_filename */); + false /* has_user_gesture */); mojom::BeginNavigationParamsPtr begin_params = mojom::BeginNavigationParams::New( std::string() /* headers */, net::LOAD_NORMAL,
diff --git a/content/browser/devtools/devtools_url_interceptor_request_job.cc b/content/browser/devtools/devtools_url_interceptor_request_job.cc index 622f681..b966e334 100644 --- a/content/browser/devtools/devtools_url_interceptor_request_job.cc +++ b/content/browser/devtools/devtools_url_interceptor_request_job.cc
@@ -155,8 +155,7 @@ resource_request_info->ShouldReportRawHeaders(), resource_request_info->IsAsync(), resource_request_info->GetPreviewsState(), resource_request_info->body(), - resource_request_info->initiated_in_secure_context(), - resource_request_info->suggested_filename()); + resource_request_info->initiated_in_secure_context()); extra_data->AssociateWithRequest(request_.get()); if (request_details.post_data) @@ -549,12 +548,9 @@ // should not have this problem, as it's on top of MIME sniffer. std::string mime_type; subrequest->GetMimeType(&mime_type); - bool is_cross_origin = navigation_loader_util::IsCrossOriginRequest( - orig_request->url(), orig_request->initiator()); return req_info->allow_download() && navigation_loader_util::IsDownload( - orig_request->url(), subrequest->response_headers(), mime_type, - req_info->suggested_filename().has_value(), is_cross_origin); + orig_request->url(), subrequest->response_headers(), mime_type); } } // namespace
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.cc b/content/browser/devtools/devtools_url_loader_interceptor.cc index 0178aa6..751c113 100644 --- a/content/browser/devtools/devtools_url_loader_interceptor.cc +++ b/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -172,7 +172,6 @@ const base::UnguessableToken& frame_token, int32_t process_id, std::unique_ptr<CreateLoaderParameters> create_loader_params, - bool has_suggested_download_filename, network::mojom::URLLoaderRequest loader_request, network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderFactoryPtr target_factory); @@ -264,7 +263,6 @@ InterceptionStage stage_; std::unique_ptr<CreateLoaderParameters> create_loader_params_; - const bool has_suggested_download_filename_; mojo::Binding<network::mojom::URLLoaderClient> client_binding_; mojo::Binding<network::mojom::URLLoader> loader_binding_; @@ -311,7 +309,6 @@ void CreateJob(const base::UnguessableToken& frame_token, int32_t process_id, std::unique_ptr<CreateLoaderParameters> create_params, - bool has_suggested_download_filename, network::mojom::URLLoaderRequest loader_request, network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderFactoryPtr target_factory) { @@ -320,10 +317,10 @@ static int last_id = 0; std::string id = base::StringPrintf("interception-job-%d", ++last_id); - InterceptionJob* job = new InterceptionJob( - this, id, frame_token, process_id, std::move(create_params), - has_suggested_download_filename, std::move(loader_request), - std::move(client), std::move(target_factory)); + InterceptionJob* job = + new InterceptionJob(this, id, frame_token, process_id, + std::move(create_params), std::move(loader_request), + std::move(client), std::move(target_factory)); jobs_.emplace(std::move(id), job); } @@ -403,7 +400,6 @@ DevToolsURLLoaderFactoryProxy( const base::UnguessableToken& frame_token, int32_t process_id, - bool has_suggested_download_filename, network::mojom::URLLoaderFactoryRequest loader_request, network::mojom::URLLoaderFactoryPtrInfo target_factory_info, base::WeakPtr<DevToolsURLLoaderInterceptor::Impl> interceptor); @@ -428,7 +424,6 @@ const base::UnguessableToken frame_token_; const int32_t process_id_; - const bool has_suggested_download_filename_; network::mojom::URLLoaderFactoryPtr target_factory_; base::WeakPtr<DevToolsURLLoaderInterceptor::Impl> interceptor_; @@ -440,13 +435,11 @@ DevToolsURLLoaderFactoryProxy::DevToolsURLLoaderFactoryProxy( const base::UnguessableToken& frame_token, int32_t process_id, - bool has_suggested_download_filename, network::mojom::URLLoaderFactoryRequest loader_request, network::mojom::URLLoaderFactoryPtrInfo target_factory_info, base::WeakPtr<DevToolsURLLoaderInterceptor::Impl> interceptor) : frame_token_(frame_token), process_id_(process_id), - has_suggested_download_filename_(has_suggested_download_filename), interceptor_(std::move(interceptor)) { DETACH_FROM_SEQUENCE(sequence_checker_); BrowserThread::PostTask( @@ -480,8 +473,8 @@ network::mojom::URLLoaderFactoryPtr factory_clone; target_factory_->Clone(MakeRequest(&factory_clone)); interceptor->CreateJob(frame_token_, process_id_, std::move(creation_params), - has_suggested_download_filename_, std::move(loader), - std::move(client), std::move(factory_clone)); + std::move(loader), std::move(client), + std::move(factory_clone)); } void DevToolsURLLoaderFactoryProxy::StartOnIO( @@ -600,7 +593,6 @@ bool DevToolsURLLoaderInterceptor::CreateProxyForInterception( const base::UnguessableToken frame_token, int process_id, - bool has_suggested_download_filename, network::mojom::URLLoaderFactoryRequest* request) const { if (!enabled_) return false; @@ -609,9 +601,9 @@ network::mojom::URLLoaderFactoryPtrInfo target_ptr_info; *request = MakeRequest(&target_ptr_info); - new DevToolsURLLoaderFactoryProxy( - frame_token, process_id, has_suggested_download_filename, - std::move(original_request), std::move(target_ptr_info), weak_impl_); + new DevToolsURLLoaderFactoryProxy(frame_token, process_id, + std::move(original_request), + std::move(target_ptr_info), weak_impl_); return true; } @@ -621,7 +613,6 @@ const base::UnguessableToken& frame_token, int process_id, std::unique_ptr<CreateLoaderParameters> create_loader_params, - bool has_suggested_download_filename, network::mojom::URLLoaderRequest loader_request, network::mojom::URLLoaderClientPtr client, network::mojom::URLLoaderFactoryPtr target_factory) @@ -636,7 +627,6 @@ report_upload_(!!create_loader_params->request.request_body), interceptor_(interceptor), create_loader_params_(std::move(create_loader_params)), - has_suggested_download_filename_(has_suggested_download_filename), client_binding_(this), loader_binding_(this), client_(std::move(client)), @@ -1140,13 +1130,10 @@ auto request_info = BuildRequestInfo(&head); const network::ResourceRequest& request = create_loader_params_->request; - bool is_cross_origin = navigation_loader_util::IsCrossOriginRequest( - request.url, request.request_initiator); request_info->is_download = request_info->is_navigation && request.allow_download && - navigation_loader_util::IsDownload( - request.url, head.headers.get(), head.mime_type, - has_suggested_download_filename_, is_cross_origin); + navigation_loader_util::IsDownload(request.url, head.headers.get(), + head.mime_type); NotifyClient(std::move(request_info)); }
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.h b/content/browser/devtools/devtools_url_loader_interceptor.h index 8c123c9..36f3774 100644 --- a/content/browser/devtools/devtools_url_loader_interceptor.h +++ b/content/browser/devtools/devtools_url_loader_interceptor.h
@@ -53,7 +53,6 @@ bool CreateProxyForInterception( const base::UnguessableToken frame_token, int process_id, // 0 for navigation - bool has_suggested_download_filename, network::mojom::URLLoaderFactoryRequest* request) const; private:
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index 7d66f47..567b26c7 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -1857,12 +1857,10 @@ bool NetworkHandler::MaybeCreateProxyForInterception( const base::UnguessableToken& frame_token, int process_id, - bool has_suggested_download_filename, network::mojom::URLLoaderFactoryRequest* target_factory_request) { return url_loader_interceptor_ && url_loader_interceptor_->CreateProxyForInterception( - frame_token, process_id, has_suggested_download_filename, - target_factory_request); + frame_token, process_id, target_factory_request); } void NetworkHandler::ApplyOverrides(net::HttpRequestHeaders* headers,
diff --git a/content/browser/devtools/protocol/network_handler.h b/content/browser/devtools/protocol/network_handler.h index 5a0787eb..2669e08 100644 --- a/content/browser/devtools/protocol/network_handler.h +++ b/content/browser/devtools/protocol/network_handler.h
@@ -135,7 +135,6 @@ bool MaybeCreateProxyForInterception( const base::UnguessableToken& frame_token, int process_id, - bool has_suggested_download_filename, network::mojom::URLLoaderFactoryRequest* target_factory_request); void ApplyOverrides(net::HttpRequestHeaders* headers,
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc index e0daf093..572843f 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.cc +++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -296,7 +296,6 @@ bool RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory( RenderFrameHostImpl* rfh, bool is_navigation, - bool has_suggested_download_filename, network::mojom::URLLoaderFactoryRequest* target_factory_request) { FrameTreeNode* frame_tree_node = rfh->frame_tree_node(); base::UnguessableToken frame_token = frame_tree_node->devtools_frame_token(); @@ -305,11 +304,9 @@ if (!agent_host) return false; int process_id = is_navigation ? 0 : rfh->GetProcess()->GetID(); - DCHECK(!has_suggested_download_filename || is_navigation); for (auto* network : protocol::NetworkHandler::ForAgentHost(agent_host)) { - if (network->MaybeCreateProxyForInterception( - frame_token, process_id, has_suggested_download_filename, - target_factory_request)) { + if (network->MaybeCreateProxyForInterception(frame_token, process_id, + target_factory_request)) { return true; } }
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.h b/content/browser/devtools/render_frame_devtools_agent_host.h index 2fa68895..afd6191 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.h +++ b/content/browser/devtools/render_frame_devtools_agent_host.h
@@ -73,7 +73,6 @@ static bool WillCreateURLLoaderFactory( RenderFrameHostImpl* rfh, bool is_navigation, - bool has_suggested_download_filename, network::mojom::URLLoaderFactoryRequest* loader_factory_request); static void OnNavigationRequestWillBeSent(
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc index 7264de65..9b7f2de 100644 --- a/content/browser/download/download_browsertest.cc +++ b/content/browser/download/download_browsertest.cc
@@ -2932,7 +2932,7 @@ } // A cross-origin request that fails before it gets a response from the server -// should result in the old page staying current. +// should result in an network error page. IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeNetworkError) { SetupErrorInjectionDownloads(); GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index bcbfb5e..7d2fb68 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc
@@ -251,8 +251,7 @@ scoped_refptr<download::DownloadURLLoaderFactoryGetter> CreateDownloadURLLoaderFactoryGetter(StoragePartitionImpl* storage_partition, - RenderFrameHost* rfh, - bool has_suggested_filename) { + RenderFrameHost* rfh) { network::mojom::URLLoaderFactoryPtrInfo proxy_factory_ptr_info; network::mojom::URLLoaderFactoryRequest proxy_factory_request; if (rfh) { @@ -261,7 +260,7 @@ MakeRequest(&devtools_factory_ptr_info); if (RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory( static_cast<RenderFrameHostImpl*>(rfh), true, - has_suggested_filename, &devtools_factory_request)) { + &devtools_factory_request)) { proxy_factory_ptr_info = std::move(devtools_factory_ptr_info); proxy_factory_request = std::move(devtools_factory_request); } @@ -716,7 +715,6 @@ void DownloadManagerImpl::InterceptNavigation( std::unique_ptr<network::ResourceRequest> resource_request, std::vector<GURL> url_chain, - const base::Optional<std::string>& suggested_filename, scoped_refptr<network::ResourceResponse> response, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, net::CertStatus cert_status, @@ -738,7 +736,7 @@ on_download_checks_done = base::BindOnce( &DownloadManagerImpl::InterceptNavigationOnChecksComplete, weak_factory_.GetWeakPtr(), web_contents_getter, - std::move(resource_request), std::move(url_chain), suggested_filename, + std::move(resource_request), std::move(url_chain), std::move(response), cert_status, std::move(url_loader_client_endpoints)); @@ -979,7 +977,6 @@ ResourceRequestInfo::WebContentsGetter web_contents_getter, std::unique_ptr<network::ResourceRequest> resource_request, std::vector<GURL> url_chain, - const base::Optional<std::string>& suggested_filename, scoped_refptr<network::ResourceResponse> response, net::CertStatus cert_status, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, @@ -1011,11 +1008,10 @@ GetStoragePartition(browser_context_, render_process_id, render_frame_id); in_progress_manager_->InterceptDownloadFromNavigation( std::move(resource_request), render_process_id, render_frame_id, site_url, - tab_url, tab_referrer_url, std::move(url_chain), suggested_filename, - std::move(response), std::move(cert_status), - std::move(url_loader_client_endpoints), - CreateDownloadURLLoaderFactoryGetter(storage_partition, render_frame_host, - suggested_filename.has_value())); + tab_url, tab_referrer_url, std::move(url_chain), std::move(response), + std::move(cert_status), std::move(url_loader_client_endpoints), + CreateDownloadURLLoaderFactoryGetter(storage_partition, + render_frame_host)); } void DownloadManagerImpl::BeginDownloadInternal( @@ -1060,8 +1056,8 @@ base::MakeRefCounted<BlobDownloadURLLoaderFactoryGetter>( params->url(), std::move(blob_data_handle)); } else { - url_loader_factory_getter = CreateDownloadURLLoaderFactoryGetter( - storage_partition, rfh, !params->suggested_name().empty()); + url_loader_factory_getter = + CreateDownloadURLLoaderFactoryGetter(storage_partition, rfh); } in_progress_manager_->BeginDownload(
diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h index f79ea71..b62b8ae7 100644 --- a/content/browser/download/download_manager_impl.h +++ b/content/browser/download/download_manager_impl.h
@@ -167,7 +167,6 @@ void InterceptNavigation( std::unique_ptr<network::ResourceRequest> resource_request, std::vector<GURL> url_chain, - const base::Optional<std::string>& suggested_filename, scoped_refptr<network::ResourceResponse> response, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints, net::CertStatus cert_status, @@ -254,7 +253,6 @@ ResourceRequestInfo::WebContentsGetter web_contents_getter, std::unique_ptr<network::ResourceRequest> resource_request, std::vector<GURL> url_chain, - const base::Optional<std::string>& suggested_filename, scoped_refptr<network::ResourceResponse> response, net::CertStatus cert_status, network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
diff --git a/content/browser/download/download_request_core.cc b/content/browser/download/download_request_core.cc index b7eb780..25068ec 100644 --- a/content/browser/download/download_request_core.cc +++ b/content/browser/download/download_request_core.cc
@@ -203,12 +203,6 @@ is_partial_request_ = save_info_->offset > 0; } else { save_info_.reset(new download::DownloadSaveInfo); - ResourceRequestInfoImpl* request_info = - ResourceRequestInfoImpl::ForRequest(request_); - if (request_info && request_info->suggested_filename().has_value()) { - save_info_->suggested_name = - base::UTF8ToUTF16(*request_info->suggested_filename()); - } } }
diff --git a/content/browser/frame_host/blocked_scheme_navigation_throttle.cc b/content/browser/frame_host/blocked_scheme_navigation_throttle.cc index c23c2931..48613b4 100644 --- a/content/browser/frame_host/blocked_scheme_navigation_throttle.cc +++ b/content/browser/frame_host/blocked_scheme_navigation_throttle.cc
@@ -36,12 +36,6 @@ if (handle->IsDownload()) return PROCEED; - // We treat <a download href="data:.."> and <a download href="filesystem:.."> - // as a navigation, but it will always result in a download, not a top-level - // navigation, so not blocking it here. - if (handle->GetSuggestedFilename().has_value()) - return PROCEED; - RenderFrameHost* top_frame = handle->frame_tree_node()->frame_tree()->root()->current_frame_host(); top_frame->AddMessageToConsole(
diff --git a/content/browser/frame_host/form_submission_throttle_browsertest.cc b/content/browser/frame_host/form_submission_throttle_browsertest.cc index 92ef88f54..96083c7 100644 --- a/content/browser/frame_host/form_submission_throttle_browsertest.cc +++ b/content/browser/frame_host/form_submission_throttle_browsertest.cc
@@ -73,7 +73,6 @@ false, // started_from_context_menu CSPDisposition::CHECK, // should_check_main_world_csp true, // is_form_submission - base::nullopt, // suggested_filename nullptr); // navigation_ui_data // Test the expectations with a FormSubmissionThrottle. @@ -111,7 +110,6 @@ false, // started_from_context_menu CSPDisposition::DO_NOT_CHECK, // should_check_main_world_csp true, // is_form_submission - base::nullopt, // suggested_filename nullptr); // navigation_ui_data // Test that the navigation is allowed because "should_by_pass_main_world_csp"
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc index fc4bf669..ed68927 100644 --- a/content/browser/frame_host/frame_tree_node.cc +++ b/content/browser/frame_host/frame_tree_node.cc
@@ -600,8 +600,7 @@ expected_pending_nav_entry_id = navigation_request_->navigation_handle()->pending_nav_entry_id(); } - navigator_->DiscardPendingEntryIfNeeded(expected_pending_nav_entry_id, - false /* is_download */); + navigator_->DiscardPendingEntryIfNeeded(expected_pending_nav_entry_id); } ResetNavigationRequest(false, true); }
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index 004b046..0968e48 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -809,7 +809,6 @@ entry->set_source_site_instance( static_cast<SiteInstanceImpl*>(params.source_site_instance.get())); entry->SetRedirectChain(params.redirect_chain); - entry->set_suggested_filename(params.suggested_filename); } // Set the FTN ID (only used in non-site-per-process, for tests). @@ -1922,8 +1921,7 @@ bool should_replace_current_entry, const std::string& method, scoped_refptr<network::ResourceRequestBody> post_body, - const std::string& extra_headers, - const base::Optional<std::string>& suggested_filename) { + const std::string& extra_headers) { FrameTreeNode* node = render_frame_host->frame_tree_node(); // Create a NavigationEntry for the transfer, without making it the pending // entry. Subframe transfers should have a clone of the last committed entry @@ -1963,7 +1961,6 @@ static_cast<SiteInstanceImpl*>(source_site_instance)); entry->root_node()->frame_entry->set_method(method); } - entry->set_suggested_filename(suggested_filename); // Don't allow an entry replacement if there is no entry to replace. // http://crbug.com/457149
diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h index 0897fb7e..7fc6d9d 100644 --- a/content/browser/frame_host/navigation_controller_impl.h +++ b/content/browser/frame_host/navigation_controller_impl.h
@@ -113,8 +113,7 @@ bool should_replace_current_entry, const std::string& method, scoped_refptr<network::ResourceRequestBody> post_body, - const std::string& extra_headers, - const base::Optional<std::string>& suggested_filename); + const std::string& extra_headers); void ClearAllScreenshots() override;
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index a23fbb7..fa309525 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -8097,39 +8097,4 @@ EXPECT_TRUE(capturer.is_same_document()); } -IN_PROC_BROWSER_TEST_F(ContentBrowserTest, HideDownloadFromUnmodifiedNewTab) { - GURL url("data:application/octet-stream,"); - - const NavigationControllerImpl& controller = - static_cast<const NavigationControllerImpl&>( - shell()->web_contents()->GetController()); - - { - base::ScopedAllowBlockingForTesting allow_blocking; - base::ScopedTempDir downloads_directory; - ASSERT_TRUE(downloads_directory.CreateUniqueTempDir()); - DownloadManager* download_manager = BrowserContext::GetDownloadManager( - shell()->web_contents()->GetBrowserContext()); - ShellDownloadManagerDelegate* download_delegate = - static_cast<ShellDownloadManagerDelegate*>( - download_manager->GetDelegate()); - download_delegate->SetDownloadBehaviorForTesting( - downloads_directory.GetPath()); - - DownloadTestObserverTerminal observer( - download_manager, 1, DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); - - OpenURLParams params(url, Referrer(), WindowOpenDisposition::CURRENT_TAB, - ui::PAGE_TRANSITION_LINK, true); - params.suggested_filename = std::string("foo"); - - shell()->web_contents()->OpenURL(params); - WaitForLoadStop(shell()->web_contents()); - observer.WaitForFinished(); - } - - EXPECT_FALSE(controller.GetPendingEntry()); - EXPECT_FALSE(controller.GetVisibleEntry()); -} - } // namespace content
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc index 039906c..e1012eab 100644 --- a/content/browser/frame_host/navigation_entry_impl.cc +++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -654,7 +654,6 @@ // ResetForCommit: reload_type_ copy->extra_data_ = extra_data_; copy->replaced_entry_data_ = replaced_entry_data_; - // ResetForCommit: suggested_filename_ return copy; } @@ -693,7 +692,7 @@ navigation_start, method, post_body ? post_body : post_data_, base::Optional<SourceLocation>(), CSPDisposition::CHECK /* should_check_main_world_csp */, - has_started_from_context_menu(), has_user_gesture(), suggested_filename_); + has_started_from_context_menu(), has_user_gesture()); } RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams( @@ -771,7 +770,6 @@ // loaded again in the future. set_intent_received_timestamp(base::TimeTicks()); #endif - suggested_filename_.reset(); } NavigationEntryImpl::TreeNode* NavigationEntryImpl::GetTreeNode(
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h index 5d711d1..0e1adbf 100644 --- a/content/browser/frame_host/navigation_entry_impl.h +++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -430,14 +430,6 @@ replaced_entry_data_ = data; } - const base::Optional<std::string> suggested_filename() const { - return suggested_filename_; - } - void set_suggested_filename( - const base::Optional<std::string> suggested_filename) { - suggested_filename_ = suggested_filename; - } - private: // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING // Session/Tab restore save portions of this class so that it can be recreated @@ -581,11 +573,6 @@ // why the field is listed here. base::Optional<ReplacedNavigationEntryData> replaced_entry_data_; - // If this event was triggered by an anchor element with a download - // attribute, |suggested_filename_| will contain the (possibly empty) value of - // that attribute. Reset at commit and not persisted. - base::Optional<std::string> suggested_filename_; - DISALLOW_COPY_AND_ASSIGN(NavigationEntryImpl); };
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index b0cd9e4b..df35ab90 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -118,7 +118,6 @@ bool started_from_context_menu, CSPDisposition should_check_main_world_csp, bool is_form_submission, - const base::Optional<std::string>& suggested_filename, std::unique_ptr<NavigationUIData> navigation_ui_data, const std::string& method, net::HttpRequestHeaders request_headers, @@ -133,10 +132,10 @@ url, redirect_chain, frame_tree_node, is_renderer_initiated, is_same_document, navigation_start, pending_nav_entry_id, started_from_context_menu, should_check_main_world_csp, - is_form_submission, suggested_filename, std::move(navigation_ui_data), - method, std::move(request_headers), resource_request_body, - sanitized_referrer, has_user_gesture, transition, is_external_protocol, - request_context_type, mixed_content_context_type)); + is_form_submission, std::move(navigation_ui_data), method, + std::move(request_headers), resource_request_body, sanitized_referrer, + has_user_gesture, transition, is_external_protocol, request_context_type, + mixed_content_context_type)); } NavigationHandleImpl::NavigationHandleImpl( @@ -150,7 +149,6 @@ bool started_from_context_menu, CSPDisposition should_check_main_world_csp, bool is_form_submission, - const base::Optional<std::string>& suggested_filename, std::unique_ptr<NavigationUIData> navigation_ui_data, const std::string& method, net::HttpRequestHeaders request_headers, @@ -192,7 +190,6 @@ navigation_type_(NAVIGATION_TYPE_UNKNOWN), should_check_main_world_csp_(should_check_main_world_csp), expected_render_process_host_id_(ChildProcessHost::kInvalidUniqueID), - suggested_filename_(suggested_filename), is_transferring_(false), is_form_submission_(is_form_submission), should_replace_current_entry_(false), @@ -602,11 +599,6 @@ return is_form_submission_; } -const base::Optional<std::string>& -NavigationHandleImpl::GetSuggestedFilename() { - return suggested_filename_; -} - void NavigationHandleImpl::InitServiceWorkerHandle( ServiceWorkerContextWrapper* service_worker_context) { service_worker_handle_.reset( @@ -794,16 +786,8 @@ // If the navigation is done processing the response, then it's ready to // commit. Inform observers that the navigation is now ready to commit, unless // it is not set to commit (204/205s/downloads). - if (result.action() == NavigationThrottle::PROCEED && render_frame_host_) { - CHECK(!suggested_filename_.has_value() || - !(url_.SchemeIsBlob() || url_.SchemeIsFileSystem() || - url_.SchemeIs(url::kAboutScheme) || - url_.SchemeIs(url::kDataScheme))) - << "Blob, filesystem, data, and about URLs with a suggested filename " - "should always result in a download, so we should never process a " - "navigation response here."; + if (result.action() == NavigationThrottle::PROCEED && render_frame_host_) ReadyToCommitNavigation(render_frame_host_, false); - } TRACE_EVENT_ASYNC_STEP_INTO1("navigation", "NavigationHandle", this, "ProcessResponse", "result", result.action());
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h index e2a7a8b..3e7d25f4 100644 --- a/content/browser/frame_host/navigation_handle_impl.h +++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -66,7 +66,6 @@ bool started_from_context_menu, CSPDisposition should_check_main_world_csp, bool is_form_submission, - const base::Optional<std::string>& suggested_filename, std::unique_ptr<NavigationUIData> navigation_ui_data, const std::string& method = std::string(), net::HttpRequestHeaders request_headers = net::HttpRequestHeaders(), @@ -159,7 +158,6 @@ const GlobalRequestID& GetGlobalRequestID() override; bool IsDownload() override; bool IsFormSubmission() override; - const base::Optional<std::string>& GetSuggestedFilename() override; // Resume and CancelDeferredNavigation must only be called by the // NavigationThrottle that is currently deferring the navigation. @@ -381,7 +379,6 @@ bool started_from_context_menu, CSPDisposition should_check_main_world_csp, bool is_form_submission, - const base::Optional<std::string>& suggested_filename, std::unique_ptr<NavigationUIData> navigation_ui_data, const std::string& method, net::HttpRequestHeaders request_headers, @@ -557,11 +554,6 @@ // in it. int expected_render_process_host_id_; - // If this navigation was triggered by an anchor element with a download - // attribute, the |suggested_filename_| contains the attribute's (possibly - // empty) value. - base::Optional<std::string> suggested_filename_; - // Whether the navigation is in the middle of a transfer. Set to false when // the DidStartProvisionalLoad is received from the new renderer. bool is_transferring_;
diff --git a/content/browser/frame_host/navigation_handle_impl_unittest.cc b/content/browser/frame_host/navigation_handle_impl_unittest.cc index 6d06027..e63fa54 100644 --- a/content/browser/frame_host/navigation_handle_impl_unittest.cc +++ b/content/browser/frame_host/navigation_handle_impl_unittest.cc
@@ -258,7 +258,6 @@ false, // started_from_context_menu CSPDisposition::CHECK, // should_check_main_world_csp false, // is_form_submission - base::nullopt, // suggested_filename nullptr, // navigation_ui_data "GET", net::HttpRequestHeaders(), nullptr, // resource_request_body
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index b108f913..1cf85fe 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -607,9 +607,8 @@ common_params_.navigation_start, nav_entry_id_, common_params_.started_from_context_menu, common_params_.should_check_main_world_csp, - begin_params_->is_form_submission, common_params_.suggested_filename, - std::move(navigation_ui_data_), common_params_.method, - std::move(headers), common_params_.post_data, + begin_params_->is_form_submission, std::move(navigation_ui_data_), + common_params_.method, std::move(headers), common_params_.post_data, Referrer::SanitizeForRequest(common_params_.url, common_params_.referrer), common_params_.has_user_gesture, common_params_.transition, @@ -1028,15 +1027,11 @@ if (navigation_handle_.get()) navigation_handle_->set_net_error_code(static_cast<net::Error>(net_error)); - int expected_pending_entry_id = nav_entry_id_; - bool is_download = false; - if (navigation_handle_.get()) { - expected_pending_entry_id = navigation_handle_->pending_nav_entry_id(); - is_download = navigation_handle_->IsDownload(); - } - + int expected_pending_entry_id = + navigation_handle_.get() ? navigation_handle_->pending_nav_entry_id() + : nav_entry_id_; frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded( - expected_pending_entry_id, is_download); + expected_pending_entry_id); // If the request was canceled by the user do not show an error page. if (net_error == net::ERR_ABORTED) { @@ -1350,9 +1345,8 @@ BrowserContext::GetDownloadManager(browser_context)); download_manager->InterceptNavigation( std::move(resource_request), navigation_handle_->GetRedirectChain(), - common_params_.suggested_filename, response_, - std::move(url_loader_client_endpoints_), ssl_info_.cert_status, - frame_tree_node_->frame_tree_node_id()); + response_, std::move(url_loader_client_endpoints_), + ssl_info_.cert_status, frame_tree_node_->frame_tree_node_id()); OnRequestFailed(false, net::ERR_ABORTED, base::nullopt); return;
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h index 960b0190..128bb52d 100644 --- a/content/browser/frame_host/navigator.h +++ b/content/browser/frame_host/navigator.h
@@ -141,8 +141,7 @@ WindowOpenDisposition disposition, bool should_replace_current_entry, bool user_gesture, - blink::WebTriggeringEventInfo triggering_event_info, - const base::Optional<std::string>& suggested_filename) {} + blink::WebTriggeringEventInfo triggering_event_info) {} // Called when a document requests a navigation in another document through a // RenderFrameProxy. If |method| is "POST", then |post_body| needs to specify @@ -156,8 +155,7 @@ bool should_replace_current_entry, const std::string& method, scoped_refptr<network::ResourceRequestBody> post_body, - const std::string& extra_headers, - const base::Optional<std::string>& suggested_filename) {} + const std::string& extra_headers) {} // Called after receiving a BeforeUnloadACK IPC from the renderer. If // |frame_tree_node| has a NavigationRequest waiting for the renderer @@ -211,8 +209,7 @@ // With sufficiently bad interleaving of IPCs, this may no longer be the // pending NavigationEntry, in which case the pending NavigationEntry will not // be discarded. - virtual void DiscardPendingEntryIfNeeded(int expected_pending_entry_id, - bool is_download) {} + virtual void DiscardPendingEntryIfNeeded(int expected_pending_entry_id) {} protected: friend class base::RefCounted<Navigator>;
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 799fbb8..1d1e2c43 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -237,13 +237,11 @@ } // Discard the pending navigation entry if needed. - int expected_pending_entry_id = 0; - if (render_frame_host->GetNavigationHandle()) { - expected_pending_entry_id = - render_frame_host->GetNavigationHandle()->pending_nav_entry_id(); - DCHECK(!render_frame_host->GetNavigationHandle()->IsDownload()); - } - DiscardPendingEntryIfNeeded(expected_pending_entry_id, false); + int expected_pending_entry_id = + render_frame_host->GetNavigationHandle() + ? render_frame_host->GetNavigationHandle()->pending_nav_entry_id() + : 0; + DiscardPendingEntryIfNeeded(expected_pending_entry_id); } void NavigatorImpl::DidFailLoadWithError( @@ -556,8 +554,7 @@ WindowOpenDisposition disposition, bool should_replace_current_entry, bool user_gesture, - blink::WebTriggeringEventInfo triggering_event_info, - const base::Optional<std::string>& suggested_filename) { + blink::WebTriggeringEventInfo triggering_event_info) { // Note: This can be called for subframes (even when OOPIFs are not possible) // if the disposition calls for a different window. @@ -606,7 +603,6 @@ params.should_replace_current_entry = should_replace_current_entry; params.user_gesture = user_gesture; params.triggering_event_info = triggering_event_info; - params.suggested_filename = suggested_filename; // RequestOpenURL is used only for local frames, so we can get here only if // the navigation is initiated by a frame in the same SiteInstance as this @@ -645,8 +641,7 @@ bool should_replace_current_entry, const std::string& method, scoped_refptr<network::ResourceRequestBody> post_body, - const std::string& extra_headers, - const base::Optional<std::string>& suggested_filename) { + const std::string& extra_headers) { // |method != "POST"| should imply absence of |post_body|. if (method != "POST" && post_body) { NOTREACHED(); @@ -694,7 +689,7 @@ controller_->NavigateFromFrameProxy( render_frame_host, url, is_renderer_initiated, source_site_instance, referrer_to_use, page_transition, should_replace_current_entry, method, - post_body, extra_headers, suggested_filename); + post_body, extra_headers); } void NavigatorImpl::OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, @@ -884,15 +879,14 @@ } } -void NavigatorImpl::DiscardPendingEntryIfNeeded(int expected_pending_entry_id, - bool is_download) { +void NavigatorImpl::DiscardPendingEntryIfNeeded(int expected_pending_entry_id) { // Racy conditions can cause a fail message to arrive after its corresponding // pending entry has been replaced by another navigation. If // |DiscardPendingEntry| is called in this case, then the completely valid // entry for the new navigation would be discarded. See crbug.com/513742. To // catch this case, the current pending entry is compared against the current // navigation handle's entry id, which should correspond to the failed load. - NavigationEntryImpl* pending_entry = controller_->GetPendingEntry(); + NavigationEntry* pending_entry = controller_->GetPendingEntry(); bool pending_matches_fail_msg = pending_entry && expected_pending_entry_id == pending_entry->GetUniqueID(); @@ -913,13 +907,9 @@ // allow the view to clear the pending entry and typed URL if the user // requests (e.g., hitting Escape with focus in the address bar). // - // Note that the pending entry does not need to be preserved for downloads, - // since the user is unlikely to try again. - // // Note: don't touch the transient entry, since an interstitial may exist. - bool should_preserve_entry = (controller_->IsUnmodifiedBlankTab() || - delegate_->ShouldPreserveAbortedURLs()) && - !is_download; + bool should_preserve_entry = controller_->IsUnmodifiedBlankTab() || + delegate_->ShouldPreserveAbortedURLs(); if (pending_entry != controller_->GetVisibleEntry() || !should_preserve_entry) { controller_->DiscardPendingEntry(true);
diff --git a/content/browser/frame_host/navigator_impl.h b/content/browser/frame_host/navigator_impl.h index 99aeea9e..741e7a0e 100644 --- a/content/browser/frame_host/navigator_impl.h +++ b/content/browser/frame_host/navigator_impl.h
@@ -86,8 +86,7 @@ WindowOpenDisposition disposition, bool should_replace_current_entry, bool user_gesture, - blink::WebTriggeringEventInfo triggering_event_info, - const base::Optional<std::string>& suggested_filename) override; + blink::WebTriggeringEventInfo triggering_event_info) override; void NavigateFromFrameProxy( RenderFrameHostImpl* render_frame_host, const GURL& url, @@ -97,8 +96,7 @@ bool should_replace_current_entry, const std::string& method, scoped_refptr<network::ResourceRequestBody> post_body, - const std::string& extra_headers, - const base::Optional<std::string>& suggested_filename) override; + const std::string& extra_headers) override; void OnBeforeUnloadACK(FrameTreeNode* frame_tree_node, bool proceed, const base::TimeTicks& proceed_time) override; @@ -117,8 +115,7 @@ const base::TimeTicks& renderer_before_unload_end_time) override; void CancelNavigation(FrameTreeNode* frame_tree_node, bool inform_renderer) override; - void DiscardPendingEntryIfNeeded(int expected_pending_entry_id, - bool is_download) override; + void DiscardPendingEntryIfNeeded(int expected_pending_entry_id) override; private: // Holds data used to track browser side navigation metrics.
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 3430e16..20bf6abe 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1490,7 +1490,7 @@ this, validated_url, params.uses_post, params.resource_request_body, params.extra_headers, params.referrer, params.disposition, params.should_replace_current_entry, params.user_gesture, - params.triggering_event_info, params.suggested_filename); + params.triggering_event_info); } void RenderFrameHostImpl::CancelInitialHistoryLoad() { @@ -3529,8 +3529,7 @@ GURL(), GURL(), PREVIEWS_OFF, base::TimeTicks::Now(), "GET", nullptr, base::Optional<SourceLocation>(), CSPDisposition::CHECK /* should_check_main_world_csp */, - false /* started_from_context_menu */, false /* has_user_gesture */, - base::nullopt /* suggested_filename */); + false /* started_from_context_menu */, false /* has_user_gesture */); CommitNavigation(nullptr, network::mojom::URLLoaderClientEndpointsPtr(), common_params, RequestNavigationParams(), false, base::nullopt, base::nullopt /* subresource_overrides */, @@ -3795,7 +3794,7 @@ this, false /* is_navigation */, &factory_request); // Keep DevTools proxy lasy, i.e. closest to the network. RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory( - this, false, false /* have_suggested_filename */, &factory_request); + this, false, &factory_request); factory.second->Clone(std::move(factory_request)); subresource_loader_factories->factories_info().emplace( factory.first, std::move(factory_proxy_info)); @@ -4367,7 +4366,7 @@ this, false /* is_navigation */, &default_factory_request); // Keep DevTools proxy lasy, i.e. closest to the network. RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory( - this, false, false, &default_factory_request); + this, false, &default_factory_request); StoragePartitionImpl* storage_partition = static_cast<StoragePartitionImpl*>( BrowserContext::GetStoragePartition(context, GetSiteInstance())); if (g_create_network_factory_callback_for_test.Get().is_null()) { @@ -4732,7 +4731,6 @@ false, // started_from_context_menu CSPDisposition::CHECK, // should_check_main_world_csp false, // is_form_submission - base::nullopt, // suggested_filename nullptr); // navigation_ui_data } @@ -4794,7 +4792,6 @@ false, // started_from_context_menu CSPDisposition::CHECK, // should_check_main_world_csp false, // is_form_submission - base::nullopt, // suggested_filename nullptr); // navigation_ui_data }
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 0347880f..73b66a5 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -514,12 +514,9 @@ // already updated its state properly, and doesn't need to be notified. if (speculative_render_frame_host_->GetNavigationHandle() && request.from_begin_navigation()) { - DCHECK(!speculative_render_frame_host_->GetNavigationHandle() - ->IsDownload()); frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded( speculative_render_frame_host_->GetNavigationHandle() - ->pending_nav_entry_id(), - false /* is_download */); + ->pending_nav_entry_id()); } DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); } @@ -556,12 +553,9 @@ if (speculative_render_frame_host_ && speculative_render_frame_host_->GetNavigationHandle() && request.from_begin_navigation()) { - DCHECK(!speculative_render_frame_host_->GetNavigationHandle() - ->IsDownload()); frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded( speculative_render_frame_host_->GetNavigationHandle() - ->pending_nav_entry_id(), - false /* is_download */); + ->pending_nav_entry_id()); } // If a previous speculative RenderFrameHost didn't exist or if its
diff --git a/content/browser/frame_host/render_frame_proxy_host.cc b/content/browser/frame_host/render_frame_proxy_host.cc index 6dcca03..fecf653 100644 --- a/content/browser/frame_host/render_frame_proxy_host.cc +++ b/content/browser/frame_host/render_frame_proxy_host.cc
@@ -306,7 +306,7 @@ current_rfh, validated_url, site_instance_.get(), params.referrer, ui::PAGE_TRANSITION_LINK, params.should_replace_current_entry, params.uses_post ? "POST" : "GET", params.resource_request_body, - params.extra_headers, params.suggested_filename); + params.extra_headers); } void RenderFrameProxyHost::OnCheckCompleted() {
diff --git a/content/browser/gpu/gpu_client_impl.cc b/content/browser/gpu/gpu_client_impl.cc index 2444086..a591794 100644 --- a/content/browser/gpu/gpu_client_impl.cc +++ b/content/browser/gpu/gpu_client_impl.cc
@@ -25,30 +25,30 @@ return gpu_client; } -GpuClientImpl::GpuClientImpl(int client_id) - : client_id_(client_id), weak_factory_(this) { - gpu_bindings_.set_connection_error_handler( +GpuClientImpl::GpuClientImpl(int render_process_id) + : render_process_id_(render_process_id), weak_factory_(this) { + bindings_.set_connection_error_handler( base::Bind(&GpuClientImpl::OnError, base::Unretained(this), ErrorReason::kConnectionLost)); } GpuClientImpl::~GpuClientImpl() { DCHECK_CURRENTLY_ON(BrowserThread::IO); - gpu_bindings_.CloseAllBindings(); + bindings_.CloseAllBindings(); OnError(ErrorReason::kInDestructor); } void GpuClientImpl::Add(ui::mojom::GpuRequest request) { - gpu_bindings_.AddBinding(this, std::move(request)); + bindings_.AddBinding(this, std::move(request)); } void GpuClientImpl::OnError(ErrorReason reason) { ClearCallback(); - if (gpu_bindings_.empty()) { + if (bindings_.empty()) { BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager = BrowserGpuMemoryBufferManager::current(); if (gpu_memory_buffer_manager) - gpu_memory_buffer_manager->ProcessRemoved(client_id_); + gpu_memory_buffer_manager->ProcessRemoved(render_process_id_); } if (reason == ErrorReason::kConnectionLost && connection_error_handler_) std::move(connection_error_handler_).Run(this); @@ -85,8 +85,8 @@ } if (callback) { // A request is waiting. - std::move(callback).Run(client_id_, std::move(channel_handle), gpu_info, - gpu_feature_info); + std::move(callback).Run(render_process_id_, std::move(channel_handle), + gpu_info, gpu_feature_info); return; } if (status == GpuProcessHost::EstablishChannelStatus::SUCCESS) { @@ -108,7 +108,7 @@ if (!callback_) return; EstablishGpuChannelCallback callback = std::move(callback_); - std::move(callback).Run(client_id_, mojo::ScopedMessagePipeHandle(), + std::move(callback).Run(render_process_id_, mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(), gpu::GpuFeatureInfo()); DCHECK(!callback_); } @@ -123,8 +123,8 @@ // 2) if callback is empty, it's PreEstablishGpyChannel() being called // more than once, no need to do anything. if (callback) { - std::move(callback).Run(client_id_, std::move(channel_handle_), gpu_info_, - gpu_feature_info_); + std::move(callback).Run(render_process_id_, std::move(channel_handle_), + gpu_info_, gpu_feature_info_); DCHECK(!channel_handle_.is_valid()); } return; @@ -132,8 +132,9 @@ GpuProcessHost* host = GpuProcessHost::Get(); if (!host) { if (callback) { - std::move(callback).Run(client_id_, mojo::ScopedMessagePipeHandle(), - gpu::GPUInfo(), gpu::GpuFeatureInfo()); + std::move(callback).Run(render_process_id_, + mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(), + gpu::GpuFeatureInfo()); } return; } @@ -145,8 +146,9 @@ bool allow_view_command_buffers = false; bool allow_real_time_streams = false; host->EstablishGpuChannel( - client_id_, - ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(client_id_), + render_process_id_, + ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId( + render_process_id_), preempts, allow_view_command_buffers, allow_real_time_streams, base::Bind(&GpuClientImpl::OnEstablishGpuChannel, weak_factory_.GetWeakPtr())); @@ -173,7 +175,7 @@ const gfx::Size& size, gfx::BufferFormat format, gfx::BufferUsage usage, - ui::mojom::GpuMemoryBufferFactory::CreateGpuMemoryBufferCallback callback) { + ui::mojom::Gpu::CreateGpuMemoryBufferCallback callback) { DCHECK(BrowserGpuMemoryBufferManager::current()); base::CheckedNumeric<int> bytes = size.width(); @@ -185,7 +187,7 @@ BrowserGpuMemoryBufferManager::current() ->AllocateGpuMemoryBufferForChildProcess( - id, size, format, usage, client_id_, + id, size, format, usage, render_process_id_, base::BindOnce(&GpuClientImpl::OnCreateGpuMemoryBuffer, weak_factory_.GetWeakPtr(), std::move(callback))); } @@ -195,12 +197,7 @@ DCHECK(BrowserGpuMemoryBufferManager::current()); BrowserGpuMemoryBufferManager::current()->ChildProcessDeletedGpuMemoryBuffer( - id, client_id_, sync_token); -} - -void GpuClientImpl::CreateGpuMemoryBufferFactory( - ui::mojom::GpuMemoryBufferFactoryRequest request) { - gpu_memory_buffer_factory_bindings_.AddBinding(this, std::move(request)); + id, render_process_id_, sync_token); } } // namespace content
diff --git a/content/browser/gpu/gpu_client_impl.h b/content/browser/gpu/gpu_client_impl.h index 4d518c8..03e29bf4 100644 --- a/content/browser/gpu/gpu_client_impl.h +++ b/content/browser/gpu/gpu_client_impl.h
@@ -13,9 +13,7 @@ namespace content { -class GpuClientImpl : public ui::mojom::GpuMemoryBufferFactory, - public ui::mojom::Gpu, - public GpuClient { +class GpuClientImpl : public ui::mojom::Gpu, public GpuClient { public: explicit GpuClientImpl(int render_process_id); ~GpuClientImpl() override; @@ -27,27 +25,6 @@ void SetConnectionErrorHandler( ConnectionErrorHandlerClosure connection_error_handler); - // ui::mojom::GpuMemoryBufferFactory overrides: - void CreateGpuMemoryBuffer( - gfx::GpuMemoryBufferId id, - const gfx::Size& size, - gfx::BufferFormat format, - gfx::BufferUsage usage, - ui::mojom::GpuMemoryBufferFactory::CreateGpuMemoryBufferCallback callback) - override; - void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, - const gpu::SyncToken& sync_token) override; - - // ui::mojom::Gpu overrides: - void CreateGpuMemoryBufferFactory( - ui::mojom::GpuMemoryBufferFactoryRequest request) override; - void EstablishGpuChannel(EstablishGpuChannelCallback callback) override; - void CreateJpegDecodeAccelerator( - media::mojom::JpegDecodeAcceleratorRequest jda_request) override; - void CreateVideoEncodeAcceleratorProvider( - media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request) - override; - private: enum class ErrorReason { // OnError() is being called from the destructor. @@ -64,10 +41,24 @@ const gfx::GpuMemoryBufferHandle& handle); void ClearCallback(); - const int client_id_; - mojo::BindingSet<ui::mojom::GpuMemoryBufferFactory> - gpu_memory_buffer_factory_bindings_; - mojo::BindingSet<ui::mojom::Gpu> gpu_bindings_; + // ui::mojom::Gpu overrides: + void EstablishGpuChannel(EstablishGpuChannelCallback callback) override; + void CreateJpegDecodeAccelerator( + media::mojom::JpegDecodeAcceleratorRequest jda_request) override; + void CreateVideoEncodeAcceleratorProvider( + media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request) + override; + void CreateGpuMemoryBuffer( + gfx::GpuMemoryBufferId id, + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + ui::mojom::Gpu::CreateGpuMemoryBufferCallback callback) override; + void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, + const gpu::SyncToken& sync_token) override; + + const int render_process_id_; + mojo::BindingSet<ui::mojom::Gpu> bindings_; bool gpu_channel_requested_ = false; EstablishGpuChannelCallback callback_; mojo::ScopedMessagePipeHandle channel_handle_;
diff --git a/content/browser/loader/mime_sniffing_resource_handler.cc b/content/browser/loader/mime_sniffing_resource_handler.cc index 577f62b5..305f48e6 100644 --- a/content/browser/loader/mime_sniffing_resource_handler.cc +++ b/content/browser/loader/mime_sniffing_resource_handler.cc
@@ -557,23 +557,11 @@ must_download_is_set_ = true; - bool is_cross_origin = - (request()->initiator().has_value() && - !request()->url_chain().back().SchemeIsBlob() && - !request()->url_chain().back().SchemeIsFileSystem() && - !request()->url_chain().back().SchemeIs(url::kAboutScheme) && - !request()->url_chain().back().SchemeIs(url::kDataScheme) && - request()->initiator()->GetURL() != - request()->url_chain().back().GetOrigin()); - std::string disposition; request()->GetResponseHeaderByName("content-disposition", &disposition); if (!disposition.empty() && net::HttpContentDisposition(disposition, std::string()).is_attachment()) { must_download_ = true; - } else if (GetRequestInfo()->suggested_filename().has_value() && - !is_cross_origin) { - must_download_ = true; } else if (GetContentClient()->browser()->ShouldForceDownloadResource( request()->url(), response_->head.mime_type)) { must_download_ = true; @@ -592,11 +580,6 @@ must_download_ = false; } - if (GetRequestInfo()->suggested_filename().has_value() && !must_download_) { - download::RecordDownloadCount( - download::CROSS_ORIGIN_DOWNLOAD_WITHOUT_CONTENT_DISPOSITION); - } - return must_download_; }
diff --git a/content/browser/loader/navigation_loader_util.cc b/content/browser/loader/navigation_loader_util.cc index 6a49ee5..96a7879 100644 --- a/content/browser/loader/navigation_loader_util.cc +++ b/content/browser/loader/navigation_loader_util.cc
@@ -17,9 +17,7 @@ bool MustDownload(const GURL& url, net::HttpResponseHeaders* headers, - const std::string& mime_type, - bool have_suggested_filename, - bool is_cross_origin) { + const std::string& mime_type) { if (headers) { std::string disposition; if (headers->GetNormalizedHeader("content-disposition", &disposition) && @@ -28,8 +26,6 @@ .is_attachment()) { return true; } - if (have_suggested_filename && !is_cross_origin) - return true; if (GetContentClient()->browser()->ShouldForceDownloadResource(url, mime_type)) return true; @@ -48,13 +44,9 @@ bool IsDownload(const GURL& url, net::HttpResponseHeaders* headers, - const std::string& mime_type, - bool have_suggested_filename, - bool is_cross_origin) { - if (MustDownload(url, headers, mime_type, have_suggested_filename, - is_cross_origin)) { + const std::string& mime_type) { + if (MustDownload(url, headers, mime_type)) return true; - } if (blink::IsSupportedMimeType(mime_type)) return false; @@ -62,14 +54,5 @@ return !headers || headers->response_code() / 100 == 2; } -bool IsCrossOriginRequest(const GURL& request_url, - const base::Optional<url::Origin>& initiator) { - return initiator.has_value() && !request_url.SchemeIsBlob() && - !request_url.SchemeIsFileSystem() && - !request_url.SchemeIs(url::kAboutScheme) && - !request_url.SchemeIs(url::kDataScheme) && - initiator->GetURL() != request_url.GetOrigin(); -} - } // namespace navigation_loader_util } // namespace content
diff --git a/content/browser/loader/navigation_loader_util.h b/content/browser/loader/navigation_loader_util.h index 69ae9d5..d574155 100644 --- a/content/browser/loader/navigation_loader_util.h +++ b/content/browser/loader/navigation_loader_util.h
@@ -13,9 +13,6 @@ namespace net { class HttpResponseHeaders; } -namespace url { -class Origin; -} namespace content { namespace navigation_loader_util { @@ -23,22 +20,15 @@ // Returns true if the given response must be downloaded because of the headers. bool MustDownload(const GURL& url, net::HttpResponseHeaders* headers, - const std::string& mime_type, - bool have_suggested_filename, - bool is_cross_origin); + const std::string& mime_type); // Determines whether given response would result in a download. // Note this doesn't handle the case when a plugin exists for the |mime_type|. bool IsDownload(const GURL& url, net::HttpResponseHeaders* headers, - const std::string& mime_type, - bool have_suggested_filename, - bool is_cross_origin); - -bool IsCrossOriginRequest(const GURL& request_url, - const base::Optional<url::Origin>& initiator); + const std::string& mime_type); } // namespace navigation_loader_util } // namespace content -#endif // CONTENT_BROWSER_LOADER_NAVIGATION_LOADER_UTIL_H_ \ No newline at end of file +#endif // CONTENT_BROWSER_LOADER_NAVIGATION_LOADER_UTIL_H_
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc index fcac66e..2832ad4 100644 --- a/content/browser/loader/navigation_url_loader_network_service.cc +++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -149,14 +149,6 @@ "combination of both) limits the scope of these requests." )"); -bool HasContentDispositionAttachment(const net::HttpResponseHeaders& headers) { - std::string disposition; - return headers.GetNormalizedHeader("content-disposition", &disposition) && - !disposition.empty() && - net::HttpContentDisposition(disposition, std::string()) - .is_attachment(); -} - std::unique_ptr<network::ResourceRequest> CreateResourceRequest( NavigationRequestInfo* request_info, int frame_tree_node_id, @@ -289,8 +281,6 @@ ResourceContext* resource_context, scoped_refptr<URLLoaderFactoryGetter> default_url_loader_factory_getter, const GURL& url, - base::Optional<url::Origin> initiator_origin, - base::Optional<std::string> suggested_filename, network::mojom::URLLoaderFactoryRequest proxied_factory_request, network::mojom::URLLoaderFactoryPtrInfo proxied_factory_info, std::set<std::string> known_schemes, @@ -300,8 +290,6 @@ resource_context_(resource_context), default_url_loader_factory_getter_(default_url_loader_factory_getter), url_(url), - initiator_origin_(initiator_origin), - suggested_filename_(suggested_filename), owner_(owner), response_loader_binding_(this), proxied_factory_request_(std::move(proxied_factory_request)), @@ -811,17 +799,8 @@ bool is_stream; std::unique_ptr<NavigationData> cloned_navigation_data; if (IsLoaderInterceptionEnabled()) { - DCHECK(url_chain_.empty() || url_ == url_chain_.back()); - bool is_cross_origin = - navigation_loader_util::IsCrossOriginRequest(url_, initiator_origin_); bool must_download = navigation_loader_util::MustDownload( - url_, head.headers.get(), head.mime_type, - suggested_filename_.has_value(), is_cross_origin); - if (must_download && suggested_filename_.has_value() && is_cross_origin && - (!head.headers || !HasContentDispositionAttachment(*head.headers))) { - download::RecordDownloadCount( - download::CROSS_ORIGIN_DOWNLOAD_WITHOUT_CONTENT_DISPOSITION); - } + url_, head.headers.get(), head.mime_type); bool known_mime_type = blink::IsSupportedMimeType(head.mime_type); #if BUILDFLAG(ENABLE_PLUGINS) @@ -1095,13 +1074,6 @@ // Current URL that is being navigated, updated after redirection. GURL url_; - base::Optional<url::Origin> initiator_origin_; - - // If this request was triggered by an anchor tag with a download attribute, - // the |suggested_filename_| will be the (possibly empty) value of said - // attribute. - base::Optional<std::string> suggested_filename_; - // Currently used by the AppCache loader to pass its factory to the // renderer which enables it to handle subresources. base::Optional<SubresourceLoaderParams> subresource_loader_params_; @@ -1207,8 +1179,6 @@ std::move(new_request), resource_context, /* default_url_factory_getter = */ nullptr, request_info->common_params.url, - request_info->begin_params->initiator_origin, - request_info->common_params.suggested_filename, /* proxied_url_loader_factory_request */ nullptr, /* proxied_url_loader_factory_info */ nullptr, std::set<std::string>(), weak_factory_.GetWeakPtr()); @@ -1259,9 +1229,7 @@ frame_tree_node->current_frame_host(), true /* is_navigation */, &factory_request); if (RenderFrameDevToolsAgentHost::WillCreateURLLoaderFactory( - frame_tree_node->current_frame_host(), true, - request_info->common_params.suggested_filename.has_value(), - &factory_request)) { + frame_tree_node->current_frame_host(), true, &factory_request)) { use_proxy = true; } if (use_proxy) { @@ -1285,8 +1253,6 @@ request_controller_ = std::make_unique<URLLoaderRequestController>( std::move(initial_interceptors), std::move(new_request), resource_context, partition->url_loader_factory_getter(), request_info->common_params.url, - request_info->begin_params->initiator_origin, - request_info->common_params.suggested_filename, std::move(proxied_factory_request), std::move(proxied_factory_info), std::move(known_schemes), weak_factory_.GetWeakPtr()); BrowserThread::PostTask(
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index 2baf6b5..c2f29f6 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1050,8 +1050,7 @@ request_data.referrer_policy), request_data.is_prerendering, resource_context, report_raw_headers, !is_sync_load, request_data.previews_state, request_data.request_body, - request_data.initiated_in_secure_context, - base::nullopt); // suggested_filename + request_data.initiated_in_secure_context); extra_info->SetBlobHandles(std::move(blob_handles)); // Request takes ownership. @@ -1308,8 +1307,7 @@ true, // is_async previews_state, // previews_state nullptr, // body - false, // initiated_in_secure_context - base::nullopt); // suggested_filename + false); // initiated_in_secure_context } void ResourceDispatcherHostImpl::OnRenderViewHostCreated( @@ -1690,8 +1688,7 @@ // subresource requests, so it doesn't matter what value it gets here. // If in the future this changes this should be updated to somehow get a // meaningful value. - false, // initiated_in_secure_context - info.common_params.suggested_filename); // suggested_filename + false); // initiated_in_secure_context extra_info->SetBlobHandles(std::move(blob_handles)); extra_info->set_navigation_ui_data(std::move(navigation_ui_data));
diff --git a/content/browser/loader/resource_request_info_impl.cc b/content/browser/loader/resource_request_info_impl.cc index 36ffa04..4714491 100644 --- a/content/browser/loader/resource_request_info_impl.cc +++ b/content/browser/loader/resource_request_info_impl.cc
@@ -84,8 +84,7 @@ is_async, // is_async previews_state, // previews_state nullptr, // body - false, // initiated_in_secure_context - base::nullopt); // suggested_filename + false); // initiated_in_secure_context info->AssociateWithRequest(request); info->set_navigation_ui_data(std::move(navigation_ui_data)); } @@ -152,8 +151,7 @@ bool is_async, PreviewsState previews_state, const scoped_refptr<network::ResourceRequestBody> body, - bool initiated_in_secure_context, - const base::Optional<std::string>& suggested_filename) + bool initiated_in_secure_context) : detachable_handler_(nullptr), requester_info_(std::move(requester_info)), route_id_(route_id), @@ -183,7 +181,6 @@ previews_state_(previews_state), body_(body), initiated_in_secure_context_(initiated_in_secure_context), - suggested_filename_(suggested_filename), blocked_cross_site_document_(false), first_auth_attempt_(true) {}
diff --git a/content/browser/loader/resource_request_info_impl.h b/content/browser/loader/resource_request_info_impl.h index 93f3018..e9b9745 100644 --- a/content/browser/loader/resource_request_info_impl.h +++ b/content/browser/loader/resource_request_info_impl.h
@@ -69,8 +69,7 @@ bool is_async, PreviewsState previews_state, const scoped_refptr<network::ResourceRequestBody> body, - bool initiated_in_secure_context, - const base::Optional<std::string>& suggested_filename); + bool initiated_in_secure_context); ~ResourceRequestInfoImpl() override; // ResourceRequestInfo implementation: @@ -181,10 +180,6 @@ void SetBlobHandles(BlobHandles blob_handles); - const base::Optional<std::string>& suggested_filename() const { - return suggested_filename_; - } - bool blocked_cross_site_document() const { return blocked_cross_site_document_; } @@ -239,7 +234,6 @@ scoped_refptr<network::ResourceRequestBody> body_; bool initiated_in_secure_context_; std::unique_ptr<NavigationUIData> navigation_ui_data_; - base::Optional<std::string> suggested_filename_; bool blocked_cross_site_document_; bool first_auth_attempt_;
diff --git a/content/browser/media/audio_input_stream_broker.cc b/content/browser/media/audio_input_stream_broker.cc new file mode 100644 index 0000000..d4bbd8c --- /dev/null +++ b/content/browser/media/audio_input_stream_broker.cc
@@ -0,0 +1,161 @@ +// 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 "content/browser/media/audio_input_stream_broker.h" + +#include <utility> + +#include "base/command_line.h" +#include "content/browser/browser_main_loop.h" +#include "content/browser/media/media_internals.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/content_browser_client.h" +#include "content/public/browser/media_observer.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/common/content_client.h" +#include "media/audio/audio_logging.h" +#include "media/base/media_switches.h" +#include "mojo/public/cpp/system/platform_handle.h" + +#if defined(OS_CHROMEOS) +#include "content/browser/media/keyboard_mic_registration.h" +#endif + +namespace content { + +AudioInputStreamBroker::AudioInputStreamBroker( + int render_process_id, + int render_frame_id, + const std::string& device_id, + const media::AudioParameters& params, + uint32_t shared_memory_count, + bool enable_agc, + AudioStreamBroker::DeleterCallback deleter, + mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client) + : AudioStreamBroker(render_process_id, render_frame_id), + device_id_(device_id), + params_(params), + shared_memory_count_(shared_memory_count), + enable_agc_(enable_agc), + deleter_(std::move(deleter)), + renderer_factory_client_(std::move(renderer_factory_client)), + observer_binding_(this), + weak_ptr_factory_(this) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(renderer_factory_client_); + DCHECK(deleter_); + + // Unretained is safe because |this| owns |renderer_factory_client_|. + renderer_factory_client_.set_connection_error_handler( + base::BindOnce(&AudioInputStreamBroker::Cleanup, base::Unretained(this))); + + // Notify RenderProcessHost about input stream so the renderer is not + // background. + auto* process_host = RenderProcessHost::FromID(render_process_id); + if (process_host) + process_host->OnMediaStreamAdded(); + + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kUseFakeDeviceForMediaStream)) { + params_.set_format(media::AudioParameters::AUDIO_FAKE); + } + +#if defined(OS_CHROMEOS) + if (params_.channel_layout() == + media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) { + BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance(); + + // May be null in unit tests. + if (browser_main_loop) + browser_main_loop->keyboard_mic_registration()->Register(); + } +#endif +} + +AudioInputStreamBroker::~AudioInputStreamBroker() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + +#if defined(OS_CHROMEOS) + if (params_.channel_layout() == + media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC) { + BrowserMainLoop* browser_main_loop = BrowserMainLoop::GetInstance(); + + // May be null in unit tests. + if (browser_main_loop) + browser_main_loop->keyboard_mic_registration()->Deregister(); + } +#endif + + auto* process_host = RenderProcessHost::FromID(render_process_id()); + if (process_host) + process_host->OnMediaStreamRemoved(); + + // TODO(https://crbug.com/829317) update tab recording indicator. +} + +void AudioInputStreamBroker::CreateStream( + audio::mojom::StreamFactory* factory) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(!observer_binding_.is_bound()); + DCHECK(!client_request_); + + media::mojom::AudioInputStreamClientPtr client; + client_request_ = mojo::MakeRequest(&client); + + media::mojom::AudioInputStreamPtr stream; + media::mojom::AudioInputStreamRequest stream_request = + mojo::MakeRequest(&stream); + + media::mojom::AudioInputStreamObserverPtr observer_ptr; + observer_binding_.Bind(mojo::MakeRequest(&observer_ptr)); + + // Unretained is safe because |this| owns |observer_binding_|. + observer_binding_.set_connection_error_handler( + base::BindOnce(&AudioInputStreamBroker::Cleanup, base::Unretained(this))); + + // Note that the component id for AudioLog is used to differentiate between + // several users of the same audio log. Since this audio log is for a single + // stream, the component id used doesn't matter. + // TODO(https://crbug.com/836226) pass valid user input monitor handle when + // switching to audio service input streams. + constexpr int log_component_id = 0; + factory->CreateInputStream( + std::move(stream_request), std::move(client), std::move(observer_ptr), + MediaInternals::GetInstance()->CreateMojoAudioLog( + media::AudioLogFactory::AudioComponent::AUDIO_INPUT_CONTROLLER, + log_component_id, render_process_id(), render_frame_id()), + device_id_, params_, shared_memory_count_, enable_agc_, + mojo::ScopedSharedBufferHandle(), + base::BindOnce(&AudioInputStreamBroker::StreamCreated, + weak_ptr_factory_.GetWeakPtr(), std::move(stream))); +} + +void AudioInputStreamBroker::DidStartRecording() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + // TODO(https://crbug.com/829317) update tab recording indicator. +} + +void AudioInputStreamBroker::StreamCreated( + media::mojom::AudioInputStreamPtr stream, + media::mojom::AudioDataPipePtr data_pipe, + bool initially_muted) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + if (!data_pipe) { + Cleanup(); + return; + } + + DCHECK(renderer_factory_client_); + renderer_factory_client_->StreamCreated( + std::move(stream), std::move(client_request_), std::move(data_pipe), + initially_muted); +} + +void AudioInputStreamBroker::Cleanup() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + std::move(deleter_).Run(this); +} + +} // namespace content
diff --git a/content/browser/media/audio_input_stream_broker.h b/content/browser/media/audio_input_stream_broker.h new file mode 100644 index 0000000..4697479 --- /dev/null +++ b/content/browser/media/audio_input_stream_broker.h
@@ -0,0 +1,70 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_MEDIA_AUDIO_INPUT_STREAM_BROKER_H_ +#define CONTENT_BROWSER_MEDIA_AUDIO_INPUT_STREAM_BROKER_H_ + +#include <string> + +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "content/browser/media/audio_stream_broker.h" +#include "content/common/content_export.h" +#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" +#include "media/base/audio_parameters.h" +#include "media/mojo/interfaces/audio_input_stream.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/audio/public/mojom/stream_factory.mojom.h" + +namespace content { + +// AudioInputStreamBroker is used to broker a connection between a client +// (typically renderer) and the audio service. It is operated on the UI thread. +class CONTENT_EXPORT AudioInputStreamBroker final + : public AudioStreamBroker, + public media::mojom::AudioInputStreamObserver { + public: + AudioInputStreamBroker( + int render_process_id, + int render_frame_id, + const std::string& device_id, + const media::AudioParameters& params, + uint32_t shared_memory_count, + bool enable_agc, + AudioStreamBroker::DeleterCallback deleter, + mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client); + + ~AudioInputStreamBroker() final; + + // Creates the stream. + void CreateStream(audio::mojom::StreamFactory* factory) final; + + // media::AudioInputStreamObserver implementation. + void DidStartRecording() final; + + private: + void StreamCreated(media::mojom::AudioInputStreamPtr stream, + media::mojom::AudioDataPipePtr data_pipe, + bool initially_muted); + void Cleanup(); + + const std::string device_id_; + media::AudioParameters params_; + const uint32_t shared_memory_count_; + const bool enable_agc_; + + DeleterCallback deleter_; + + mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client_; + mojo::Binding<AudioInputStreamObserver> observer_binding_; + media::mojom::AudioInputStreamClientRequest client_request_; + + base::WeakPtrFactory<AudioInputStreamBroker> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(AudioInputStreamBroker); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_MEDIA_AUDIO_INPUT_STREAM_BROKER_H_
diff --git a/content/browser/media/audio_input_stream_broker_unittest.cc b/content/browser/media/audio_input_stream_broker_unittest.cc new file mode 100644 index 0000000..1d078d3 --- /dev/null +++ b/content/browser/media/audio_input_stream_broker_unittest.cc
@@ -0,0 +1,296 @@ +// 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 "content/browser/media/audio_input_stream_broker.h" + +#include <memory> +#include <utility> + +#include "base/sync_socket.h" +#include "base/test/mock_callback.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "media/mojo/interfaces/audio_input_stream.mojom.h" +#include "mojo/public/cpp/system/platform_handle.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::Test; +using ::testing::Mock; +using ::testing::StrictMock; +using ::testing::InSequence; + +namespace content { + +namespace { + +const int kRenderProcessId = 123; +const int kRenderFrameId = 234; +const uint32_t kShMemCount = 10; +const bool kEnableAgc = false; +const char kDeviceId[] = "testdeviceid"; +const bool kInitiallyMuted = false; + +media::AudioParameters TestParams() { + return media::AudioParameters::UnavailableDeviceParams(); +} + +using MockDeleterCallback = StrictMock< + base::MockCallback<base::OnceCallback<void(AudioStreamBroker*)>>>; + +class MockRendererAudioInputStreamFactoryClient + : public mojom::RendererAudioInputStreamFactoryClient { + public: + MockRendererAudioInputStreamFactoryClient() : binding_(this) {} + ~MockRendererAudioInputStreamFactoryClient() override {} + + mojom::RendererAudioInputStreamFactoryClientPtr MakePtr() { + mojom::RendererAudioInputStreamFactoryClientPtr ret; + binding_.Bind(mojo::MakeRequest(&ret)); + return ret; + } + + MOCK_METHOD0(OnStreamCreated, void()); + + void StreamCreated(media::mojom::AudioInputStreamPtr input_stream, + media::mojom::AudioInputStreamClientRequest client_request, + media::mojom::AudioDataPipePtr data_pipe, + bool initially_muted) override { + input_stream_ = std::move(input_stream); + client_request_ = std::move(client_request); + OnStreamCreated(); + } + + void CloseBinding() { binding_.Close(); } + + private: + mojo::Binding<mojom::RendererAudioInputStreamFactoryClient> binding_; + media::mojom::AudioInputStreamPtr input_stream_; + media::mojom::AudioInputStreamClientRequest client_request_; +}; + +class MockStreamFactory : public audio::mojom::StreamFactory { + public: + MockStreamFactory() : binding_(this) {} + ~MockStreamFactory() final {} + + audio::mojom::StreamFactoryPtr MakePtr() { + audio::mojom::StreamFactoryPtr ret; + binding_.Bind(mojo::MakeRequest(&ret)); + return ret; + } + + void CloseBinding() { binding_.Close(); } + + // State of an expected stream creation. |device_id| and |params| are set + // ahead of time and verified during request. The other fields are filled in + // when the request is received. + struct StreamRequestData { + StreamRequestData(const std::string& device_id, + const media::AudioParameters& params) + : device_id(device_id), params(params) {} + + bool requested = false; + media::mojom::AudioInputStreamRequest stream_request; + media::mojom::AudioInputStreamClientPtr client; + media::mojom::AudioInputStreamObserverPtr observer; + media::mojom::AudioLogPtr log; + const std::string device_id; + const media::AudioParameters params; + uint32_t shared_memory_count; + bool enable_agc; + mojo::ScopedSharedBufferHandle key_press_count_buffer; + CreateInputStreamCallback created_callback; + }; + + void ExpectStreamCreation(StreamRequestData* ex) { + stream_request_data_ = ex; + } + + private: + void CreateInputStream(media::mojom::AudioInputStreamRequest stream_request, + media::mojom::AudioInputStreamClientPtr client, + media::mojom::AudioInputStreamObserverPtr observer, + media::mojom::AudioLogPtr log, + const std::string& device_id, + const media::AudioParameters& params, + uint32_t shared_memory_count, + bool enable_agc, + mojo::ScopedSharedBufferHandle key_press_count_buffer, + CreateInputStreamCallback created_callback) final { + // No way to cleanly exit the test here in case of failure, so use CHECK. + CHECK(stream_request_data_); + EXPECT_EQ(stream_request_data_->device_id, device_id); + EXPECT_TRUE(stream_request_data_->params.Equals(params)); + stream_request_data_->requested = true; + stream_request_data_->stream_request = std::move(stream_request); + stream_request_data_->client = std::move(client); + stream_request_data_->observer = std::move(observer); + stream_request_data_->log = std::move(log); + stream_request_data_->shared_memory_count = shared_memory_count; + stream_request_data_->enable_agc = enable_agc; + stream_request_data_->key_press_count_buffer = + std::move(key_press_count_buffer); + stream_request_data_->created_callback = std::move(created_callback); + } + + void CreateOutputStream( + media::mojom::AudioOutputStreamRequest stream_request, + media::mojom::AudioOutputStreamObserverAssociatedPtrInfo observer_info, + media::mojom::AudioLogPtr log, + const std::string& output_device_id, + const media::AudioParameters& params, + const base::UnguessableToken& group_id, + CreateOutputStreamCallback created_callback) final { + ADD_FAILURE() << "Unexpected output stream creation in input test."; + } + + void BindMuter(audio::mojom::LocalMuterAssociatedRequest request, + const base::UnguessableToken& group_id) final { + ADD_FAILURE() << "Unexpected muting in input stream test"; + } + + mojo::Binding<audio::mojom::StreamFactory> binding_; + StreamRequestData* stream_request_data_; +}; + +struct TestEnvironment { + TestEnvironment() + : broker(std::make_unique<AudioInputStreamBroker>( + kRenderProcessId, + kRenderFrameId, + kDeviceId, + TestParams(), + kShMemCount, + kEnableAgc, + deleter.Get(), + renderer_factory_client.MakePtr())) {} + + void RunUntilIdle() { thread_bundle.RunUntilIdle(); } + + TestBrowserThreadBundle thread_bundle; + MockDeleterCallback deleter; + StrictMock<MockRendererAudioInputStreamFactoryClient> renderer_factory_client; + std::unique_ptr<AudioInputStreamBroker> broker; + MockStreamFactory stream_factory; + audio::mojom::StreamFactoryPtr factory_ptr = stream_factory.MakePtr(); +}; + +} // namespace + +TEST(AudioInputStreamBrokerTest, StoresProcessAndFrameId) { + TestBrowserThreadBundle thread_bundle; + MockDeleterCallback deleter; + StrictMock<MockRendererAudioInputStreamFactoryClient> renderer_factory_client; + + AudioInputStreamBroker broker( + kRenderProcessId, kRenderFrameId, kDeviceId, TestParams(), kShMemCount, + kEnableAgc, deleter.Get(), renderer_factory_client.MakePtr()); + + EXPECT_EQ(kRenderProcessId, broker.render_process_id()); + EXPECT_EQ(kRenderFrameId, broker.render_frame_id()); +} + +TEST(AudioInputStreamBrokerTest, StreamCreationSuccess_Propagates) { + TestEnvironment env; + MockStreamFactory::StreamRequestData stream_request_data(kDeviceId, + TestParams()); + env.stream_factory.ExpectStreamCreation(&stream_request_data); + + env.broker->CreateStream(env.factory_ptr.get()); + env.RunUntilIdle(); + + EXPECT_TRUE(stream_request_data.requested); + + // Set up test IPC primitives. + const size_t shmem_size = 456; + base::SyncSocket socket1, socket2; + base::SyncSocket::CreatePair(&socket1, &socket2); + std::move(stream_request_data.created_callback) + .Run({base::in_place, mojo::SharedBufferHandle::Create(shmem_size), + mojo::WrapPlatformFile(socket1.Release())}, + kInitiallyMuted); + + EXPECT_CALL(env.renderer_factory_client, OnStreamCreated()); + + env.RunUntilIdle(); + + Mock::VerifyAndClear(&env.renderer_factory_client); + + env.broker.reset(); +} + +TEST(AudioInputStreamBrokerTest, StreamCreationFailure_CallsDeleter) { + TestEnvironment env; + MockStreamFactory::StreamRequestData stream_request_data(kDeviceId, + TestParams()); + env.stream_factory.ExpectStreamCreation(&stream_request_data); + + env.broker->CreateStream(env.factory_ptr.get()); + env.RunUntilIdle(); + + EXPECT_TRUE(stream_request_data.requested); + EXPECT_CALL(env.deleter, Run(env.broker.release())) + .WillOnce(testing::DeleteArg<0>()); + + std::move(stream_request_data.created_callback).Run(nullptr, kInitiallyMuted); + + env.RunUntilIdle(); +} + +TEST(AudioInputStreamBrokerTest, RendererFactoryClientDisconnect_CallsDeleter) { + InSequence seq; + TestEnvironment env; + MockStreamFactory::StreamRequestData stream_request_data(kDeviceId, + TestParams()); + env.stream_factory.ExpectStreamCreation(&stream_request_data); + + env.broker->CreateStream(env.factory_ptr.get()); + env.RunUntilIdle(); + EXPECT_TRUE(stream_request_data.requested); + + EXPECT_CALL(env.deleter, Run(env.broker.release())) + .WillOnce(testing::DeleteArg<0>()); + env.renderer_factory_client.CloseBinding(); + env.RunUntilIdle(); + Mock::VerifyAndClear(&env.deleter); + + env.stream_factory.CloseBinding(); + env.RunUntilIdle(); +} + +TEST(AudioInputStreamBrokerTest, ObserverDisconnect_CallsDeleter) { + InSequence seq; + TestEnvironment env; + MockStreamFactory::StreamRequestData stream_request_data(kDeviceId, + TestParams()); + env.stream_factory.ExpectStreamCreation(&stream_request_data); + + env.broker->CreateStream(env.factory_ptr.get()); + env.RunUntilIdle(); + EXPECT_TRUE(stream_request_data.requested); + + EXPECT_CALL(env.deleter, Run(env.broker.release())) + .WillOnce(testing::DeleteArg<0>()); + stream_request_data.observer.reset(); + env.RunUntilIdle(); + Mock::VerifyAndClear(&env.deleter); + + env.stream_factory.CloseBinding(); + env.RunUntilIdle(); +} + +TEST(AudioInputStreamBrokerTest, + FactoryDisconnectDuringConstruction_CallsDeleter) { + TestEnvironment env; + + env.broker->CreateStream(env.factory_ptr.get()); + env.stream_factory.CloseBinding(); + + EXPECT_CALL(env.deleter, Run(env.broker.release())) + .WillOnce(testing::DeleteArg<0>()); + + env.RunUntilIdle(); +} + +} // namespace content
diff --git a/content/browser/media/audio_output_stream_broker.cc b/content/browser/media/audio_output_stream_broker.cc index c32c664..72dab68 100644 --- a/content/browser/media/audio_output_stream_broker.cc +++ b/content/browser/media/audio_output_stream_broker.cc
@@ -113,6 +113,7 @@ } void AudioOutputStreamBroker::Cleanup() { + DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_); std::move(deleter_).Run(this); }
diff --git a/content/browser/media/audio_output_stream_broker_unittest.cc b/content/browser/media/audio_output_stream_broker_unittest.cc index e4d0f26..4b94dca 100644 --- a/content/browser/media/audio_output_stream_broker_unittest.cc +++ b/content/browser/media/audio_output_stream_broker_unittest.cc
@@ -169,8 +169,7 @@ TestParams(), group, deleter.Get(), - provider_client.MakePtr())), - factory_ptr(stream_factory.MakePtr()) {} + provider_client.MakePtr())) {} void RunUntilIdle() { env.RunUntilIdle(); }
diff --git a/content/browser/media/audio_stream_broker.cc b/content/browser/media/audio_stream_broker.cc index 82dc1908..abe535a 100644 --- a/content/browser/media/audio_stream_broker.cc +++ b/content/browser/media/audio_stream_broker.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "content/browser/media/audio_input_stream_broker.h" #include "content/browser/media/audio_output_stream_broker.h" namespace content { @@ -17,6 +18,22 @@ AudioStreamBrokerFactoryImpl() = default; ~AudioStreamBrokerFactoryImpl() final = default; + std::unique_ptr<AudioStreamBroker> CreateAudioInputStreamBroker( + int render_process_id, + int render_frame_id, + const std::string& device_id, + const media::AudioParameters& params, + uint32_t shared_memory_count, + bool enable_agc, + AudioStreamBroker::DeleterCallback deleter, + mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client) + final { + return std::make_unique<AudioInputStreamBroker>( + render_process_id, render_frame_id, device_id, params, + shared_memory_count, enable_agc, std::move(deleter), + std::move(renderer_factory_client)); + } + std::unique_ptr<AudioStreamBroker> CreateAudioOutputStreamBroker( int render_process_id, int render_frame_id,
diff --git a/content/browser/media/audio_stream_broker.h b/content/browser/media/audio_stream_broker.h index 6636907..29e3079 100644 --- a/content/browser/media/audio_stream_broker.h +++ b/content/browser/media/audio_stream_broker.h
@@ -11,6 +11,8 @@ #include "base/callback.h" #include "base/macros.h" #include "content/common/content_export.h" +#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" +#include "media/mojo/interfaces/audio_input_stream.mojom.h" #include "media/mojo/interfaces/audio_output_stream.mojom.h" namespace audio { @@ -60,6 +62,17 @@ AudioStreamBrokerFactory(); virtual ~AudioStreamBrokerFactory(); + virtual std::unique_ptr<AudioStreamBroker> CreateAudioInputStreamBroker( + int render_process_id, + int render_frame_id, + const std::string& device_id, + const media::AudioParameters& params, + uint32_t shared_memory_count, + bool enable_agc, + AudioStreamBroker::DeleterCallback deleter, + mojom::RendererAudioInputStreamFactoryClientPtr + renderer_factory_client) = 0; + virtual std::unique_ptr<AudioStreamBroker> CreateAudioOutputStreamBroker( int render_process_id, int render_frame_id,
diff --git a/content/browser/media/forwarding_audio_stream_factory.cc b/content/browser/media/forwarding_audio_stream_factory.cc index 64fbc59..e94f4b3 100644 --- a/content/browser/media/forwarding_audio_stream_factory.cc +++ b/content/browser/media/forwarding_audio_stream_factory.cc
@@ -23,7 +23,8 @@ std::unique_ptr<AudioStreamBrokerFactory> broker_factory) : WebContentsObserver(web_contents), connector_(std::move(connector)), - broker_factory_(std::move(broker_factory)) { + broker_factory_(std::move(broker_factory)), + group_id_(base::UnguessableToken::Create()) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK(web_contents); DCHECK(broker_factory_); @@ -33,6 +34,28 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); } +void ForwardingAudioStreamFactory::CreateInputStream( + RenderFrameHost* frame, + const std::string& device_id, + const media::AudioParameters& params, + uint32_t shared_memory_count, + bool enable_agc, + mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + const int process_id = frame->GetProcess()->GetID(); + const int frame_id = frame->GetRoutingID(); + inputs_ + .insert(broker_factory_->CreateAudioInputStreamBroker( + process_id, frame_id, device_id, params, shared_memory_count, + enable_agc, + base::BindOnce(&ForwardingAudioStreamFactory::RemoveInput, + base::Unretained(this)), + std::move(renderer_factory_client))) + .first->get() + ->CreateStream(GetFactory()); +} + void ForwardingAudioStreamFactory::CreateOutputStream( RenderFrameHost* frame, const std::string& device_id, @@ -70,6 +93,7 @@ void ForwardingAudioStreamFactory::WebContentsDestroyed() { DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(inputs_.empty()); DCHECK(outputs_.empty()); } @@ -85,11 +109,20 @@ broker->render_frame_id() == frame_id; }; + base::EraseIf(inputs_, match_rfh); base::EraseIf(outputs_, match_rfh); ResetRemoteFactoryPtrIfIdle(); } +void ForwardingAudioStreamFactory::RemoveInput(AudioStreamBroker* broker) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + size_t removed = inputs_.erase(broker); + DCHECK_EQ(1u, removed); + + ResetRemoteFactoryPtrIfIdle(); +} + void ForwardingAudioStreamFactory::RemoveOutput(AudioStreamBroker* broker) { DCHECK_CURRENTLY_ON(BrowserThread::UI); size_t removed = outputs_.erase(broker); @@ -114,13 +147,14 @@ void ForwardingAudioStreamFactory::ResetRemoteFactoryPtrIfIdle() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (outputs_.empty()) + if (inputs_.empty() && outputs_.empty()) remote_factory_.reset(); } void ForwardingAudioStreamFactory::ResetRemoteFactoryPtr() { DCHECK_CURRENTLY_ON(BrowserThread::UI); remote_factory_.reset(); + inputs_.clear(); outputs_.clear(); }
diff --git a/content/browser/media/forwarding_audio_stream_factory.h b/content/browser/media/forwarding_audio_stream_factory.h index 6aef571..fce7320d 100644 --- a/content/browser/media/forwarding_audio_stream_factory.h +++ b/content/browser/media/forwarding_audio_stream_factory.h
@@ -11,8 +11,10 @@ #include "base/containers/flat_set.h" #include "base/containers/unique_ptr_adapters.h" #include "base/macros.h" +#include "base/unguessable_token.h" #include "content/browser/media/audio_stream_broker.h" #include "content/common/content_export.h" +#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "content/public/browser/web_contents_observer.h" #include "services/audio/public/mojom/stream_factory.mojom.h" @@ -41,9 +43,19 @@ ~ForwardingAudioStreamFactory() final; - // TODO(https://crbug.com/803102): Add input streams, loopback, and muting. + const base::UnguessableToken& group_id() { return group_id_; } + + // TODO(https://crbug.com/803102): Add loopback and muting streams. // TODO(https://crbug.com/787806): Automatically restore streams on audio // service restart. + void CreateInputStream( + RenderFrameHost* frame, + const std::string& device_id, + const media::AudioParameters& params, + uint32_t shared_memory_count, + bool enable_agc, + mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client); + void CreateOutputStream( RenderFrameHost* frame, const std::string& device_id, @@ -62,6 +74,7 @@ void CleanupStreamsBelongingTo(RenderFrameHost* render_frame_host); + void RemoveInput(AudioStreamBroker* handle); void RemoveOutput(AudioStreamBroker* handle); audio::mojom::StreamFactory* GetFactory(); @@ -71,6 +84,11 @@ const std::unique_ptr<service_manager::Connector> connector_; const std::unique_ptr<AudioStreamBrokerFactory> broker_factory_; + // Unique id indentifying all streams belonging to the WebContents owning + // |this|. + // TODO(https://crbug.com/824019): Use this for loopback. + const base::UnguessableToken group_id_; + // Lazily acquired. Reset on connection error and when we no longer have any // streams. Note: we don't want muting to force the connection to be open, // since we want to clean up the service when not in use. If we have active @@ -84,6 +102,7 @@ // remove it. int stream_id_counter_ = 0; + StreamBrokerSet inputs_; StreamBrokerSet outputs_; DISALLOW_COPY_AND_ASSIGN(ForwardingAudioStreamFactory);
diff --git a/content/browser/media/forwarding_audio_stream_factory_unittest.cc b/content/browser/media/forwarding_audio_stream_factory_unittest.cc index 9ce1c4c..2d47c7d 100644 --- a/content/browser/media/forwarding_audio_stream_factory_unittest.cc +++ b/content/browser/media/forwarding_audio_stream_factory_unittest.cc
@@ -11,8 +11,8 @@ #include "base/bind_helpers.h" #include "base/macros.h" #include "base/test/mock_callback.h" -#include "base/test/scoped_task_environment.h" #include "base/unguessable_token.h" +#include "content/common/media/renderer_audio_input_stream_factory.mojom.h" #include "content/public/browser/render_process_host.h" #include "content/public/test/test_renderer_host.h" #include "media/base/audio_parameters.h" @@ -33,6 +33,8 @@ namespace content { +namespace { + class MockBroker : public AudioStreamBroker { public: explicit MockBroker(RenderFrameHost* rfh) @@ -46,8 +48,6 @@ // Can be used to verify that |this| has been destructed. base::WeakPtr<MockBroker> GetWeakPtr() { return weak_factory_.GetWeakPtr(); } - int stream_id; - base::UnguessableToken group_id; DeleterCallback deleter; private: @@ -58,14 +58,40 @@ public: MockBrokerFactory() {} ~MockBrokerFactory() final { + EXPECT_TRUE(prepared_input_stream_brokers_.empty()) + << "Input broker creation was expected but didn't happen"; EXPECT_TRUE(prepared_output_stream_brokers_.empty()) - << "Broker creation was expected but didn't happen"; + << "Output broker creation was expected but didn't happen"; + } + + void ExpectInputStreamBrokerCreation(std::unique_ptr<MockBroker> broker) { + prepared_input_stream_brokers_.push(std::move(broker)); } void ExpectOutputStreamBrokerCreation(std::unique_ptr<MockBroker> broker) { prepared_output_stream_brokers_.push(std::move(broker)); } + std::unique_ptr<AudioStreamBroker> CreateAudioInputStreamBroker( + int render_process_id, + int render_frame_id, + const std::string& device_id, + const media::AudioParameters& params, + uint32_t shared_memory_count, + bool enable_agc, + AudioStreamBroker::DeleterCallback deleter, + mojom::RendererAudioInputStreamFactoryClientPtr renderer_factory_client) + final { + std::unique_ptr<MockBroker> prepared_broker = + std::move(prepared_input_stream_brokers_.front()); + prepared_input_stream_brokers_.pop(); + CHECK_NE(nullptr, prepared_broker.get()); + EXPECT_EQ(render_process_id, prepared_broker->render_process_id()); + EXPECT_EQ(render_frame_id, prepared_broker->render_frame_id()); + prepared_broker->deleter = std::move(deleter); + return std::move(prepared_broker); + } + std::unique_ptr<AudioStreamBroker> CreateAudioOutputStreamBroker( int render_process_id, int render_frame_id, @@ -81,13 +107,12 @@ CHECK_NE(nullptr, prepared_broker.get()); EXPECT_EQ(render_process_id, prepared_broker->render_process_id()); EXPECT_EQ(render_frame_id, prepared_broker->render_frame_id()); - prepared_broker->stream_id = stream_id; - prepared_broker->group_id = group_id; prepared_broker->deleter = std::move(deleter); return std::move(prepared_broker); } private: + base::queue<std::unique_ptr<MockBroker>> prepared_input_stream_brokers_; base::queue<std::unique_ptr<MockBroker>> prepared_output_stream_brokers_; }; @@ -111,13 +136,21 @@ RenderViewHostTestHarness::SetUp(); RenderFrameHostTester::For(main_rfh())->InitializeRenderFrameIfNeeded(); other_rfh_ = - RenderFrameHostTester::For(main_rfh())->AppendChild("sderfdgijho"); + RenderFrameHostTester::For(main_rfh())->AppendChild("other_rfh"); } void SetPendingFactoryRequest(mojo::ScopedMessagePipeHandle factory_request) { pending_factory_request_ = std::move(factory_request); } + base::WeakPtr<MockBroker> ExpectInputBrokerConstruction( + RenderFrameHost* rfh) { + auto broker = std::make_unique<StrictMock<MockBroker>>(rfh); + auto weak_broker = broker->GetWeakPtr(); + broker_factory_->ExpectInputStreamBrokerCreation(std::move(broker)); + return weak_broker; + } + base::WeakPtr<MockBroker> ExpectOutputBrokerConstruction( RenderFrameHost* rfh) { auto broker = std::make_unique<StrictMock<MockBroker>>(rfh); @@ -128,8 +161,11 @@ RenderFrameHost* other_rfh() { return other_rfh_; } - static const char kDeviceId[]; + static const char kInputDeviceId[]; + static const char kOutputDeviceId[]; static const media::AudioParameters kParams; + static const uint32_t kSharedMemoryCount; + static const bool kEnableAgc; service_manager::mojom::ConnectorRequest connector_request_; std::unique_ptr<service_manager::Connector> connector_; mojo::ScopedMessagePipeHandle pending_factory_request_; @@ -137,9 +173,29 @@ std::unique_ptr<MockBrokerFactory> broker_factory_; }; -const char ForwardingAudioStreamFactoryTest::kDeviceId[] = "test device id"; +const char ForwardingAudioStreamFactoryTest::kInputDeviceId[] = + "test input device id"; +const char ForwardingAudioStreamFactoryTest::kOutputDeviceId[] = + "test output device id"; const media::AudioParameters ForwardingAudioStreamFactoryTest::kParams = media::AudioParameters::UnavailableDeviceParams(); +const uint32_t ForwardingAudioStreamFactoryTest::kSharedMemoryCount = 10; +const bool ForwardingAudioStreamFactoryTest::kEnableAgc = false; + +} // namespace + +TEST_F(ForwardingAudioStreamFactoryTest, CreateInputStream_CreatesInputStream) { + mojom::RendererAudioInputStreamFactoryClientPtr client; + base::WeakPtr<MockBroker> broker = ExpectInputBrokerConstruction(main_rfh()); + + ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_), + std::move(broker_factory_)); + + EXPECT_CALL(*broker, CreateStream(NotNull())); + mojo::MakeRequest(&client); + factory.CreateInputStream(main_rfh(), kInputDeviceId, kParams, + kSharedMemoryCount, kEnableAgc, std::move(client)); +} TEST_F(ForwardingAudioStreamFactoryTest, CreateOutputStream_CreatesOutputStream) { @@ -151,15 +207,17 @@ EXPECT_CALL(*broker, CreateStream(NotNull())); mojo::MakeRequest(&client); - factory.CreateOutputStream(main_rfh(), kDeviceId, kParams, std::move(client)); + factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams, + std::move(client)); } -TEST_F(ForwardingAudioStreamFactoryTest, DeleterCalled_DestroysOutputStream) { - media::mojom::AudioOutputStreamProviderClientPtr client; +TEST_F(ForwardingAudioStreamFactoryTest, + InputBrokerDeleterCalled_DestroysInputStream) { + mojom::RendererAudioInputStreamFactoryClientPtr client; base::WeakPtr<MockBroker> main_rfh_broker = - ExpectOutputBrokerConstruction(main_rfh()); + ExpectInputBrokerConstruction(main_rfh()); base::WeakPtr<MockBroker> other_rfh_broker = - ExpectOutputBrokerConstruction(other_rfh()); + ExpectInputBrokerConstruction(other_rfh()); ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_), std::move(broker_factory_)); @@ -167,26 +225,28 @@ { EXPECT_CALL(*main_rfh_broker, CreateStream(NotNull())); mojo::MakeRequest(&client); - factory.CreateOutputStream(main_rfh(), kDeviceId, kParams, - std::move(client)); + factory.CreateInputStream(main_rfh(), kInputDeviceId, kParams, + kSharedMemoryCount, kEnableAgc, + std::move(client)); testing::Mock::VerifyAndClear(&*main_rfh_broker); } { EXPECT_CALL(*other_rfh_broker, CreateStream(NotNull())); mojo::MakeRequest(&client); - factory.CreateOutputStream(other_rfh(), kDeviceId, kParams, - std::move(client)); + factory.CreateInputStream(other_rfh(), kInputDeviceId, kParams, + kSharedMemoryCount, kEnableAgc, + std::move(client)); testing::Mock::VerifyAndClear(&*other_rfh_broker); } std::move(other_rfh_broker->deleter).Run(&*other_rfh_broker); EXPECT_FALSE(other_rfh_broker) - << "Broker should be destructed when deleter is called."; + << "Input broker should be destructed when deleter is called."; EXPECT_TRUE(main_rfh_broker); } TEST_F(ForwardingAudioStreamFactoryTest, - DestroyFrame_DestroysRelatedOutputStream) { + OutputBrokerDeleterCalled_DestroysOutputStream) { media::mojom::AudioOutputStreamProviderClientPtr client; base::WeakPtr<MockBroker> main_rfh_broker = ExpectOutputBrokerConstruction(main_rfh()); @@ -199,93 +259,210 @@ { EXPECT_CALL(*main_rfh_broker, CreateStream(NotNull())); mojo::MakeRequest(&client); - factory.CreateOutputStream(main_rfh(), kDeviceId, kParams, + factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams, std::move(client)); testing::Mock::VerifyAndClear(&*main_rfh_broker); } { EXPECT_CALL(*other_rfh_broker, CreateStream(NotNull())); mojo::MakeRequest(&client); - factory.CreateOutputStream(other_rfh(), kDeviceId, kParams, + factory.CreateOutputStream(other_rfh(), kOutputDeviceId, kParams, std::move(client)); testing::Mock::VerifyAndClear(&*other_rfh_broker); } factory.FrameDeleted(other_rfh()); EXPECT_FALSE(other_rfh_broker) - << "Broker should be destructed when owning frame is destructed."; + << "Output broker should be destructed when deleter is called."; EXPECT_TRUE(main_rfh_broker); } -TEST_F(ForwardingAudioStreamFactoryTest, - DestroyWebContents_DestroysOutputStream) { - media::mojom::AudioOutputStreamProviderClientPtr client; - base::WeakPtr<MockBroker> broker = ExpectOutputBrokerConstruction(main_rfh()); +TEST_F(ForwardingAudioStreamFactoryTest, DestroyFrame_DestroysRelatedStreams) { + mojom::RendererAudioInputStreamFactoryClientPtr input_client; + base::WeakPtr<MockBroker> main_rfh_input_broker = + ExpectInputBrokerConstruction(main_rfh()); + base::WeakPtr<MockBroker> other_rfh_input_broker = + ExpectInputBrokerConstruction(other_rfh()); - ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_), - std::move(broker_factory_)); - - EXPECT_CALL(*broker, CreateStream(NotNull())); - mojo::MakeRequest(&client); - factory.CreateOutputStream(main_rfh(), kDeviceId, kParams, std::move(client)); - - DeleteContents(); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(broker) - << "Broker should be destructed when owning WebContents is destructed."; -} - -TEST_F(ForwardingAudioStreamFactoryTest, DestroyRemoteFactory_CleansUpStreams) { - media::mojom::AudioOutputStreamProviderClientPtr client; - base::WeakPtr<MockBroker> broker = ExpectOutputBrokerConstruction(main_rfh()); - - ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_), - std::move(broker_factory_)); - - EXPECT_CALL(*broker, CreateStream(NotNull())); - mojo::MakeRequest(&client); - factory.CreateOutputStream(main_rfh(), kDeviceId, kParams, std::move(client)); - - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(broker); - pending_factory_request_.reset(); // Triggers connection error. - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(broker) - << "Broker should be destructed when owning WebContents is destructed."; -} - -TEST_F(ForwardingAudioStreamFactoryTest, LastStreamDeleted_ClearsFactoryPtr) { - media::mojom::AudioOutputStreamProviderClientPtr client; - base::WeakPtr<MockBroker> main_rfh_broker = + media::mojom::AudioOutputStreamProviderClientPtr output_client; + base::WeakPtr<MockBroker> main_rfh_output_broker = ExpectOutputBrokerConstruction(main_rfh()); - base::WeakPtr<MockBroker> other_rfh_broker = + base::WeakPtr<MockBroker> other_rfh_output_broker = ExpectOutputBrokerConstruction(other_rfh()); ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_), std::move(broker_factory_)); { - EXPECT_CALL(*main_rfh_broker, CreateStream(NotNull())); - mojo::MakeRequest(&client); - factory.CreateOutputStream(main_rfh(), kDeviceId, kParams, - std::move(client)); - testing::Mock::VerifyAndClear(&*main_rfh_broker); + EXPECT_CALL(*main_rfh_input_broker, CreateStream(NotNull())); + mojo::MakeRequest(&input_client); + factory.CreateInputStream(main_rfh(), kInputDeviceId, kParams, + kSharedMemoryCount, kEnableAgc, + std::move(input_client)); + testing::Mock::VerifyAndClear(&*main_rfh_input_broker); } { - EXPECT_CALL(*other_rfh_broker, CreateStream(NotNull())); - mojo::MakeRequest(&client); - factory.CreateOutputStream(other_rfh(), kDeviceId, kParams, - std::move(client)); - testing::Mock::VerifyAndClear(&*other_rfh_broker); + EXPECT_CALL(*other_rfh_input_broker, CreateStream(NotNull())); + mojo::MakeRequest(&input_client); + factory.CreateInputStream(other_rfh(), kInputDeviceId, kParams, + kSharedMemoryCount, kEnableAgc, + std::move(input_client)); + testing::Mock::VerifyAndClear(&*other_rfh_input_broker); + } + + { + EXPECT_CALL(*main_rfh_output_broker, CreateStream(NotNull())); + mojo::MakeRequest(&output_client); + factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams, + std::move(output_client)); + testing::Mock::VerifyAndClear(&*main_rfh_output_broker); + } + { + EXPECT_CALL(*other_rfh_output_broker, CreateStream(NotNull())); + mojo::MakeRequest(&output_client); + factory.CreateOutputStream(other_rfh(), kOutputDeviceId, kParams, + std::move(output_client)); + testing::Mock::VerifyAndClear(&*other_rfh_output_broker); + } + + factory.FrameDeleted(other_rfh()); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(other_rfh_input_broker) + << "Input broker should be destructed when owning frame is destructed."; + EXPECT_TRUE(main_rfh_input_broker); + EXPECT_FALSE(other_rfh_output_broker) + << "Output broker should be destructed when owning frame is destructed."; + EXPECT_TRUE(main_rfh_output_broker); +} + +TEST_F(ForwardingAudioStreamFactoryTest, DestroyWebContents_DestroysStreams) { + mojom::RendererAudioInputStreamFactoryClientPtr input_client; + base::WeakPtr<MockBroker> input_broker = + ExpectInputBrokerConstruction(main_rfh()); + + media::mojom::AudioOutputStreamProviderClientPtr output_client; + base::WeakPtr<MockBroker> output_broker = + ExpectOutputBrokerConstruction(main_rfh()); + + ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_), + std::move(broker_factory_)); + + EXPECT_CALL(*input_broker, CreateStream(NotNull())); + mojo::MakeRequest(&input_client); + factory.CreateInputStream(main_rfh(), kInputDeviceId, kParams, + kSharedMemoryCount, kEnableAgc, + std::move(input_client)); + + EXPECT_CALL(*output_broker, CreateStream(NotNull())); + mojo::MakeRequest(&output_client); + factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams, + std::move(output_client)); + + DeleteContents(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(input_broker) << "Input broker should be destructed when owning " + "WebContents is destructed."; + EXPECT_FALSE(output_broker) + << "Output broker should be destructed when owning " + "WebContents is destructed."; +} + +TEST_F(ForwardingAudioStreamFactoryTest, DestroyRemoteFactory_CleansUpStreams) { + mojom::RendererAudioInputStreamFactoryClientPtr input_client; + base::WeakPtr<MockBroker> input_broker = + ExpectInputBrokerConstruction(main_rfh()); + media::mojom::AudioOutputStreamProviderClientPtr output_client; + base::WeakPtr<MockBroker> output_broker = + ExpectOutputBrokerConstruction(main_rfh()); + + ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_), + std::move(broker_factory_)); + + EXPECT_CALL(*input_broker, CreateStream(NotNull())); + mojo::MakeRequest(&input_client); + factory.CreateInputStream(main_rfh(), kInputDeviceId, kParams, + kSharedMemoryCount, kEnableAgc, + std::move(input_client)); + + EXPECT_CALL(*output_broker, CreateStream(NotNull())); + mojo::MakeRequest(&output_client); + factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams, + std::move(output_client)); + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(input_broker); + EXPECT_TRUE(output_broker); + pending_factory_request_.reset(); // Triggers connection error. + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(input_broker) << "Input broker should be destructed when owning " + "WebContents is destructed."; + EXPECT_FALSE(output_broker) << "Output broker should be destructed when " + "owning WebContents is destructed."; +} + +TEST_F(ForwardingAudioStreamFactoryTest, LastStreamDeleted_ClearsFactoryPtr) { + mojom::RendererAudioInputStreamFactoryClientPtr input_client; + base::WeakPtr<MockBroker> main_rfh_input_broker = + ExpectInputBrokerConstruction(main_rfh()); + base::WeakPtr<MockBroker> other_rfh_input_broker = + ExpectInputBrokerConstruction(other_rfh()); + + media::mojom::AudioOutputStreamProviderClientPtr output_client; + base::WeakPtr<MockBroker> main_rfh_output_broker = + ExpectOutputBrokerConstruction(main_rfh()); + base::WeakPtr<MockBroker> other_rfh_output_broker = + ExpectOutputBrokerConstruction(other_rfh()); + + ForwardingAudioStreamFactory factory(web_contents(), std::move(connector_), + std::move(broker_factory_)); + + { + EXPECT_CALL(*main_rfh_input_broker, CreateStream(NotNull())); + mojo::MakeRequest(&input_client); + factory.CreateInputStream(main_rfh(), kInputDeviceId, kParams, + kSharedMemoryCount, kEnableAgc, + std::move(input_client)); + testing::Mock::VerifyAndClear(&*main_rfh_input_broker); + } + { + EXPECT_CALL(*other_rfh_input_broker, CreateStream(NotNull())); + mojo::MakeRequest(&input_client); + factory.CreateInputStream(other_rfh(), kInputDeviceId, kParams, + kSharedMemoryCount, kEnableAgc, + std::move(input_client)); + testing::Mock::VerifyAndClear(&*other_rfh_input_broker); + } + + { + EXPECT_CALL(*main_rfh_output_broker, CreateStream(NotNull())); + mojo::MakeRequest(&output_client); + factory.CreateOutputStream(main_rfh(), kOutputDeviceId, kParams, + std::move(output_client)); + testing::Mock::VerifyAndClear(&*main_rfh_output_broker); + } + { + EXPECT_CALL(*other_rfh_output_broker, CreateStream(NotNull())); + mojo::MakeRequest(&output_client); + factory.CreateOutputStream(other_rfh(), kOutputDeviceId, kParams, + std::move(output_client)); + testing::Mock::VerifyAndClear(&*other_rfh_output_broker); } base::RunLoop().RunUntilIdle(); EXPECT_FALSE(pending_factory_request_->QuerySignalsState().peer_closed()); - std::move(other_rfh_broker->deleter).Run(&*other_rfh_broker); + std::move(other_rfh_input_broker->deleter).Run(&*other_rfh_input_broker); + base::RunLoop().RunUntilIdle(); + // Connection should still be open, since there are still streams left. + EXPECT_FALSE(pending_factory_request_->QuerySignalsState().peer_closed()); + std::move(main_rfh_input_broker->deleter).Run(&*main_rfh_input_broker); + base::RunLoop().RunUntilIdle(); + // Connection should still be open, since there are still streams left. + EXPECT_FALSE(pending_factory_request_->QuerySignalsState().peer_closed()); + std::move(other_rfh_output_broker->deleter).Run(&*other_rfh_output_broker); base::RunLoop().RunUntilIdle(); // Connection should still be open, since there's still a stream left. EXPECT_FALSE(pending_factory_request_->QuerySignalsState().peer_closed()); - std::move(main_rfh_broker->deleter).Run(&*main_rfh_broker); + std::move(main_rfh_output_broker->deleter).Run(&*main_rfh_output_broker); base::RunLoop().RunUntilIdle(); // Now there are no streams left, connection should be broken. EXPECT_TRUE(pending_factory_request_->QuerySignalsState().peer_closed());
diff --git a/content/browser/media/keyboard_mic_registration.cc b/content/browser/media/keyboard_mic_registration.cc new file mode 100644 index 0000000..785f6d3 --- /dev/null +++ b/content/browser/media/keyboard_mic_registration.cc
@@ -0,0 +1,31 @@ +// 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 "content/browser/media/keyboard_mic_registration.h" + +#include "chromeos/audio/cras_audio_handler.h" +#include "content/public/browser/browser_thread.h" + +namespace content { + +KeyboardMicRegistration::KeyboardMicRegistration() = default; + +KeyboardMicRegistration::~KeyboardMicRegistration() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK_EQ(0, register_count_); +} + +void KeyboardMicRegistration::Register() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (++register_count_ == 1) + chromeos::CrasAudioHandler::Get()->SetKeyboardMicActive(true); +} + +void KeyboardMicRegistration::Deregister() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (--register_count_ == 0) + chromeos::CrasAudioHandler::Get()->SetKeyboardMicActive(false); +} + +} // namespace content
diff --git a/content/browser/media/keyboard_mic_registration.h b/content/browser/media/keyboard_mic_registration.h new file mode 100644 index 0000000..267d0de --- /dev/null +++ b/content/browser/media/keyboard_mic_registration.h
@@ -0,0 +1,31 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_MEDIA_KEYBOARD_MIC_REGISTRATION_H_ +#define CONTENT_BROWSER_MEDIA_KEYBOARD_MIC_REGISTRATION_H_ + +#include "base/macros.h" + +namespace content { + +// Chrome OS keyboard mic stream registration. Used on UI thread only and owned +// by BrowserMainLoop; instance must be obtained through +// BrowserMainLoop::keyboard_mic_registration(). +class KeyboardMicRegistration { + public: + KeyboardMicRegistration(); + ~KeyboardMicRegistration(); + + void Register(); + void Deregister(); + + private: + int register_count_ = 0; + + DISALLOW_COPY_AND_ASSIGN(KeyboardMicRegistration); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_MEDIA_KEYBOARD_MIC_REGISTRATION_H_
diff --git a/content/browser/network_service_restart_browsertest.cc b/content/browser/network_service_restart_browsertest.cc index eca40978..9655197 100644 --- a/content/browser/network_service_restart_browsertest.cc +++ b/content/browser/network_service_restart_browsertest.cc
@@ -458,7 +458,14 @@ // Make sure the factory info returned from // |StoragePartition::GetURLLoaderFactoryForBrowserProcessIOThread()| can be // used after crashes. -IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, BrowserIOFactoryInfo) { +// Flaky on Windows. https://crbug.com/840127 +#if defined(OS_WIN) +#define MAYBE_BrowserIOFactoryInfo DISABLED_BrowserIOFactoryInfo +#else +#define MAYBE_BrowserIOFactoryInfo BrowserIOFactoryInfo +#endif +IN_PROC_BROWSER_TEST_F(NetworkServiceRestartBrowserTest, + MAYBE_BrowserIOFactoryInfo) { auto* partition = BrowserContext::GetDefaultStoragePartition(browser_context()); auto shared_url_loader_factory_info =
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_mac.h b/content/browser/renderer_host/input/synthetic_gesture_target_mac.h index 4ecf50f..1074c50 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_target_mac.h +++ b/content/browser/renderer_host/input/synthetic_gesture_target_mac.h
@@ -20,6 +20,9 @@ // SyntheticGestureTarget: void DispatchInputEventToPlatform(const blink::WebInputEvent& event) override; + void DispatchWebTouchEventToPlatform( + const blink::WebTouchEvent& event, + const ui::LatencyInfo& latency_info) override; private: RenderWidgetHostViewCocoa* cocoa_view_;
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_mac.mm b/content/browser/renderer_host/input/synthetic_gesture_target_mac.mm index 71b3c59..3ea4f8c 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_target_mac.mm +++ b/content/browser/renderer_host/input/synthetic_gesture_target_mac.mm
@@ -131,4 +131,10 @@ SyntheticGestureTargetBase::DispatchInputEventToPlatform(event); } +void SyntheticGestureTargetMac::DispatchWebTouchEventToPlatform( + const blink::WebTouchEvent& web_touch, + const ui::LatencyInfo& latency_info) { + render_widget_host()->GetView()->InjectTouchEvent(web_touch, latency_info); +} + } // namespace content
diff --git a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc index 898bf03..934e7ba 100644 --- a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc +++ b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
@@ -9,14 +9,13 @@ #include "build/build_config.h" #include "content/browser/renderer_host/media/in_process_launched_video_capture_device.h" #include "content/browser/renderer_host/media/video_capture_controller.h" -#include "content/browser/renderer_host/media/video_capture_dependencies.h" +#include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/media_stream_request.h" #include "media/base/bind_to_current_loop.h" #include "media/capture/video/video_capture_buffer_pool_impl.h" #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h" #include "media/capture/video/video_capture_device_client.h" -#include "media/capture/video/video_capture_jpeg_decoder_impl.h" #include "media/capture/video/video_frame_receiver.h" #include "media/capture/video/video_frame_receiver_on_task_runner.h" @@ -41,11 +40,7 @@ std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder( media::VideoCaptureJpegDecoder::DecodeDoneCB decode_done_cb, base::Callback<void(const std::string&)> send_log_message_cb) { - return std::make_unique<media::VideoCaptureJpegDecoderImpl>( - base::BindRepeating( - &content::VideoCaptureDependencies::CreateJpegDecodeAccelerator), - content::BrowserThread::GetTaskRunnerForThread( - content::BrowserThread::IO), + return std::make_unique<content::VideoCaptureGpuJpegDecoder>( std::move(decode_done_cb), std::move(send_log_message_cb)); }
diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc index cfc8f6b..366ad60 100644 --- a/content/browser/renderer_host/media/media_stream_manager.cc +++ b/content/browser/renderer_host/media/media_stream_manager.cc
@@ -35,7 +35,6 @@ #include "content/browser/renderer_host/media/media_devices_manager.h" #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" #include "content/browser/renderer_host/media/service_video_capture_provider.h" -#include "content/browser/renderer_host/media/video_capture_dependencies.h" #include "content/browser/renderer_host/media/video_capture_manager.h" #include "content/browser/renderer_host/media/video_capture_provider_switcher.h" #include "content/browser/renderer_host/render_process_host_impl.h" @@ -96,6 +95,42 @@ return label; } +void CreateJpegDecodeAcceleratorOnIOThread( + media::mojom::JpegDecodeAcceleratorRequest request) { + auto* host = + GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, false); + if (host) { + host->gpu_service()->CreateJpegDecodeAccelerator(std::move(request)); + } else { + LOG(ERROR) << "No GpuProcessHost"; + } +} + +void CreateJpegDecodeAccelerator( + media::mojom::JpegDecodeAcceleratorRequest request) { + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(&CreateJpegDecodeAcceleratorOnIOThread, + std::move(request))); +} + +void CreateJpegEncodeAcceleratorOnIOThread( + media::mojom::JpegEncodeAcceleratorRequest request) { + auto* host = + GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, false); + if (host) { + host->gpu_service()->CreateJpegEncodeAccelerator(std::move(request)); + } else { + LOG(ERROR) << "No GpuProcessHost"; + } +} + +void CreateJpegEncodeAccelerator( + media::mojom::JpegEncodeAcceleratorRequest request) { + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(&CreateJpegEncodeAcceleratorOnIOThread, + std::move(request))); +} + void ParseStreamType(const StreamControls& controls, MediaStreamType* audio_type, MediaStreamType* video_type) { @@ -473,10 +508,8 @@ media::VideoCaptureDeviceFactory::CreateFactory( BrowserThread::GetTaskRunnerForThread(BrowserThread::UI), BrowserGpuMemoryBufferManager::current(), - base::BindRepeating( - &VideoCaptureDependencies::CreateJpegDecodeAccelerator), - base::BindRepeating( - &VideoCaptureDependencies::CreateJpegEncodeAccelerator))), + base::BindRepeating(&CreateJpegDecodeAccelerator), + base::BindRepeating(&CreateJpegEncodeAccelerator))), std::move(device_task_runner), base::BindRepeating(&SendVideoCaptureLogMessage)); }
diff --git a/content/browser/renderer_host/media/service_video_capture_provider.cc b/content/browser/renderer_host/media/service_video_capture_provider.cc index dd765959..1211057d 100644 --- a/content/browser/renderer_host/media/service_video_capture_provider.cc +++ b/content/browser/renderer_host/media/service_video_capture_provider.cc
@@ -4,15 +4,11 @@ #include "content/browser/renderer_host/media/service_video_capture_provider.h" -#include "content/browser/gpu/gpu_client_impl.h" #include "content/browser/renderer_host/media/service_video_capture_device_launcher.h" -#include "content/browser/renderer_host/media/video_capture_dependencies.h" #include "content/browser/renderer_host/media/video_capture_factory_delegate.h" -#include "content/common/child_process_host_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/service_manager_connection.h" #include "mojo/public/cpp/bindings/callback_helpers.h" -#include "mojo/public/cpp/bindings/strong_binding.h" #include "services/service_manager/public/cpp/connector.h" #include "services/video_capture/public/mojom/constants.mojom.h" #include "services/video_capture/public/uma/video_capture_service_event.h" @@ -23,7 +19,7 @@ : public content::ServiceVideoCaptureProvider::ServiceConnector { public: ServiceConnectorImpl() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); // In unit test environments, there may not be any connector. auto* connection = content::ServiceManagerConnection::GetForProcess(); if (!connection) @@ -48,66 +44,34 @@ std::unique_ptr<service_manager::Connector> connector_; }; -class DelegateToBrowserGpuServiceAcceleratorFactory - : public video_capture::mojom::AcceleratorFactory { - public: - void CreateJpegDecodeAccelerator( - media::mojom::JpegDecodeAcceleratorRequest jda_request) override { - content::VideoCaptureDependencies::CreateJpegDecodeAccelerator( - std::move(jda_request)); - } - void CreateJpegEncodeAccelerator( - media::mojom::JpegEncodeAcceleratorRequest jea_request) override { - content::VideoCaptureDependencies::CreateJpegEncodeAccelerator( - std::move(jea_request)); - } -}; - -std::unique_ptr<ui::mojom::GpuMemoryBufferFactory> CreateGpuClient() { - const auto gpu_client_id = - content::ChildProcessHostImpl::GenerateChildProcessUniqueId(); - return std::make_unique<content::GpuClientImpl>(gpu_client_id); -} - -std::unique_ptr<video_capture::mojom::AcceleratorFactory> -CreateAcceleratorFactory() { - return std::make_unique<DelegateToBrowserGpuServiceAcceleratorFactory>(); -} - } // anonymous namespace namespace content { ServiceVideoCaptureProvider::ServiceVideoCaptureProvider( base::RepeatingCallback<void(const std::string&)> emit_log_message_cb) - : ServiceVideoCaptureProvider( - std::make_unique<ServiceConnectorImpl>(), - base::BindRepeating(&CreateGpuClient), - base::BindRepeating(&CreateAcceleratorFactory), - std::move(emit_log_message_cb)) {} + : ServiceVideoCaptureProvider(std::make_unique<ServiceConnectorImpl>(), + std::move(emit_log_message_cb)) {} ServiceVideoCaptureProvider::ServiceVideoCaptureProvider( std::unique_ptr<ServiceConnector> service_connector, - CreateMemoryBufferFactoryCallback create_memory_buffer_factory_cb, - CreateAcceleratorFactoryCallback create_accelerator_factory_cb, base::RepeatingCallback<void(const std::string&)> emit_log_message_cb) : service_connector_(std::move(service_connector)), - create_memory_buffer_factory_cb_( - std::move(create_memory_buffer_factory_cb)), - create_accelerator_factory_cb_(std::move(create_accelerator_factory_cb)), emit_log_message_cb_(std::move(emit_log_message_cb)), usage_count_(0), launcher_has_connected_to_device_factory_(false), - weak_ptr_factory_(this) {} + weak_ptr_factory_(this) { + DETACH_FROM_SEQUENCE(sequence_checker_); +} ServiceVideoCaptureProvider::~ServiceVideoCaptureProvider() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); UninitializeInternal(ReasonForUninitialize::kShutdown); } void ServiceVideoCaptureProvider::GetDeviceInfosAsync( GetDeviceInfosCallback result_callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); emit_log_message_cb_.Run("ServiceVideoCaptureProvider::GetDeviceInfosAsync"); IncreaseUsageCount(); LazyConnectToService(); @@ -122,7 +86,7 @@ std::unique_ptr<VideoCaptureDeviceLauncher> ServiceVideoCaptureProvider::CreateDeviceLauncher() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return std::make_unique<ServiceVideoCaptureDeviceLauncher>( base::BindRepeating(&ServiceVideoCaptureProvider::ConnectToDeviceFactory, weak_ptr_factory_.GetWeakPtr())); @@ -130,7 +94,7 @@ void ServiceVideoCaptureProvider::ConnectToDeviceFactory( std::unique_ptr<VideoCaptureFactoryDelegate>* out_factory) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); IncreaseUsageCount(); LazyConnectToService(); launcher_has_connected_to_device_factory_ = true; @@ -141,7 +105,6 @@ } void ServiceVideoCaptureProvider::LazyConnectToService() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); if (device_factory_provider_.is_bound()) return; @@ -160,15 +123,7 @@ launcher_has_connected_to_device_factory_ = false; time_of_last_connect_ = base::TimeTicks::Now(); - video_capture::mojom::AcceleratorFactoryPtr accelerator_factory; - ui::mojom::GpuMemoryBufferFactoryPtr memory_buffer_factory; - mojo::MakeStrongBinding(create_accelerator_factory_cb_.Run(), - mojo::MakeRequest(&accelerator_factory)); - mojo::MakeStrongBinding(create_memory_buffer_factory_cb_.Run(), - mojo::MakeRequest(&memory_buffer_factory)); service_connector_->BindFactoryProvider(&device_factory_provider_); - device_factory_provider_->InjectGpuDependencies( - std::move(memory_buffer_factory), std::move(accelerator_factory)); device_factory_provider_->ConnectToDeviceFactory( mojo::MakeRequest(&device_factory_)); // Unretained |this| is safe, because |this| owns |device_factory_|. @@ -180,13 +135,13 @@ void ServiceVideoCaptureProvider::OnDeviceInfosReceived( GetDeviceInfosCallback result_callback, const std::vector<media::VideoCaptureDeviceInfo>& infos) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); base::ResetAndReturn(&result_callback).Run(infos); DecreaseUsageCount(); } void ServiceVideoCaptureProvider::OnLostConnectionToDeviceFactory() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); emit_log_message_cb_.Run( "ServiceVideoCaptureProvider::OnLostConnectionToDeviceFactory"); // This may indicate that the video capture service has crashed. Uninitialize @@ -196,12 +151,12 @@ } void ServiceVideoCaptureProvider::IncreaseUsageCount() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); usage_count_++; } void ServiceVideoCaptureProvider::DecreaseUsageCount() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); usage_count_--; DCHECK_GE(usage_count_, 0); if (usage_count_ == 0) @@ -210,7 +165,7 @@ void ServiceVideoCaptureProvider::UninitializeInternal( ReasonForUninitialize reason) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (!device_factory_.is_bound()) { return; }
diff --git a/content/browser/renderer_host/media/service_video_capture_provider.h b/content/browser/renderer_host/media/service_video_capture_provider.h index f2e67f4..2ee46aae 100644 --- a/content/browser/renderer_host/media/service_video_capture_provider.h +++ b/content/browser/renderer_host/media/service_video_capture_provider.h
@@ -27,23 +27,14 @@ video_capture::mojom::DeviceFactoryProviderPtr* provider) = 0; }; - using CreateMemoryBufferFactoryCallback = base::RepeatingCallback< - std::unique_ptr<ui::mojom::GpuMemoryBufferFactory>()>; - using CreateAcceleratorFactoryCallback = base::RepeatingCallback< - std::unique_ptr<video_capture::mojom::AcceleratorFactory>()>; - - // This constructor creates a default ServiceConnector which + // The parameterless constructor creates a default ServiceConnector which // uses the ServiceManager associated with the current process to connect - // to the video capture service. It uses a default factory for instances of - // ui::mojom::Gpu which produces instances of class content::GpuClient. + // to the video capture service. explicit ServiceVideoCaptureProvider( base::RepeatingCallback<void(const std::string&)> emit_log_message_cb); - // Lets clients provide a custom ServiceConnector and factory method for - // creating instances of ui::mojom::Gpu. + // Lets clients provide a custom ServiceConnector. ServiceVideoCaptureProvider( std::unique_ptr<ServiceConnector> service_connector, - CreateMemoryBufferFactoryCallback create_memory_buffer_factory_cb, - CreateAcceleratorFactoryCallback create_accelerator_factory_cb, base::RepeatingCallback<void(const std::string&)> emit_log_message_cb); ~ServiceVideoCaptureProvider() override; @@ -65,8 +56,6 @@ void UninitializeInternal(ReasonForUninitialize reason); std::unique_ptr<ServiceConnector> service_connector_; - CreateMemoryBufferFactoryCallback create_memory_buffer_factory_cb_; - CreateAcceleratorFactoryCallback create_accelerator_factory_cb_; base::RepeatingCallback<void(const std::string&)> emit_log_message_cb_; // We must hold on to |device_factory_provider_| because it holds the // service-side binding for |device_factory_|. @@ -74,6 +63,7 @@ video_capture::mojom::DeviceFactoryPtr device_factory_; // Used for automatically uninitializing when no longer in use. int usage_count_; + SEQUENCE_CHECKER(sequence_checker_); bool launcher_has_connected_to_device_factory_; base::TimeTicks time_of_last_connect_;
diff --git a/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc b/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc index 39bfe73..6a683e5 100644 --- a/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc +++ b/content/browser/renderer_host/media/service_video_capture_provider_unittest.cc
@@ -6,9 +6,9 @@ #include "base/run_loop.h" #include "base/test/mock_callback.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread.h" #include "content/public/browser/video_capture_device_launcher.h" -#include "content/public/test/test_browser_thread_bundle.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/video_capture/public/mojom/device_factory.mojom.h" #include "services/video_capture/public/mojom/device_factory_provider.mojom.h" @@ -44,17 +44,6 @@ DoConnectToDeviceFactory(request); } - void InjectGpuDependencies( - ui::mojom::GpuMemoryBufferFactoryPtr memory_buffer_factory, - video_capture::mojom::AcceleratorFactoryPtr accelerator_factory) - override { - DoInjectGpuDependencies(memory_buffer_factory, accelerator_factory); - } - - MOCK_METHOD2( - DoInjectGpuDependencies, - void(ui::mojom::GpuMemoryBufferFactoryPtr& memory_buffer_factory, - video_capture::mojom::AcceleratorFactoryPtr& accelerator_factory)); MOCK_METHOD1(SetShutdownDelayInSeconds, void(float seconds)); MOCK_METHOD1(DoConnectToDeviceFactory, void(video_capture::mojom::DeviceFactoryRequest& request)); @@ -121,13 +110,7 @@ auto mock_service_connector = std::make_unique<MockServiceConnector>(); mock_service_connector_ = mock_service_connector.get(); provider_ = std::make_unique<ServiceVideoCaptureProvider>( - std::move(mock_service_connector), base::BindRepeating([]() { - return std::unique_ptr<ui::mojom::GpuMemoryBufferFactory>(); - }), - base::BindRepeating([]() { - return std::unique_ptr<video_capture::mojom::AcceleratorFactory>(); - }), - kIgnoreLogMessageCB); + std::move(mock_service_connector), kIgnoreLogMessageCB); ON_CALL(*mock_service_connector_, BindFactoryProvider(_)) .WillByDefault( @@ -150,7 +133,7 @@ void TearDown() override {} - content::TestBrowserThreadBundle test_browser_thread_bundle_; + base::test::ScopedTaskEnvironment scoped_task_environment_; MockServiceConnector* mock_service_connector_; MockDeviceFactoryProvider mock_device_factory_provider_; mojo::Binding<video_capture::mojom::DeviceFactoryProvider>
diff --git a/content/browser/renderer_host/media/video_capture_browsertest.cc b/content/browser/renderer_host/media/video_capture_browsertest.cc index 128d9064..59b89dc8 100644 --- a/content/browser/renderer_host/media/video_capture_browsertest.cc +++ b/content/browser/renderer_host/media/video_capture_browsertest.cc
@@ -115,8 +115,6 @@ params_ = TestParams(GetParam()); if (params_.use_mojo_service) { scoped_feature_list_.InitAndEnableFeature(features::kMojoVideoCapture); - } else { - scoped_feature_list_.InitAndDisableFeature(features::kMojoVideoCapture); } } @@ -233,6 +231,11 @@ if (params_.use_mojo_service) return; #endif + // Mojo video capture currently does not support accelerated jpeg decoding. + // TODO(chfremer): Remove this as soon as https://crbug.com/720604 is + // resolved. + if (params_.use_mojo_service && params_.exercise_accelerated_jpeg_decoding) + return; SetUpRequiringBrowserMainLoopOnMainThread(); base::RunLoop run_loop; @@ -250,8 +253,16 @@ run_loop.Run(); } +// Flaky on MSAN. https://crbug.com/840294 +#if defined(MEMORY_SANITIZER) +#define MAYBE_ReceiveFramesFromFakeCaptureDevice \ + DISABLED_ReceiveFramesFromFakeCaptureDevice +#else +#define MAYBE_ReceiveFramesFromFakeCaptureDevice \ + ReceiveFramesFromFakeCaptureDevice +#endif IN_PROC_BROWSER_TEST_P(VideoCaptureBrowserTest, - ReceiveFramesFromFakeCaptureDevice) { + MAYBE_ReceiveFramesFromFakeCaptureDevice) { #if defined(OS_ANDROID) // TODO(chfremer): This test case is flaky on Android. Find out cause of // flakiness and then re-enable. See https://crbug.com/709039. @@ -263,11 +274,21 @@ if (params_.use_mojo_service) return; #endif + // Mojo video capture currently does not support accelerated jpeg decoding. + // TODO(chfremer): Remove this as soon as https://crbug.com/720604 is + // resolved. + if (params_.use_mojo_service && params_.exercise_accelerated_jpeg_decoding) + return; // Only fake device with index 2 delivers MJPEG. if (params_.exercise_accelerated_jpeg_decoding && - params_.device_index_to_use != 2) { + params_.device_index_to_use != 2) return; - } + // There is an intermittent use-after-free in GpuChannelHost::Send() during + // Browser shutdown, which causes MSan tests to fail. + // TODO(chfremer): Remove this as soon as https://crbug.com/725271 is + // resolved. + if (params_.exercise_accelerated_jpeg_decoding) + return; SetUpRequiringBrowserMainLoopOnMainThread();
diff --git a/content/browser/renderer_host/media/video_capture_controller_unittest.cc b/content/browser/renderer_host/media/video_capture_controller_unittest.cc index 75e032b..cb0e911 100644 --- a/content/browser/renderer_host/media/video_capture_controller_unittest.cc +++ b/content/browser/renderer_host/media/video_capture_controller_unittest.cc
@@ -22,6 +22,7 @@ #include "content/browser/renderer_host/media/media_stream_provider.h" #include "content/browser/renderer_host/media/mock_video_capture_provider.h" #include "content/browser/renderer_host/media/video_capture_controller_event_handler.h" +#include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h" #include "content/browser/renderer_host/media/video_capture_manager.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -30,7 +31,6 @@ #include "media/capture/video/video_capture_buffer_pool_impl.h" #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h" #include "media/capture/video/video_capture_device_client.h" -#include "media/capture/video/video_capture_jpeg_decoder_impl.h" #include "media/capture/video/video_frame_receiver_on_task_runner.h" #include "media/capture/video_capture_types.h" #include "testing/gmock/include/gmock/gmock.h" @@ -44,6 +44,12 @@ namespace content { +std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder( + media::VideoCaptureJpegDecoder::DecodeDoneCB decode_done_cb) { + return std::make_unique<content::VideoCaptureGpuJpegDecoder>( + std::move(decode_done_cb), base::DoNothing()); +} + class MockVideoCaptureControllerEventHandler : public VideoCaptureControllerEventHandler { public: @@ -157,7 +163,10 @@ std::make_unique<media::VideoFrameReceiverOnTaskRunner>( controller_->GetWeakPtrForIOThread(), BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)), - buffer_pool_, media::VideoCaptureJpegDecoderFactoryCB())); + buffer_pool_, + base::Bind(&CreateGpuJpegDecoder, + base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer, + controller_->GetWeakPtrForIOThread())))); } void SendStubFrameToDeviceClient(const media::VideoCaptureFormat format) {
diff --git a/content/browser/renderer_host/media/video_capture_dependencies.cc b/content/browser/renderer_host/media/video_capture_dependencies.cc deleted file mode 100644 index 26567c65..0000000 --- a/content/browser/renderer_host/media/video_capture_dependencies.cc +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/browser/renderer_host/media/video_capture_dependencies.h" - -#include "content/browser/gpu/gpu_process_host.h" -#include "content/public/browser/browser_thread.h" -#include "mojo/public/cpp/bindings/strong_binding.h" - -namespace content { - -// static -void VideoCaptureDependencies::CreateJpegDecodeAccelerator( - media::mojom::JpegDecodeAcceleratorRequest accelerator) { - if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::BindOnce(&VideoCaptureDependencies::CreateJpegDecodeAccelerator, - std::move(accelerator))); - return; - } - - auto* host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, - true /*force_create*/); - if (host) { - host->gpu_service()->CreateJpegDecodeAccelerator(std::move(accelerator)); - } else { - LOG(ERROR) << "No GpuProcessHost"; - } -} - -// static -void VideoCaptureDependencies::CreateJpegEncodeAccelerator( - media::mojom::JpegEncodeAcceleratorRequest accelerator) { - if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::BindOnce(&VideoCaptureDependencies::CreateJpegEncodeAccelerator, - std::move(accelerator))); - return; - } - - auto* host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, - true /*force_create*/); - if (host) { - host->gpu_service()->CreateJpegEncodeAccelerator(std::move(accelerator)); - } else { - LOG(ERROR) << "No GpuProcessHost"; - } -} - -} // namespace content
diff --git a/content/browser/renderer_host/media/video_capture_dependencies.h b/content/browser/renderer_host/media/video_capture_dependencies.h deleted file mode 100644 index 5804eef..0000000 --- a/content/browser/renderer_host/media/video_capture_dependencies.h +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_DEPENDENCIES_H_ -#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_DEPENDENCIES_H_ - -#include "content/common/content_export.h" -#include "services/video_capture/public/mojom/device_factory.mojom.h" -#include "services/viz/privileged/interfaces/gl/gpu_service.mojom.h" - -namespace content { - -// Browser-provided GPU dependencies for video capture. -class CONTENT_EXPORT VideoCaptureDependencies { - public: - static void CreateJpegDecodeAccelerator( - media::mojom::JpegDecodeAcceleratorRequest accelerator); - static void CreateJpegEncodeAccelerator( - media::mojom::JpegEncodeAcceleratorRequest accelerator); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_DEPENDENCIES_H_
diff --git a/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc b/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc new file mode 100644 index 0000000..f9769023 --- /dev/null +++ b/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.cc
@@ -0,0 +1,336 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/command_line.h" +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "base/single_thread_task_runner.h" +#include "base/strings/stringprintf.h" +#include "base/synchronization/waitable_event.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/trace_event/trace_event.h" +#include "build/build_config.h" +#include "content/browser/browser_main_loop.h" +#include "content/browser/gpu/gpu_process_host.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/content_switches.h" +#include "media/base/bind_to_current_loop.h" +#include "media/base/media_switches.h" +#include "media/base/video_frame.h" +#include "mojo/public/cpp/system/platform_handle.h" +#include "services/ui/public/cpp/gpu/gpu.h" + +namespace content { + +VideoCaptureGpuJpegDecoder::VideoCaptureGpuJpegDecoder( + DecodeDoneCB decode_done_cb, + base::Callback<void(const std::string&)> send_log_message_cb) + : decode_done_cb_(std::move(decode_done_cb)), + send_log_message_cb_(std::move(send_log_message_cb)), + has_received_decoded_frame_(false), + next_bitstream_buffer_id_(0), + in_buffer_id_(media::JpegDecodeAccelerator::kInvalidBitstreamBufferId), + decoder_status_(INIT_PENDING), + weak_ptr_factory_(this) {} + +VideoCaptureGpuJpegDecoder::~VideoCaptureGpuJpegDecoder() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // |this| was set as |decoder_|'s client. |decoder_| has to be deleted before + // this destructor returns to ensure that it doesn't call back into its + // client. Hence, we wait here while we delete |decoder_| on the IO thread. + if (decoder_) { + base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + // base::Unretained is safe because |this| will be valid until |event| + // is signaled. + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::BindOnce(&VideoCaptureGpuJpegDecoder::DestroyDecoderOnIOThread, + base::Unretained(this), &event)); + event.Wait(); + } +} + +void VideoCaptureGpuJpegDecoder::Initialize() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + base::AutoLock lock(lock_); + bool is_platform_supported = + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kUseFakeJpegDecodeAccelerator); +#if defined(OS_CHROMEOS) + // Non-ChromeOS platforms do not support HW JPEG decode now. Do not establish + // gpu channel to avoid introducing overhead. + is_platform_supported = true; +#endif + + if (!is_platform_supported || + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableAcceleratedMjpegDecode)) { + decoder_status_ = FAILED; + RecordInitDecodeUMA_Locked(); + return; + } + + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(&RequestGPUInfoOnIOThread, + base::ThreadTaskRunnerHandle::Get(), + weak_ptr_factory_.GetWeakPtr())); +} + +VideoCaptureGpuJpegDecoder::STATUS VideoCaptureGpuJpegDecoder::GetStatus() + const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::AutoLock lock(lock_); + return decoder_status_; +} + +void VideoCaptureGpuJpegDecoder::DecodeCapturedData( + const uint8_t* data, + size_t in_buffer_size, + const media::VideoCaptureFormat& frame_format, + base::TimeTicks reference_time, + base::TimeDelta timestamp, + media::VideoCaptureDevice::Client::Buffer out_buffer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(decoder_); + + TRACE_EVENT_ASYNC_BEGIN0("jpeg", "VideoCaptureGpuJpegDecoder decoding", + next_bitstream_buffer_id_); + TRACE_EVENT0("jpeg", "VideoCaptureGpuJpegDecoder::DecodeCapturedData"); + + // TODO(kcwu): enqueue decode requests in case decoding is not fast enough + // (say, if decoding time is longer than 16ms for 60fps 4k image) + { + base::AutoLock lock(lock_); + if (IsDecoding_Locked()) { + DVLOG(1) << "Drop captured frame. Previous jpeg frame is still decoding"; + return; + } + } + + // Enlarge input buffer if necessary. + if (!in_shared_memory_.get() || + in_buffer_size > in_shared_memory_->mapped_size()) { + // Reserve 2x space to avoid frequent reallocations for initial frames. + const size_t reserved_size = 2 * in_buffer_size; + in_shared_memory_.reset(new base::SharedMemory); + if (!in_shared_memory_->CreateAndMapAnonymous(reserved_size)) { + base::AutoLock lock(lock_); + decoder_status_ = FAILED; + LOG(WARNING) << "CreateAndMapAnonymous failed, size=" << reserved_size; + return; + } + } + memcpy(in_shared_memory_->memory(), data, in_buffer_size); + + // No need to lock for |in_buffer_id_| since IsDecoding_Locked() is false. + in_buffer_id_ = next_bitstream_buffer_id_; + media::BitstreamBuffer in_buffer(in_buffer_id_, in_shared_memory_->handle(), + in_buffer_size); + // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. + next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; + + // The API of |decoder_| requires us to wrap the |out_buffer| in a VideoFrame. + const gfx::Size dimensions = frame_format.frame_size; + std::unique_ptr<media::VideoCaptureBufferHandle> out_buffer_access = + out_buffer.handle_provider->GetHandleForInProcessAccess(); + base::SharedMemoryHandle out_handle = + out_buffer.handle_provider->GetNonOwnedSharedMemoryHandleForLegacyIPC(); + scoped_refptr<media::VideoFrame> out_frame = + media::VideoFrame::WrapExternalSharedMemory( + media::PIXEL_FORMAT_I420, // format + dimensions, // coded_size + gfx::Rect(dimensions), // visible_rect + dimensions, // natural_size + out_buffer_access->data(), // data + out_buffer_access->mapped_size(), // data_size + out_handle, // handle + 0, // shared_memory_offset + timestamp); // timestamp + if (!out_frame) { + base::AutoLock lock(lock_); + decoder_status_ = FAILED; + LOG(ERROR) << "DecodeCapturedData: WrapExternalSharedMemory failed"; + return; + } + // Hold onto the buffer access handle for the lifetime of the VideoFrame, to + // ensure the data pointers remain valid. + out_frame->AddDestructionObserver(base::BindOnce( + [](std::unique_ptr<media::VideoCaptureBufferHandle> handle) {}, + std::move(out_buffer_access))); + out_frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, + frame_format.frame_rate); + + out_frame->metadata()->SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, + reference_time); + + media::mojom::VideoFrameInfoPtr out_frame_info = + media::mojom::VideoFrameInfo::New(); + out_frame_info->timestamp = timestamp; + out_frame_info->pixel_format = media::PIXEL_FORMAT_I420; + out_frame_info->coded_size = dimensions; + out_frame_info->visible_rect = gfx::Rect(dimensions); + out_frame_info->metadata = out_frame->metadata()->GetInternalValues().Clone(); + + { + base::AutoLock lock(lock_); + decode_done_closure_ = + base::Bind(decode_done_cb_, out_buffer.id, out_buffer.frame_feedback_id, + base::Passed(&out_buffer.access_permission), + base::Passed(&out_frame_info)); + } + + // base::Unretained is safe because |decoder_| is deleted on the IO thread. + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, + base::BindOnce(&media::JpegDecodeAccelerator::Decode, + base::Unretained(decoder_.get()), + in_buffer, std::move(out_frame))); +} + +void VideoCaptureGpuJpegDecoder::VideoFrameReady(int32_t bitstream_buffer_id) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + TRACE_EVENT0("jpeg", "VideoCaptureGpuJpegDecoder::VideoFrameReady"); + if (!has_received_decoded_frame_) { + send_log_message_cb_.Run("Received decoded frame from Gpu Jpeg decoder"); + has_received_decoded_frame_ = true; + } + base::AutoLock lock(lock_); + + if (!IsDecoding_Locked()) { + LOG(ERROR) << "Got decode response while not decoding"; + return; + } + + if (bitstream_buffer_id != in_buffer_id_) { + LOG(ERROR) << "Unexpected bitstream_buffer_id " << bitstream_buffer_id + << ", expected " << in_buffer_id_; + return; + } + in_buffer_id_ = media::JpegDecodeAccelerator::kInvalidBitstreamBufferId; + + decode_done_closure_.Run(); + decode_done_closure_.Reset(); + + TRACE_EVENT_ASYNC_END0("jpeg", "VideoCaptureGpuJpegDecoder decoding", + bitstream_buffer_id); +} + +void VideoCaptureGpuJpegDecoder::NotifyError( + int32_t bitstream_buffer_id, + media::JpegDecodeAccelerator::Error error) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + LOG(ERROR) << "Decode error, bitstream_buffer_id=" << bitstream_buffer_id + << ", error=" << error; + send_log_message_cb_.Run("Gpu Jpeg decoder failed"); + base::AutoLock lock(lock_); + decode_done_closure_.Reset(); + decoder_status_ = FAILED; +} + +// static +void VideoCaptureGpuJpegDecoder::RequestGPUInfoOnIOThread( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + GpuProcessHost* host = + GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, false); + if (host) { + host->RequestGPUInfo( + base::Bind(&VideoCaptureGpuJpegDecoder::DidReceiveGPUInfoOnIOThread, + task_runner, weak_this)); + } else { + DidReceiveGPUInfoOnIOThread(std::move(task_runner), std::move(weak_this), + gpu::GPUInfo()); + } +} + +// static +void VideoCaptureGpuJpegDecoder::DidReceiveGPUInfoOnIOThread( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this, + const gpu::GPUInfo& gpu_info) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + media::mojom::JpegDecodeAcceleratorPtr remote_decoder; + + if (gpu_info.jpeg_decode_accelerator_supported) { + GpuProcessHost* host = + GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, false); + if (host) { + host->gpu_service()->CreateJpegDecodeAccelerator( + mojo::MakeRequest(&remote_decoder)); + } + } + + task_runner->PostTask( + FROM_HERE, + base::BindOnce(&VideoCaptureGpuJpegDecoder::FinishInitialization, + weak_this, remote_decoder.PassInterface())); +} + +void VideoCaptureGpuJpegDecoder::FinishInitialization( + media::mojom::JpegDecodeAcceleratorPtrInfo unbound_remote_decoder) { + TRACE_EVENT0("gpu", "VideoCaptureGpuJpegDecoder::FinishInitialization"); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (unbound_remote_decoder.is_valid()) { + base::AutoLock lock(lock_); + decoder_ = std::make_unique<media::MojoJpegDecodeAccelerator>( + BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), + std::move(unbound_remote_decoder)); + + // base::Unretained is safe because |decoder_| is deleted on the IO thread. + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::BindOnce(&media::JpegDecodeAccelerator::InitializeAsync, + base::Unretained(decoder_.get()), this, + media::BindToCurrentLoop(base::Bind( + &VideoCaptureGpuJpegDecoder::OnInitializationDone, + weak_ptr_factory_.GetWeakPtr())))); + } else { + OnInitializationDone(false); + } +} + +void VideoCaptureGpuJpegDecoder::OnInitializationDone(bool success) { + TRACE_EVENT0("gpu", "VideoCaptureGpuJpegDecoder::OnInitializationDone"); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + base::AutoLock lock(lock_); + if (!success) { + BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, decoder_.release()); + DLOG(ERROR) << "Failed to initialize JPEG decoder"; + } + + decoder_status_ = success ? INIT_PASSED : FAILED; + RecordInitDecodeUMA_Locked(); +} + +bool VideoCaptureGpuJpegDecoder::IsDecoding_Locked() const { + lock_.AssertAcquired(); + return !decode_done_closure_.is_null(); +} + +void VideoCaptureGpuJpegDecoder::RecordInitDecodeUMA_Locked() { + UMA_HISTOGRAM_BOOLEAN("Media.VideoCaptureGpuJpegDecoder.InitDecodeSuccess", + decoder_status_ == INIT_PASSED); +} + +void VideoCaptureGpuJpegDecoder::DestroyDecoderOnIOThread( + base::WaitableEvent* event) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + decoder_.reset(); + event->Signal(); +} + +} // namespace content
diff --git a/media/capture/video/video_capture_jpeg_decoder_impl.h b/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h similarity index 60% rename from media/capture/video/video_capture_jpeg_decoder_impl.h rename to content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h index b3010fb..bf089ba 100644 --- a/media/capture/video/video_capture_jpeg_decoder_impl.h +++ b/content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h
@@ -1,9 +1,9 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. +// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MEDIA_CAPTURE_VIDEO_VIDEO_CAPTURE_JPEG_DECODER_IMPL_H_ -#define MEDIA_CAPTURE_VIDEO_VIDEO_CAPTURE_JPEG_DECODER_IMPL_H_ +#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_GPU_JPEG_DECODER_H_ +#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_GPU_JPEG_DECODER_H_ #include <stddef.h> #include <stdint.h> @@ -15,9 +15,8 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" +#include "content/common/content_export.h" #include "gpu/config/gpu_info.h" -#include "media/capture/capture_export.h" -#include "media/capture/video/video_capture_device_factory.h" #include "media/capture/video/video_capture_jpeg_decoder.h" #include "media/mojo/clients/mojo_jpeg_decode_accelerator.h" @@ -25,28 +24,26 @@ class WaitableEvent; } -namespace media { +namespace content { -// Implementation of media::VideoCaptureJpegDecoder that delegates to a -// media::mojom::JpegDecodeAccelerator. When a frame is received in -// DecodeCapturedData(), it is copied to |in_shared_memory| for IPC transport -// to |decoder_|. When the decoder is finished with the frame, |decode_done_cb_| -// is invoked. Until |decode_done_cb_| is invoked, subsequent calls to -// DecodeCapturedData() are ignored. -// The given |decoder_task_runner| must allow blocking on |lock_|. -class CAPTURE_EXPORT VideoCaptureJpegDecoderImpl +// Adapter to GpuJpegDecodeAccelerator for VideoCaptureDevice::Client. It takes +// care of GpuJpegDecodeAccelerator creation, shared memory, and threading +// issues. +// +// All public methods except JpegDecodeAccelerator::Client ones should be called +// on the same thread. JpegDecodeAccelerator::Client methods should be called on +// the IO thread. +class CONTENT_EXPORT VideoCaptureGpuJpegDecoder : public media::VideoCaptureJpegDecoder, public media::JpegDecodeAccelerator::Client { public: // |decode_done_cb| is called on the IO thread when decode succeeds. This can // be on any thread. |decode_done_cb| is never called after // VideoCaptureGpuJpegDecoder is destroyed. - VideoCaptureJpegDecoderImpl( - MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory, - scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner, + VideoCaptureGpuJpegDecoder( DecodeDoneCB decode_done_cb, - base::RepeatingCallback<void(const std::string&)> send_log_message_cb); - ~VideoCaptureJpegDecoderImpl() override; + base::Callback<void(const std::string&)> send_log_message_cb); + ~VideoCaptureGpuJpegDecoder() override; // Implementation of VideoCaptureJpegDecoder: void Initialize() override; @@ -66,7 +63,17 @@ media::JpegDecodeAccelerator::Error error) override; private: - void FinishInitialization(); + static void RequestGPUInfoOnIOThread( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this); + + static void DidReceiveGPUInfoOnIOThread( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + base::WeakPtr<VideoCaptureGpuJpegDecoder> weak_this, + const gpu::GPUInfo& gpu_info); + + void FinishInitialization( + media::mojom::JpegDecodeAcceleratorPtrInfo unbound_remote_decoder); void OnInitializationDone(bool success); // Returns true if the decoding of last frame is not finished yet. @@ -77,23 +84,20 @@ void DestroyDecoderOnIOThread(base::WaitableEvent* event); - MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_; - scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner_; - // The underlying JPEG decode accelerator. std::unique_ptr<media::JpegDecodeAccelerator> decoder_; // The callback to run when decode succeeds. const DecodeDoneCB decode_done_cb_; - const base::RepeatingCallback<void(const std::string&)> send_log_message_cb_; + const base::Callback<void(const std::string&)> send_log_message_cb_; bool has_received_decoded_frame_; // Guards |decode_done_closure_| and |decoder_status_|. mutable base::Lock lock_; // The closure of |decode_done_cb_| with bound parameters. - base::OnceClosure decode_done_closure_; + base::Closure decode_done_closure_; // Next id for input BitstreamBuffer. int32_t next_bitstream_buffer_id_; @@ -109,11 +113,11 @@ SEQUENCE_CHECKER(sequence_checker_); - base::WeakPtrFactory<VideoCaptureJpegDecoderImpl> weak_ptr_factory_; + base::WeakPtrFactory<VideoCaptureGpuJpegDecoder> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(VideoCaptureJpegDecoderImpl); + DISALLOW_COPY_AND_ASSIGN(VideoCaptureGpuJpegDecoder); }; -} // namespace media +} // namespace content -#endif // MEDIA_CAPTURE_VIDEO_VIDEO_CAPTURE_JPEG_DECODER_IMPL_H_ +#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_GPU_JPEG_DECODER_H_
diff --git a/content/browser/renderer_host/render_frame_metadata_provider_impl.cc b/content/browser/renderer_host/render_frame_metadata_provider_impl.cc index c0aec90..025702c 100644 --- a/content/browser/renderer_host/render_frame_metadata_provider_impl.cc +++ b/content/browser/renderer_host/render_frame_metadata_provider_impl.cc
@@ -10,8 +10,10 @@ namespace content { RenderFrameMetadataProviderImpl::RenderFrameMetadataProviderImpl( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, FrameTokenMessageQueue* frame_token_message_queue) - : frame_token_message_queue_(frame_token_message_queue), + : task_runner_(task_runner), + frame_token_message_queue_(frame_token_message_queue), render_frame_metadata_observer_client_binding_(this), weak_factory_(this) {} @@ -30,8 +32,8 @@ mojom::RenderFrameMetadataObserverPtr observer) { render_frame_metadata_observer_ptr_ = std::move(observer); render_frame_metadata_observer_client_binding_.Close(); - render_frame_metadata_observer_client_binding_.Bind( - std::move(client_request)); + render_frame_metadata_observer_client_binding_.Bind(std::move(client_request), + task_runner_); } void RenderFrameMetadataProviderImpl::ReportAllFrameSubmissionsForTesting(
diff --git a/content/browser/renderer_host/render_frame_metadata_provider_impl.h b/content/browser/renderer_host/render_frame_metadata_provider_impl.h index fb101fb..ff93d90 100644 --- a/content/browser/renderer_host/render_frame_metadata_provider_impl.h +++ b/content/browser/renderer_host/render_frame_metadata_provider_impl.h
@@ -27,7 +27,8 @@ : public RenderFrameMetadataProvider, public mojom::RenderFrameMetadataObserverClient { public: - explicit RenderFrameMetadataProviderImpl( + RenderFrameMetadataProviderImpl( + scoped_refptr<base::SingleThreadTaskRunner> task_runner, FrameTokenMessageQueue* frame_token_message_queue); ~RenderFrameMetadataProviderImpl() override; @@ -69,6 +70,8 @@ base::Optional<viz::LocalSurfaceId> last_local_surface_id_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + // Not owned. FrameTokenMessageQueue* const frame_token_message_queue_;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index ddda2189..8a5c3e1 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1976,8 +1976,8 @@ if (gpu_client_) { // |gpu_client_| outlives the registry, because its destruction is posted to // IO thread from the destructor of |this|. - registry->AddInterface(base::BindRepeating( - &GpuClientImpl::Add, base::Unretained(gpu_client_.get()))); + registry->AddInterface( + base::Bind(&GpuClientImpl::Add, base::Unretained(gpu_client_.get()))); } registry->AddInterface(
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 35e004dc..2e65c33 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -369,7 +369,13 @@ compositor_frame_sink_binding_(this), frame_token_message_queue_( std::make_unique<FrameTokenMessageQueue>(this)), - render_frame_metadata_provider_(frame_token_message_queue_.get()), + render_frame_metadata_provider_( +#if defined(OS_MACOSX) + ui::WindowResizeHelperMac::Get()->task_runner(), +#else + base::ThreadTaskRunnerHandle::Get(), +#endif + frame_token_message_queue_.get()), frame_sink_id_(base::checked_cast<uint32_t>(process_->GetID()), base::checked_cast<uint32_t>(routing_id_)), weak_factory_(this) {
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc index aeef5d5..d4d8e7350 100644 --- a/content/browser/renderer_host/render_widget_host_input_event_router.cc +++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -1218,11 +1218,21 @@ base::debug::SetCrashKeyString( target_ptr_key, base::StringPrintf("%p", touchscreen_gesture_target_.target)); + static auto* root_ptr_key = base::debug::AllocateCrashKeyString( + "touchscreen-gesture-root-ptr", base::debug::CrashKeySize::Size64); + base::debug::SetCrashKeyString(root_ptr_key, + base::StringPrintf("%p", root_view)); static auto* target_ptr_in_map_key = base::debug::AllocateCrashKeyString( "touchscreen-gesture-target-in-map", base::debug::CrashKeySize::Size32); base::debug::SetCrashKeyString( target_ptr_in_map_key, touchscreen_gesture_target_in_map_ ? "true" : "false"); + static auto* map_size_key = base::debug::AllocateCrashKeyString( + "touchscreen-gesture-map-size", base::debug::CrashKeySize::Size32); + base::debug::SetCrashKeyString( + map_size_key, + base::StringPrintf("%u", static_cast<int>(owner_map_.size()))); + touchscreen_gesture_target_.target->ProcessGestureEvent(event, latency); }
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index cd7fba6d..288401cd 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -327,6 +327,9 @@ gfx::PointF* transformed_point, bool* out_query_renderer); + virtual void InjectTouchEvent(const blink::WebTouchEvent& event, + const ui::LatencyInfo& latency) {} + virtual void PreProcessMouseEvent(const blink::WebMouseEvent& event) {} virtual void PreProcessTouchEvent(const blink::WebTouchEvent& event) {}
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index ac758e5..3671fef 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -25,6 +25,7 @@ #include "ui/accelerated_widget_mac/accelerated_widget_mac.h" #include "ui/accelerated_widget_mac/display_link_mac.h" #include "ui/base/cocoa/remote_layer_api.h" +#include "ui/events/gesture_detection/filtered_gesture_provider.h" namespace content { class CursorManager; @@ -67,6 +68,7 @@ public RenderWidgetHostNSViewClient, public BrowserCompositorMacClient, public TextInputManager::Observer, + public ui::GestureProviderClient, public ui::AcceleratedWidgetMacNSView, public IPC::Sender { public: @@ -120,6 +122,7 @@ void UpdateCursor(const WebCursor& cursor) override; void DisplayCursor(const WebCursor& cursor) override; CursorManager* GetCursorManager() override; + void OnDidNavigateMainFrameToNewPage() override; void SetIsLoading(bool is_loading) override; void RenderProcessGone(base::TerminationStatus status, int error_code) override; @@ -166,6 +169,8 @@ bool IsKeyboardLocked() override; void GestureEventAck(const blink::WebGestureEvent& event, InputEventAckState ack_result) override; + void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch, + InputEventAckState ack_result) override; void DidOverscroll(const ui::DidOverscrollParams& params) override; @@ -184,6 +189,11 @@ // consumer, such as PDF or maps, wants to intercept them and implement a // custom behavior. void SendGesturePinchEvent(blink::WebGestureEvent* event); + + // Inject synthetic touch events. + void InjectTouchEvent(const blink::WebTouchEvent& event, + const ui::LatencyInfo& latency_info) override; + bool TransformPointToLocalCoordSpace(const gfx::PointF& point, const viz::SurfaceId& original_surface, gfx::PointF* transformed_point) override; @@ -209,15 +219,15 @@ void OnTextSelectionChanged(TextInputManager* text_input_manager, RenderWidgetHostViewBase* updated_view) override; + // ui::GestureProviderClient implementation. + void OnGestureEvent(const ui::GestureEventData& gesture) override; + // RenderFrameMetadataProvider::Observer void OnRenderFrameMetadataChanged() override; // IPC::Sender implementation. bool Send(IPC::Message* message) override; - // Forwards the mouse event to the renderer. - void ForwardMouseEvent(const blink::WebMouseEvent& event); - void SetTextInputActive(bool active); // Returns true and stores first rectangle for character range if the @@ -515,6 +525,10 @@ // Used to track active password input sessions. std::unique_ptr<ui::ScopedPasswordInputEnabler> password_input_enabler_; + // Provides gesture synthesis given a stream of touch events and touch event + // acks. This is for generating gesture events from injected touch events. + ui::FilteredGestureProvider gesture_provider_; + // Used to ensure that a consistent RenderWidgetHost is targeted throughout // the duration of a keyboard event. bool in_keyboard_event_ = false;
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index cac0ea2c..9936425d 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -19,6 +19,7 @@ #include "base/strings/utf_string_conversions.h" #include "content/browser/accessibility/browser_accessibility_manager_mac.h" #include "content/browser/renderer_host/cursor_manager.h" +#include "content/browser/renderer_host/input/motion_event_web.h" #import "content/browser/renderer_host/input/synthetic_gesture_target_mac.h" #include "content/browser/renderer_host/input/web_input_event_builders_mac.h" #include "content/browser/renderer_host/render_view_host_delegate.h" @@ -28,6 +29,7 @@ #import "content/browser/renderer_host/render_widget_host_ns_view_bridge.h" #import "content/browser/renderer_host/render_widget_host_view_cocoa.h" #import "content/browser/renderer_host/text_input_client_mac.h" +#import "content/browser/renderer_host/ui_events_helper.h" #include "content/common/text_input_state.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_context.h" @@ -45,6 +47,7 @@ #include "ui/base/cocoa/text_services_context_menu.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "ui/events/gesture_detection/gesture_provider_config_helper.h" #include "ui/events/keycodes/dom/dom_code.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/mac/coordinate_conversion.h" @@ -53,6 +56,7 @@ using blink::WebInputEvent; using blink::WebMouseEvent; using blink::WebGestureEvent; +using blink::WebTouchEvent; namespace content { @@ -132,6 +136,9 @@ is_loading_(false), allow_pause_for_resize_or_repaint_(true), is_guest_view_hack_(is_guest_view_hack), + gesture_provider_(ui::GetGestureProviderConfig( + ui::GestureProviderConfigType::CURRENT_PLATFORM), + this), weak_factory_(this) { // The NSView is on the other side of |ns_view_bridge_|. ns_view_bridge_ = RenderWidgetHostNSViewBridge::Create(this); @@ -415,6 +422,10 @@ return cursor_manager_.get(); } +void RenderWidgetHostViewMac::OnDidNavigateMainFrameToNewPage() { + gesture_provider_.ResetDetection(); +} + void RenderWidgetHostViewMac::SetIsLoading(bool is_loading) { is_loading_ = is_loading; // If we ever decide to show the waiting cursor while the page is loading @@ -521,6 +532,22 @@ selection->range()); } +void RenderWidgetHostViewMac::OnGestureEvent( + const ui::GestureEventData& gesture) { + blink::WebGestureEvent web_gesture = + ui::CreateWebGestureEventFromGestureEventData(gesture); + + ui::LatencyInfo latency_info(ui::SourceEventType::TOUCH); + + if (ShouldRouteEvent(web_gesture)) { + blink::WebGestureEvent gesture_event(web_gesture); + host()->delegate()->GetInputEventRouter()->RouteGestureEvent( + this, &gesture_event, latency_info); + } else { + host()->ForwardGestureEventWithLatencyInfo(web_gesture, latency_info); + } +} + void RenderWidgetHostViewMac::OnRenderFrameMetadataChanged() { last_frame_root_background_color_ = host() ->render_frame_metadata_provider() @@ -1015,6 +1042,23 @@ mouse_wheel_phase_handler_.GestureEventAck(event, ack_result); } +void RenderWidgetHostViewMac::ProcessAckedTouchEvent( + const TouchEventWithLatencyInfo& touch, + InputEventAckState ack_result) { + const bool event_consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED; + gesture_provider_.OnTouchEventAck( + touch.event.unique_touch_event_id, event_consumed, + InputEventAckStateIsSetNonBlocking(ack_result)); + if (touch.event.touch_start_or_first_touch_move && event_consumed && + host()->delegate() && host()->delegate()->GetInputEventRouter()) { + host() + ->delegate() + ->GetInputEventRouter() + ->OnHandledTouchStartOrFirstTouchMove( + touch.event.unique_touch_event_id); + } +} + void RenderWidgetHostViewMac::DidOverscroll( const ui::DidOverscrollParams& params) { [cocoa_view() processedOverscroll:params]; @@ -1041,9 +1085,8 @@ // See also RenderWidgetHostViewAura::ShouldRouteEvent. // TODO(wjmaclean): Update this function if RenderWidgetHostViewMac implements // OnTouchEvent(), to match what we are doing in RenderWidgetHostViewAura. - DCHECK(WebInputEvent::IsMouseEventType(event.GetType()) || - event.GetType() == WebInputEvent::kMouseWheel || - WebInputEvent::IsPinchGestureEventType(event.GetType())); + // The only touch events and touch gesture events expected here are + // injected synthetic events. return host()->delegate() && host()->delegate()->GetInputEventRouter(); } @@ -1059,6 +1102,23 @@ host()->ForwardGestureEvent(*event); } +void RenderWidgetHostViewMac::InjectTouchEvent( + const WebTouchEvent& event, + const ui::LatencyInfo& latency_info) { + ui::FilteredGestureProvider::TouchHandlingResult result = + gesture_provider_.OnTouchEvent(MotionEventWeb(event)); + if (!result.succeeded) + return; + + if (ShouldRouteEvent(event)) { + WebTouchEvent touch_event(event); + host()->delegate()->GetInputEventRouter()->RouteTouchEvent( + this, &touch_event, latency_info); + } else { + host()->ForwardTouchEventWithLatencyInfo(event, latency_info); + } +} + bool RenderWidgetHostViewMac::TransformPointToLocalCoordSpace( const gfx::PointF& point, const viz::SurfaceId& original_surface,
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc index 3bf2e9e..9f13f95e 100644 --- a/content/browser/security_exploit_browsertest.cc +++ b/content/browser/security_exploit_browsertest.cc
@@ -103,8 +103,7 @@ wc->GetFrameTree()->root()->navigator()->RequestOpenURL( wc->GetFrameTree()->root()->current_frame_host(), extension_url, false, nullptr, std::string(), Referrer(), WindowOpenDisposition::CURRENT_TAB, - false, true, blink::WebTriggeringEventInfo::kFromTrustedEvent, - base::nullopt); + false, true, blink::WebTriggeringEventInfo::kFromTrustedEvent); // Since the navigation above requires a cross-process swap, there will be a // speculative/pending RenderFrameHost. Ensure it exists and is in a different
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc index 6cced7e1..39aeeb3 100644 --- a/content/browser/service_worker/embedded_worker_instance.cc +++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -417,13 +417,16 @@ network::mojom::URLLoaderFactoryPtrInfo non_network_loader_factory_info) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - // We allocated a process but will not use it. Tell the process manager to - // release the process, by making a WorkerProcessHandle and immediately - // destroying it. - if (status == SERVICE_WORKER_OK && !instance_->context_) { - WorkerProcessHandle(process_manager, instance_->embedded_worker_id(), - process_info->process_id); - status = SERVICE_WORKER_ERROR_ABORT; + std::unique_ptr<WorkerProcessHandle> process_handle; + if (status == SERVICE_WORKER_OK) { + // If we allocated a process, WorkerProcessHandle has to be created before + // returning to ensure the process is eventually released. + process_handle = std::make_unique<WorkerProcessHandle>( + process_manager, instance_->embedded_worker_id(), + process_info->process_id); + + if (!instance_->context_) + status = SERVICE_WORKER_ERROR_ABORT; } if (status != SERVICE_WORKER_OK) { @@ -452,11 +455,7 @@ // Notify the instance that a process is allocated. state_ = ProcessAllocationState::ALLOCATED; - instance_->OnProcessAllocated( - std::make_unique<WorkerProcessHandle>(process_manager, - instance_->embedded_worker_id(), - process_info->process_id), - start_situation); + instance_->OnProcessAllocated(std::move(process_handle), start_situation); // Notify the instance that it is registered to the DevTools manager. instance_->OnRegisteredToDevToolsManager(std::move(devtools_proxy), @@ -464,14 +463,9 @@ network::mojom::URLLoaderFactoryPtr non_network_loader_factory( std::move(non_network_loader_factory_info)); - status = instance_->SendStartWorker(std::move(params), - std::move(non_network_loader_factory)); - if (status != SERVICE_WORKER_OK) { - StatusCallback callback = std::move(start_callback_); - start_callback_.Reset(); - instance_->OnStartFailed(std::move(callback), status); - // |this| may be destroyed. - } + instance_->SendStartWorker(std::move(params), + std::move(non_network_loader_factory)); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("ServiceWorker", "INITIALIZING_ON_RENDERER", this); // |this|'s work is done here, but |instance_| still uses its state until @@ -642,23 +636,10 @@ observer.OnRegisteredToDevToolsManager(); } -ServiceWorkerStatusCode EmbeddedWorkerInstance::SendStartWorker( +void EmbeddedWorkerInstance::SendStartWorker( mojom::EmbeddedWorkerStartParamsPtr params, network::mojom::URLLoaderFactoryPtr non_network_loader_factory) { DCHECK(context_); - - if (!context_->GetDispatcherHost(process_id())) { - // Check if there's a dispatcher host, which is a good sign the process is - // still alive. It's possible that previously the process crashed, and the - // Mojo connection error via |client_| detected it and this instance was - // detached, but on restart ServiceWorkerProcessManager assigned us the - // process again before RenderProcessHostImpl itself or - // ServiceWorkerProcessManager knew it crashed, and by the time we get here - // RenderProcessHostImpl::EnableSendQueue may have been called in - // anticipation of the RPHI being reused for another renderer process, so - // Mojo doesn't consider it an error. See https://crbug.com/732729. - return SERVICE_WORKER_ERROR_IPC_FAILED; - } DCHECK(params->dispatcher_request.is_pending()); DCHECK(params->controller_request.is_pending()); DCHECK(params->service_worker_host.is_valid()); @@ -677,12 +658,7 @@ .Run(process_id(), std::move(non_network_loader_factory)); client_->StartWorker(std::move(params)); registry_->BindWorkerToProcess(process_id(), embedded_worker_id()); - OnStartWorkerMessageSent(is_script_streaming); - return SERVICE_WORKER_OK; -} -void EmbeddedWorkerInstance::OnStartWorkerMessageSent( - bool is_script_streaming) { if (!step_time_.is_null()) { base::TimeDelta duration = UpdateStepTime(); if (inflight_start_task_->is_installed()) {
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h index bc0d96b..d0556eb 100644 --- a/content/browser/service_worker/embedded_worker_instance.h +++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -244,13 +244,10 @@ // |non_network_loader_factory| is non-null when the service worker script URL // has a non-http(s) scheme. In that case, it is used to load the script since // the usual network factory can't be used. - ServiceWorkerStatusCode SendStartWorker( + void SendStartWorker( mojom::EmbeddedWorkerStartParamsPtr params, network::mojom::URLLoaderFactoryPtr non_network_loader_factory); - // Called back from StartTask after a start worker message is sent. - void OnStartWorkerMessageSent(bool is_script_streaming); - // Implements mojom::EmbeddedWorkerInstanceHost. // These functions all run on the IO thread. void RequestTermination() override;
diff --git a/content/browser/service_worker/embedded_worker_instance_unittest.cc b/content/browser/service_worker/embedded_worker_instance_unittest.cc index 9ee02ba..ed9ac4d 100644 --- a/content/browser/service_worker/embedded_worker_instance_unittest.cc +++ b/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -234,13 +234,6 @@ worker->status_ = status; } - ServiceWorkerStatusCode SimulateSendStartWorker( - EmbeddedWorkerInstance* worker, - mojom::EmbeddedWorkerStartParamsPtr params) { - return worker->SendStartWorker(std::move(params), - nullptr /* non_network_loader_factory */); - } - blink::mojom::ServiceWorkerInstalledScriptsInfoPtr GetInstalledScriptsInfoPtr() { installed_scripts_managers_.emplace_back(); @@ -976,21 +969,4 @@ EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, worker->status()); } -// Test that SendStartWorker checks if dispatcher host exists. -TEST_F(EmbeddedWorkerInstanceTest, NoDispatcherHost) { - const GURL scope("http://example.com/"); - const GURL url("http://example.com/worker.js"); - - RegistrationAndVersionPair pair = PrepareRegistrationAndVersion(scope, url); - std::unique_ptr<EmbeddedWorkerInstance> worker = - embedded_worker_registry()->CreateWorker(pair.second.get()); - SetWorkerStatus(worker.get(), EmbeddedWorkerStatus::STARTING); - auto params = mojom::EmbeddedWorkerStartParams::New(); - ServiceWorkerStatusCode result = - SimulateSendStartWorker(worker.get(), std::move(params)); - EXPECT_EQ(SERVICE_WORKER_ERROR_IPC_FAILED, result); - // Set to STOPPED because EWInstance's destructor DCHECKs status. - SetWorkerStatus(worker.get(), EmbeddedWorkerStatus::STOPPED); -} - } // namespace content
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc index afa17e4..c2da069 100644 --- a/content/browser/service_worker/service_worker_context_core.cc +++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -269,7 +269,7 @@ } ServiceWorkerContextCore::ServiceWorkerContextCore( - const base::FilePath& path, + const base::FilePath& user_data_directory, scoped_refptr<base::SequencedTaskRunner> database_task_runner, storage::QuotaManagerProxy* quota_manager_proxy, storage::SpecialStoragePolicy* special_storage_policy, @@ -290,8 +290,8 @@ // These get a WeakPtr from |weak_factory_|, so must be set after // |weak_factory_| is initialized. storage_ = ServiceWorkerStorage::Create( - path, AsWeakPtr(), std::move(database_task_runner), quota_manager_proxy, - special_storage_policy); + user_data_directory, AsWeakPtr(), std::move(database_task_runner), + quota_manager_proxy, special_storage_policy); embedded_worker_registry_ = EmbeddedWorkerRegistry::Create(AsWeakPtr()); job_coordinator_ = std::make_unique<ServiceWorkerJobCoordinator>(AsWeakPtr()); } @@ -768,6 +768,14 @@ return it->second.count; } +void ServiceWorkerContextCore::NotifyRegistrationStored(int64_t registration_id, + const GURL& pattern) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + observer_list_->Notify( + FROM_HERE, &ServiceWorkerContextCoreObserver::OnRegistrationStored, + registration_id, pattern); +} + void ServiceWorkerContextCore::OnStorageWiped() { observer_list_->Notify(FROM_HERE, &ServiceWorkerContextCoreObserver::OnStorageWiped);
diff --git a/content/browser/service_worker/service_worker_context_core.h b/content/browser/service_worker/service_worker_context_core.h index 71f4b53..8268537 100644 --- a/content/browser/service_worker/service_worker_context_core.h +++ b/content/browser/service_worker/service_worker_context_core.h
@@ -287,6 +287,9 @@ // version. The count resets to zero when the worker successfully starts. int GetVersionFailureCount(int64_t version_id); + // Called by ServiceWorkerStorage when StoreRegistration() succeeds. + void NotifyRegistrationStored(int64_t registration_id, const GURL& pattern); + URLLoaderFactoryGetter* loader_factory_getter() { return loader_factory_getter_.get(); }
diff --git a/content/browser/service_worker/service_worker_context_core_observer.h b/content/browser/service_worker/service_worker_context_core_observer.h index 4b00077c..1a5a4d2 100644 --- a/content/browser/service_worker/service_worker_context_core_observer.h +++ b/content/browser/service_worker/service_worker_context_core_observer.h
@@ -91,11 +91,18 @@ const std::string& uuid) {} // Called when the ServiceWorkerContainer.register() promise is resolved. // - // This is called before the service worker registration is persisted to disk. - // The caller cannot assume that the ServiceWorkerContextCore will find the - // registration at this point. + // This is called before the service worker registration is persisted to + // storage. The implementation cannot assume that the ServiceWorkerContextCore + // will find the registration at this point. virtual void OnRegistrationCompleted(int64_t registration_id, const GURL& pattern) {} + // Called after a service worker registration is persisted to storage. + // + // This happens after OnRegistrationCompleted(). The implementation can assume + // that ServiceWorkerContextCore will find the registration, and can safely + // add user data to the registration. + virtual void OnRegistrationStored(int64_t registration_id, + const GURL& pattern) {} virtual void OnRegistrationDeleted(int64_t registration_id, const GURL& pattern) {}
diff --git a/content/browser/service_worker/service_worker_context_unittest.cc b/content/browser/service_worker/service_worker_context_unittest.cc index f01c68f..c496e2b 100644 --- a/content/browser/service_worker/service_worker_context_unittest.cc +++ b/content/browser/service_worker/service_worker_context_unittest.cc
@@ -112,6 +112,7 @@ enum NotificationType { REGISTRATION_COMPLETED, + REGISTRATION_STORED, REGISTRATION_DELETED, STORAGE_RECOVERED, }; @@ -146,6 +147,14 @@ log.registration_id = registration_id; notifications_.push_back(log); } + void OnRegistrationStored(int64_t registration_id, + const GURL& pattern) override { + NotificationLog log; + log.type = REGISTRATION_STORED; + log.pattern = pattern; + log.registration_id = registration_id; + notifications_.push_back(log); + } void OnRegistrationDeleted(int64_t registration_id, const GURL& pattern) override { NotificationLog log; @@ -217,8 +226,8 @@ base::RunLoop().RunUntilIdle(); EXPECT_TRUE(called); - ASSERT_EQ(2UL, helper_->dispatched_events()->size()); - ASSERT_EQ(1UL, client->events().size()); + ASSERT_EQ(2u, helper_->dispatched_events()->size()); + ASSERT_EQ(1u, client->events().size()); EXPECT_EQ(RecordableEmbeddedWorkerInstanceClient::Message::StartWorker, client->events()[0]); EXPECT_EQ(EmbeddedWorkerTestHelper::Event::Install, @@ -228,10 +237,13 @@ EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, registration_id); - ASSERT_EQ(1u, notifications_.size()); + ASSERT_EQ(2u, notifications_.size()); EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type); EXPECT_EQ(pattern, notifications_[0].pattern); EXPECT_EQ(registration_id, notifications_[0].registration_id); + EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type); + EXPECT_EQ(pattern, notifications_[1].pattern); + EXPECT_EQ(registration_id, notifications_[1].registration_id); context()->storage()->FindRegistrationForId( registration_id, pattern.GetOrigin(), @@ -266,8 +278,8 @@ base::RunLoop().RunUntilIdle(); EXPECT_TRUE(called); - ASSERT_EQ(1UL, helper_->dispatched_events()->size()); - ASSERT_EQ(2UL, client->events().size()); + ASSERT_EQ(1u, helper_->dispatched_events()->size()); + ASSERT_EQ(2u, client->events().size()); EXPECT_EQ(RecordableEmbeddedWorkerInstanceClient::Message::StartWorker, client->events()[0]); EXPECT_EQ(EmbeddedWorkerTestHelper::Event::Install, @@ -314,8 +326,8 @@ base::RunLoop().RunUntilIdle(); EXPECT_TRUE(called); - ASSERT_EQ(2UL, helper_->dispatched_events()->size()); - ASSERT_EQ(1UL, client->events().size()); + ASSERT_EQ(2u, helper_->dispatched_events()->size()); + ASSERT_EQ(1u, client->events().size()); EXPECT_EQ(RecordableEmbeddedWorkerInstanceClient::Message::StartWorker, client->events()[0]); EXPECT_EQ(EmbeddedWorkerTestHelper::Event::Install, @@ -325,10 +337,13 @@ EXPECT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, registration_id); - ASSERT_EQ(1u, notifications_.size()); + ASSERT_EQ(2u, notifications_.size()); EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type); EXPECT_EQ(pattern, notifications_[0].pattern); EXPECT_EQ(registration_id, notifications_[0].registration_id); + EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type); + EXPECT_EQ(pattern, notifications_[1].pattern); + EXPECT_EQ(registration_id, notifications_[1].registration_id); context()->storage()->FindRegistrationForId( registration_id, pattern.GetOrigin(), @@ -368,13 +383,16 @@ false /* expect_waiting */, false /* expect_active */)); base::RunLoop().RunUntilIdle(); - ASSERT_EQ(2u, notifications_.size()); + ASSERT_EQ(3u, notifications_.size()); EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type); EXPECT_EQ(pattern, notifications_[0].pattern); EXPECT_EQ(registration_id, notifications_[0].registration_id); - EXPECT_EQ(REGISTRATION_DELETED, notifications_[1].type); + EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type); EXPECT_EQ(pattern, notifications_[1].pattern); EXPECT_EQ(registration_id, notifications_[1].registration_id); + EXPECT_EQ(REGISTRATION_DELETED, notifications_[2].type); + EXPECT_EQ(pattern, notifications_[2].pattern); + EXPECT_EQ(registration_id, notifications_[2].registration_id); } // Make sure registrations are cleaned up when they are unregistered in bulk. @@ -473,25 +491,37 @@ base::RunLoop().RunUntilIdle(); - ASSERT_EQ(6u, notifications_.size()); + ASSERT_EQ(10u, notifications_.size()); EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type); EXPECT_EQ(registration_id1, notifications_[0].registration_id); EXPECT_EQ(origin1_p1, notifications_[0].pattern); - EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[1].type); - EXPECT_EQ(origin1_p2, notifications_[1].pattern); - EXPECT_EQ(registration_id2, notifications_[1].registration_id); + EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type); + EXPECT_EQ(registration_id1, notifications_[1].registration_id); + EXPECT_EQ(origin1_p1, notifications_[1].pattern); EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[2].type); - EXPECT_EQ(origin2_p1, notifications_[2].pattern); - EXPECT_EQ(registration_id3, notifications_[2].registration_id); - EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[3].type); - EXPECT_EQ(origin3_p1, notifications_[3].pattern); - EXPECT_EQ(registration_id4, notifications_[3].registration_id); - EXPECT_EQ(REGISTRATION_DELETED, notifications_[4].type); - EXPECT_EQ(origin1_p1, notifications_[4].pattern); - EXPECT_EQ(registration_id1, notifications_[4].registration_id); - EXPECT_EQ(REGISTRATION_DELETED, notifications_[5].type); - EXPECT_EQ(origin1_p2, notifications_[5].pattern); - EXPECT_EQ(registration_id2, notifications_[5].registration_id); + EXPECT_EQ(origin1_p2, notifications_[2].pattern); + EXPECT_EQ(registration_id2, notifications_[2].registration_id); + EXPECT_EQ(REGISTRATION_STORED, notifications_[3].type); + EXPECT_EQ(origin1_p2, notifications_[3].pattern); + EXPECT_EQ(registration_id2, notifications_[3].registration_id); + EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[4].type); + EXPECT_EQ(origin2_p1, notifications_[4].pattern); + EXPECT_EQ(registration_id3, notifications_[4].registration_id); + EXPECT_EQ(REGISTRATION_STORED, notifications_[5].type); + EXPECT_EQ(origin2_p1, notifications_[5].pattern); + EXPECT_EQ(registration_id3, notifications_[5].registration_id); + EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[6].type); + EXPECT_EQ(origin3_p1, notifications_[6].pattern); + EXPECT_EQ(registration_id4, notifications_[6].registration_id); + EXPECT_EQ(REGISTRATION_STORED, notifications_[7].type); + EXPECT_EQ(origin3_p1, notifications_[7].pattern); + EXPECT_EQ(registration_id4, notifications_[7].registration_id); + EXPECT_EQ(REGISTRATION_DELETED, notifications_[8].type); + EXPECT_EQ(origin1_p1, notifications_[8].pattern); + EXPECT_EQ(registration_id1, notifications_[8].registration_id); + EXPECT_EQ(REGISTRATION_DELETED, notifications_[9].type); + EXPECT_EQ(origin1_p2, notifications_[9].pattern); + EXPECT_EQ(registration_id2, notifications_[9].registration_id); } // Make sure registering a new script shares an existing registration. @@ -528,13 +558,19 @@ new_registration_id); EXPECT_EQ(old_registration_id, new_registration_id); - ASSERT_EQ(2u, notifications_.size()); + ASSERT_EQ(4u, notifications_.size()); EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type); EXPECT_EQ(pattern, notifications_[0].pattern); EXPECT_EQ(old_registration_id, notifications_[0].registration_id); - EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[1].type); + EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type); EXPECT_EQ(pattern, notifications_[1].pattern); - EXPECT_EQ(new_registration_id, notifications_[1].registration_id); + EXPECT_EQ(old_registration_id, notifications_[1].registration_id); + EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[2].type); + EXPECT_EQ(pattern, notifications_[2].pattern); + EXPECT_EQ(new_registration_id, notifications_[2].registration_id); + EXPECT_EQ(REGISTRATION_STORED, notifications_[3].type); + EXPECT_EQ(pattern, notifications_[3].pattern); + EXPECT_EQ(new_registration_id, notifications_[3].registration_id); } // Make sure that when registering a duplicate pattern+script_url @@ -570,13 +606,16 @@ ASSERT_TRUE(called); EXPECT_EQ(old_registration_id, new_registration_id); - ASSERT_EQ(2u, notifications_.size()); + ASSERT_EQ(3u, notifications_.size()); EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type); EXPECT_EQ(pattern, notifications_[0].pattern); EXPECT_EQ(old_registration_id, notifications_[0].registration_id); - EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[1].type); + EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type); EXPECT_EQ(pattern, notifications_[1].pattern); EXPECT_EQ(old_registration_id, notifications_[1].registration_id); + EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[2].type); + EXPECT_EQ(pattern, notifications_[2].pattern); + EXPECT_EQ(old_registration_id, notifications_[2].registration_id); } TEST_F(ServiceWorkerContextTest, ProviderHostIterator) { @@ -753,14 +792,20 @@ // taken by the running registration, so the following method calls return 3. EXPECT_EQ(3, context()->GetNewServiceWorkerHandleId()); - ASSERT_EQ(3u, notifications_.size()); + ASSERT_EQ(5u, notifications_.size()); EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[0].type); EXPECT_EQ(pattern, notifications_[0].pattern); EXPECT_EQ(registration_id, notifications_[0].registration_id); - EXPECT_EQ(STORAGE_RECOVERED, notifications_[1].type); - EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[2].type); - EXPECT_EQ(pattern, notifications_[2].pattern); - EXPECT_EQ(registration_id, notifications_[2].registration_id); + EXPECT_EQ(REGISTRATION_STORED, notifications_[1].type); + EXPECT_EQ(pattern, notifications_[1].pattern); + EXPECT_EQ(registration_id, notifications_[1].registration_id); + EXPECT_EQ(STORAGE_RECOVERED, notifications_[2].type); + EXPECT_EQ(REGISTRATION_COMPLETED, notifications_[3].type); + EXPECT_EQ(pattern, notifications_[3].pattern); + EXPECT_EQ(registration_id, notifications_[3].registration_id); + EXPECT_EQ(REGISTRATION_STORED, notifications_[4].type); + EXPECT_EQ(pattern, notifications_[4].pattern); + EXPECT_EQ(registration_id, notifications_[4].registration_id); } INSTANTIATE_TEST_CASE_P(ServiceWorkerContextRecoveryTest,
diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc index 8233ff3..81676aa 100644 --- a/content/browser/service_worker/service_worker_storage.cc +++ b/content/browser/service_worker/service_worker_storage.cc
@@ -120,24 +120,25 @@ // static std::unique_ptr<ServiceWorkerStorage> ServiceWorkerStorage::Create( - const base::FilePath& path, + const base::FilePath& user_data_directory, const base::WeakPtr<ServiceWorkerContextCore>& context, scoped_refptr<base::SequencedTaskRunner> database_task_runner, storage::QuotaManagerProxy* quota_manager_proxy, storage::SpecialStoragePolicy* special_storage_policy) { - return base::WrapUnique( - new ServiceWorkerStorage(path, context, std::move(database_task_runner), - quota_manager_proxy, special_storage_policy)); + return base::WrapUnique(new ServiceWorkerStorage( + user_data_directory, context, std::move(database_task_runner), + quota_manager_proxy, special_storage_policy)); } // static std::unique_ptr<ServiceWorkerStorage> ServiceWorkerStorage::Create( const base::WeakPtr<ServiceWorkerContextCore>& context, ServiceWorkerStorage* old_storage) { - return base::WrapUnique(new ServiceWorkerStorage( - old_storage->path_, context, old_storage->database_task_runner_, - old_storage->quota_manager_proxy_.get(), - old_storage->special_storage_policy_.get())); + return base::WrapUnique( + new ServiceWorkerStorage(old_storage->user_data_directory_, context, + old_storage->database_task_runner_, + old_storage->quota_manager_proxy_.get(), + old_storage->special_storage_policy_.get())); } void ServiceWorkerStorage::FindRegistrationForDocument( @@ -1051,7 +1052,7 @@ } ServiceWorkerStorage::ServiceWorkerStorage( - const base::FilePath& path, + const base::FilePath& user_data_directory, base::WeakPtr<ServiceWorkerContextCore> context, scoped_refptr<base::SequencedTaskRunner> database_task_runner, storage::QuotaManagerProxy* quota_manager_proxy, @@ -1061,7 +1062,7 @@ next_resource_id_(kInvalidServiceWorkerResourceId), state_(UNINITIALIZED), expecting_done_with_disk_on_disable_(false), - path_(path), + user_data_directory_(user_data_directory), context_(context), database_task_runner_(std::move(database_task_runner)), quota_manager_proxy_(quota_manager_proxy), @@ -1074,16 +1075,18 @@ } base::FilePath ServiceWorkerStorage::GetDatabasePath() { - if (path_.empty()) + if (user_data_directory_.empty()) return base::FilePath(); - return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory) + return user_data_directory_ + .Append(ServiceWorkerContextCore::kServiceWorkerDirectory) .Append(kDatabaseName); } base::FilePath ServiceWorkerStorage::GetDiskCachePath() { - if (path_.empty()) + if (user_data_directory_.empty()) return base::FilePath(); - return path_.Append(ServiceWorkerContextCore::kServiceWorkerDirectory) + return user_data_directory_ + .Append(ServiceWorkerContextCore::kServiceWorkerDirectory) .Append(kDiskCacheName); } @@ -1388,6 +1391,8 @@ deleted_version.resources_total_size_bytes); } + context_->NotifyRegistrationStored(new_version.registration_id, + new_version.scope); std::move(callback).Run(SERVICE_WORKER_OK); if (!context_->GetLiveVersion(deleted_version.version_id))
diff --git a/content/browser/service_worker/service_worker_storage.h b/content/browser/service_worker/service_worker_storage.h index 3daafe9..88a1c29 100644 --- a/content/browser/service_worker/service_worker_storage.h +++ b/content/browser/service_worker/service_worker_storage.h
@@ -97,7 +97,7 @@ ~ServiceWorkerStorage() override; static std::unique_ptr<ServiceWorkerStorage> Create( - const base::FilePath& path, + const base::FilePath& user_data_directory, const base::WeakPtr<ServiceWorkerContextCore>& context, scoped_refptr<base::SequencedTaskRunner> database_task_runner, storage::QuotaManagerProxy* quota_manager_proxy, @@ -356,7 +356,7 @@ ServiceWorkerDatabase::Status status)>; ServiceWorkerStorage( - const base::FilePath& path, + const base::FilePath& user_data_directory, base::WeakPtr<ServiceWorkerContextCore> context, scoped_refptr<base::SequencedTaskRunner> database_task_runner, storage::QuotaManagerProxy* quota_manager_proxy, @@ -583,7 +583,7 @@ // ... so it's easier to keep track of the case when it will happen. bool expecting_done_with_disk_on_disable_; - base::FilePath path_; + base::FilePath user_data_directory_; // The context should be valid while the storage is alive. base::WeakPtr<ServiceWorkerContextCore> context_;
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index eed2f40e..426695a4 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -11556,9 +11556,10 @@ // Tests that when a large OOPIF has been scaled, the compositor raster area // sent from the embedder is correct. -#if defined(OS_ANDROID) +#if defined(OS_ANDROID) || defined(OS_MACOSX) // Temporarily disabled on Android because this doesn't account for browser // control height or page scale factor. +// Flaky on Mac. https://crbug.com/840314 #define MAYBE_ScaledIframeRasterSize DISABLED_ScaledframeRasterSize #else #define MAYBE_ScaledIframeRasterSize ScaledIframeRasterSize
diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc index e664d56..a4ffea58 100644 --- a/content/browser/utility_process_host.cc +++ b/content/browser/utility_process_host.cc
@@ -276,9 +276,7 @@ switches::kOverrideUseSoftwareGLForTests, switches::kOverrideEnabledCdmInterfaceVersion, switches::kProxyServer, - switches::kDisableAcceleratedMjpegDecode, switches::kUseFakeDeviceForMediaStream, - switches::kUseFakeJpegDecodeAccelerator, switches::kUseFileForFakeVideoCapture, switches::kUseMockCertVerifierForTesting, switches::kUtilityStartupDialog,
diff --git a/content/browser/webrtc/webrtc_add_stream_no_deadlock_browsertest.cc b/content/browser/webrtc/webrtc_add_stream_no_deadlock_browsertest.cc new file mode 100644 index 0000000..d3cd2eb9 --- /dev/null +++ b/content/browser/webrtc/webrtc_add_stream_no_deadlock_browsertest.cc
@@ -0,0 +1,50 @@ +// Copyright (c) 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 "base/command_line.h" +#include "build/build_config.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "content/browser/webrtc/webrtc_content_browsertest_base.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/content_browser_test_utils.h" +#include "content/public/test/test_utils.h" + +namespace content { + +#if defined(OS_ANDROID) && defined(ADDRESS_SANITIZER) +// Renderer crashes under Android ASAN: https://crbug.com/408496. +#define MAYBE_WebRtcAddStreamNoDeadlockBrowserTest \ + DISABLED_WebRtcAddStreamNoDeadlockBrowserTest +#else +#define MAYBE_WebRtcAddStreamNoDeadlockBrowserTest \ + WebRtcAddStreamNoDeadlockBrowserTest +#endif + +// This test sets up a peer connection in a specific way which previously +// resulted in a deadlock. The test succeeds if the JavaScript completes +// without errors. If the deadlock is re-introduced the test will time out. +// This is a regression test for https://crbug.com/736725. +class MAYBE_WebRtcAddStreamNoDeadlockBrowserTest + : public WebRtcContentBrowserTestBase { + public: + MAYBE_WebRtcAddStreamNoDeadlockBrowserTest() {} + ~MAYBE_WebRtcAddStreamNoDeadlockBrowserTest() override {} + + void SetUpCommandLine(base::CommandLine* command_line) override { + WebRtcContentBrowserTestBase::SetUpCommandLine(command_line); + // Automatically grant device permission. + AppendUseFakeUIForMediaStreamFlag(); + } + + protected: + void MakeTypicalPeerConnectionCall(const std::string& javascript) { + MakeTypicalCall(javascript, "/media/peerconnection-add-stream.html"); + } +}; + +IN_PROC_BROWSER_TEST_F(MAYBE_WebRtcAddStreamNoDeadlockBrowserTest, + AddStreamDoesNotCauseDeadlock) { + MakeTypicalPeerConnectionCall("runTest();"); +} +} // namespace content
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 78a1061..350988d 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -7,7 +7,6 @@ import("//build/config/features.gni") import("//build/config/ui.gni") import("//ipc/features.gni") -import("//media/media_options.gni") import("//mojo/public/tools/bindings/mojom.gni") import("//ppapi/buildflags/buildflags.gni") import("//sandbox/features.gni") @@ -231,6 +230,8 @@ "notifications/notification_struct_traits.cc", "notifications/notification_struct_traits.h", "origin_util.cc", + "p2p_messages.h", + "p2p_socket_type.h", "page_message_enums.h", "page_messages.h", "page_state_serialization.cc", @@ -376,6 +377,8 @@ "//third_party/angle:angle_gpu_info_util", "//third_party/boringssl", "//third_party/icu", + "//third_party/webrtc/rtc_base:rtc_base", + "//third_party/webrtc_overrides", "//ui/base", "//ui/base/ime", "//ui/display", @@ -433,17 +436,6 @@ deps += [ "//ppapi/proxy:ipc_sources" ] } - if (enable_webrtc) { - sources += [ - "p2p_messages.h", - "p2p_socket_type.h", - ] - deps += [ - "//third_party/webrtc/rtc_base:rtc_base", - "//third_party/webrtc_overrides", - ] - } - if (use_ozone) { deps += [ "//ui/ozone" ] } else {
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 5b1b037..f61f24dd 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -478,7 +478,6 @@ IPC_STRUCT_TRAITS_MEMBER(should_check_main_world_csp) IPC_STRUCT_TRAITS_MEMBER(has_user_gesture) IPC_STRUCT_TRAITS_MEMBER(started_from_context_menu) - IPC_STRUCT_TRAITS_MEMBER(suggested_filename) IPC_STRUCT_TRAITS_END() IPC_STRUCT_TRAITS_BEGIN(content::NavigationTiming) @@ -555,7 +554,6 @@ IPC_STRUCT_MEMBER(bool, user_gesture) IPC_STRUCT_MEMBER(bool, is_history_navigation_in_new_child) IPC_STRUCT_MEMBER(blink::WebTriggeringEventInfo, triggering_event_info) - IPC_STRUCT_MEMBER(base::Optional<std::string>, suggested_filename) IPC_STRUCT_END() IPC_STRUCT_BEGIN(FrameHostMsg_DownloadUrl_Params)
diff --git a/content/common/input/synthetic_web_input_event_builders.cc b/content/common/input/synthetic_web_input_event_builders.cc index d8fd877..5cf6591 100644 --- a/content/common/input/synthetic_web_input_event_builders.cc +++ b/content/common/input/synthetic_web_input_event_builders.cc
@@ -35,6 +35,7 @@ DCHECK(WebInputEvent::IsMouseEventType(type)); WebMouseEvent result(type, modifiers, ui::EventTimeForNow()); result.SetPositionInWidget(window_x, window_y); + result.SetPositionInScreen(window_x, window_y); result.SetModifiers(modifiers); result.pointer_type = pointer_type; result.id = ui::MouseEvent::kMousePointerId; @@ -198,6 +199,7 @@ point.rotation_angle = 1.f; point.force = 1.f; point.tilt_x = point.tilt_y = 0; + point.pointer_type = blink::WebPointerProperties::PointerType::kTouch; ++touches_length; WebTouchEventTraits::ResetType(WebInputEvent::kTouchStart, TimeStamp(), this); return point.id;
diff --git a/content/common/navigation_params.cc b/content/common/navigation_params.cc index 6d18f9fe..362669b0 100644 --- a/content/common/navigation_params.cc +++ b/content/common/navigation_params.cc
@@ -44,8 +44,7 @@ base::Optional<SourceLocation> source_location, CSPDisposition should_check_main_world_csp, bool started_from_context_menu, - bool has_user_gesture, - const base::Optional<std::string>& suggested_filename) + bool has_user_gesture) : url(url), referrer(referrer), transition(transition), @@ -63,8 +62,7 @@ source_location(source_location), should_check_main_world_csp(should_check_main_world_csp), started_from_context_menu(started_from_context_menu), - has_user_gesture(has_user_gesture), - suggested_filename(suggested_filename) { + has_user_gesture(has_user_gesture) { // |method != "POST"| should imply absence of |post_data|. if (method != "POST" && post_data) { NOTREACHED();
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h index 7d5a93f..e761d92 100644 --- a/content/common/navigation_params.h +++ b/content/common/navigation_params.h
@@ -76,8 +76,7 @@ base::Optional<SourceLocation> source_location, CSPDisposition should_check_main_world_csp, bool started_from_context_menu, - bool has_user_gesture, - const base::Optional<std::string>& suggested_filename); + bool has_user_gesture); CommonNavigationParams(const CommonNavigationParams& other); ~CommonNavigationParams(); @@ -161,11 +160,6 @@ // True if the request was user initiated. bool has_user_gesture = false; - - // If the navigation started in response to a HTML anchor element with a - // download attribute, this is the (possible empty) value of the download - // attribute. - base::Optional<std::string> suggested_filename; }; // Provided by the browser -----------------------------------------------------
diff --git a/content/common/resource_timing_info.h b/content/common/resource_timing_info.h index 78b9a61..cb327f7f 100644 --- a/content/common/resource_timing_info.h +++ b/content/common/resource_timing_info.h
@@ -11,6 +11,7 @@ #include <vector> #include "base/optional.h" +#include "base/time/time.h" namespace content { @@ -36,22 +37,22 @@ ResourceLoadTiming(const ResourceLoadTiming&); ~ResourceLoadTiming(); - double request_time = 0.0; - double proxy_start = 0.0; - double proxy_end = 0.0; - double dns_start = 0.0; - double dns_end = 0.0; - double connect_start = 0.0; - double connect_end = 0.0; - double worker_start = 0.0; - double worker_ready = 0.0; - double send_start = 0.0; - double send_end = 0.0; - double receive_headers_end = 0.0; - double ssl_start = 0.0; - double ssl_end = 0.0; - double push_start = 0.0; - double push_end = 0.0; + base::TimeTicks request_time; + base::TimeTicks proxy_start; + base::TimeTicks proxy_end; + base::TimeTicks dns_start; + base::TimeTicks dns_end; + base::TimeTicks connect_start; + base::TimeTicks connect_end; + base::TimeTicks worker_start; + base::TimeTicks worker_ready; + base::TimeTicks send_start; + base::TimeTicks send_end; + base::TimeTicks receive_headers_end; + base::TimeTicks ssl_start; + base::TimeTicks ssl_end; + base::TimeTicks push_start; + base::TimeTicks push_end; }; // TODO(dcheng): Migrate this struct over to Mojo so it doesn't need to be
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index c9e95a6..fe062d6 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -4,7 +4,6 @@ import("//build/config/jumbo.gni") import("//build/config/ui.gni") -import("//media/media_options.gni") # See //content/BUILD.gn for how this works. group("browser") { @@ -93,6 +92,8 @@ "content_browser_client.h", "context_factory.h", "cookie_store_factory.h", + "desktop_capture.cc", + "desktop_capture.h", "desktop_media_id.cc", "desktop_media_id.h", "devtools_agent_host.h", @@ -300,6 +301,8 @@ "web_ui_url_loader_factory.h", "webrtc_event_logger.cc", "webrtc_event_logger.h", + "webrtc_log.cc", + "webrtc_log.h", "websocket_handshake_request_info.h", "webvr_service_provider.cc", "webvr_service_provider.h", @@ -323,6 +326,7 @@ "//services/service_manager/public/cpp", "//services/tracing/public/cpp", "//services/ui/public/interfaces", + "//third_party/webrtc/modules/desktop_capture", # We expose skia headers in the public API. "//skia", @@ -375,14 +379,4 @@ "zoom_level_delegate.h", ] } - - if (enable_webrtc) { - sources += [ - "desktop_capture.cc", - "desktop_capture.h", - "webrtc_log.cc", - "webrtc_log.h", - ] - public_deps += [ "//third_party/webrtc/modules/desktop_capture" ] - } }
diff --git a/content/public/browser/navigation_controller.h b/content/public/browser/navigation_controller.h index 3bd12f4..9bba376 100644 --- a/content/public/browser/navigation_controller.h +++ b/content/public/browser/navigation_controller.h
@@ -199,11 +199,6 @@ // Indicates whether or not this navigation was initiated via context menu. bool started_from_context_menu; - // If this event was triggered by an anchor element with a download - // attribute, |suggested_filename| will contain the (possibly empty) value - // of that attribute. - base::Optional<std::string> suggested_filename; - // This value should only be set for main frame navigations. Subframe // navigations will always get their NavigationUIData from // ContentBrowserClient::GetNavigationUIData.
diff --git a/content/public/browser/navigation_handle.cc b/content/public/browser/navigation_handle.cc index a109ce3..f0770fdd 100644 --- a/content/public/browser/navigation_handle.cc +++ b/content/public/browser/navigation_handle.cc
@@ -50,7 +50,6 @@ false, // started_from_context_menu CSPDisposition::CHECK, // should_check_main_world_csp is_form_submission, // is_form_submission - base::nullopt, // suggested_filename nullptr, // navigation_ui_data method, net::HttpRequestHeaders(), resource_request_body, Referrer(), false, // has_user_gesture
diff --git a/content/public/browser/navigation_handle.h b/content/public/browser/navigation_handle.h index 28e3bf68..fbcb339 100644 --- a/content/public/browser/navigation_handle.h +++ b/content/public/browser/navigation_handle.h
@@ -262,10 +262,6 @@ // Returns true if this navigation was initiated by a form submission. virtual bool IsFormSubmission() = 0; - // If this navigation was triggered by an anchor with a download attribute, - // this returns the (possibly empty) value of that attribute. - virtual const base::Optional<std::string>& GetSuggestedFilename() = 0; - // Testing methods ---------------------------------------------------------- // // The following methods should be used exclusively for writing unit tests.
diff --git a/content/public/browser/page_navigator.h b/content/public/browser/page_navigator.h index a7572a8..1f16e0f 100644 --- a/content/public/browser/page_navigator.h +++ b/content/public/browser/page_navigator.h
@@ -108,11 +108,6 @@ // Indicates whether this navigation was started via context menu. bool started_from_context_menu; - // If this event was triggered by an anchor element with a download - // attribute, |suggested_filename| will contain the (possibly empty) value of - // that attribute. - base::Optional<std::string> suggested_filename; - // Indicates that the navigation should happen in an app window if // possible, i.e. if an app for the URL is installed. bool open_app_window_if_possible;
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn index ebb4d5e..aa2ada2 100644 --- a/content/public/common/BUILD.gn +++ b/content/public/common/BUILD.gn
@@ -8,7 +8,6 @@ import("//build/config/jumbo.gni") import("//build/config/ui.gni") import("//content/public/common/zygote_features.gni") -import("//media/media_options.gni") import("//mojo/public/tools/bindings/mojom.gni") import("//ppapi/buildflags/buildflags.gni") import("//third_party/webrtc/webrtc.gni") @@ -242,6 +241,8 @@ "webplugininfo.cc", "webplugininfo.h", "webplugininfo_param_traits.h", + "webrtc_ip_handling_policy.cc", + "webrtc_ip_handling_policy.h", "zygote_fork_delegate_linux.h", ] @@ -319,13 +320,6 @@ ] } - if (enable_webrtc) { - sources += [ - "webrtc_ip_handling_policy.cc", - "webrtc_ip_handling_policy.h", - ] - } - if (use_zygote_handle) { sources += [ "zygote_handle.h" ] }
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index f4f8ab9..0ec4696 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -79,6 +79,11 @@ // Disable gpu-accelerated 2d canvas. const char kDisableAccelerated2dCanvas[] = "disable-accelerated-2d-canvas"; +// Disable hardware acceleration of mjpeg decode for captured frame, where +// available. +const char kDisableAcceleratedMjpegDecode[] = + "disable-accelerated-mjpeg-decode"; + // Disables hardware acceleration of video decode, where available. const char kDisableAcceleratedVideoDecode[] = "disable-accelerated-video-decode";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index 8a960021..9a64c0d 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -33,6 +33,7 @@ CONTENT_EXPORT extern const char kDisable3DAPIs[]; CONTENT_EXPORT extern const char kDisableAccelerated2dCanvas[]; CONTENT_EXPORT extern const char kDisableAcceleratedJpegDecoding[]; +CONTENT_EXPORT extern const char kDisableAcceleratedMjpegDecode[]; CONTENT_EXPORT extern const char kDisableAcceleratedVideoDecode[]; CONTENT_EXPORT extern const char kDisableAcceleratedVideoEncode[]; CONTENT_EXPORT extern const char kDisableAudioSupportForDesktopShare[];
diff --git a/content/public/renderer/BUILD.gn b/content/public/renderer/BUILD.gn index 18e34b8..ea773ce 100644 --- a/content/public/renderer/BUILD.gn +++ b/content/public/renderer/BUILD.gn
@@ -42,6 +42,16 @@ "document_state.h", "fixed_received_data.cc", "fixed_received_data.h", + "media_stream_audio_renderer.h", + "media_stream_audio_sink.cc", + "media_stream_audio_sink.h", + "media_stream_renderer_factory.h", + "media_stream_sink.h", + "media_stream_utils.cc", + "media_stream_utils.h", + "media_stream_video_renderer.h", + "media_stream_video_sink.cc", + "media_stream_video_sink.h", "navigation_state.cc", "navigation_state.h", "pepper_plugin_instance.h", @@ -72,6 +82,7 @@ "v8_value_converter.h", "video_encode_accelerator.cc", "video_encode_accelerator.h", + "webrtc_log_message_delegate.h", "websocket_handshake_throttle_provider.h", "window_features_converter.cc", "window_features_converter.h", @@ -86,7 +97,9 @@ deps = [ "//content/public/child:child_sources", + "//content/public/common:buildflags", "//content/public/common:common_sources", + "//content/public/common:feature_h264_with_openh264_ffmpeg", "//content/renderer", "//gin", "//media/capture", @@ -96,6 +109,7 @@ "//ppapi/c", "//skia", "//third_party/blink/public:blink_headers", + "//third_party/webrtc_overrides", "//third_party/widevine/cdm:headers", "//ui/base", "//ui/base/ime", @@ -114,27 +128,6 @@ deps += [ "//sandbox" ] } - if (enable_webrtc) { - sources += [ - "media_stream_audio_renderer.h", - "media_stream_audio_sink.cc", - "media_stream_audio_sink.h", - "media_stream_renderer_factory.h", - "media_stream_sink.h", - "media_stream_utils.cc", - "media_stream_utils.h", - "media_stream_video_renderer.h", - "media_stream_video_sink.cc", - "media_stream_video_sink.h", - "webrtc_log_message_delegate.h", - ] - deps += [ - "//content/public/common:buildflags", - "//content/public/common:feature_h264_with_openh264_ffmpeg", - "//third_party/webrtc_overrides", - ] - } - if (enable_plugins) { sources += [ "plugin_instance_throttler.h" ] }
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc index c75faa8..39a356fb 100644 --- a/content/public/test/render_view_test.cc +++ b/content/public/test/render_view_test.cc
@@ -546,8 +546,7 @@ PREVIEWS_UNSPECIFIED, base::TimeTicks::Now(), "GET", nullptr, base::Optional<SourceLocation>(), CSPDisposition::CHECK /* should_check_main_world_csp */, - false /* started_from_context_menu */, false /* has_user_gesture */, - base::nullopt /* suggested_filename */); + false /* started_from_context_menu */, false /* has_user_gesture */); RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); TestRenderFrame* frame = static_cast<TestRenderFrame*>(impl->GetMainRenderFrame()); @@ -689,8 +688,7 @@ GURL(), PREVIEWS_UNSPECIFIED, base::TimeTicks::Now(), "GET", nullptr, base::Optional<SourceLocation>(), CSPDisposition::CHECK /* should_check_main_world_csp */, - false /* started_from_context_menu */, false /* has_user_gesture */, - base::nullopt /* suggested_filename */); + false /* started_from_context_menu */, false /* has_user_gesture */); RequestNavigationParams request_params; request_params.page_state = state; request_params.nav_entry_id = pending_offset + 1;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 261a8928..fee5fc9c 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -160,6 +160,8 @@ "history_serialization.h", "idle_user_detector.cc", "idle_user_detector.h", + "image_capture/image_capture_frame_grabber.cc", + "image_capture/image_capture_frame_grabber.h", "image_downloader/image_downloader_base.cc", "image_downloader/image_downloader_base.h", "image_downloader/image_downloader_impl.cc", @@ -303,12 +305,180 @@ "media/renderer_webaudiodevice_impl.h", "media/renderer_webmediaplayer_delegate.cc", "media/renderer_webmediaplayer_delegate.h", + "media/stream/aec_dump_message_filter.cc", + "media/stream/aec_dump_message_filter.h", + "media/stream/apply_constraints_processor.cc", + "media/stream/apply_constraints_processor.h", + "media/stream/external_media_stream_audio_source.cc", + "media/stream/external_media_stream_audio_source.h", + "media/stream/local_media_stream_audio_source.cc", + "media/stream/local_media_stream_audio_source.h", + "media/stream/media_stream_audio_deliverer.h", + "media/stream/media_stream_audio_level_calculator.cc", + "media/stream/media_stream_audio_level_calculator.h", + "media/stream/media_stream_audio_processor.cc", + "media/stream/media_stream_audio_processor.h", + "media/stream/media_stream_audio_processor_options.cc", + "media/stream/media_stream_audio_processor_options.h", + "media/stream/media_stream_audio_source.cc", + "media/stream/media_stream_audio_source.h", + "media/stream/media_stream_audio_track.cc", + "media/stream/media_stream_audio_track.h", + "media/stream/media_stream_center.cc", + "media/stream/media_stream_center.h", + "media/stream/media_stream_constraints_util.cc", + "media/stream/media_stream_constraints_util.h", + "media/stream/media_stream_constraints_util_audio.cc", + "media/stream/media_stream_constraints_util_audio.h", + "media/stream/media_stream_constraints_util_sets.cc", + "media/stream/media_stream_constraints_util_sets.h", + "media/stream/media_stream_constraints_util_video_content.cc", + "media/stream/media_stream_constraints_util_video_content.h", + "media/stream/media_stream_constraints_util_video_device.cc", + "media/stream/media_stream_constraints_util_video_device.h", + "media/stream/media_stream_device_observer.cc", + "media/stream/media_stream_device_observer.h", + "media/stream/media_stream_dispatcher_eventhandler.h", + "media/stream/media_stream_registry_interface.h", + "media/stream/media_stream_renderer_factory_impl.cc", + "media/stream/media_stream_renderer_factory_impl.h", + "media/stream/media_stream_source.cc", + "media/stream/media_stream_source.h", + "media/stream/media_stream_track.cc", + "media/stream/media_stream_track.h", + "media/stream/media_stream_video_capturer_source.cc", + "media/stream/media_stream_video_capturer_source.h", + "media/stream/media_stream_video_renderer_sink.cc", + "media/stream/media_stream_video_renderer_sink.h", + "media/stream/media_stream_video_source.cc", + "media/stream/media_stream_video_source.h", + "media/stream/media_stream_video_track.cc", + "media/stream/media_stream_video_track.h", + "media/stream/processed_local_audio_source.cc", + "media/stream/processed_local_audio_source.h", + "media/stream/remote_media_stream_track_adapter.cc", + "media/stream/remote_media_stream_track_adapter.h", + "media/stream/secure_display_link_tracker.h", + "media/stream/track_audio_renderer.cc", + "media/stream/track_audio_renderer.h", + "media/stream/user_media_client_impl.cc", + "media/stream/user_media_client_impl.h", + "media/stream/user_media_processor.cc", + "media/stream/user_media_processor.h", + "media/stream/video_track_adapter.cc", + "media/stream/video_track_adapter.h", + "media/stream/webaudio_media_stream_source.cc", + "media/stream/webaudio_media_stream_source.h", + "media/stream/webmediaplayer_ms.cc", + "media/stream/webmediaplayer_ms.h", + "media/stream/webmediaplayer_ms_compositor.cc", + "media/stream/webmediaplayer_ms_compositor.h", "media/video_capture_impl.cc", "media/video_capture_impl.h", "media/video_capture_impl_manager.cc", "media/video_capture_impl_manager.h", "media/web_media_element_source_utils.cc", "media/web_media_element_source_utils.h", + "media/webrtc/audio_codec_factory.cc", + "media/webrtc/audio_codec_factory.h", + "media/webrtc/media_stream_remote_video_source.cc", + "media/webrtc/media_stream_remote_video_source.h", + "media/webrtc/media_stream_track_metrics.cc", + "media/webrtc/media_stream_track_metrics.h", + "media/webrtc/media_stream_video_webrtc_sink.cc", + "media/webrtc/media_stream_video_webrtc_sink.h", + "media/webrtc/peer_connection_dependency_factory.cc", + "media/webrtc/peer_connection_dependency_factory.h", + "media/webrtc/peer_connection_remote_audio_source.cc", + "media/webrtc/peer_connection_remote_audio_source.h", + "media/webrtc/peer_connection_tracker.cc", + "media/webrtc/peer_connection_tracker.h", + "media/webrtc/rtc_certificate.cc", + "media/webrtc/rtc_certificate.h", + "media/webrtc/rtc_certificate_generator.cc", + "media/webrtc/rtc_certificate_generator.h", + "media/webrtc/rtc_data_channel_handler.cc", + "media/webrtc/rtc_data_channel_handler.h", + "media/webrtc/rtc_dtmf_sender_handler.cc", + "media/webrtc/rtc_dtmf_sender_handler.h", + "media/webrtc/rtc_event_log_output_sink.h", + "media/webrtc/rtc_event_log_output_sink_proxy.cc", + "media/webrtc/rtc_event_log_output_sink_proxy.h", + "media/webrtc/rtc_peer_connection_handler.cc", + "media/webrtc/rtc_peer_connection_handler.h", + "media/webrtc/rtc_rtp_contributing_source.cc", + "media/webrtc/rtc_rtp_contributing_source.h", + "media/webrtc/rtc_rtp_parameters.cc", + "media/webrtc/rtc_rtp_parameters.h", + "media/webrtc/rtc_rtp_receiver.cc", + "media/webrtc/rtc_rtp_receiver.h", + "media/webrtc/rtc_rtp_sender.cc", + "media/webrtc/rtc_rtp_sender.h", + "media/webrtc/rtc_stats.cc", + "media/webrtc/rtc_stats.h", + "media/webrtc/rtc_video_decoder.cc", + "media/webrtc/rtc_video_decoder.h", + "media/webrtc/rtc_video_decoder_factory.cc", + "media/webrtc/rtc_video_decoder_factory.h", + "media/webrtc/rtc_video_encoder.cc", + "media/webrtc/rtc_video_encoder.h", + "media/webrtc/rtc_video_encoder_factory.cc", + "media/webrtc/rtc_video_encoder_factory.h", + "media/webrtc/stun_field_trial.cc", + "media/webrtc/stun_field_trial.h", + "media/webrtc/track_observer.cc", + "media/webrtc/track_observer.h", + "media/webrtc/two_keys_adapter_map.h", + "media/webrtc/webrtc_audio_device_impl.cc", + "media/webrtc/webrtc_audio_device_impl.h", + "media/webrtc/webrtc_audio_device_not_impl.cc", + "media/webrtc/webrtc_audio_device_not_impl.h", + "media/webrtc/webrtc_audio_renderer.cc", + "media/webrtc/webrtc_audio_renderer.h", + "media/webrtc/webrtc_audio_sink.cc", + "media/webrtc/webrtc_audio_sink.h", + "media/webrtc/webrtc_media_stream_adapter.cc", + "media/webrtc/webrtc_media_stream_adapter.h", + "media/webrtc/webrtc_media_stream_adapter_map.cc", + "media/webrtc/webrtc_media_stream_adapter_map.h", + "media/webrtc/webrtc_media_stream_track_adapter.cc", + "media/webrtc/webrtc_media_stream_track_adapter.h", + "media/webrtc/webrtc_media_stream_track_adapter_map.cc", + "media/webrtc/webrtc_media_stream_track_adapter_map.h", + "media/webrtc/webrtc_set_remote_description_observer.cc", + "media/webrtc/webrtc_set_remote_description_observer.h", + "media/webrtc/webrtc_uma_histograms.cc", + "media/webrtc/webrtc_uma_histograms.h", + "media/webrtc/webrtc_video_capturer_adapter.cc", + "media/webrtc/webrtc_video_capturer_adapter.h", + "media/webrtc/webrtc_video_frame_adapter.cc", + "media/webrtc/webrtc_video_frame_adapter.h", + "media/webrtc_local_audio_source_provider.cc", + "media/webrtc_local_audio_source_provider.h", + "media/webrtc_logging.cc", + "media/webrtc_logging.h", + "media_capture_from_element/canvas_capture_handler.cc", + "media_capture_from_element/canvas_capture_handler.h", + "media_capture_from_element/html_audio_element_capturer_source.cc", + "media_capture_from_element/html_audio_element_capturer_source.h", + "media_capture_from_element/html_video_element_capturer_source.cc", + "media_capture_from_element/html_video_element_capturer_source.h", + "media_recorder/audio_track_encoder.cc", + "media_recorder/audio_track_encoder.h", + "media_recorder/audio_track_opus_encoder.cc", + "media_recorder/audio_track_opus_encoder.h", + "media_recorder/audio_track_pcm_encoder.cc", + "media_recorder/audio_track_pcm_encoder.h", + "media_recorder/audio_track_recorder.cc", + "media_recorder/audio_track_recorder.h", + "media_recorder/media_recorder_handler.cc", + "media_recorder/media_recorder_handler.h", + "media_recorder/vea_encoder.cc", + "media_recorder/vea_encoder.h", + "media_recorder/video_track_recorder.cc", + "media_recorder/video_track_recorder.h", + "media_recorder/vpx_encoder.cc", + "media_recorder/vpx_encoder.h", "menu_item_builder.cc", "menu_item_builder.h", "message_delivery_policy.h", @@ -328,7 +498,28 @@ "notifications/notification_dispatcher.h", "notifications/notification_manager.cc", "notifications/notification_manager.h", + "p2p/empty_network_manager.cc", + "p2p/empty_network_manager.h", + "p2p/filtering_network_manager.cc", + "p2p/filtering_network_manager.h", + "p2p/host_address_request.cc", + "p2p/host_address_request.h", + "p2p/ipc_network_manager.cc", + "p2p/ipc_network_manager.h", + "p2p/ipc_socket_factory.cc", + "p2p/ipc_socket_factory.h", "p2p/network_list_manager.h", + "p2p/network_list_observer.h", + "p2p/network_manager_uma.cc", + "p2p/network_manager_uma.h", + "p2p/port_allocator.cc", + "p2p/port_allocator.h", + "p2p/socket_client.h", + "p2p/socket_client_delegate.h", + "p2p/socket_client_impl.cc", + "p2p/socket_client_impl.h", + "p2p/socket_dispatcher.cc", + "p2p/socket_dispatcher.h", "pepper/fullscreen_container.h", "peripheral_content_heuristic.cc", "peripheral_content_heuristic.h", @@ -510,6 +701,7 @@ "//content/public/common:buildflags", "//content/public/common:feature_h264_with_openh264_ffmpeg", "//content/public/common:service_names", + "//crypto", "//crypto:platform", "//device/base/synchronization", "//device/gamepad/public/cpp:shared_with_blink", @@ -519,6 +711,7 @@ "//gpu", "//gpu/command_buffer/client:gles2_interface", "//gpu/command_buffer/client:raster_interface", + "//jingle:jingle_glue", "//media", "//media:media_buildflags", "//media/blink", @@ -554,7 +747,49 @@ "//third_party/blink/public/common", "//third_party/boringssl", "//third_party/icu", + "//third_party/libvpx", "//third_party/libyuv", + "//third_party/opus", + "//third_party/webrtc/api:libjingle_logging_api", + "//third_party/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/api:optional", + "//third_party/webrtc/api:rtc_stats_api", + "//third_party/webrtc/api:video_frame_api", + "//third_party/webrtc/api:video_frame_api_i420", + "//third_party/webrtc/api/audio:aec3_factory", + "//third_party/webrtc/api/audio_codecs:audio_codecs_api", + "//third_party/webrtc/api/audio_codecs/L16:audio_decoder_L16", + "//third_party/webrtc/api/audio_codecs/L16:audio_encoder_L16", + "//third_party/webrtc/api/audio_codecs/g711:audio_decoder_g711", + "//third_party/webrtc/api/audio_codecs/g711:audio_encoder_g711", + "//third_party/webrtc/api/audio_codecs/g722:audio_decoder_g722", + "//third_party/webrtc/api/audio_codecs/g722:audio_encoder_g722", + "//third_party/webrtc/api/audio_codecs/isac:audio_decoder_isac", + "//third_party/webrtc/api/audio_codecs/isac:audio_encoder_isac", + "//third_party/webrtc/api/audio_codecs/opus:audio_decoder_opus", + "//third_party/webrtc/api/audio_codecs/opus:audio_encoder_opus", + "//third_party/webrtc/api/video_codecs:video_codecs_api", + "//third_party/webrtc/common_video:common_video", + "//third_party/webrtc/media:rtc_internal_video_codecs", + "//third_party/webrtc/media:rtc_media", + "//third_party/webrtc/media:rtc_media_base", + "//third_party/webrtc/modules/audio_device", + "//third_party/webrtc/modules/audio_processing", + "//third_party/webrtc/modules/audio_processing:audio_processing_statistics", + "//third_party/webrtc/modules/audio_processing/aec_dump", + "//third_party/webrtc/modules/video_coding:video_codec_interface", + "//third_party/webrtc/modules/video_coding:webrtc_h264", + "//third_party/webrtc/p2p:libstunprober", + "//third_party/webrtc/p2p:rtc_p2p", + "//third_party/webrtc/pc:libjingle_peerconnection", + "//third_party/webrtc/pc:peerconnection", + "//third_party/webrtc/pc:rtc_pc", + "//third_party/webrtc/pc:rtc_pc_base", + "//third_party/webrtc/rtc_base:rtc_base", + "//third_party/webrtc/rtc_base:rtc_task_queue", + "//third_party/webrtc/stats", + "//third_party/webrtc/system_wrappers", + "//third_party/webrtc_overrides:init_webrtc", "//third_party/widevine/cdm:headers", "//ui/accessibility", "//ui/base", @@ -625,279 +860,31 @@ deps += [ "//media/remoting" ] } - if (enable_webrtc) { - # WebRTC plugin-related stuff goes in a different section below. + if (enable_plugins) { sources += [ - "image_capture/image_capture_frame_grabber.cc", - "image_capture/image_capture_frame_grabber.h", - "media/stream/aec_dump_message_filter.cc", - "media/stream/aec_dump_message_filter.h", - "media/stream/apply_constraints_processor.cc", - "media/stream/apply_constraints_processor.h", - "media/stream/external_media_stream_audio_source.cc", - "media/stream/external_media_stream_audio_source.h", - "media/stream/local_media_stream_audio_source.cc", - "media/stream/local_media_stream_audio_source.h", - "media/stream/media_stream_audio_deliverer.h", - "media/stream/media_stream_audio_level_calculator.cc", - "media/stream/media_stream_audio_level_calculator.h", - "media/stream/media_stream_audio_processor.cc", - "media/stream/media_stream_audio_processor.h", - "media/stream/media_stream_audio_processor_options.cc", - "media/stream/media_stream_audio_processor_options.h", - "media/stream/media_stream_audio_source.cc", - "media/stream/media_stream_audio_source.h", - "media/stream/media_stream_audio_track.cc", - "media/stream/media_stream_audio_track.h", - "media/stream/media_stream_center.cc", - "media/stream/media_stream_center.h", - "media/stream/media_stream_constraints_util.cc", - "media/stream/media_stream_constraints_util.h", - "media/stream/media_stream_constraints_util_audio.cc", - "media/stream/media_stream_constraints_util_audio.h", - "media/stream/media_stream_constraints_util_sets.cc", - "media/stream/media_stream_constraints_util_sets.h", - "media/stream/media_stream_constraints_util_video_content.cc", - "media/stream/media_stream_constraints_util_video_content.h", - "media/stream/media_stream_constraints_util_video_device.cc", - "media/stream/media_stream_constraints_util_video_device.h", - "media/stream/media_stream_device_observer.cc", - "media/stream/media_stream_device_observer.h", - "media/stream/media_stream_dispatcher_eventhandler.h", - "media/stream/media_stream_registry_interface.h", - "media/stream/media_stream_renderer_factory_impl.cc", - "media/stream/media_stream_renderer_factory_impl.h", - "media/stream/media_stream_source.cc", - "media/stream/media_stream_source.h", - "media/stream/media_stream_track.cc", - "media/stream/media_stream_track.h", - "media/stream/media_stream_video_capturer_source.cc", - "media/stream/media_stream_video_capturer_source.h", - "media/stream/media_stream_video_renderer_sink.cc", - "media/stream/media_stream_video_renderer_sink.h", - "media/stream/media_stream_video_source.cc", - "media/stream/media_stream_video_source.h", - "media/stream/media_stream_video_track.cc", - "media/stream/media_stream_video_track.h", - "media/stream/processed_local_audio_source.cc", - "media/stream/processed_local_audio_source.h", - "media/stream/remote_media_stream_track_adapter.cc", - "media/stream/remote_media_stream_track_adapter.h", - "media/stream/secure_display_link_tracker.h", - "media/stream/track_audio_renderer.cc", - "media/stream/track_audio_renderer.h", - "media/stream/user_media_client_impl.cc", - "media/stream/user_media_client_impl.h", - "media/stream/user_media_processor.cc", - "media/stream/user_media_processor.h", - "media/stream/video_track_adapter.cc", - "media/stream/video_track_adapter.h", - "media/stream/webaudio_media_stream_source.cc", - "media/stream/webaudio_media_stream_source.h", - "media/stream/webmediaplayer_ms.cc", - "media/stream/webmediaplayer_ms.h", - "media/stream/webmediaplayer_ms_compositor.cc", - "media/stream/webmediaplayer_ms_compositor.h", - "media/webrtc/audio_codec_factory.cc", - "media/webrtc/audio_codec_factory.h", - "media/webrtc/media_stream_remote_video_source.cc", - "media/webrtc/media_stream_remote_video_source.h", - "media/webrtc/media_stream_track_metrics.cc", - "media/webrtc/media_stream_track_metrics.h", - "media/webrtc/media_stream_video_webrtc_sink.cc", - "media/webrtc/media_stream_video_webrtc_sink.h", - "media/webrtc/peer_connection_dependency_factory.cc", - "media/webrtc/peer_connection_dependency_factory.h", - "media/webrtc/peer_connection_remote_audio_source.cc", - "media/webrtc/peer_connection_remote_audio_source.h", - "media/webrtc/peer_connection_tracker.cc", - "media/webrtc/peer_connection_tracker.h", - "media/webrtc/rtc_certificate.cc", - "media/webrtc/rtc_certificate.h", - "media/webrtc/rtc_certificate_generator.cc", - "media/webrtc/rtc_certificate_generator.h", - "media/webrtc/rtc_data_channel_handler.cc", - "media/webrtc/rtc_data_channel_handler.h", - "media/webrtc/rtc_dtmf_sender_handler.cc", - "media/webrtc/rtc_dtmf_sender_handler.h", - "media/webrtc/rtc_event_log_output_sink.h", - "media/webrtc/rtc_event_log_output_sink_proxy.cc", - "media/webrtc/rtc_event_log_output_sink_proxy.h", - "media/webrtc/rtc_peer_connection_handler.cc", - "media/webrtc/rtc_peer_connection_handler.h", - "media/webrtc/rtc_rtp_contributing_source.cc", - "media/webrtc/rtc_rtp_contributing_source.h", - "media/webrtc/rtc_rtp_parameters.cc", - "media/webrtc/rtc_rtp_parameters.h", - "media/webrtc/rtc_rtp_receiver.cc", - "media/webrtc/rtc_rtp_receiver.h", - "media/webrtc/rtc_rtp_sender.cc", - "media/webrtc/rtc_rtp_sender.h", - "media/webrtc/rtc_stats.cc", - "media/webrtc/rtc_stats.h", - "media/webrtc/rtc_video_decoder.cc", - "media/webrtc/rtc_video_decoder.h", - "media/webrtc/rtc_video_decoder_factory.cc", - "media/webrtc/rtc_video_decoder_factory.h", - "media/webrtc/rtc_video_encoder.cc", - "media/webrtc/rtc_video_encoder.h", - "media/webrtc/rtc_video_encoder_factory.cc", - "media/webrtc/rtc_video_encoder_factory.h", - "media/webrtc/stun_field_trial.cc", - "media/webrtc/stun_field_trial.h", - "media/webrtc/track_observer.cc", - "media/webrtc/track_observer.h", - "media/webrtc/two_keys_adapter_map.h", - "media/webrtc/webrtc_audio_device_impl.cc", - "media/webrtc/webrtc_audio_device_impl.h", - "media/webrtc/webrtc_audio_device_not_impl.cc", - "media/webrtc/webrtc_audio_device_not_impl.h", - "media/webrtc/webrtc_audio_renderer.cc", - "media/webrtc/webrtc_audio_renderer.h", - "media/webrtc/webrtc_audio_sink.cc", - "media/webrtc/webrtc_audio_sink.h", - "media/webrtc/webrtc_media_stream_adapter.cc", - "media/webrtc/webrtc_media_stream_adapter.h", - "media/webrtc/webrtc_media_stream_adapter_map.cc", - "media/webrtc/webrtc_media_stream_adapter_map.h", - "media/webrtc/webrtc_media_stream_track_adapter.cc", - "media/webrtc/webrtc_media_stream_track_adapter.h", - "media/webrtc/webrtc_media_stream_track_adapter_map.cc", - "media/webrtc/webrtc_media_stream_track_adapter_map.h", - "media/webrtc/webrtc_set_remote_description_observer.cc", - "media/webrtc/webrtc_set_remote_description_observer.h", - "media/webrtc/webrtc_uma_histograms.cc", - "media/webrtc/webrtc_uma_histograms.h", - "media/webrtc/webrtc_video_capturer_adapter.cc", - "media/webrtc/webrtc_video_capturer_adapter.h", - "media/webrtc/webrtc_video_frame_adapter.cc", - "media/webrtc/webrtc_video_frame_adapter.h", - "media/webrtc_local_audio_source_provider.cc", - "media/webrtc_local_audio_source_provider.h", - "media/webrtc_logging.cc", - "media/webrtc_logging.h", - "media_capture_from_element/canvas_capture_handler.cc", - "media_capture_from_element/canvas_capture_handler.h", - "media_capture_from_element/html_audio_element_capturer_source.cc", - "media_capture_from_element/html_audio_element_capturer_source.h", - "media_capture_from_element/html_video_element_capturer_source.cc", - "media_capture_from_element/html_video_element_capturer_source.h", - "media_recorder/audio_track_encoder.cc", - "media_recorder/audio_track_encoder.h", - "media_recorder/audio_track_opus_encoder.cc", - "media_recorder/audio_track_opus_encoder.h", - "media_recorder/audio_track_pcm_encoder.cc", - "media_recorder/audio_track_pcm_encoder.h", - "media_recorder/audio_track_recorder.cc", - "media_recorder/audio_track_recorder.h", - "media_recorder/media_recorder_handler.cc", - "media_recorder/media_recorder_handler.h", - "media_recorder/vea_encoder.cc", - "media_recorder/vea_encoder.h", - "media_recorder/video_track_recorder.cc", - "media_recorder/video_track_recorder.h", - "media_recorder/vpx_encoder.cc", - "media_recorder/vpx_encoder.h", - "p2p/empty_network_manager.cc", - "p2p/empty_network_manager.h", - "p2p/filtering_network_manager.cc", - "p2p/filtering_network_manager.h", - "p2p/host_address_request.cc", - "p2p/host_address_request.h", - "p2p/ipc_network_manager.cc", - "p2p/ipc_network_manager.h", - "p2p/ipc_socket_factory.cc", - "p2p/ipc_socket_factory.h", - "p2p/network_list_observer.h", - "p2p/network_manager_uma.cc", - "p2p/network_manager_uma.h", - "p2p/port_allocator.cc", - "p2p/port_allocator.h", - "p2p/socket_client.h", - "p2p/socket_client_delegate.h", - "p2p/socket_client_impl.cc", - "p2p/socket_client_impl.h", - "p2p/socket_dispatcher.cc", - "p2p/socket_dispatcher.h", + "media/pepper/pepper_to_video_track_adapter.cc", + "media/pepper/pepper_to_video_track_adapter.h", + "media/pepper/video_track_to_pepper_adapter.cc", + "media/pepper/video_track_to_pepper_adapter.h", + "pepper/pepper_media_stream_audio_track_host.cc", + "pepper/pepper_media_stream_audio_track_host.h", + "pepper/pepper_media_stream_track_host_base.cc", + "pepper/pepper_media_stream_track_host_base.h", + "pepper/pepper_media_stream_video_track_host.cc", + "pepper/pepper_media_stream_video_track_host.h", + "pepper/pepper_video_destination_host.cc", + "pepper/pepper_video_destination_host.h", + "pepper/pepper_video_source_host.cc", + "pepper/pepper_video_source_host.h", ] + } - if (enable_plugins) { - sources += [ - "media/pepper/pepper_to_video_track_adapter.cc", - "media/pepper/pepper_to_video_track_adapter.h", - "media/pepper/video_track_to_pepper_adapter.cc", - "media/pepper/video_track_to_pepper_adapter.h", - "pepper/pepper_media_stream_audio_track_host.cc", - "pepper/pepper_media_stream_audio_track_host.h", - "pepper/pepper_media_stream_track_host_base.cc", - "pepper/pepper_media_stream_track_host_base.h", - "pepper/pepper_media_stream_video_track_host.cc", - "pepper/pepper_media_stream_video_track_host.h", - "pepper/pepper_video_destination_host.cc", - "pepper/pepper_video_destination_host.h", - "pepper/pepper_video_source_host.cc", - "pepper/pepper_video_source_host.h", - ] - } - - deps += [ - "//crypto", - "//jingle:jingle_glue", - "//third_party/libvpx", - "//third_party/opus", - "//third_party/webrtc/api:libjingle_logging_api", - "//third_party/webrtc/api:libjingle_peerconnection_api", - "//third_party/webrtc/api:optional", - "//third_party/webrtc/api:rtc_stats_api", - "//third_party/webrtc/api:video_frame_api", - "//third_party/webrtc/api:video_frame_api_i420", - "//third_party/webrtc/api/audio:aec3_factory", - "//third_party/webrtc/api/audio_codecs:audio_codecs_api", - "//third_party/webrtc/api/audio_codecs/L16:audio_decoder_L16", - "//third_party/webrtc/api/audio_codecs/L16:audio_encoder_L16", - "//third_party/webrtc/api/audio_codecs/g711:audio_decoder_g711", - "//third_party/webrtc/api/audio_codecs/g711:audio_encoder_g711", - "//third_party/webrtc/api/audio_codecs/g722:audio_decoder_g722", - "//third_party/webrtc/api/audio_codecs/g722:audio_encoder_g722", - "//third_party/webrtc/api/audio_codecs/isac:audio_decoder_isac", - "//third_party/webrtc/api/audio_codecs/isac:audio_encoder_isac", - "//third_party/webrtc/api/audio_codecs/opus:audio_decoder_opus", - "//third_party/webrtc/api/audio_codecs/opus:audio_encoder_opus", - "//third_party/webrtc/api/video_codecs:video_codecs_api", - "//third_party/webrtc/common_video:common_video", - "//third_party/webrtc/media:rtc_internal_video_codecs", - "//third_party/webrtc/media:rtc_media", - "//third_party/webrtc/media:rtc_media_base", - "//third_party/webrtc/modules/audio_device", - "//third_party/webrtc/modules/audio_processing", - "//third_party/webrtc/modules/audio_processing:audio_processing_statistics", - "//third_party/webrtc/modules/audio_processing/aec_dump", - "//third_party/webrtc/modules/video_coding:video_codec_interface", - "//third_party/webrtc/modules/video_coding:webrtc_h264", - "//third_party/webrtc/p2p:libstunprober", - "//third_party/webrtc/p2p:rtc_p2p", - "//third_party/webrtc/pc:libjingle_peerconnection", - "//third_party/webrtc/pc:peerconnection", - "//third_party/webrtc/pc:rtc_pc", - "//third_party/webrtc/pc:rtc_pc_base", - "//third_party/webrtc/rtc_base:rtc_base", - "//third_party/webrtc/rtc_base:rtc_task_queue", - "//third_party/webrtc/stats", - "//third_party/webrtc/system_wrappers", - "//third_party/webrtc_overrides:init_webrtc", - ] - if (rtc_use_h264) { - sources += [ - "media_recorder/h264_encoder.cc", - "media_recorder/h264_encoder.h", - ] - deps += [ "//third_party/openh264:encoder" ] - } - } else { + if (rtc_use_h264) { sources += [ - "media/webrtc_logging.h", - "media/webrtc_logging_noop.cc", + "media_recorder/h264_encoder.cc", + "media_recorder/h264_encoder.h", ] + deps += [ "//third_party/openh264:encoder" ] } if (enable_plugins) {
diff --git a/content/renderer/gpu/actions_parser.cc b/content/renderer/gpu/actions_parser.cc index 5cb285a..fe0b34a 100644 --- a/content/renderer/gpu/actions_parser.cc +++ b/content/renderer/gpu/actions_parser.cc
@@ -117,14 +117,6 @@ if (source_type_.empty()) { source_type_ = source_type; - -#if defined(OS_MACOSX) - if (source_type == "touch") { - error_message_ = - base::StringPrintf("Mac OS does not support touch events"); - return false; - } -#endif // defined(OS_MACOSX) } if (source_type_ != source_type) {
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc index c7d09c3..622625df 100644 --- a/content/renderer/loader/web_url_loader_impl.cc +++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -142,32 +142,21 @@ WebURLLoadTiming* url_timing) { DCHECK(!load_timing.request_start.is_null()); - const TimeTicks kNullTicks; url_timing->Initialize(); - url_timing->SetRequestTime( - (load_timing.request_start - kNullTicks).InSecondsF()); - url_timing->SetProxyStart( - (load_timing.proxy_resolve_start - kNullTicks).InSecondsF()); - url_timing->SetProxyEnd( - (load_timing.proxy_resolve_end - kNullTicks).InSecondsF()); - url_timing->SetDNSStart( - (load_timing.connect_timing.dns_start - kNullTicks).InSecondsF()); - url_timing->SetDNSEnd( - (load_timing.connect_timing.dns_end - kNullTicks).InSecondsF()); - url_timing->SetConnectStart( - (load_timing.connect_timing.connect_start - kNullTicks).InSecondsF()); - url_timing->SetConnectEnd( - (load_timing.connect_timing.connect_end - kNullTicks).InSecondsF()); - url_timing->SetSSLStart( - (load_timing.connect_timing.ssl_start - kNullTicks).InSecondsF()); - url_timing->SetSSLEnd( - (load_timing.connect_timing.ssl_end - kNullTicks).InSecondsF()); - url_timing->SetSendStart((load_timing.send_start - kNullTicks).InSecondsF()); - url_timing->SetSendEnd((load_timing.send_end - kNullTicks).InSecondsF()); - url_timing->SetReceiveHeadersEnd( - (load_timing.receive_headers_end - kNullTicks).InSecondsF()); - url_timing->SetPushStart((load_timing.push_start - kNullTicks).InSecondsF()); - url_timing->SetPushEnd((load_timing.push_end - kNullTicks).InSecondsF()); + url_timing->SetRequestTime(load_timing.request_start); + url_timing->SetProxyStart(load_timing.proxy_resolve_start); + url_timing->SetProxyEnd(load_timing.proxy_resolve_end); + url_timing->SetDNSStart(load_timing.connect_timing.dns_start); + url_timing->SetDNSEnd(load_timing.connect_timing.dns_end); + url_timing->SetConnectStart(load_timing.connect_timing.connect_start); + url_timing->SetConnectEnd(load_timing.connect_timing.connect_end); + url_timing->SetSSLStart(load_timing.connect_timing.ssl_start); + url_timing->SetSSLEnd(load_timing.connect_timing.ssl_end); + url_timing->SetSendStart(load_timing.send_start); + url_timing->SetSendEnd(load_timing.send_end); + url_timing->SetReceiveHeadersEnd(load_timing.receive_headers_end); + url_timing->SetPushStart(load_timing.push_start); + url_timing->SetPushEnd(load_timing.push_end); } net::RequestPriority ConvertWebKitPriorityToNetPriority( @@ -1237,11 +1226,8 @@ if (!info.load_timing.receive_headers_end.is_null()) { WebURLLoadTiming timing; PopulateURLLoadTiming(info.load_timing, &timing); - const TimeTicks kNullTicks; - timing.SetWorkerStart( - (info.service_worker_start_time - kNullTicks).InSecondsF()); - timing.SetWorkerReady( - (info.service_worker_ready_time - kNullTicks).InSecondsF()); + timing.SetWorkerStart(info.service_worker_start_time); + timing.SetWorkerReady(info.service_worker_ready_time); response->SetLoadTiming(timing); }
diff --git a/content/renderer/media/stream/media_stream_constraints_util.cc b/content/renderer/media/stream/media_stream_constraints_util.cc index bcc96ef2..52a4824e 100644 --- a/content/renderer/media/stream/media_stream_constraints_util.cc +++ b/content/renderer/media/stream/media_stream_constraints_util.cc
@@ -9,6 +9,7 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "content/public/common/media_stream_request.h" #include "content/renderer/media/stream/media_stream_constraints_util_sets.h" #include "content/renderer/media/stream/media_stream_constraints_util_video_device.h" #include "third_party/blink/public/platform/web_string.h" @@ -327,11 +328,15 @@ const blink::WebString& device_id, const media::VideoCaptureFormats& formats, media::VideoFacingMode facing_mode, - bool is_device_capture) { + bool is_device_capture, + const base::Optional<std::string>& group_id) { blink::WebMediaStreamSource::Capabilities capabilities; - capabilities.device_id = device_id; - if (is_device_capture) + capabilities.device_id = std::move(device_id); + if (is_device_capture) { capabilities.facing_mode = ToWebFacingMode(facing_mode); + if (group_id) + capabilities.group_id = blink::WebString::FromUTF8(*group_id); + } if (!formats.empty()) { int max_width = 1; int max_height = 1;
diff --git a/content/renderer/media/stream/media_stream_constraints_util.h b/content/renderer/media/stream/media_stream_constraints_util.h index fcd85ec2..0e40d07 100644 --- a/content/renderer/media/stream/media_stream_constraints_util.h +++ b/content/renderer/media/stream/media_stream_constraints_util.h
@@ -373,10 +373,12 @@ // This method computes capabilities for a video source based on the given // |formats|. |facing_mode| is valid only in case of video device capture. blink::WebMediaStreamSource::Capabilities CONTENT_EXPORT -ComputeCapabilitiesForVideoSource(const blink::WebString& device_id, - const media::VideoCaptureFormats& formats, - media::VideoFacingMode facing_mode, - bool is_device_capture); +ComputeCapabilitiesForVideoSource( + const blink::WebString& device_id, + const media::VideoCaptureFormats& formats, + media::VideoFacingMode facing_mode, + bool is_device_capture, + const base::Optional<std::string>& group_id = base::nullopt); } // namespace content
diff --git a/content/renderer/media/stream/user_media_processor.cc b/content/renderer/media/stream/user_media_processor.cc index cc173a1..c4642c9 100644 --- a/content/renderer/media/stream/user_media_processor.cc +++ b/content/renderer/media/stream/user_media_processor.cc
@@ -812,7 +812,8 @@ source.SetCapabilities(ComputeCapabilitiesForVideoSource( blink::WebString::FromUTF8(device.id), *current_request_info_->GetNativeVideoFormats(device.id), - device.video_facing, current_request_info_->is_video_device_capture())); + device.video_facing, current_request_info_->is_video_device_capture(), + device.group_id)); local_sources_.push_back(source); } return source;
diff --git a/content/renderer/media/webrtc_logging_noop.cc b/content/renderer/media/webrtc_logging_noop.cc deleted file mode 100644 index 00bfdef..0000000 --- a/content/renderer/media/webrtc_logging_noop.cc +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2013 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 "content/renderer/media/webrtc_logging.h" - -namespace content { - -void WebRtcLogMessage(const std::string& message) {} - -} // namespace content
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index a0be375f..3e30a5e3 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -554,11 +554,7 @@ base::TimeTicks::Now(), info.url_request.HttpMethod().Latin1(), GetRequestBodyForWebURLRequest(info.url_request), source_location, should_check_main_world_csp, false /* started_from_context_menu */, - info.url_request.HasUserGesture(), - info.url_request.GetSuggestedFilename().has_value() - ? base::Optional<std::string>( - info.url_request.GetSuggestedFilename()->Utf8()) - : base::nullopt); + info.url_request.HasUserGesture()); } WebFrameLoadType NavigationTypeToLoadType( @@ -5967,10 +5963,7 @@ info.url_request.CheckForBrowserSideNavigation() && // No need to dispatch beforeunload if the frame has not committed a // navigation and contains an empty initial document. - (has_accessed_initial_document_ || !current_history_item_.IsNull()) && - // Don't dispatch beforeunload if the navigation might end up as a - // download. - !info.url_request.GetSuggestedFilename().has_value(); + (has_accessed_initial_document_ || !current_history_item_.IsNull()); if (should_dispatch_before_unload) { // Execute the BeforeUnload event. If asked not to proceed or the frame is @@ -6406,11 +6399,6 @@ : content::Referrer(); params.disposition = RenderViewImpl::NavigationPolicyToDisposition(policy); params.triggering_event_info = info.triggering_event_info; - params.suggested_filename = - info.url_request.GetSuggestedFilename().has_value() - ? base::Optional<std::string>( - info.url_request.GetSuggestedFilename()->Utf8()) - : base::nullopt; if (IsBrowserInitiated(pending_navigation_params_.get())) { // This is necessary to preserve the should_replace_current_entry value on
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 6ef8d1fd..a355de34 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -770,10 +770,6 @@ params.should_replace_current_entry = should_replace_current_entry; params.user_gesture = request.HasUserGesture(); params.triggering_event_info = blink::WebTriggeringEventInfo::kUnknown; - params.suggested_filename = - request.GetSuggestedFilename().has_value() - ? base::Optional<std::string>(request.GetSuggestedFilename()->Utf8()) - : base::nullopt; Send(new FrameHostMsg_OpenURL(routing_id_, params)); }
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index f6ae808..424f38f 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -966,7 +966,14 @@ static_cast<blink::WebEffectiveConnectionType>( prefs.low_priority_iframes_threshold)); - settings->SetPictureInPictureEnabled(prefs.picture_in_picture_enabled); + // TODO(crbug.com/806249): Remove this once Picture-in-Picture is compatible + // without GPU compositing. + RenderThreadImpl* render_thread = RenderThreadImpl::current(); + if (render_thread && render_thread->IsGpuCompositingDisabled()) { + settings->SetPictureInPictureEnabled(false); + } else { + settings->SetPictureInPictureEnabled(prefs.picture_in_picture_enabled); + } #if defined(OS_MACOSX) settings->SetDoubleTapToZoomEnabled(true);
diff --git a/content/shell/browser/shell.cc b/content/shell/browser/shell.cc index e2831bb..61a248f6 100644 --- a/content/shell/browser/shell.cc +++ b/content/shell/browser/shell.cc
@@ -402,7 +402,6 @@ load_url_params.is_renderer_initiated = params.is_renderer_initiated; load_url_params.should_replace_current_entry = params.should_replace_current_entry; - load_url_params.suggested_filename = params.suggested_filename; if (params.uses_post) { load_url_params.load_type = NavigationController::LOAD_TYPE_HTTP_POST;
diff --git a/content/shell/test_runner/web_frame_test_client.cc b/content/shell/test_runner/web_frame_test_client.cc index 28bf873..f5c58ed 100644 --- a/content/shell/test_runner/web_frame_test_client.cc +++ b/content/shell/test_runner/web_frame_test_client.cc
@@ -386,15 +386,6 @@ void WebFrameTestClient::DidStartProvisionalLoad( blink::WebDocumentLoader* document_loader, blink::WebURLRequest& request) { - if (request.GetSuggestedFilename().has_value() && - test_runner()->shouldWaitUntilExternalURLLoad()) { - delegate_->PrintMessage( - std::string("Downloading URL with suggested filename \"") + - request.GetSuggestedFilename()->Utf8() + "\"\n"); - delegate_->PostTask(base::BindRepeating(&WebTestDelegate::TestFinished, - base::Unretained(delegate_))); - } - // PlzNavigate // A provisional load notification is received when a frame navigation is // sent to the browser. We don't want to log it again during commit.
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 7f4738f..4a33896c 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -174,6 +174,18 @@ "../public/test/web_contents_binding_set_test_binder.h", "../public/test/web_contents_tester.cc", "../public/test/web_contents_tester.h", + "../renderer/media/stream/mock_mojo_media_stream_dispatcher_host.cc", + "../renderer/media/stream/mock_mojo_media_stream_dispatcher_host.h", + "../renderer/media/webrtc/mock_data_channel_impl.cc", + "../renderer/media/webrtc/mock_data_channel_impl.h", + "../renderer/media/webrtc/mock_peer_connection_dependency_factory.cc", + "../renderer/media/webrtc/mock_peer_connection_dependency_factory.h", + "../renderer/media/webrtc/mock_peer_connection_impl.cc", + "../renderer/media/webrtc/mock_peer_connection_impl.h", + "../renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc", + "../renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h", + "../renderer/media/webrtc/test/webrtc_stats_report_obtainer.cc", + "../renderer/media/webrtc/test/webrtc_stats_report_obtainer.h", "accessibility_browser_test_utils.cc", "accessibility_browser_test_utils.h", "appcache_test_helper.cc", @@ -339,6 +351,14 @@ "//storage/common", "//testing/gmock", "//testing/gtest", + "//third_party/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/api:rtc_stats_api", + "//third_party/webrtc/media:rtc_media_base", + "//third_party/webrtc/modules/video_capture", + "//third_party/webrtc/pc:libjingle_peerconnection", + "//third_party/webrtc/rtc_base:rtc_base_approved", + "//third_party/webrtc/stats:rtc_stats", + "//third_party/webrtc_overrides:init_webrtc", "//tools/v8_context_snapshot:v8_context_snapshot", "//ui/accessibility:ax_enums_mojo", "//ui/base", @@ -389,34 +409,6 @@ ] } - if (enable_webrtc) { - sources += [ - "../renderer/media/stream/mock_mojo_media_stream_dispatcher_host.cc", - "../renderer/media/stream/mock_mojo_media_stream_dispatcher_host.h", - "../renderer/media/webrtc/mock_data_channel_impl.cc", - "../renderer/media/webrtc/mock_data_channel_impl.h", - "../renderer/media/webrtc/mock_peer_connection_dependency_factory.cc", - "../renderer/media/webrtc/mock_peer_connection_dependency_factory.h", - "../renderer/media/webrtc/mock_peer_connection_impl.cc", - "../renderer/media/webrtc/mock_peer_connection_impl.h", - "../renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc", - "../renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h", - "../renderer/media/webrtc/test/webrtc_stats_report_obtainer.cc", - "../renderer/media/webrtc/test/webrtc_stats_report_obtainer.h", - ] - - deps += [ - "//third_party/webrtc/api:libjingle_peerconnection_api", - "//third_party/webrtc/api:rtc_stats_api", - "//third_party/webrtc/media:rtc_media_base", - "//third_party/webrtc/modules/video_capture", - "//third_party/webrtc/pc:libjingle_peerconnection", - "//third_party/webrtc/rtc_base:rtc_base_approved", - "//third_party/webrtc/stats:rtc_stats", - "//third_party/webrtc_overrides:init_webrtc", - ] - } - if (use_glib) { configs += [ "//build/config/linux:glib" ] } @@ -838,6 +830,28 @@ "../browser/web_contents_binding_set_browsertest.cc", "../browser/web_package/web_package_request_handler_browsertest.cc", "../browser/webkit_browsertest.cc", + "../browser/webrtc/webrtc_add_stream_no_deadlock_browsertest.cc", + "../browser/webrtc/webrtc_audio_browsertest.cc", + "../browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc", + "../browser/webrtc/webrtc_browsertest.cc", + "../browser/webrtc/webrtc_capture_from_element_browsertest.cc", + "../browser/webrtc/webrtc_constraints_browsertest.cc", + "../browser/webrtc/webrtc_content_browsertest_base.cc", + "../browser/webrtc/webrtc_content_browsertest_base.h", + "../browser/webrtc/webrtc_data_browsertest.cc", + "../browser/webrtc/webrtc_datachannel_browsertest.cc", + "../browser/webrtc/webrtc_depth_capture_browsertest.cc", + "../browser/webrtc/webrtc_getusermedia_browsertest.cc", + "../browser/webrtc/webrtc_image_capture_browsertest.cc", + "../browser/webrtc/webrtc_internals_browsertest.cc", + "../browser/webrtc/webrtc_ip_permissions_browsertest.cc", + "../browser/webrtc/webrtc_media_recorder_browsertest.cc", + "../browser/webrtc/webrtc_stress_pause_browsertest.cc", + "../browser/webrtc/webrtc_stress_resolution_switch_browsertest.cc", + "../browser/webrtc/webrtc_stress_source_switch_browsertest.cc", + "../browser/webrtc/webrtc_video_capture_browsertest.cc", + "../browser/webrtc/webrtc_webcam_browsertest.cc", + "../browser/webrtc/webrtc_webcam_browsertest.h", "../browser/webui/web_ui_mojo_browsertest.cc", "../renderer/accessibility/render_accessibility_impl_browsertest.cc", "../renderer/blink_platform_audio_hardware_browsertest.cc", @@ -891,6 +905,7 @@ "//content/public/browser", "//content/public/child", "//content/public/common", + "//content/public/common:buildflags", "//content/public/gpu", "//content/public/renderer", "//content/renderer:for_content_tests", @@ -1094,36 +1109,6 @@ [ "../browser/compositor/image_transport_factory_browsertest.cc" ] } - if (enable_webrtc) { - sources += [ - "../browser/webrtc/webrtc_audio_browsertest.cc", - "../browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc", - "../browser/webrtc/webrtc_browsertest.cc", - "../browser/webrtc/webrtc_capture_from_element_browsertest.cc", - "../browser/webrtc/webrtc_constraints_browsertest.cc", - "../browser/webrtc/webrtc_content_browsertest_base.cc", - "../browser/webrtc/webrtc_content_browsertest_base.h", - "../browser/webrtc/webrtc_data_browsertest.cc", - "../browser/webrtc/webrtc_datachannel_browsertest.cc", - "../browser/webrtc/webrtc_depth_capture_browsertest.cc", - "../browser/webrtc/webrtc_getusermedia_browsertest.cc", - "../browser/webrtc/webrtc_image_capture_browsertest.cc", - "../browser/webrtc/webrtc_internals_browsertest.cc", - "../browser/webrtc/webrtc_ip_permissions_browsertest.cc", - "../browser/webrtc/webrtc_media_recorder_browsertest.cc", - "../browser/webrtc/webrtc_stress_pause_browsertest.cc", - "../browser/webrtc/webrtc_stress_resolution_switch_browsertest.cc", - "../browser/webrtc/webrtc_stress_source_switch_browsertest.cc", - "../browser/webrtc/webrtc_video_capture_browsertest.cc", - "../browser/webrtc/webrtc_webcam_browsertest.cc", - "../browser/webrtc/webrtc_webcam_browsertest.h", - ] - deps += [ - "//content/public/common:buildflags", - "//testing/perf", - ] - } - if (enable_plugins) { sources += [ "../browser/plugin_service_impl_browsertest.cc", @@ -1369,6 +1354,7 @@ "../browser/manifest/manifest_icon_downloader_unittest.cc", "../browser/manifest/manifest_icon_selector_unittest.cc", "../browser/media/audible_metrics_unittest.cc", + "../browser/media/audio_input_stream_broker_unittest.cc", "../browser/media/audio_output_stream_broker_unittest.cc", "../browser/media/audio_stream_monitor_unittest.cc", "../browser/media/capture/audio_mirroring_manager_unittest.cc", @@ -1458,6 +1444,11 @@ "../browser/renderer_host/media/video_capture_manager_unittest.cc", "../browser/renderer_host/media/video_capture_unittest.cc", "../browser/renderer_host/overscroll_controller_unittest.cc", + "../browser/renderer_host/p2p/socket_host_tcp_server_unittest.cc", + "../browser/renderer_host/p2p/socket_host_tcp_unittest.cc", + "../browser/renderer_host/p2p/socket_host_test_utils.cc", + "../browser/renderer_host/p2p/socket_host_test_utils.h", + "../browser/renderer_host/p2p/socket_host_udp_unittest.cc", "../browser/renderer_host/render_process_host_unittest.cc", "../browser/renderer_host/render_view_host_unittest.cc", "../browser/renderer_host/render_widget_host_input_event_router_unittest.cc", @@ -1528,6 +1519,8 @@ "../browser/web_package/signed_exchange_header_parser_unittest.cc", "../browser/web_package/signed_exchange_header_unittest.cc", "../browser/web_package/signed_exchange_signature_verifier_unittest.cc", + "../browser/webrtc/webrtc_internals_message_handler_unittest.cc", + "../browser/webrtc/webrtc_internals_unittest.cc", "../browser/websockets/websocket_manager_unittest.cc", "../browser/webui/url_data_manager_backend_unittest.cc", "../browser/webui/web_ui_data_source_unittest.cc", @@ -1621,9 +1614,65 @@ "../renderer/media/mojo_audio_output_ipc_unittest.cc", "../renderer/media/render_media_log_unittest.cc", "../renderer/media/renderer_webaudiodevice_impl_unittest.cc", + "../renderer/media/stream/media_stream_audio_processor_unittest.cc", + "../renderer/media/stream/media_stream_audio_unittest.cc", + "../renderer/media/stream/media_stream_constraints_util_audio_unittest.cc", + "../renderer/media/stream/media_stream_constraints_util_sets_unittest.cc", + "../renderer/media/stream/media_stream_constraints_util_unittest.cc", + "../renderer/media/stream/media_stream_constraints_util_video_content_unittest.cc", + "../renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc", + "../renderer/media/stream/media_stream_device_observer_unittest.cc", + "../renderer/media/stream/media_stream_video_capturer_source_unittest.cc", + "../renderer/media/stream/media_stream_video_renderer_sink_unittest.cc", + "../renderer/media/stream/media_stream_video_source_unittest.cc", + "../renderer/media/stream/media_stream_video_track_unittest.cc", + "../renderer/media/stream/mock_constraint_factory.cc", + "../renderer/media/stream/mock_constraint_factory.h", + "../renderer/media/stream/mock_media_stream_registry.cc", + "../renderer/media/stream/mock_media_stream_registry.h", + "../renderer/media/stream/mock_media_stream_video_sink.cc", + "../renderer/media/stream/mock_media_stream_video_sink.h", + "../renderer/media/stream/mock_media_stream_video_source.cc", + "../renderer/media/stream/mock_media_stream_video_source.h", + "../renderer/media/stream/processed_local_audio_source_unittest.cc", + "../renderer/media/stream/user_media_client_impl_unittest.cc", + "../renderer/media/stream/video_track_adapter_unittest.cc", + "../renderer/media/stream/webmediaplayer_ms_unittest.cc", "../renderer/media/video_capture_impl_manager_unittest.cc", "../renderer/media/video_capture_impl_unittest.cc", + "../renderer/media/webrtc/media_stream_remote_video_source_unittest.cc", + "../renderer/media/webrtc/media_stream_track_metrics_unittest.cc", + "../renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc", + "../renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc", + "../renderer/media/webrtc/peer_connection_tracker_unittest.cc", + "../renderer/media/webrtc/rtc_data_channel_handler_unittest.cc", + "../renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc", + "../renderer/media/webrtc/rtc_rtp_parameters_unittest.cc", + "../renderer/media/webrtc/rtc_rtp_receiver_unittest.cc", + "../renderer/media/webrtc/rtc_rtp_sender_unittest.cc", + "../renderer/media/webrtc/rtc_stats_unittest.cc", + "../renderer/media/webrtc/rtc_video_decoder_unittest.cc", + "../renderer/media/webrtc/rtc_video_encoder_unittest.cc", + "../renderer/media/webrtc/stun_field_trial_unittest.cc", + "../renderer/media/webrtc/two_keys_adapter_map_unittest.cc", + "../renderer/media/webrtc/webrtc_audio_renderer_unittest.cc", + "../renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc", + "../renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc", + "../renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc", + "../renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc", + "../renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc", + "../renderer/media/webrtc/webrtc_uma_histograms_unittest.cc", + "../renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc", + "../renderer/media/webrtc_local_audio_source_provider_unittest.cc", + "../renderer/media_capture_from_element/canvas_capture_handler_unittest.cc", + "../renderer/media_capture_from_element/html_audio_element_capturer_source_unittest.cc", + "../renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc", + "../renderer/media_recorder/audio_track_recorder_unittest.cc", + "../renderer/media_recorder/media_recorder_handler_unittest.cc", + "../renderer/media_recorder/video_track_recorder_unittest.cc", "../renderer/notifications/notification_data_conversions_unittest.cc", + "../renderer/p2p/filtering_network_manager_unittest.cc", + "../renderer/p2p/ipc_network_manager_unittest.cc", "../renderer/peripheral_content_heuristic_unittest.cc", "../renderer/render_thread_impl_unittest.cc", "../renderer/render_widget_unittest.cc", @@ -1738,6 +1787,7 @@ "//services/device/public/cpp/generic_sensor", "//services/device/public/cpp/test:test_support", "//services/device/public/mojom", + "//services/device/public/mojom", "//services/file:lib", "//services/file/public/mojom", "//services/metrics/public/cpp:ukm_builders", @@ -1760,8 +1810,24 @@ "//third_party/blink/public:blink", "//third_party/icu", "//third_party/leveldatabase", + "//third_party/libyuv", "//third_party/metrics_proto", + "//third_party/opus", "//third_party/re2", + "//third_party/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/api:rtc_stats_api", + "//third_party/webrtc/api:video_frame_api", + "//third_party/webrtc/api:video_frame_api_i420", + "//third_party/webrtc/api/video_codecs:video_codecs_api", + "//third_party/webrtc/media:rtc_media", + "//third_party/webrtc/modules/desktop_capture:primitives", + "//third_party/webrtc/modules/video_capture", + "//third_party/webrtc/modules/video_coding:video_codec_interface", + "//third_party/webrtc/pc:libjingle_peerconnection", + "//third_party/webrtc/rtc_base:rtc_base", + "//third_party/webrtc/stats:rtc_stats_test_utils", + "//third_party/webrtc_overrides", + "//third_party/webrtc_overrides:init_webrtc", "//third_party/widevine/cdm:headers", "//ui/accessibility", "//ui/base:test_support", @@ -1779,6 +1845,7 @@ "//ui/gl", "//ui/gl:test_support", "//ui/latency:test_support", + "//ui/shell_dialogs:shell_dialogs", ] data_deps = [ @@ -1796,8 +1863,6 @@ } if (enable_plugins) { - # Put WebRTC-related plugins sources in the "enable_webrtc && - # enable_plugins" section below. sources += [ "../browser/plugin_service_impl_unittest.cc", "../browser/renderer_host/pepper/browser_ppapi_host_test.cc", @@ -1806,6 +1871,8 @@ "../browser/renderer_host/pepper/pepper_gamepad_host_unittest.cc", "../browser/renderer_host/pepper/pepper_printing_host_unittest.cc", "../browser/renderer_host/pepper/quota_reservation_unittest.cc", + "../renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc", + "../renderer/media/pepper/video_track_to_pepper_adapter_unittest.cc", "../renderer/pepper/event_conversion_unittest.cc", "../renderer/pepper/host_var_tracker_unittest.cc", "../renderer/pepper/mock_resource.h", @@ -1827,121 +1894,22 @@ ] } - if (enable_webrtc) { - # Put WebRTC-related plugins sources in the "enable_webrtc && - # enable_plugins" section below. - sources += [ - "../browser/renderer_host/p2p/socket_host_tcp_server_unittest.cc", - "../browser/renderer_host/p2p/socket_host_tcp_unittest.cc", - "../browser/renderer_host/p2p/socket_host_test_utils.cc", - "../browser/renderer_host/p2p/socket_host_test_utils.h", - "../browser/renderer_host/p2p/socket_host_udp_unittest.cc", - "../browser/webrtc/webrtc_internals_message_handler_unittest.cc", - "../browser/webrtc/webrtc_internals_unittest.cc", - "../renderer/media/stream/media_stream_audio_processor_unittest.cc", - "../renderer/media/stream/media_stream_audio_unittest.cc", - "../renderer/media/stream/media_stream_constraints_util_audio_unittest.cc", - "../renderer/media/stream/media_stream_constraints_util_sets_unittest.cc", - "../renderer/media/stream/media_stream_constraints_util_unittest.cc", - "../renderer/media/stream/media_stream_constraints_util_video_content_unittest.cc", - "../renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc", - "../renderer/media/stream/media_stream_device_observer_unittest.cc", - "../renderer/media/stream/media_stream_video_capturer_source_unittest.cc", - "../renderer/media/stream/media_stream_video_renderer_sink_unittest.cc", - "../renderer/media/stream/media_stream_video_source_unittest.cc", - "../renderer/media/stream/media_stream_video_track_unittest.cc", - "../renderer/media/stream/mock_constraint_factory.cc", - "../renderer/media/stream/mock_constraint_factory.h", - "../renderer/media/stream/mock_media_stream_registry.cc", - "../renderer/media/stream/mock_media_stream_registry.h", - "../renderer/media/stream/mock_media_stream_video_sink.cc", - "../renderer/media/stream/mock_media_stream_video_sink.h", - "../renderer/media/stream/mock_media_stream_video_source.cc", - "../renderer/media/stream/mock_media_stream_video_source.h", - "../renderer/media/stream/processed_local_audio_source_unittest.cc", - "../renderer/media/stream/user_media_client_impl_unittest.cc", - "../renderer/media/stream/video_track_adapter_unittest.cc", - "../renderer/media/stream/webmediaplayer_ms_unittest.cc", - "../renderer/media/webrtc/media_stream_remote_video_source_unittest.cc", - "../renderer/media/webrtc/media_stream_track_metrics_unittest.cc", - "../renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc", - "../renderer/media/webrtc/peer_connection_dependency_factory_unittest.cc", - "../renderer/media/webrtc/peer_connection_tracker_unittest.cc", - "../renderer/media/webrtc/rtc_data_channel_handler_unittest.cc", - "../renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc", - "../renderer/media/webrtc/rtc_rtp_parameters_unittest.cc", - "../renderer/media/webrtc/rtc_rtp_receiver_unittest.cc", - "../renderer/media/webrtc/rtc_rtp_sender_unittest.cc", - "../renderer/media/webrtc/rtc_stats_unittest.cc", - "../renderer/media/webrtc/rtc_video_decoder_unittest.cc", - "../renderer/media/webrtc/rtc_video_encoder_unittest.cc", - "../renderer/media/webrtc/stun_field_trial_unittest.cc", - "../renderer/media/webrtc/two_keys_adapter_map_unittest.cc", - "../renderer/media/webrtc/webrtc_audio_renderer_unittest.cc", - "../renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc", - "../renderer/media/webrtc/webrtc_media_stream_adapter_unittest.cc", - "../renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc", - "../renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc", - "../renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc", - "../renderer/media/webrtc/webrtc_uma_histograms_unittest.cc", - "../renderer/media/webrtc/webrtc_video_capturer_adapter_unittest.cc", - "../renderer/media/webrtc_local_audio_source_provider_unittest.cc", - "../renderer/media_capture_from_element/canvas_capture_handler_unittest.cc", - "../renderer/media_capture_from_element/html_audio_element_capturer_source_unittest.cc", - "../renderer/media_capture_from_element/html_video_element_capturer_source_unittest.cc", + if (is_chromecast) { + sources -= [ "../renderer/media_recorder/audio_track_recorder_unittest.cc", "../renderer/media_recorder/media_recorder_handler_unittest.cc", "../renderer/media_recorder/video_track_recorder_unittest.cc", - "../renderer/p2p/filtering_network_manager_unittest.cc", - "../renderer/p2p/ipc_network_manager_unittest.cc", - ] - deps += [ - "//services/device/public/mojom", - "//third_party/libyuv", - "//third_party/opus", - "//third_party/webrtc/api:libjingle_peerconnection_api", - "//third_party/webrtc/api:rtc_stats_api", - "//third_party/webrtc/api:video_frame_api", - "//third_party/webrtc/api:video_frame_api_i420", - "//third_party/webrtc/api/video_codecs:video_codecs_api", - "//third_party/webrtc/media:rtc_media", - "//third_party/webrtc/modules/desktop_capture:primitives", - "//third_party/webrtc/modules/video_capture", - "//third_party/webrtc/modules/video_coding:video_codec_interface", - "//third_party/webrtc/pc:libjingle_peerconnection", - "//third_party/webrtc/rtc_base:rtc_base", - "//third_party/webrtc/stats:rtc_stats_test_utils", - "//third_party/webrtc_overrides", - "//third_party/webrtc_overrides:init_webrtc", - "//ui/shell_dialogs:shell_dialogs", - ] - - if (is_linux || is_mac || is_win) { - sources += - [ "../browser/media/capture/desktop_capture_device_unittest.cc" ] - deps += [ "//third_party/webrtc/modules/desktop_capture" ] - } - - if (is_chromecast) { - sources -= [ - "../renderer/media_recorder/audio_track_recorder_unittest.cc", - "../renderer/media_recorder/media_recorder_handler_unittest.cc", - "../renderer/media_recorder/video_track_recorder_unittest.cc", - ] - } - } - - if (enable_webrtc && enable_plugins) { - sources += [ - "../renderer/media/pepper/pepper_to_video_track_adapter_unittest.cc", - "../renderer/media/pepper/video_track_to_pepper_adapter_unittest.cc", ] } # Screen capture unit tests. if (is_linux || is_mac || is_win) { - deps += [ "//third_party/libyuv" ] + deps += [ + "//third_party/libyuv", + "//third_party/webrtc/modules/desktop_capture", + ] sources += [ + "../browser/media/capture/desktop_capture_device_unittest.cc", "../browser/media/capture/frame_sink_video_capture_device_unittest.cc", ] if (use_aura) {
diff --git a/content/test/data/media/peerconnection-add-stream.html b/content/test/data/media/peerconnection-add-stream.html new file mode 100644 index 0000000..1eefa16f --- /dev/null +++ b/content/test/data/media/peerconnection-add-stream.html
@@ -0,0 +1,33 @@ +<html> +<body id="body"> + <h1>PeerConnection add stream test</h1> +</body> +<script type="text/javascript" src="webrtc_test_utilities.js"></script> +<script type="text/javascript"> + +function runTest() { + let pc1 = new RTCPeerConnection(); + var stream; + navigator.mediaDevices.getUserMedia({audio: true, video: true}) + .then(theStream => { + stream = theStream; + pc1.addStream(stream); + return pc1.createOffer({offerToReceiveAudio: true, offerToReceiveVideo: true}); + }).then(offer => { + pc1.setLocalDescription(offer); + return offer; + }).then(offer => { + const pc2 = new RTCPeerConnection(); + pc2.setRemoteDescription(pc1.localDescription); + pc2.addStream(stream); + pc2.createAnswer(); + }).then(() => { + reportTestSuccess(); + }).catch(e => { + console.error(`Unexpected error: ${e}`); + failTest(`Unexpected error: ${e}`); + }); +} + +</script> +</html>
diff --git a/extensions/browser/extension_navigation_throttle.cc b/extensions/browser/extension_navigation_throttle.cc index 9ff926c..880a1b8b 100644 --- a/extensions/browser/extension_navigation_throttle.cc +++ b/extensions/browser/extension_navigation_throttle.cc
@@ -85,13 +85,6 @@ navigation_handle()->GetStartingSiteInstance()->GetSiteURL()); if (!url_has_extension_scheme && !current_frame_is_extension_process) { - // Relax this restriction for navigations that will result in downloads. - // See https://crbug.com/714373. - if (target_origin.scheme() == kExtensionScheme && - navigation_handle()->GetSuggestedFilename().has_value()) { - return content::NavigationThrottle::PROCEED; - } - // Relax this restriction for apps that use <webview>. See // https://crbug.com/652077. bool has_webview_permission =
diff --git a/headless/test/headless_render_browsertest.cc b/headless/test/headless_render_browsertest.cc index 9716436..56429bdc 100644 --- a/headless/test/headless_render_browsertest.cc +++ b/headless/test/headless_render_browsertest.cc
@@ -510,7 +510,13 @@ "http://www.example.com/FAIL")); } }; -HEADLESS_RENDER_BROWSERTEST(ServerRedirectToFailure); +// Flaky on Linux. https://crbug.com/839747 +#if defined(OS_LINUX) +#define MAYBE_HEADLESS_RENDER_BROWSERTEST DISABLED_HEADLESS_RENDER_BROWSERTEST +#else +#define MAYBE_HEADLESS_RENDER_BROWSERTEST HEADLESS_RENDER_BROWSERTEST +#endif +MAYBE_HEADLESS_RENDER_BROWSERTEST(ServerRedirectToFailure); class ServerRedirectRelativeChain : public HeadlessRenderTest { private: @@ -1001,7 +1007,8 @@ ElementsAre("http://www.example.com/")); } }; -HEADLESS_RENDER_BROWSERTEST(RedirectInvalidUrl); +// Flaky on Linux. https://crbug.com/839747 +MAYBE_HEADLESS_RENDER_BROWSERTEST(RedirectInvalidUrl); class RedirectKeepsFragment : public HeadlessRenderTest { private: @@ -1164,11 +1171,6 @@ }; // Flaky on Linux. https://crbug.com/839747 -#if defined(OS_LINUX) -#define MAYBE_HEADLESS_RENDER_BROWSERTEST DISABLED_HEADLESS_RENDER_BROWSERTEST -#else -#define MAYBE_HEADLESS_RENDER_BROWSERTEST HEADLESS_RENDER_BROWSERTEST -#endif MAYBE_HEADLESS_RENDER_BROWSERTEST(CookieSetFromJs_NoCookies); class CookieUpdatedFromJs : public HeadlessRenderTest {
diff --git a/ios/chrome/browser/payments/payment_request.mm b/ios/chrome/browser/payments/payment_request.mm index 361b287..8da4ae53 100644 --- a/ios/chrome/browser/payments/payment_request.mm +++ b/ios/chrome/browser/payments/payment_request.mm
@@ -523,7 +523,8 @@ void PaymentRequest::PopulatePaymentMethodCache( std::vector<std::unique_ptr<IOSPaymentInstrument>> native_app_instruments) { const std::vector<autofill::CreditCard*>& credit_cards_to_suggest = - personal_data_manager_->GetCreditCardsToSuggest(); + personal_data_manager_->GetCreditCardsToSuggest( + /*include_server_cards=*/true); // Return early if the user has no stored credit cards or installed payment // apps.
diff --git a/ios/chrome/browser/services/gcm/ios_chrome_gcm_profile_service_factory.cc b/ios/chrome/browser/services/gcm/ios_chrome_gcm_profile_service_factory.cc index 6895a989..6a9939f 100644 --- a/ios/chrome/browser/services/gcm/ios_chrome_gcm_profile_service_factory.cc +++ b/ios/chrome/browser/services/gcm/ios_chrome_gcm_profile_service_factory.cc
@@ -67,6 +67,7 @@ browser_state->GetPrefs(), browser_state->GetStatePath(), browser_state->GetRequestContext(), ::GetChannel(), GetProductCategoryForSubtypes(), + ios::SigninManagerFactory::GetForBrowserState(browser_state), base::WrapUnique(new ProfileIdentityProvider( ios::SigninManagerFactory::GetForBrowserState(browser_state), OAuth2TokenServiceFactory::GetForBrowserState(browser_state),
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h index cbab300..7307341 100644 --- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h +++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h
@@ -86,6 +86,7 @@ bool IsContextSecure() override; bool ShouldShowSigninPromo() override; bool IsAutofillSupported() override; + bool AreServerCardsSupported() override; void ExecuteCommand(int id) override; private:
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm index 72cc98c..45159d7a6 100644 --- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm +++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
@@ -227,4 +227,8 @@ return true; } +bool ChromeAutofillClientIOS::AreServerCardsSupported() { + return true; +} + } // namespace autofill
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 383001c..3afa7a2 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -4115,6 +4115,16 @@ return _isOffTheRecord; } +- (BOOL)isFindInPageAvailable { + Tab* tab = [_model currentTab]; + if (!tab) { + return NO; + } + + auto* helper = FindTabHelper::FromWebState(tab.webState); + return (helper && helper->CurrentPageSupportsFindInPage()); +} + - (NSUInteger)tabsCount { return [_model count]; }
diff --git a/ios/chrome/browser/ui/key_commands_provider.h b/ios/chrome/browser/ui/key_commands_provider.h index 22972d7..3cac5459 100644 --- a/ios/chrome/browser/ui/key_commands_provider.h +++ b/ios/chrome/browser/ui/key_commands_provider.h
@@ -18,6 +18,10 @@ // Whether the current profile is off-the-record. - (BOOL)isOffTheRecord; +// Whether the Find in Page is available on current page. For example it's not +// supported on NTP and other native content pages. +- (BOOL)isFindInPageAvailable; + // Returns the current number of tabs. - (NSUInteger)tabsCount;
diff --git a/ios/chrome/browser/ui/key_commands_provider.mm b/ios/chrome/browser/ui/key_commands_provider.mm index 97d09d2..44170e6 100644 --- a/ios/chrome/browser/ui/key_commands_provider.mm +++ b/ios/chrome/browser/ui/key_commands_provider.mm
@@ -114,6 +114,33 @@ // List the commands that only appear when there is at least a tab. When they // appear, they are in the HUD since they have titles. if (hasTabs) { + if ([consumer isFindInPageAvailable]) { + [keyCommands addObjectsFromArray:@[ + + [UIKeyCommand + cr_keyCommandWithInput:@"f" + modifierFlags:UIKeyModifierCommand + title:l10n_util::GetNSStringWithFixup( + IDS_IOS_TOOLS_MENU_FIND_IN_PAGE) + action:^{ + [weakDispatcher showFindInPage]; + }], + [UIKeyCommand cr_keyCommandWithInput:@"g" + modifierFlags:UIKeyModifierCommand + title:nil + action:^{ + [weakDispatcher findNextStringInPage]; + }], + [UIKeyCommand + cr_keyCommandWithInput:@"g" + modifierFlags:UIKeyModifierCommand | UIKeyModifierShift + title:nil + action:^{ + [weakDispatcher findPreviousStringInPage]; + }] + ]]; + } + [keyCommands addObjectsFromArray:@[ [UIKeyCommand cr_keyCommandWithInput:@"l" modifierFlags:UIKeyModifierCommand @@ -137,26 +164,6 @@ action:^{ [weakDispatcher bookmarkPage]; }], - [UIKeyCommand cr_keyCommandWithInput:@"f" - modifierFlags:UIKeyModifierCommand - title:l10n_util::GetNSStringWithFixup( - IDS_IOS_TOOLS_MENU_FIND_IN_PAGE) - action:^{ - [weakDispatcher showFindInPage]; - }], - [UIKeyCommand cr_keyCommandWithInput:@"g" - modifierFlags:UIKeyModifierCommand - title:nil - action:^{ - [weakDispatcher findNextStringInPage]; - }], - [UIKeyCommand - cr_keyCommandWithInput:@"g" - modifierFlags:UIKeyModifierCommand | UIKeyModifierShift - title:nil - action:^{ - [weakDispatcher findPreviousStringInPage]; - }], [UIKeyCommand cr_keyCommandWithInput:@"r" modifierFlags:UIKeyModifierCommand title:l10n_util::GetNSStringWithFixup(
diff --git a/ios/chrome/browser/ui/key_commands_provider_unittest.mm b/ios/chrome/browser/ui/key_commands_provider_unittest.mm index 4a6e58b..091b493 100644 --- a/ios/chrome/browser/ui/key_commands_provider_unittest.mm +++ b/ios/chrome/browser/ui/key_commands_provider_unittest.mm
@@ -65,6 +65,7 @@ // Tabs. [[[mockConsumer expect] andReturnUnsignedInteger:1] tabsCount]; + [[[mockConsumer expect] andReturnBool:YES] isFindInPageAvailable]; NSUInteger numberOfKeyCommandsWithTabs = [[provider keyCommandsForConsumer:mockConsumer baseViewController:nil @@ -82,6 +83,7 @@ // Not editing text. [[[mockConsumer expect] andReturnUnsignedInteger:1] tabsCount]; + [[[mockConsumer expect] andReturnBool:YES] isFindInPageAvailable]; NSUInteger numberOfKeyCommandsWhenNotEditingText = [[provider keyCommandsForConsumer:mockConsumer baseViewController:nil @@ -90,6 +92,7 @@ // Editing text. [[[mockConsumer expect] andReturnUnsignedInteger:1] tabsCount]; + [[[mockConsumer expect] andReturnBool:YES] isFindInPageAvailable]; NSUInteger numberOfKeyCommandsWhenEditingText = [[provider keyCommandsForConsumer:mockConsumer baseViewController:nil @@ -100,4 +103,31 @@ numberOfKeyCommandsWhenNotEditingText); } +TEST_F(KeyCommandsProviderTest, MoreKeyboardCommandsWhenFindInPageAvailable) { + KeyCommandsProvider* provider = [[KeyCommandsProvider alloc] init]; + id mockConsumer = + [OCMockObject mockForProtocol:@protocol(KeyCommandsPlumbing)]; + id<ApplicationCommands, BrowserCommands, OmniboxFocuser> dispatcher = nil; + + // No Find in Page. + [[[mockConsumer expect] andReturnUnsignedInteger:1] tabsCount]; + [[[mockConsumer expect] andReturnBool:NO] isFindInPageAvailable]; + NSUInteger numberOfKeyCommandsWithoutFIP = + [[provider keyCommandsForConsumer:mockConsumer + baseViewController:nil + dispatcher:dispatcher + editingText:NO] count]; + + // Tabs. + [[[mockConsumer expect] andReturnUnsignedInteger:1] tabsCount]; + [[[mockConsumer expect] andReturnBool:YES] isFindInPageAvailable]; + NSUInteger numberOfKeyCommandsWithFIP = + [[provider keyCommandsForConsumer:mockConsumer + baseViewController:nil + dispatcher:dispatcher + editingText:NO] count]; + + EXPECT_GT(numberOfKeyCommandsWithFIP, numberOfKeyCommandsWithoutFIP); +} + } // namespace
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h index b8d772e..9b1573b 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h +++ b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h
@@ -216,6 +216,11 @@ NSMutableAttributedString* attributing_display_string_; OmniboxPopupProvider* popup_provider_; // weak + + // A flag that is set whenever any input or copy/paste event happened in the + // omnibox while it was focused. Used to count event "user focuses the omnibox + // to view the complete URL and immediately defocuses it". + BOOL omnibox_interacted_while_focused_; }; #endif // IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_VIEW_IOS_H_
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm index f0cee02..e1043e3 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
@@ -397,6 +397,9 @@ } void OmniboxViewIOS::OnDidBeginEditing() { + // Reset the changed flag. + omnibox_interacted_while_focused_ = NO; + // If Open from Clipboard offers a suggestion, the popup may be opened when // |OnSetFocus| is called on the model. The state of the popup is saved early // to ignore that case. @@ -449,6 +452,11 @@ // Blow away any in-progress edits. RevertAll(); DCHECK(![field_ hasAutocompleteText]); + + if (!omnibox_interacted_while_focused_) { + RecordAction( + UserMetricsAction("Mobile_FocusedDefocusedOmnibox_WithNoAction")); + } } bool OmniboxViewIOS::OnWillChange(NSRange range, NSString* new_text) { @@ -536,6 +544,8 @@ } void OmniboxViewIOS::OnDidChange(bool processing_user_event) { + omnibox_interacted_while_focused_ = YES; + // Sanitize pasted text. if (model()->is_pasting()) { base::string16 pastedText = base::SysNSStringToUTF16([field_ text]); @@ -611,6 +621,7 @@ } bool OmniboxViewIOS::OnCopy() { + omnibox_interacted_while_focused_ = YES; UIPasteboard* board = [UIPasteboard generalPasteboard]; NSString* selectedText = nil; NSInteger start_location = 0;
diff --git a/ios/web_view/internal/autofill/web_view_autofill_client_ios.h b/ios/web_view/internal/autofill/web_view_autofill_client_ios.h index 35cecb199..0851e46 100644 --- a/ios/web_view/internal/autofill/web_view_autofill_client_ios.h +++ b/ios/web_view/internal/autofill/web_view_autofill_client_ios.h
@@ -78,6 +78,7 @@ bool IsContextSecure() override; bool ShouldShowSigninPromo() override; bool IsAutofillSupported() override; + bool AreServerCardsSupported() override; void ExecuteCommand(int id) override; private:
diff --git a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm index 9e1bc36..6b96091 100644 --- a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm +++ b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm
@@ -152,4 +152,8 @@ return true; } +bool WebViewAutofillClientIOS::AreServerCardsSupported() { + return true; +} + } // namespace autofill
diff --git a/ios/web_view/internal/cwv_web_view.mm b/ios/web_view/internal/cwv_web_view.mm index 9d399aec..bdf1e4b 100644 --- a/ios/web_view/internal/cwv_web_view.mm +++ b/ios/web_view/internal/cwv_web_view.mm
@@ -87,6 +87,8 @@ // Handles presentation of JavaScript dialogs. std::unique_ptr<ios_web_view::WebViewJavaScriptDialogPresenter> _javaScriptDialogPresenter; + std::map<std::string, web::WebState::ScriptCommandCallback> + _scriptCommandCallbacks; } // Redefine these properties as readwrite to define setters, which send KVO @@ -429,13 +431,15 @@ return [handler webView:weakSelf handleScriptCommand:command]; }); - _webState->AddScriptCommandCallback(callback, - base::SysNSStringToUTF8(commandPrefix)); + std::string stdCommandPrefix = base::SysNSStringToUTF8(commandPrefix); + _webState->AddScriptCommandCallback(callback, stdCommandPrefix); + _scriptCommandCallbacks[stdCommandPrefix] = callback; } - (void)removeScriptCommandHandlerForCommandPrefix:(NSString*)commandPrefix { - _webState->RemoveScriptCommandCallback( - base::SysNSStringToUTF8(commandPrefix)); + std::string stdCommandPrefix = base::SysNSStringToUTF8(commandPrefix); + _webState->RemoveScriptCommandCallback(stdCommandPrefix); + _scriptCommandCallbacks.erase(stdCommandPrefix); } #pragma mark - Translation @@ -518,6 +522,9 @@ if (_webStateObserver) { _webState->RemoveObserver(_webStateObserver.get()); } + for (const auto& pair : _scriptCommandCallbacks) { + _webState->RemoveScriptCommandCallback(pair.first); + } // The web view provided by the old |_webState| has been added as a subview. // It must be removed and replaced with a new |_webState|'s web view, which @@ -551,6 +558,10 @@ std::make_unique<ios_web_view::WebViewJavaScriptDialogPresenter>(self, nullptr); + for (const auto& pair : _scriptCommandCallbacks) { + _webState->AddScriptCommandCallback(pair.second, pair.first); + } + _scrollView.proxy = _webState.get()->GetWebViewProxy().scrollViewProxy; if (_translationController) {
diff --git a/ios/web_view/test/web_view_restorable_state_inttest.mm b/ios/web_view/test/web_view_restorable_state_inttest.mm index 946141c..c4a8400 100644 --- a/ios/web_view/test/web_view_restorable_state_inttest.mm +++ b/ios/web_view/test/web_view_restorable_state_inttest.mm
@@ -14,24 +14,6 @@ namespace ios_web_view { -namespace { - -// Creates a new web view and restores its state from |source_web_view|. -CWVWebView* CreateWebViewWithState(CWVWebView* source_web_view) { - NSMutableData* data = [[NSMutableData alloc] init]; - NSKeyedArchiver* archiver = - [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; - [source_web_view encodeRestorableStateWithCoder:archiver]; - [archiver finishEncoding]; - NSKeyedUnarchiver* unarchiver = - [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; - CWVWebView* result = test::CreateWebView(); - [result decodeRestorableStateWithCoder:unarchiver]; - return result; -} - -} // namespace - // Tests encodeRestorableStateWithCoder: and decodeRestorableStateWithCoder: // methods. typedef ios_web_view::WebViewIntTest WebViewRestorableStateTest; @@ -51,7 +33,8 @@ ASSERT_FALSE([web_view_ canGoForward]); // Create second web view and restore its state from the first web view. - CWVWebView* restored_web_view = CreateWebViewWithState(web_view_); + CWVWebView* restored_web_view = test::CreateWebView(); + test::CopyWebViewState(web_view_, restored_web_view); // Verify that the state has been restored correctly. EXPECT_NSEQ(@"about:blank",
diff --git a/ios/web_view/test/web_view_script_command_inttest.mm b/ios/web_view/test/web_view_script_command_inttest.mm index 442f056..ac9fee3 100644 --- a/ios/web_view/test/web_view_script_command_inttest.mm +++ b/ios/web_view/test/web_view_script_command_inttest.mm
@@ -78,4 +78,43 @@ [web_view_ removeScriptCommandHandlerForCommandPrefix:@"test"]; } +// Tests that added script commands are still valid after state restoration. +// Tests the same thing as TestScriptCommand() after state restoration. +TEST_F(WebViewScriptCommandTest, TestScriptCommandAfterStateRestoration) { + CWVFakeScriptCommandHandler* handler = + [[CWVFakeScriptCommandHandler alloc] init]; + [web_view_ addScriptCommandHandler:handler commandPrefix:@"test"]; + + CWVWebView* source_web_view = test::CreateWebView(); + test::CopyWebViewState(source_web_view, web_view_); + + // Uses GetUrlForPageWithHtmlBody() instead of simply using about:blank + // because it looks __gCrWeb may not be available on about:blank. + // TODO(crbug.com/836114): Analyze why. + NSURL* url = net::NSURLWithGURL(GetUrlForPageWithHtmlBody("")); + ASSERT_TRUE(test::LoadUrl(web_view_, url)); + ASSERT_TRUE(test::WaitForWebViewLoadCompletionOrTimeout(web_view_)); + + NSString* script = + @"__gCrWeb.message.invokeOnHost(" + @"{'command': 'test.command1', 'key1': 'value1', 'key2': 42});"; + NSError* script_error = nil; + test::EvaluateJavaScript(web_view_, script, &script_error); + ASSERT_NSEQ(nil, script_error); + + EXPECT_TRUE(testing::WaitUntilConditionOrTimeout( + testing::kWaitForJSCompletionTimeout, ^{ + return handler.lastReceivedCommand != nil; + })); + + EXPECT_NSEQ(@"test.command1", + handler.lastReceivedCommand.content[@"command"]); + EXPECT_NSEQ(@"value1", handler.lastReceivedCommand.content[@"key1"]); + EXPECT_NSEQ(@42, handler.lastReceivedCommand.content[@"key2"]); + EXPECT_NSEQ(url, handler.lastReceivedCommand.mainDocumentURL); + EXPECT_FALSE(handler.lastReceivedCommand.userInteracting); + + [web_view_ removeScriptCommandHandlerForCommandPrefix:@"test"]; +} + } // namespace ios_web_view
diff --git a/ios/web_view/test/web_view_test_util.h b/ios/web_view/test/web_view_test_util.h index 3be1f61..c56989a 100644 --- a/ios/web_view/test/web_view_test_util.h +++ b/ios/web_view/test/web_view_test_util.h
@@ -42,6 +42,11 @@ bool WaitForWebViewLoadCompletionOrTimeout(CWVWebView* web_view) WARN_UNUSED_RESULT; +// Copies the state of |source_web_view| to |destination_web_view| using state +// restoration. +void CopyWebViewState(CWVWebView* source_web_view, + CWVWebView* destination_web_view); + } // namespace test } // namespace ios_web_view
diff --git a/ios/web_view/test/web_view_test_util.mm b/ios/web_view/test/web_view_test_util.mm index 4d67901..fedd60a 100644 --- a/ios/web_view/test/web_view_test_util.mm +++ b/ios/web_view/test/web_view_test_util.mm
@@ -81,5 +81,17 @@ }); } +void CopyWebViewState(CWVWebView* source_web_view, + CWVWebView* destination_web_view) { + NSMutableData* data = [[NSMutableData alloc] init]; + NSKeyedArchiver* archiver = + [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; + [source_web_view encodeRestorableStateWithCoder:archiver]; + [archiver finishEncoding]; + NSKeyedUnarchiver* unarchiver = + [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; + [destination_web_view decodeRestorableStateWithCoder:unarchiver]; +} + } // namespace test } // namespace ios_web_view
diff --git a/jingle/BUILD.gn b/jingle/BUILD.gn index a6785cf..7d481e3 100644 --- a/jingle/BUILD.gn +++ b/jingle/BUILD.gn
@@ -3,212 +3,183 @@ # found in the LICENSE file. import("//build/config/features.gni") -import("//media/media_options.gni") import("//testing/test.gni") -if (enable_webrtc || !is_android) { - static_library("jingle_glue") { - sources = [ +static_library("jingle_glue") { + sources = [ + "glue/chrome_async_socket.cc", + "glue/chrome_async_socket.h", + "glue/fake_ssl_client_socket.cc", + "glue/fake_ssl_client_socket.h", + "glue/resolving_client_socket_factory.h", + "glue/task_pump.cc", + "glue/task_pump.h", + "glue/thread_wrapper.cc", + "glue/thread_wrapper.h", + "glue/utils.cc", + "glue/utils.h", + "glue/xmpp_client_socket_factory.cc", + "glue/xmpp_client_socket_factory.h", + ] + public_deps = [ + "//third_party/webrtc_overrides", + ] + deps = [ + "//base", + "//base/third_party/dynamic_annotations", + "//net", + "//services/network:network_service", + ] + + configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] + + if (is_nacl) { + sources -= [ "glue/chrome_async_socket.cc", - "glue/chrome_async_socket.h", - "glue/fake_ssl_client_socket.cc", - "glue/fake_ssl_client_socket.h", - "glue/resolving_client_socket_factory.h", - "glue/task_pump.cc", - "glue/task_pump.h", - "glue/thread_wrapper.cc", - "glue/thread_wrapper.h", - "glue/utils.cc", - "glue/utils.h", "glue/xmpp_client_socket_factory.cc", - "glue/xmpp_client_socket_factory.h", ] - public_deps = [ - "//third_party/webrtc_overrides", - ] - deps = [ - "//base", - "//base/third_party/dynamic_annotations", - "//net", - "//services/network:network_service", - ] - - configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] - - if (is_nacl) { - sources -= [ - "glue/chrome_async_socket.cc", - "glue/xmpp_client_socket_factory.cc", - ] - deps -= [ "//services/network:network_service" ] - } + deps -= [ "//services/network:network_service" ] } +} - # A library for sending and receiving peer-issued notifications. - static_library("notifier") { - sources = [ - "notifier/base/const_communicator.h", - "notifier/base/gaia_constants.cc", - "notifier/base/gaia_constants.h", - "notifier/base/gaia_token_pre_xmpp_auth.cc", - "notifier/base/gaia_token_pre_xmpp_auth.h", - "notifier/base/notification_method.cc", - "notifier/base/notification_method.h", - "notifier/base/notifier_options.cc", - "notifier/base/notifier_options.h", - "notifier/base/notifier_options_util.cc", - "notifier/base/notifier_options_util.h", - "notifier/base/server_information.cc", - "notifier/base/server_information.h", - "notifier/base/weak_xmpp_client.cc", - "notifier/base/weak_xmpp_client.h", - "notifier/base/xmpp_connection.cc", - "notifier/base/xmpp_connection.h", - "notifier/communicator/connection_settings.cc", - "notifier/communicator/connection_settings.h", - "notifier/communicator/login.cc", - "notifier/communicator/login.h", - "notifier/communicator/login_settings.cc", - "notifier/communicator/login_settings.h", - "notifier/communicator/single_login_attempt.cc", - "notifier/communicator/single_login_attempt.h", - "notifier/listener/non_blocking_push_client.cc", - "notifier/listener/non_blocking_push_client.h", - "notifier/listener/notification_constants.cc", - "notifier/listener/notification_constants.h", - "notifier/listener/notification_defines.cc", - "notifier/listener/notification_defines.h", - "notifier/listener/push_client.cc", - "notifier/listener/push_client.h", - "notifier/listener/push_client_observer.cc", - "notifier/listener/push_client_observer.h", - "notifier/listener/push_notifications_listen_task.cc", - "notifier/listener/push_notifications_listen_task.h", - "notifier/listener/push_notifications_send_update_task.cc", - "notifier/listener/push_notifications_send_update_task.h", - "notifier/listener/push_notifications_subscribe_task.cc", - "notifier/listener/push_notifications_subscribe_task.h", - "notifier/listener/send_ping_task.cc", - "notifier/listener/send_ping_task.h", - "notifier/listener/xml_element_util.cc", - "notifier/listener/xml_element_util.h", - "notifier/listener/xmpp_push_client.cc", - "notifier/listener/xmpp_push_client.h", - ] - defines = [ "_CRT_SECURE_NO_WARNINGS" ] +# A library for sending and receiving peer-issued notifications. +static_library("notifier") { + sources = [ + "notifier/base/const_communicator.h", + "notifier/base/gaia_constants.cc", + "notifier/base/gaia_constants.h", + "notifier/base/gaia_token_pre_xmpp_auth.cc", + "notifier/base/gaia_token_pre_xmpp_auth.h", + "notifier/base/notification_method.cc", + "notifier/base/notification_method.h", + "notifier/base/notifier_options.cc", + "notifier/base/notifier_options.h", + "notifier/base/notifier_options_util.cc", + "notifier/base/notifier_options_util.h", + "notifier/base/server_information.cc", + "notifier/base/server_information.h", + "notifier/base/weak_xmpp_client.cc", + "notifier/base/weak_xmpp_client.h", + "notifier/base/xmpp_connection.cc", + "notifier/base/xmpp_connection.h", + "notifier/communicator/connection_settings.cc", + "notifier/communicator/connection_settings.h", + "notifier/communicator/login.cc", + "notifier/communicator/login.h", + "notifier/communicator/login_settings.cc", + "notifier/communicator/login_settings.h", + "notifier/communicator/single_login_attempt.cc", + "notifier/communicator/single_login_attempt.h", + "notifier/listener/non_blocking_push_client.cc", + "notifier/listener/non_blocking_push_client.h", + "notifier/listener/notification_constants.cc", + "notifier/listener/notification_constants.h", + "notifier/listener/notification_defines.cc", + "notifier/listener/notification_defines.h", + "notifier/listener/push_client.cc", + "notifier/listener/push_client.h", + "notifier/listener/push_client_observer.cc", + "notifier/listener/push_client_observer.h", + "notifier/listener/push_notifications_listen_task.cc", + "notifier/listener/push_notifications_listen_task.h", + "notifier/listener/push_notifications_send_update_task.cc", + "notifier/listener/push_notifications_send_update_task.h", + "notifier/listener/push_notifications_subscribe_task.cc", + "notifier/listener/push_notifications_subscribe_task.h", + "notifier/listener/send_ping_task.cc", + "notifier/listener/send_ping_task.h", + "notifier/listener/xml_element_util.cc", + "notifier/listener/xml_element_util.h", + "notifier/listener/xmpp_push_client.cc", + "notifier/listener/xmpp_push_client.h", + ] + defines = [ "_CRT_SECURE_NO_WARNINGS" ] - public_deps = [ - "//third_party/libjingle_xmpp", - "//third_party/webrtc_overrides", - ] - deps = [ - ":jingle_glue", - "//base", - "//net", - "//third_party/expat", - "//url", - ] - } + public_deps = [ + "//third_party/libjingle_xmpp", + "//third_party/webrtc_overrides", + ] + deps = [ + ":jingle_glue", + "//base", + "//net", + "//third_party/expat", + "//url", + ] +} - static_library("notifier_test_util") { - testonly = true - sources = [ - "notifier/base/fake_base_task.cc", - "notifier/base/fake_base_task.h", - "notifier/listener/fake_push_client.cc", - "notifier/listener/fake_push_client.h", - "notifier/listener/fake_push_client_observer.cc", - "notifier/listener/fake_push_client_observer.h", - ] - public_deps = [ - ":jingle_glue", - ":notifier", - ] - deps = [ - "//base", - "//testing/gmock", - ] - } +static_library("notifier_test_util") { + testonly = true + sources = [ + "notifier/base/fake_base_task.cc", + "notifier/base/fake_base_task.h", + "notifier/listener/fake_push_client.cc", + "notifier/listener/fake_push_client.h", + "notifier/listener/fake_push_client_observer.cc", + "notifier/listener/fake_push_client_observer.h", + ] + public_deps = [ + ":jingle_glue", + ":notifier", + ] + deps = [ + "//base", + "//testing/gmock", + ] +} - test("jingle_unittests") { - sources = [ +test("jingle_unittests") { + sources = [ + "glue/chrome_async_socket_unittest.cc", + "glue/fake_ssl_client_socket_unittest.cc", + "glue/jingle_glue_mock_objects.cc", + "glue/jingle_glue_mock_objects.h", + "glue/logging_unittest.cc", + "glue/mock_task.cc", + "glue/mock_task.h", + "glue/task_pump_unittest.cc", + "glue/thread_wrapper_unittest.cc", + "notifier/base/weak_xmpp_client_unittest.cc", + "notifier/base/xmpp_connection_unittest.cc", + "notifier/communicator/connection_settings_unittest.cc", + "notifier/communicator/login_settings_unittest.cc", + "notifier/communicator/single_login_attempt_unittest.cc", + "notifier/listener/non_blocking_push_client_unittest.cc", + "notifier/listener/notification_defines_unittest.cc", + "notifier/listener/push_client_unittest.cc", + "notifier/listener/push_notifications_send_update_task_unittest.cc", + "notifier/listener/push_notifications_subscribe_task_unittest.cc", + "notifier/listener/send_ping_task_unittest.cc", + "notifier/listener/xml_element_util_unittest.cc", + "notifier/listener/xmpp_push_client_unittest.cc", + ] + + if (is_android || is_ios) { + sources -= [ + # TODO(jrg): + # EXPECT_DEBUG_DEATH() uses features not enabled. + # Should we -std=c++0x or -std=gnu++0x? "glue/chrome_async_socket_unittest.cc", - "glue/fake_ssl_client_socket_unittest.cc", - "glue/jingle_glue_mock_objects.cc", - "glue/jingle_glue_mock_objects.h", - "glue/logging_unittest.cc", - "glue/mock_task.cc", - "glue/mock_task.h", - "glue/task_pump_unittest.cc", - "glue/thread_wrapper_unittest.cc", - "notifier/base/weak_xmpp_client_unittest.cc", "notifier/base/xmpp_connection_unittest.cc", - "notifier/communicator/connection_settings_unittest.cc", - "notifier/communicator/login_settings_unittest.cc", - "notifier/communicator/single_login_attempt_unittest.cc", - "notifier/listener/non_blocking_push_client_unittest.cc", - "notifier/listener/notification_defines_unittest.cc", - "notifier/listener/push_client_unittest.cc", - "notifier/listener/push_notifications_send_update_task_unittest.cc", - "notifier/listener/push_notifications_subscribe_task_unittest.cc", - "notifier/listener/send_ping_task_unittest.cc", - "notifier/listener/xml_element_util_unittest.cc", - "notifier/listener/xmpp_push_client_unittest.cc", - ] - - if (is_android || is_ios) { - sources -= [ - # TODO(jrg): - # EXPECT_DEBUG_DEATH() uses features not enabled. - # Should we -std=c++0x or -std=gnu++0x? - "glue/chrome_async_socket_unittest.cc", - "notifier/base/xmpp_connection_unittest.cc", - ] - } - - configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] - - public_deps = [ - "//third_party/libjingle_xmpp", - "//third_party/webrtc_overrides", - ] - deps = [ - ":jingle_glue", - ":notifier", - ":notifier_test_util", - "//base", - "//base/test:run_all_unittests", - "//base/test:test_support", - "//net", - "//net:test_support", - "//testing/gmock", - "//testing/gtest", - ] - } -} else { - # !enable_webrtc and is_android - # Stub targets as Android doesn't use libjingle when webrtc is disabled. - source_set("jingle_glue") { - } - - source_set("jingle_glue_test_util") { - } - - static_library("notifier") { - sources = [ - "notifier/base/gaia_constants.cc", - "notifier/base/gaia_constants.h", - "notifier/base/notification_method.cc", - "notifier/base/notification_method.h", - "notifier/base/notifier_options.cc", - "notifier/base/notifier_options.h", - ] - deps = [ - "//base", - "//net", ] } - source_set("notifier_test_util") { - } + configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] + + public_deps = [ + "//third_party/libjingle_xmpp", + "//third_party/webrtc_overrides", + ] + deps = [ + ":jingle_glue", + ":notifier", + ":notifier_test_util", + "//base", + "//base/test:run_all_unittests", + "//base/test:test_support", + "//net", + "//net:test_support", + "//testing/gmock", + "//testing/gtest", + ] }
diff --git a/media/BUILD.gn b/media/BUILD.gn index a1467fa..8960c523 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn
@@ -33,7 +33,9 @@ "ENABLE_CDM_STORAGE_ID=$enable_cdm_storage_id", "ENABLE_MEDIA_REMOTING=$enable_media_remoting", "ENABLE_MEDIA_REMOTING_RPC=$enable_media_remoting_rpc", - "ENABLE_WEBRTC=$enable_webrtc", + + # TODO(phoglund): Remove this define from the code. + "ENABLE_WEBRTC=true", "USE_PROPRIETARY_CODECS=$proprietary_codecs", ] }
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn index 35e67c9..b5b13580 100644 --- a/media/audio/BUILD.gn +++ b/media/audio/BUILD.gn
@@ -92,6 +92,8 @@ "audio_input_device.h", "audio_input_ipc.cc", "audio_input_ipc.h", + "audio_input_stream_data_interceptor.cc", + "audio_input_stream_data_interceptor.h", "audio_input_sync_writer.cc", "audio_input_sync_writer.h", "audio_io.h", @@ -311,13 +313,6 @@ libs += [ "media_client" ] } - if (enable_webrtc) { - sources += [ - "audio_input_stream_data_interceptor.cc", - "audio_input_stream_data_interceptor.h", - ] - } - configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] } @@ -385,6 +380,7 @@ "audio_debug_recording_session_impl_unittest.cc", "audio_input_controller_unittest.cc", "audio_input_device_unittest.cc", + "audio_input_stream_data_interceptor_unittest.cc", "audio_input_sync_writer_unittest.cc", "audio_input_unittest.cc", "audio_manager_unittest.cc", @@ -416,10 +412,6 @@ "//media:media_config", ] - if (enable_webrtc) { - sources += [ "audio_input_stream_data_interceptor_unittest.cc" ] - } - if (is_android) { sources += [ "android/audio_android_unittest.cc" ] deps += [ "//ui/gl" ]
diff --git a/media/audio/mac/coreaudio_dispatch_override.cc b/media/audio/mac/coreaudio_dispatch_override.cc index 30b4e2c..2ac812b 100644 --- a/media/audio/mac/coreaudio_dispatch_override.cc +++ b/media/audio/mac/coreaudio_dispatch_override.cc
@@ -16,7 +16,7 @@ namespace { struct dyld_interpose_tuple { template <typename T> - dyld_interpose_tuple(const T* replacement, const T* replacee) + dyld_interpose_tuple(T* replacement, T* replacee) : replacement(reinterpret_cast<const void*>(replacement)), replacee(reinterpret_cast<const void*>(replacee)) {} const void* replacement;
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index c7aa2bf1..2c6b11d 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -113,11 +113,6 @@ // accelerator hardware to be present. const char kUseFakeJpegDecodeAccelerator[] = "use-fake-jpeg-decode-accelerator"; -// Disable hardware acceleration of mjpeg decode for captured frame, where -// available. -const char kDisableAcceleratedMjpegDecode[] = - "disable-accelerated-mjpeg-decode"; - // Enables support for inband text tracks in media content. const char kEnableInbandTextTracks[] = "enable-inband-text-tracks"; @@ -416,19 +411,4 @@ "PreloadMediaEngagementData", base::FEATURE_ENABLED_BY_DEFAULT}; #endif -bool IsVideoCaptureAcceleratedJpegDecodingEnabled() { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableAcceleratedMjpegDecode)) { - return false; - } - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kUseFakeJpegDecodeAccelerator)) { - return true; - } -#if defined(OS_CHROMEOS) - return true; -#endif - return false; -} - } // namespace media
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index c9077f9e..12515dbb 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -65,7 +65,6 @@ MEDIA_EXPORT extern const char kUseFileForFakeVideoCapture[]; MEDIA_EXPORT extern const char kUseFileForFakeAudioCapture[]; MEDIA_EXPORT extern const char kUseFakeJpegDecodeAccelerator[]; -MEDIA_EXPORT extern const char kDisableAcceleratedMjpegDecode[]; MEDIA_EXPORT extern const char kEnableInbandTextTracks[]; @@ -161,8 +160,6 @@ // audio focus duck flash should be enabled. MEDIA_EXPORT bool IsAudioFocusDuckFlashEnabled(); -MEDIA_EXPORT bool IsVideoCaptureAcceleratedJpegDecodingEnabled(); - } // namespace media #endif // MEDIA_BASE_MEDIA_SWITCHES_H_
diff --git a/media/capture/BUILD.gn b/media/capture/BUILD.gn index 0239813..acdf83e 100644 --- a/media/capture/BUILD.gn +++ b/media/capture/BUILD.gn
@@ -130,8 +130,6 @@ "video/video_capture_device_client.cc", "video/video_capture_device_client.h", "video/video_capture_jpeg_decoder.h", - "video/video_capture_jpeg_decoder_impl.cc", - "video/video_capture_jpeg_decoder_impl.h", "video/video_capture_system.h", "video/video_capture_system_impl.cc", "video/video_capture_system_impl.h", @@ -175,7 +173,6 @@ "//media/capture/mojom:image_capture", "//media/capture/mojom:image_capture_types", "//media/capture/mojom:video_capture", - "//media/mojo/clients:jpeg_decode_accelerator", "//media/mojo/interfaces:interfaces", "//services/service_manager/public/cpp", "//third_party/libyuv",
diff --git a/media/capture/video/video_capture_device_client.cc b/media/capture/video/video_capture_device_client.cc index 33433b8d..e301e41 100644 --- a/media/capture/video/video_capture_device_client.cc +++ b/media/capture/video/video_capture_device_client.cc
@@ -64,8 +64,7 @@ *y_plane_stride = dimensions.width(); *uv_plane_stride = *y_plane_stride / 2; } - -} // anonymous namespace +} namespace media { @@ -99,10 +98,10 @@ VideoCaptureDeviceClient::VideoCaptureDeviceClient( std::unique_ptr<VideoFrameReceiver> receiver, scoped_refptr<VideoCaptureBufferPool> buffer_pool, - VideoCaptureJpegDecoderFactoryCB optional_jpeg_decoder_factory_callback) + const VideoCaptureJpegDecoderFactoryCB& jpeg_decoder_factory) : receiver_(std::move(receiver)), - optional_jpeg_decoder_factory_callback_( - std::move(optional_jpeg_decoder_factory_callback)), + jpeg_decoder_factory_callback_(jpeg_decoder_factory), + external_jpeg_decoder_initialized_(false), buffer_pool_(std::move(buffer_pool)), last_captured_pixel_format_(PIXEL_FORMAT_UNKNOWN) { on_started_using_gpu_cb_ = @@ -139,7 +138,6 @@ base::TimeTicks reference_time, base::TimeDelta timestamp, int frame_feedback_id) { - DFAKE_SCOPED_RECURSIVE_LOCK(call_from_producer_); TRACE_EVENT0("media", "VideoCaptureDeviceClient::OnIncomingCapturedData"); if (last_captured_pixel_format_ != format.pixel_format) { @@ -147,11 +145,11 @@ last_captured_pixel_format_ = format.pixel_format; if (format.pixel_format == PIXEL_FORMAT_MJPEG && - optional_jpeg_decoder_factory_callback_) { - external_jpeg_decoder_ = - std::move(optional_jpeg_decoder_factory_callback_).Run(); - DCHECK(external_jpeg_decoder_); - external_jpeg_decoder_->Initialize(); + !external_jpeg_decoder_initialized_) { + external_jpeg_decoder_initialized_ = true; + external_jpeg_decoder_ = jpeg_decoder_factory_callback_.Run(); + if (external_jpeg_decoder_) + external_jpeg_decoder_->Initialize(); } }
diff --git a/media/capture/video/video_capture_device_client.h b/media/capture/video/video_capture_device_client.h index 778d46a1..7708de9 100644 --- a/media/capture/video/video_capture_device_client.h +++ b/media/capture/video/video_capture_device_client.h
@@ -23,15 +23,11 @@ class VideoCaptureJpegDecoder; using VideoCaptureJpegDecoderFactoryCB = - base::OnceCallback<std::unique_ptr<VideoCaptureJpegDecoder>()>; + base::Callback<std::unique_ptr<VideoCaptureJpegDecoder>()>; // Implementation of VideoCaptureDevice::Client that uses a buffer pool // to provide buffers and converts incoming data to the I420 format for -// consumption by a given VideoFrameReceiver. If -// |optional_jpeg_decoder_factory_callback| is provided, the -// VideoCaptureDeviceClient will attempt to use it for decoding of MJPEG frames. -// Otherwise, it will use libyuv to perform MJPEG to I420 conversion in -// software. +// consumption by a given VideoFrameReceiver. // // Methods of this class may be called from any thread, and in practice will // often be called on some auxiliary thread depending on the platform and the @@ -45,7 +41,7 @@ VideoCaptureDeviceClient( std::unique_ptr<VideoFrameReceiver> receiver, scoped_refptr<VideoCaptureBufferPool> buffer_pool, - VideoCaptureJpegDecoderFactoryCB optional_jpeg_decoder_factory_callback); + const VideoCaptureJpegDecoderFactoryCB& jpeg_decoder_factory); ~VideoCaptureDeviceClient() override; static Buffer MakeBufferStruct( @@ -103,8 +99,11 @@ const std::unique_ptr<VideoFrameReceiver> receiver_; std::vector<int> buffer_ids_known_by_receiver_; - VideoCaptureJpegDecoderFactoryCB optional_jpeg_decoder_factory_callback_; + const VideoCaptureJpegDecoderFactoryCB jpeg_decoder_factory_callback_; std::unique_ptr<VideoCaptureJpegDecoder> external_jpeg_decoder_; + + // Whether |external_jpeg_decoder_| has been initialized. + bool external_jpeg_decoder_initialized_; base::OnceClosure on_started_using_gpu_cb_; // The pool of shared-memory buffers used for capturing.
diff --git a/media/capture/video/video_capture_jpeg_decoder.h b/media/capture/video/video_capture_jpeg_decoder.h index e2da00d..c5b32cf 100644 --- a/media/capture/video/video_capture_jpeg_decoder.h +++ b/media/capture/video/video_capture_jpeg_decoder.h
@@ -13,8 +13,6 @@ namespace media { -// All methods are allowed to be called from any thread, but calls must be -// non-concurrently. class CAPTURE_EXPORT VideoCaptureJpegDecoder { public: // Enumeration of decoder status. The enumeration is published for clients to @@ -26,7 +24,7 @@ // decode error. }; - using DecodeDoneCB = base::RepeatingCallback<void( + using DecodeDoneCB = base::Callback<void( int buffer_id, int frame_feedback_id, std::unique_ptr<VideoCaptureDevice::Client::Buffer::
diff --git a/media/capture/video/video_capture_jpeg_decoder_impl.cc b/media/capture/video/video_capture_jpeg_decoder_impl.cc deleted file mode 100644 index bb5d16f..0000000 --- a/media/capture/video/video_capture_jpeg_decoder_impl.cc +++ /dev/null
@@ -1,260 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/capture/video/video_capture_jpeg_decoder_impl.h" - -#include "base/metrics/histogram_macros.h" -#include "media/base/media_switches.h" - -namespace media { - -VideoCaptureJpegDecoderImpl::VideoCaptureJpegDecoderImpl( - MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory, - scoped_refptr<base::SingleThreadTaskRunner> decoder_task_runner, - DecodeDoneCB decode_done_cb, - base::RepeatingCallback<void(const std::string&)> send_log_message_cb) - : jpeg_decoder_factory_(std::move(jpeg_decoder_factory)), - decoder_task_runner_(std::move(decoder_task_runner)), - decode_done_cb_(std::move(decode_done_cb)), - send_log_message_cb_(std::move(send_log_message_cb)), - has_received_decoded_frame_(false), - next_bitstream_buffer_id_(0), - in_buffer_id_(media::JpegDecodeAccelerator::kInvalidBitstreamBufferId), - decoder_status_(INIT_PENDING), - weak_ptr_factory_(this) {} - -VideoCaptureJpegDecoderImpl::~VideoCaptureJpegDecoderImpl() { - // |this| was set as |decoder_|'s client. |decoder_| has to be deleted on - // |decoder_task_runner_| before this destructor returns to ensure that it - // doesn't call back into its client. - - if (!decoder_) - return; - - if (decoder_task_runner_->RunsTasksInCurrentSequence()) { - decoder_.reset(); - return; - } - - base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - // base::Unretained is safe because |this| will be valid until |event| - // is signaled. - decoder_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&VideoCaptureJpegDecoderImpl::DestroyDecoderOnIOThread, - base::Unretained(this), &event)); - event.Wait(); -} - -void VideoCaptureJpegDecoderImpl::Initialize() { - if (!IsVideoCaptureAcceleratedJpegDecodingEnabled()) { - decoder_status_ = FAILED; - RecordInitDecodeUMA_Locked(); - return; - } - - decoder_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&VideoCaptureJpegDecoderImpl::FinishInitialization, - weak_ptr_factory_.GetWeakPtr())); -} - -VideoCaptureJpegDecoderImpl::STATUS VideoCaptureJpegDecoderImpl::GetStatus() - const { - base::AutoLock lock(lock_); - return decoder_status_; -} - -void VideoCaptureJpegDecoderImpl::DecodeCapturedData( - const uint8_t* data, - size_t in_buffer_size, - const media::VideoCaptureFormat& frame_format, - base::TimeTicks reference_time, - base::TimeDelta timestamp, - media::VideoCaptureDevice::Client::Buffer out_buffer) { - DCHECK(decoder_); - - TRACE_EVENT_ASYNC_BEGIN0("jpeg", "VideoCaptureJpegDecoderImpl decoding", - next_bitstream_buffer_id_); - TRACE_EVENT0("jpeg", "VideoCaptureJpegDecoderImpl::DecodeCapturedData"); - - // TODO(kcwu): enqueue decode requests in case decoding is not fast enough - // (say, if decoding time is longer than 16ms for 60fps 4k image) - { - base::AutoLock lock(lock_); - if (IsDecoding_Locked()) { - DVLOG(1) << "Drop captured frame. Previous jpeg frame is still decoding"; - return; - } - } - - // Enlarge input buffer if necessary. - if (!in_shared_memory_.get() || - in_buffer_size > in_shared_memory_->mapped_size()) { - // Reserve 2x space to avoid frequent reallocations for initial frames. - const size_t reserved_size = 2 * in_buffer_size; - in_shared_memory_.reset(new base::SharedMemory); - if (!in_shared_memory_->CreateAndMapAnonymous(reserved_size)) { - base::AutoLock lock(lock_); - decoder_status_ = FAILED; - LOG(WARNING) << "CreateAndMapAnonymous failed, size=" << reserved_size; - return; - } - } - memcpy(in_shared_memory_->memory(), data, in_buffer_size); - - // No need to lock for |in_buffer_id_| since IsDecoding_Locked() is false. - in_buffer_id_ = next_bitstream_buffer_id_; - media::BitstreamBuffer in_buffer(in_buffer_id_, in_shared_memory_->handle(), - in_buffer_size); - // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. - next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; - - // The API of |decoder_| requires us to wrap the |out_buffer| in a VideoFrame. - const gfx::Size dimensions = frame_format.frame_size; - std::unique_ptr<media::VideoCaptureBufferHandle> out_buffer_access = - out_buffer.handle_provider->GetHandleForInProcessAccess(); - base::SharedMemoryHandle out_handle = - out_buffer.handle_provider->GetNonOwnedSharedMemoryHandleForLegacyIPC(); - scoped_refptr<media::VideoFrame> out_frame = - media::VideoFrame::WrapExternalSharedMemory( - media::PIXEL_FORMAT_I420, // format - dimensions, // coded_size - gfx::Rect(dimensions), // visible_rect - dimensions, // natural_size - out_buffer_access->data(), // data - out_buffer_access->mapped_size(), // data_size - out_handle, // handle - 0, // shared_memory_offset - timestamp); // timestamp - if (!out_frame) { - base::AutoLock lock(lock_); - decoder_status_ = FAILED; - LOG(ERROR) << "DecodeCapturedData: WrapExternalSharedMemory failed"; - return; - } - // Hold onto the buffer access handle for the lifetime of the VideoFrame, to - // ensure the data pointers remain valid. - out_frame->AddDestructionObserver(base::BindOnce( - [](std::unique_ptr<media::VideoCaptureBufferHandle> handle) {}, - std::move(out_buffer_access))); - out_frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, - frame_format.frame_rate); - - out_frame->metadata()->SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, - reference_time); - - media::mojom::VideoFrameInfoPtr out_frame_info = - media::mojom::VideoFrameInfo::New(); - out_frame_info->timestamp = timestamp; - out_frame_info->pixel_format = media::PIXEL_FORMAT_I420; - out_frame_info->coded_size = dimensions; - out_frame_info->visible_rect = gfx::Rect(dimensions); - out_frame_info->metadata = out_frame->metadata()->GetInternalValues().Clone(); - - { - base::AutoLock lock(lock_); - decode_done_closure_ = base::BindOnce( - decode_done_cb_, out_buffer.id, out_buffer.frame_feedback_id, - base::Passed(&out_buffer.access_permission), - base::Passed(&out_frame_info)); - } - - // base::Unretained is safe because |decoder_| is deleted on - // |decoder_task_runner_|. - decoder_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&media::JpegDecodeAccelerator::Decode, - base::Unretained(decoder_.get()), in_buffer, - std::move(out_frame))); -} - -void VideoCaptureJpegDecoderImpl::VideoFrameReady(int32_t bitstream_buffer_id) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); - TRACE_EVENT0("jpeg", "VideoCaptureJpegDecoderImpl::VideoFrameReady"); - if (!has_received_decoded_frame_) { - send_log_message_cb_.Run("Received decoded frame from Gpu Jpeg decoder"); - has_received_decoded_frame_ = true; - } - base::AutoLock lock(lock_); - - if (!IsDecoding_Locked()) { - LOG(ERROR) << "Got decode response while not decoding"; - return; - } - - if (bitstream_buffer_id != in_buffer_id_) { - LOG(ERROR) << "Unexpected bitstream_buffer_id " << bitstream_buffer_id - << ", expected " << in_buffer_id_; - return; - } - in_buffer_id_ = media::JpegDecodeAccelerator::kInvalidBitstreamBufferId; - - std::move(decode_done_closure_).Run(); - - TRACE_EVENT_ASYNC_END0("jpeg", "VideoCaptureJpegDecoderImpl decoding", - bitstream_buffer_id); -} - -void VideoCaptureJpegDecoderImpl::NotifyError( - int32_t bitstream_buffer_id, - media::JpegDecodeAccelerator::Error error) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); - LOG(ERROR) << "Decode error, bitstream_buffer_id=" << bitstream_buffer_id - << ", error=" << error; - send_log_message_cb_.Run("Gpu Jpeg decoder failed"); - base::AutoLock lock(lock_); - decode_done_closure_.Reset(); - decoder_status_ = FAILED; -} - -void VideoCaptureJpegDecoderImpl::FinishInitialization() { - TRACE_EVENT0("gpu", "VideoCaptureJpegDecoderImpl::FinishInitialization"); - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); - - media::mojom::JpegDecodeAcceleratorPtr remote_decoder; - jpeg_decoder_factory_.Run(mojo::MakeRequest(&remote_decoder)); - - base::AutoLock lock(lock_); - decoder_ = std::make_unique<media::MojoJpegDecodeAccelerator>( - decoder_task_runner_, remote_decoder.PassInterface()); - - decoder_->InitializeAsync( - this, - base::BindRepeating(&VideoCaptureJpegDecoderImpl::OnInitializationDone, - weak_ptr_factory_.GetWeakPtr())); -} - -void VideoCaptureJpegDecoderImpl::OnInitializationDone(bool success) { - TRACE_EVENT0("gpu", "VideoCaptureJpegDecoderImpl::OnInitializationDone"); - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); - - base::AutoLock lock(lock_); - if (!success) { - decoder_.reset(); - DLOG(ERROR) << "Failed to initialize JPEG decoder"; - } - - decoder_status_ = success ? INIT_PASSED : FAILED; - RecordInitDecodeUMA_Locked(); -} - -bool VideoCaptureJpegDecoderImpl::IsDecoding_Locked() const { - lock_.AssertAcquired(); - return !decode_done_closure_.is_null(); -} - -void VideoCaptureJpegDecoderImpl::RecordInitDecodeUMA_Locked() { - UMA_HISTOGRAM_BOOLEAN("Media.VideoCaptureGpuJpegDecoder.InitDecodeSuccess", - decoder_status_ == INIT_PASSED); -} - -void VideoCaptureJpegDecoderImpl::DestroyDecoderOnIOThread( - base::WaitableEvent* event) { - DCHECK(decoder_task_runner_->RunsTasksInCurrentSequence()); - decoder_.reset(); - event->Signal(); -} - -} // namespace media
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn index fb42ff5..8e03ae1 100644 --- a/media/gpu/BUILD.gn +++ b/media/gpu/BUILD.gn
@@ -152,6 +152,8 @@ "android/android_image_reader_compat.h", "android/android_video_decode_accelerator.cc", "android/android_video_decode_accelerator.h", + "android/android_video_encode_accelerator.cc", + "android/android_video_encode_accelerator.h", "android/android_video_surface_chooser.h", "android/android_video_surface_chooser_impl.cc", "android/android_video_surface_chooser_impl.h", @@ -202,14 +204,8 @@ # TODO(crbug.com/789435): This can be removed once CdmManager is removed. "//media/mojo:buildflags", "//services/service_manager/public/cpp:cpp", + "//third_party/libyuv", ] - if (enable_webrtc) { - deps += [ "//third_party/libyuv" ] - sources += [ - "android/android_video_encode_accelerator.cc", - "android/android_video_encode_accelerator.h", - ] - } # TODO(crbug.com/789435): This is needed for AVDA to access the CDM # directly. Remove this dependency after VDAs are also running as part of
diff --git a/media/media_options.gni b/media/media_options.gni index 07c5551..17faf8d 100644 --- a/media/media_options.gni +++ b/media/media_options.gni
@@ -71,8 +71,6 @@ # which are encoded using HEVC require |enable_hevc_demuxing| to be enabled. enable_dolby_vision_demuxing = proprietary_codecs && is_chromecast - enable_webrtc = true - # Enable HLS with SAMPLE-AES decryption. enable_hls_sample_aes = proprietary_codecs && is_chromecast
diff --git a/media/mojo/clients/BUILD.gn b/media/mojo/clients/BUILD.gn index 90b391ac..5100e5c 100644 --- a/media/mojo/clients/BUILD.gn +++ b/media/mojo/clients/BUILD.gn
@@ -79,10 +79,7 @@ } source_set("jpeg_decode_accelerator") { - visibility = [ - "//content/browser", - "//media/capture:capture_lib", - ] + visibility = [ "//content/browser" ] sources = [ "mojo_jpeg_decode_accelerator.cc",
diff --git a/media/mojo/services/BUILD.gn b/media/mojo/services/BUILD.gn index 511e8723..938b4c6 100644 --- a/media/mojo/services/BUILD.gn +++ b/media/mojo/services/BUILD.gn
@@ -32,8 +32,6 @@ "mojo_audio_decoder_service.h", "mojo_audio_input_stream.cc", "mojo_audio_input_stream.h", - "mojo_audio_input_stream_observer.cc", - "mojo_audio_input_stream_observer.h", "mojo_audio_output_stream.cc", "mojo_audio_output_stream.h", "mojo_audio_output_stream_provider.cc", @@ -164,7 +162,6 @@ sources = [ "deferred_destroy_strong_binding_set_unittest.cc", "media_metrics_provider_unittest.cc", - "mojo_audio_input_stream_observer_unittest.cc", "mojo_audio_input_stream_unittest.cc", "mojo_audio_output_stream_provider_unittest.cc", "mojo_audio_output_stream_unittest.cc",
diff --git a/media/mojo/services/mojo_audio_input_stream_observer.cc b/media/mojo/services/mojo_audio_input_stream_observer.cc deleted file mode 100644 index d22d092..0000000 --- a/media/mojo/services/mojo_audio_input_stream_observer.cc +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/mojo/services/mojo_audio_input_stream_observer.h" - -#include <utility> - -#include "media/base/user_input_monitor.h" - -namespace media { - -MojoAudioInputStreamObserver::MojoAudioInputStreamObserver( - mojom::AudioInputStreamObserverRequest request, - base::OnceClosure recording_started_callback, - base::OnceClosure connection_error_callback, - media::UserInputMonitor* user_input_monitor) - : binding_(this, std::move(request)), - recording_started_callback_(std::move(recording_started_callback)), - connection_error_callback_(std::move(connection_error_callback)), - user_input_monitor_(user_input_monitor) { - DCHECK(recording_started_callback_); - if (user_input_monitor_) - user_input_monitor_->EnableKeyPressMonitoring(); - - // Unretained is safe because |this| owns |binding_|. - binding_.set_connection_error_handler( - base::BindOnce(&MojoAudioInputStreamObserver::OnConnectionError, - base::Unretained(this))); -} - -MojoAudioInputStreamObserver::~MojoAudioInputStreamObserver() { - DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_); - - // Check that DisableKeyPressMonitoring() was called. - DCHECK(!user_input_monitor_); -} - -void MojoAudioInputStreamObserver::DidStartRecording() { - DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_); - DCHECK(recording_started_callback_); - std::move(recording_started_callback_).Run(); -} - -void MojoAudioInputStreamObserver::OnConnectionError() { - DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_); - if (user_input_monitor_) { - user_input_monitor_->DisableKeyPressMonitoring(); - - // Set to nullptr to check that DisableKeyPressMonitoring() was called - // before destructor. - user_input_monitor_ = nullptr; - } - - std::move(connection_error_callback_).Run(); -} - -} // namespace media
diff --git a/media/mojo/services/mojo_audio_input_stream_observer.h b/media/mojo/services/mojo_audio_input_stream_observer.h deleted file mode 100644 index 2cd48b3..0000000 --- a/media/mojo/services/mojo_audio_input_stream_observer.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_MOJO_SERVICES_MOJO_AUDIO_INPUT_STREAM_OBSERVER_H_ -#define MEDIA_MOJO_SERVICES_MOJO_AUDIO_INPUT_STREAM_OBSERVER_H_ - -#include "media/mojo/interfaces/audio_input_stream.mojom.h" -#include "media/mojo/services/media_mojo_export.h" -#include "mojo/public/cpp/bindings/binding.h" - -namespace media { - -class UserInputMonitor; - -class MEDIA_MOJO_EXPORT MojoAudioInputStreamObserver - : public mojom::AudioInputStreamObserver { - public: - MojoAudioInputStreamObserver(mojom::AudioInputStreamObserverRequest request, - base::OnceClosure recording_started_callback, - base::OnceClosure connection_error_callback, - media::UserInputMonitor* user_input_monitor); - ~MojoAudioInputStreamObserver() override; - - void DidStartRecording() override; - - private: - void OnConnectionError(); - - mojo::Binding<AudioInputStreamObserver> binding_; - base::OnceClosure recording_started_callback_; - base::OnceClosure connection_error_callback_; - media::UserInputMonitor* user_input_monitor_; - - SEQUENCE_CHECKER(owning_sequence_); - - DISALLOW_COPY_AND_ASSIGN(MojoAudioInputStreamObserver); -}; - -} // namespace media - -#endif // MEDIA_MOJO_SERVICES_MOJO_AUDIO_INPUT_STREAM_OBSERVER_H_
diff --git a/media/mojo/services/mojo_audio_input_stream_observer_unittest.cc b/media/mojo/services/mojo_audio_input_stream_observer_unittest.cc deleted file mode 100644 index ab450be0..0000000 --- a/media/mojo/services/mojo_audio_input_stream_observer_unittest.cc +++ /dev/null
@@ -1,65 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/mojo/services/mojo_audio_input_stream_observer.h" - -#include <memory> -#include <utility> - -#include "base/run_loop.h" -#include "base/test/scoped_task_environment.h" -#include "mojo/public/cpp/bindings/associated_binding.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace media { - -class MojoAudioInputStreamObserverTest : public testing::Test { - public: - MojoAudioInputStreamObserverTest() {} - ~MojoAudioInputStreamObserverTest() override {} - - std::unique_ptr<MojoAudioInputStreamObserver> CreateObserver( - media::mojom::AudioInputStreamObserverRequest request) { - return std::make_unique<MojoAudioInputStreamObserver>( - std::move(request), - base::BindOnce( - &MojoAudioInputStreamObserverTest::RecordingStartedCallback, - base::Unretained(this)), - base::BindOnce( - &MojoAudioInputStreamObserverTest::BindingConnectionError, - base::Unretained(this)), - nullptr /*user_input_monitor*/); - } - - MOCK_METHOD0(RecordingStartedCallback, void()); - MOCK_METHOD0(BindingConnectionError, void()); - - private: - base::test::ScopedTaskEnvironment scoped_task_env_; - - DISALLOW_COPY_AND_ASSIGN(MojoAudioInputStreamObserverTest); -}; - -TEST_F(MojoAudioInputStreamObserverTest, DidStartRecording) { - media::mojom::AudioInputStreamObserverPtr observer_ptr; - std::unique_ptr<MojoAudioInputStreamObserver> observer = - CreateObserver(mojo::MakeRequest(&observer_ptr)); - - EXPECT_CALL(*this, RecordingStartedCallback()); - observer_ptr->DidStartRecording(); - base::RunLoop().RunUntilIdle(); -} - -TEST_F(MojoAudioInputStreamObserverTest, BindingConnectionError) { - media::mojom::AudioInputStreamObserverPtr observer_ptr; - std::unique_ptr<MojoAudioInputStreamObserver> observer = - CreateObserver(mojo::MakeRequest(&observer_ptr)); - - EXPECT_CALL(*this, BindingConnectionError()); - observer_ptr.reset(); - base::RunLoop().RunUntilIdle(); -} - -} // namespace media
diff --git a/net/BUILD.gn b/net/BUILD.gn index 5654088..0a5b5207 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1271,8 +1271,6 @@ "quic/core/quic_tag.h", "quic/core/quic_time.cc", "quic/core/quic_time.h", - "quic/core/quic_trace_visitor.cc", - "quic/core/quic_trace_visitor.h", "quic/core/quic_transmission_info.cc", "quic/core/quic_transmission_info.h", "quic/core/quic_types.cc", @@ -2281,7 +2279,6 @@ sources = [ "quic/core/proto/cached_network_parameters.proto", - "quic/core/proto/quic_trace.proto", "quic/core/proto/source_address_token.proto", ] cc_generator_options = "dllexport_decl=NET_EXPORT_PRIVATE:" @@ -2293,6 +2290,17 @@ extra_configs = [ "//build/config/compiler:wexit_time_destructors" ] } +proto_library("net_quic_trace_proto") { + visibility = [ ":simple_quic_tools" ] + + sources = [ + "quic/core/proto/quic_trace.proto", + ] + component_build_force_source_set = true + + extra_configs = [ "//build/config/compiler:wexit_time_destructors" ] +} + if (!is_proto_quic) { static_library("extras") { sources = [ @@ -3305,6 +3313,8 @@ source_set("simple_quic_tools") { sources = [ + "quic/core/quic_trace_visitor.cc", + "quic/core/quic_trace_visitor.h", "tools/quic/chlo_extractor.cc", "tools/quic/chlo_extractor.h", "tools/quic/quic_client_base.cc", @@ -3353,8 +3363,10 @@ ] deps = [ ":net", + ":net_quic_trace_proto", "//base", "//base/third_party/dynamic_annotations", + "//third_party/protobuf:protobuf_lite", "//url", ] }
diff --git a/net/quic/core/quic_trace_visitor.h b/net/quic/core/quic_trace_visitor.h index 9ec17d2..18206ecb8 100644 --- a/net/quic/core/quic_trace_visitor.h +++ b/net/quic/core/quic_trace_visitor.h
@@ -14,7 +14,7 @@ // Records a QUIC trace protocol buffer for a QuicConnection. It's the // responsibility of the user of this visitor to process or store the resulting // trace, which can be accessed via trace(). -class QUIC_EXPORT_PRIVATE QuicTraceVisitor : public QuicConnectionDebugVisitor { +class QuicTraceVisitor : public QuicConnectionDebugVisitor { public: explicit QuicTraceVisitor(const QuicConnection* connection);
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc index b25fa0db..41409fc 100644 --- a/net/socket/ssl_client_socket_impl.cc +++ b/net/socket/ssl_client_socket_impl.cc
@@ -966,6 +966,7 @@ // optimization. See https://crbug.com/boringssl/123. SSL_set_renegotiate_mode(ssl_.get(), ssl_renegotiate_freely); + SSL_set_shed_handshake_config(ssl_.get(), 1); return OK; }
diff --git a/net/socket/ssl_server_socket_impl.cc b/net/socket/ssl_server_socket_impl.cc index b00dfc4..dbe0da5 100644 --- a/net/socket/ssl_server_socket_impl.cc +++ b/net/socket/ssl_server_socket_impl.cc
@@ -216,6 +216,7 @@ weak_factory_(this) { ssl_.reset(SSL_new(context_->ssl_ctx_.get())); SSL_set_app_data(ssl_.get(), this); + SSL_set_shed_handshake_config(ssl_.get(), 1); } SSLServerContextImpl::SocketImpl::~SocketImpl() {
diff --git a/remoting/BUILD.gn b/remoting/BUILD.gn index 32bba3d6..f05a26f 100644 --- a/remoting/BUILD.gn +++ b/remoting/BUILD.gn
@@ -3,7 +3,6 @@ # found in the LICENSE file. import("//components/nacl/features.gni") -import("//media/media_options.gni") import("//remoting/build/config/remoting_build.gni") group("remoting_all") { @@ -176,9 +175,7 @@ ] } - if (enable_webrtc) { - deps += [ "//third_party/webrtc_overrides:init_webrtc" ] - } + deps += [ "//third_party/webrtc_overrides:init_webrtc" ] if (is_android) { deps += [ "//net/android:net_java" ] @@ -221,9 +218,7 @@ "//third_party/webrtc_overrides", ] - if (enable_webrtc) { - deps += [ "//third_party/webrtc_overrides:init_webrtc" ] - } + deps += [ "//third_party/webrtc_overrides:init_webrtc" ] if (is_win) { defines += [ "_ALT_NO_EXCEPTIONS" ]
diff --git a/remoting/host/BUILD.gn b/remoting/host/BUILD.gn index 08abc30..b0fca33b 100644 --- a/remoting/host/BUILD.gn +++ b/remoting/host/BUILD.gn
@@ -3,7 +3,6 @@ # found in the LICENSE file. import("//build/util/process_version.gni") -import("//media/media_options.gni") import("//remoting/build/config/remoting_build.gni") group("all_tests") { @@ -305,6 +304,7 @@ "//remoting/host/security_key", "//remoting/protocol", "//remoting/resources", + "//third_party/webrtc/modules/desktop_capture", # //remoting uses the power_save_blocker directly. See crbug.com/689423 "//services/device/wake_lock/power_save_blocker", @@ -411,10 +411,6 @@ public_deps += [ "//remoting/host/win" ] } - - if (enable_webrtc) { - deps += [ "//third_party/webrtc/modules/desktop_capture" ] - } } static_library("test_support") { @@ -441,16 +437,11 @@ public_deps = [ ":host", "//remoting/base:test_support", + "//third_party/libjingle_xmpp", "//third_party/protobuf:protobuf_lite", + "//third_party/webrtc/modules/desktop_capture", + "//third_party/webrtc_overrides:init_webrtc", ] - - if (enable_webrtc) { - public_deps += [ - "//third_party/libjingle_xmpp", - "//third_party/webrtc/modules/desktop_capture", - "//third_party/webrtc_overrides:init_webrtc", - ] - } } # The host portions of the remoting unit tests. @@ -583,6 +574,8 @@ deps = [ "//build/config:exe_and_shlib_deps", + "//third_party/libjingle_xmpp", + "//third_party/webrtc_overrides:init_webrtc", ] configs += [ "//build/config/compiler:wexit_time_destructors" ] @@ -610,13 +603,6 @@ "//remoting/host/setup", ] } - - if (enable_webrtc) { - deps += [ - "//third_party/libjingle_xmpp", - "//third_party/webrtc_overrides:init_webrtc", - ] - } } action_foreach("remoting_native_messaging_manifests") { @@ -718,7 +704,9 @@ "//remoting/base", "//remoting/host", "//remoting/proto", + "//third_party/libjingle_xmpp", "//third_party/webrtc/modules/desktop_capture", + "//third_party/webrtc_overrides:init_webrtc", ] if (is_posix) { @@ -732,13 +720,6 @@ deps += [ "//components/policy:generated" ] } - if (enable_webrtc) { - deps += [ - "//third_party/libjingle_xmpp", - "//third_party/webrtc_overrides:init_webrtc", - ] - } - if (is_desktop_linux) { deps += [ "//build/config/linux/gtk" ] }
diff --git a/remoting/host/it2me/BUILD.gn b/remoting/host/it2me/BUILD.gn index 69e9583..7e2df5c 100644 --- a/remoting/host/it2me/BUILD.gn +++ b/remoting/host/it2me/BUILD.gn
@@ -3,7 +3,6 @@ # found in the LICENSE file. import("//build/config/features.gni") -import("//media/media_options.gni") import("//remoting/remoting_options.gni") import("//remoting/remoting_locales.gni") import("//remoting/remoting_version.gni") @@ -207,6 +206,7 @@ "//remoting/host", "//remoting/host/native_messaging", "//remoting/proto", + "//third_party/webrtc_overrides:init_webrtc", "//ui/gfx", ] if (is_mac) { @@ -227,10 +227,6 @@ } } - if (enable_webrtc) { - deps += [ "//third_party/webrtc_overrides:init_webrtc" ] - } - if (is_desktop_linux) { deps += [ "//build/config/linux/gtk" ] }
diff --git a/remoting/host/win/BUILD.gn b/remoting/host/win/BUILD.gn index 875df9b5..461f190 100644 --- a/remoting/host/win/BUILD.gn +++ b/remoting/host/win/BUILD.gn
@@ -131,6 +131,7 @@ "//remoting/protocol", "//remoting/resources", "//services/device/wake_lock/power_save_blocker", + "//third_party/webrtc/modules/desktop_capture", "//ui/base", "//ui/events:dom_keycode_converter", "//ui/events/platform", @@ -139,10 +140,6 @@ if (!is_ios) { deps += [ "//components/policy:generated" ] } - - if (enable_webrtc) { - deps += [ "//third_party/webrtc/modules/desktop_capture" ] - } } source_set("unit_tests") {
diff --git a/remoting/remoting_enable.gni b/remoting/remoting_enable.gni index 8a24badb..879214d 100644 --- a/remoting/remoting_enable.gni +++ b/remoting/remoting_enable.gni
@@ -3,12 +3,11 @@ # found in the LICENSE file. import("//build/config/ui.gni") -import("//media/media_options.gni") if (is_ios) { import("//build/config/ios/ios_sdk.gni") } declare_args() { - enable_remoting = !is_chromecast && !is_fuchsia && enable_webrtc + enable_remoting = !is_chromecast && !is_fuchsia }
diff --git a/sandbox/win/src/process_mitigations_win32k_unittest.cc b/sandbox/win/src/process_mitigations_win32k_unittest.cc index 70247ae..48adf00 100644 --- a/sandbox/win/src/process_mitigations_win32k_unittest.cc +++ b/sandbox/win/src/process_mitigations_win32k_unittest.cc
@@ -633,7 +633,8 @@ // along with the policy to fake user32 and gdi32 initialization successfully // launches the target process. // The test process itself links against user32/gdi32. -TEST(ProcessMitigationsWin32kTest, CheckWin8LockDownSuccess) { +// Flaky. https://crbug.com/840335 +TEST(ProcessMitigationsWin32kTest, DISABLED_CheckWin8LockDownSuccess) { if (base::win::GetVersion() < base::win::VERSION_WIN8) return; @@ -659,7 +660,8 @@ // This test validates the even though we're running under win32k lockdown // we can use the IPC redirection to enumerate the list of monitors. -TEST(ProcessMitigationsWin32kTest, CheckWin8Redirection) { +// Flaky. https://crbug.com/840335 +TEST(ProcessMitigationsWin32kTest, DISABLED_CheckWin8Redirection) { if (base::win::GetVersion() < base::win::VERSION_WIN8) return;
diff --git a/services/audio/input_stream.cc b/services/audio/input_stream.cc index 2c6ebee1..ba5ced8 100644 --- a/services/audio/input_stream.cc +++ b/services/audio/input_stream.cc
@@ -37,13 +37,15 @@ : binding_(this, std::move(request)), client_(std::move(client)), observer_(std::move(observer)), - log_(media::mojom::ThreadSafeAudioLogPtr::Create(std::move(log))), + log_(log ? media::mojom::ThreadSafeAudioLogPtr::Create(std::move(log)) + : nullptr), created_callback_(std::move(created_callback)), delete_callback_(std::move(delete_callback)), foreign_socket_(), writer_(media::AudioInputSyncWriter::Create( - base::BindRepeating(&media::mojom::AudioLog::OnLogMessage, - base::Unretained(log_->get())), + log_ ? base::BindRepeating(&media::mojom::AudioLog::OnLogMessage, + base::Unretained(log_->get())) + : base::RepeatingCallback<void(const std::string&)>(), shared_memory_count, params, &foreign_socket_)), @@ -52,7 +54,6 @@ DCHECK(audio_manager); DCHECK(binding_.is_bound()); DCHECK(client_.is_bound()); - DCHECK(observer_.is_bound()); DCHECK(created_callback_); DCHECK(delete_callback_); @@ -61,8 +62,12 @@ base::BindRepeating(&InputStream::OnStreamError, base::Unretained(this)); binding_.set_connection_error_handler(error_handler); client_.set_connection_error_handler(error_handler); - observer_.set_connection_error_handler(std::move(error_handler)); - log_->get()->OnCreated(params, device_id); + + if (observer_) + observer_.set_connection_error_handler(std::move(error_handler)); + + if (log_) + log_->get()->OnCreated(params, device_id); // Only MONO, STEREO and STEREO_AND_KEYBOARD_MIC channel layouts are expected, // see AudioManagerBase::MakeAudioInputStream(). @@ -84,7 +89,8 @@ InputStream::~InputStream() { DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_); - log_->get()->OnClosed(); + if (log_) + log_->get()->OnClosed(); if (created_callback_) { // Didn't manage to create the stream. Call the callback anyways as mandated @@ -106,8 +112,10 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_); DCHECK(controller_); controller_->Record(); - observer_->DidStartRecording(); - log_->get()->OnStarted(); + if (observer_) + observer_->DidStartRecording(); + if (log_) + log_->get()->OnStarted(); } void InputStream::SetVolume(double volume) { @@ -121,7 +129,8 @@ } controller_->SetVolume(volume); - log_->get()->OnSetVolume(volume); + if (log_) + log_->get()->OnSetVolume(volume); } void InputStream::OnCreated(bool initially_muted) { @@ -153,13 +162,15 @@ void InputStream::OnError(media::AudioInputController::ErrorCode error_code) { DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_); client_->OnError(); - log_->get()->OnError(); + if (log_) + log_->get()->OnError(); OnStreamError(); } void InputStream::OnLog(base::StringPiece message) { DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_); - log_->get()->OnLogMessage(message.as_string()); + if (log_) + log_->get()->OnLogMessage(message.as_string()); } void InputStream::OnMuted(bool is_muted) {
diff --git a/services/audio/owning_audio_manager_accessor.cc b/services/audio/owning_audio_manager_accessor.cc index 2ac6da63..81dcd9f 100644 --- a/services/audio/owning_audio_manager_accessor.cc +++ b/services/audio/owning_audio_manager_accessor.cc
@@ -4,8 +4,12 @@ #include "services/audio/owning_audio_manager_accessor.h" +#include <memory> +#include <utility> + #include "base/macros.h" #include "base/single_thread_task_runner.h" +#include "base/threading/thread.h" #include "media/audio/audio_manager.h" #include "media/audio/audio_thread.h" @@ -14,7 +18,8 @@ namespace { // Thread class for hosting owned AudioManager on the main thread of the -// service. +// service, with a separate worker thread (started on-demand) for running things +// that shouldn't be blocked by main-thread tasks. class MainThread : public media::AudioThread { public: MainThread(); @@ -27,10 +32,17 @@ private: scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + // This is not started until the first time GetWorkerTaskRunner() is called. + base::Thread worker_thread_; + scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner_; + DISALLOW_COPY_AND_ASSIGN(MainThread); }; -MainThread::MainThread() : task_runner_(base::ThreadTaskRunnerHandle::Get()) {} +MainThread::MainThread() + : task_runner_(base::ThreadTaskRunnerHandle::Get()), + worker_thread_("AudioWorkerThread") {} MainThread::~MainThread() { DCHECK(task_runner_->BelongsToCurrentThread()); @@ -38,6 +50,10 @@ void MainThread::Stop() { DCHECK(task_runner_->BelongsToCurrentThread()); + if (worker_task_runner_) { + worker_task_runner_ = nullptr; + worker_thread_.Stop(); + } } base::SingleThreadTaskRunner* MainThread::GetTaskRunner() { @@ -45,8 +61,12 @@ } base::SingleThreadTaskRunner* MainThread::GetWorkerTaskRunner() { - NOTREACHED(); - return task_runner_.get(); + DCHECK(task_runner_->BelongsToCurrentThread()); + if (!worker_task_runner_) { + CHECK(worker_thread_.Start()); + worker_task_runner_ = worker_thread_.task_runner(); + } + return worker_task_runner_.get(); } } // namespace @@ -69,7 +89,7 @@ // TODO(http://crbug/812557): pass AudioLogFactory (needed for output // streams). audio_manager_ = std::move(audio_manager_factory_cb_) - .Run(std::make_unique<MainThread>(), nullptr); + .Run(std::make_unique<MainThread>(), &log_factory_); DCHECK(audio_manager_); } DCHECK(audio_manager_->GetTaskRunner()->BelongsToCurrentThread());
diff --git a/services/audio/owning_audio_manager_accessor.h b/services/audio/owning_audio_manager_accessor.h index 5f4766a..d978eff 100644 --- a/services/audio/owning_audio_manager_accessor.h +++ b/services/audio/owning_audio_manager_accessor.h
@@ -5,9 +5,12 @@ #ifndef SERVICES_AUDIO_OWNING_AUDIO_MANAGER_ACCESSOR_H_ #define SERVICES_AUDIO_OWNING_AUDIO_MANAGER_ACCESSOR_H_ +#include <memory> + #include "base/macros.h" #include "base/threading/thread_checker.h" #include "build/build_config.h" +#include "media/audio/fake_audio_log_factory.h" #include "services/audio/service.h" #if defined(OS_WIN) @@ -46,6 +49,11 @@ #endif AudioManagerFactoryCallback audio_manager_factory_cb_; std::unique_ptr<media::AudioManager> audio_manager_; + + // TODO(http://crbug/812557): Use a real AudioLogFactory (needed for output + // streams). + media::FakeAudioLogFactory log_factory_; + THREAD_CHECKER(thread_checker_); DISALLOW_COPY_AND_ASSIGN(OwningAudioManagerAccessor); };
diff --git a/services/audio/public/mojom/stream_factory.mojom b/services/audio/public/mojom/stream_factory.mojom index 0732e2b..61713e6 100644 --- a/services/audio/public/mojom/stream_factory.mojom +++ b/services/audio/public/mojom/stream_factory.mojom
@@ -40,8 +40,8 @@ CreateInputStream( media.mojom.AudioInputStream& stream, media.mojom.AudioInputStreamClient client, - media.mojom.AudioInputStreamObserver observer, - media.mojom.AudioLog log, + media.mojom.AudioInputStreamObserver? observer, + media.mojom.AudioLog? log, string device_id, media.mojom.AudioParameters params, uint32 shared_memory_count, bool enable_agc, handle<shared_buffer>? key_press_count_buffer)
diff --git a/services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.cc b/services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.cc index 474295c..d0df1c7 100644 --- a/services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.cc +++ b/services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.cc
@@ -36,8 +36,7 @@ } // namespace -ClientGpuMemoryBufferManager::ClientGpuMemoryBufferManager( - mojom::GpuMemoryBufferFactoryPtr gpu) +ClientGpuMemoryBufferManager::ClientGpuMemoryBufferManager(mojom::GpuPtr gpu) : thread_("GpuMemoryThread"), gpu_memory_buffer_support_( std::make_unique<gpu::GpuMemoryBufferSupport>()), @@ -56,18 +55,9 @@ FROM_HERE, base::Bind(&ClientGpuMemoryBufferManager::TearDownThread, base::Unretained(this))); thread_.Stop(); - if (optional_destruction_callback_) - std::move(optional_destruction_callback_).Run(); } -void ClientGpuMemoryBufferManager::SetOptionalDestructionCallback( - base::OnceClosure callback) { - DCHECK(!optional_destruction_callback_); - optional_destruction_callback_ = std::move(callback); -} - -void ClientGpuMemoryBufferManager::InitThread( - mojom::GpuMemoryBufferFactoryPtrInfo gpu_info) { +void ClientGpuMemoryBufferManager::InitThread(mojom::GpuPtrInfo gpu_info) { gpu_.Bind(std::move(gpu_info)); gpu_.set_connection_error_handler( base::Bind(&ClientGpuMemoryBufferManager::DisconnectGpuOnThread,
diff --git a/services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.h b/services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.h index f332406..04f51b7a 100644 --- a/services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.h +++ b/services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.h
@@ -26,17 +26,13 @@ namespace ui { -// Implements gpu::GpuMemoryBufferManager based on a given -// ui.mojom.GpuMemoryBufferFactory class ClientGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager { public: - explicit ClientGpuMemoryBufferManager(mojom::GpuMemoryBufferFactoryPtr gpu); + explicit ClientGpuMemoryBufferManager(mojom::GpuPtr gpu); ~ClientGpuMemoryBufferManager() override; - void SetOptionalDestructionCallback(base::OnceClosure callback); - private: - void InitThread(mojom::GpuMemoryBufferFactoryPtrInfo gpu_info); + void InitThread(mojom::GpuPtrInfo gpu_info); void TearDownThread(); void DisconnectGpuOnThread(); void AllocateGpuMemoryBufferOnThread(const gfx::Size& size, @@ -63,8 +59,7 @@ int counter_ = 0; // TODO(sad): Explore the option of doing this from an existing thread. base::Thread thread_; - mojom::GpuMemoryBufferFactoryPtr gpu_; - base::OnceClosure optional_destruction_callback_; + mojom::GpuPtr gpu_; base::WeakPtr<ClientGpuMemoryBufferManager> weak_ptr_; std::set<base::WaitableEvent*> pending_allocation_waiters_; std::unique_ptr<gpu::GpuMemoryBufferSupport> gpu_memory_buffer_support_;
diff --git a/services/ui/public/cpp/gpu/gpu.cc b/services/ui/public/cpp/gpu/gpu.cc index 3ec62d5..823ba44 100644 --- a/services/ui/public/cpp/gpu/gpu.cc +++ b/services/ui/public/cpp/gpu/gpu.cc
@@ -15,7 +15,6 @@ #include "base/trace_event/trace_event.h" #include "build/build_config.h" #include "gpu/command_buffer/common/scheduling_priority.h" -#include "mojo/public/cpp/bindings/strong_binding.h" #include "services/service_manager/public/cpp/connector.h" #include "services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.h" #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h" @@ -242,26 +241,16 @@ scoped_refptr<base::SingleThreadTaskRunner> task_runner) : main_task_runner_(base::ThreadTaskRunnerHandle::Get()), io_task_runner_(std::move(task_runner)), + gpu_memory_buffer_manager_( + std::make_unique<ClientGpuMemoryBufferManager>(factory.Run())), gpu_(new GpuPtrIO(), base::OnTaskRunnerDeleter(io_task_runner_)) { DCHECK(main_task_runner_); DCHECK(io_task_runner_); - mojom::GpuMemoryBufferFactoryPtr gpu_memory_buffer_factory; - auto gpu_for_buffer_factory = factory.Run(); - gpu_for_buffer_factory->CreateGpuMemoryBufferFactory( - mojo::MakeRequest(&gpu_memory_buffer_factory)); - gpu_memory_buffer_manager_ = std::make_unique<ClientGpuMemoryBufferManager>( - std::move(gpu_memory_buffer_factory)); - // Attach ownership of |gpu_for_buffer_factory| to - // |gpu_memory_buffer_manager_| to ensure |gpu_memory_buffer_factory| stays - // alive. - gpu_memory_buffer_manager_->SetOptionalDestructionCallback( - base::BindOnce([](mojom::GpuPtr) {}, std::move(gpu_for_buffer_factory))); - - // Initialize mojom::GpuPtr on the IO thread. |gpu_| can only be used on - // the IO thread after this point. It is safe to use base::Unretained with - // |gpu_| for IO thread tasks as |gpu_| is destroyed by an IO thread task - // posted from the destructor. + // Initialize mojom::GpuPtr on the IO thread. |gpu_| can only be used on the + // IO thread after this point. It is safe to use base::Unretained with |gpu_| + // for IO thread tasks as |gpu_| is destroyed by an IO thread task posted from + // the destructor. io_task_runner_->PostTask( FROM_HERE, base::BindOnce(&GpuPtrIO::Initialize, base::Unretained(gpu_.get()),
diff --git a/services/ui/public/cpp/tests/gpu_unittest.cc b/services/ui/public/cpp/tests/gpu_unittest.cc index 0dbdc57..197e3c3d 100644 --- a/services/ui/public/cpp/tests/gpu_unittest.cc +++ b/services/ui/public/cpp/tests/gpu_unittest.cc
@@ -35,9 +35,6 @@ } // ui::mojom::Gpu overrides: - void CreateGpuMemoryBufferFactory( - ui::mojom::GpuMemoryBufferFactoryRequest request) override {} - void EstablishGpuChannel(EstablishGpuChannelCallback callback) override { if (close_binding_on_request_) { // Don't run |callback| and trigger a connection error on the other end. @@ -63,6 +60,16 @@ void CreateVideoEncodeAcceleratorProvider( media::mojom::VideoEncodeAcceleratorProviderRequest request) override {} + void CreateGpuMemoryBuffer( + gfx::GpuMemoryBufferId id, + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + ui::mojom::Gpu::CreateGpuMemoryBufferCallback callback) override {} + + void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, + const gpu::SyncToken& sync_token) override {} + private: bool request_will_succeed_ = true; bool close_binding_on_request_ = false;
diff --git a/services/ui/public/interfaces/gpu.mojom b/services/ui/public/interfaces/gpu.mojom index 7af6b32..f0806bb 100644 --- a/services/ui/public/interfaces/gpu.mojom +++ b/services/ui/public/interfaces/gpu.mojom
@@ -12,25 +12,7 @@ import "ui/gfx/geometry/mojo/geometry.mojom"; import "ui/gfx/mojo/buffer_types.mojom"; -interface GpuMemoryBufferFactory { - // Tells the GPU service to create a new GPU memory buffer. - CreateGpuMemoryBuffer(gfx.mojom.GpuMemoryBufferId id, - gfx.mojom.Size size, - gfx.mojom.BufferFormat format, - gfx.mojom.BufferUsage usage) - => (gfx.mojom.GpuMemoryBufferHandle buffer_handle); - - // Tells the GPU process to destroy GPU memory buffer. - DestroyGpuMemoryBuffer(gfx.mojom.GpuMemoryBufferId id, - gpu.mojom.SyncToken sync_token); -}; - -// API exposed to clients with lower level of trust, e.g. Renderers. interface Gpu { - // Note: The bound-to GpuMemoryBufferFactory instance is only guaranteed to - // stay alive for as long as the invoked Gpu instance. - CreateGpuMemoryBufferFactory(GpuMemoryBufferFactory& request); - // Tells the GPU service to create a new channel for communication with a // client. The GPU service responds with client ID, IPC handle and // GPUInfo. @@ -45,4 +27,15 @@ // Creates a VideoEncodeAcceleratorProvider and binds it to |vea_provider|. CreateVideoEncodeAcceleratorProvider( media.mojom.VideoEncodeAcceleratorProvider& vea_provider); + + // Tells the GPU service to create a new GPU memory buffer. + CreateGpuMemoryBuffer(gfx.mojom.GpuMemoryBufferId id, + gfx.mojom.Size size, + gfx.mojom.BufferFormat format, + gfx.mojom.BufferUsage usage) + => (gfx.mojom.GpuMemoryBufferHandle buffer_handle); + + // Tells the GPU process to destroy GPU memory buffer. + DestroyGpuMemoryBuffer(gfx.mojom.GpuMemoryBufferId id, + gpu.mojom.SyncToken sync_token); };
diff --git a/services/ui/ws/gpu_client.cc b/services/ui/ws/gpu_client.cc index 285576e4..0dc12bf 100644 --- a/services/ui/ws/gpu_client.cc +++ b/services/ui/ws/gpu_client.cc
@@ -75,7 +75,7 @@ const gfx::Size& size, gfx::BufferFormat format, gfx::BufferUsage usage, - mojom::GpuMemoryBufferFactory::CreateGpuMemoryBufferCallback callback) { + mojom::Gpu::CreateGpuMemoryBufferCallback callback) { gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer( id, client_id_, size, format, usage, gpu::kNullSurfaceHandle, std::move(callback)); @@ -87,10 +87,5 @@ sync_token); } -void GpuClient::CreateGpuMemoryBufferFactory( - ui::mojom::GpuMemoryBufferFactoryRequest request) { - gpu_memory_buffer_factory_bindings_.AddBinding(this, std::move(request)); -} - } // namespace ws } // namespace ui
diff --git a/services/ui/ws/gpu_client.h b/services/ui/ws/gpu_client.h index 9a9d246..a1cb6790 100644 --- a/services/ui/ws/gpu_client.h +++ b/services/ui/ws/gpu_client.h
@@ -8,7 +8,6 @@ #include "base/memory/weak_ptr.h" #include "gpu/config/gpu_feature_info.h" #include "gpu/config/gpu_info.h" -#include "mojo/public/cpp/bindings/binding_set.h" #include "services/ui/public/interfaces/gpu.mojom.h" namespace viz { @@ -29,8 +28,7 @@ // The implementation that relays requests from clients to the real // service implementation in the GPU process over mojom.GpuService. -class GpuClient : public ui::mojom::GpuMemoryBufferFactory, - public ui::mojom::Gpu { +class GpuClient : public mojom::Gpu { public: GpuClient(int client_id, gpu::GPUInfo* gpu_info, @@ -45,30 +43,22 @@ // EstablishGpuChannelCallback: void OnGpuChannelEstablished(mojo::ScopedMessagePipeHandle channel_handle); - // ui::mojom::GpuMemoryBufferFactory overrides: + // mojom::Gpu overrides: + void EstablishGpuChannel(EstablishGpuChannelCallback callback) override; + void CreateJpegDecodeAccelerator( + media::mojom::JpegDecodeAcceleratorRequest jda_request) override; + void CreateVideoEncodeAcceleratorProvider( + media::mojom::VideoEncodeAcceleratorProviderRequest request) override; void CreateGpuMemoryBuffer( gfx::GpuMemoryBufferId id, const gfx::Size& size, gfx::BufferFormat format, gfx::BufferUsage usage, - ui::mojom::GpuMemoryBufferFactory::CreateGpuMemoryBufferCallback callback) - override; + mojom::Gpu::CreateGpuMemoryBufferCallback callback) override; void DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, const gpu::SyncToken& sync_token) override; - // ui::mojom::Gpu overrides: - void CreateGpuMemoryBufferFactory( - ui::mojom::GpuMemoryBufferFactoryRequest request) override; - void EstablishGpuChannel(EstablishGpuChannelCallback callback) override; - void CreateJpegDecodeAccelerator( - media::mojom::JpegDecodeAcceleratorRequest jda_request) override; - void CreateVideoEncodeAcceleratorProvider( - media::mojom::VideoEncodeAcceleratorProviderRequest vea_provider_request) - override; - const int client_id_; - mojo::BindingSet<ui::mojom::GpuMemoryBufferFactory> - gpu_memory_buffer_factory_bindings_; // The objects these pointers refer to are owned by the GpuHost object. const gpu::GPUInfo* gpu_info_;
diff --git a/services/video_capture/BUILD.gn b/services/video_capture/BUILD.gn index 48a56bf..c205814a 100644 --- a/services/video_capture/BUILD.gn +++ b/services/video_capture/BUILD.gn
@@ -57,7 +57,6 @@ "//media/mojo/common:common", "//mojo/public/cpp/system", "//services/service_manager/public/cpp", - "//services/ui/public/cpp/gpu:gpu", "//services/video_capture/public/cpp", "//services/video_capture/public/mojom", "//services/video_capture/public/mojom:constants",
diff --git a/services/video_capture/DEPS b/services/video_capture/DEPS index 1f82d6b..5c28bf2 100644 --- a/services/video_capture/DEPS +++ b/services/video_capture/DEPS
@@ -1,8 +1,6 @@ include_rules = [ - "+gpu/command_buffer/client", "+media/base", "+media/mojo", "+media/capture", "+ui/gfx/geometry", - "+services/ui/public/cpp/gpu", ]
diff --git a/services/video_capture/device_factory_media_to_mojo_adapter.cc b/services/video_capture/device_factory_media_to_mojo_adapter.cc index e95d3ea..d8bdb0b8 100644 --- a/services/video_capture/device_factory_media_to_mojo_adapter.cc +++ b/services/video_capture/device_factory_media_to_mojo_adapter.cc
@@ -79,10 +79,11 @@ DeviceFactoryMediaToMojoAdapter::DeviceFactoryMediaToMojoAdapter( std::unique_ptr<service_manager::ServiceContextRef> service_ref, std::unique_ptr<media::VideoCaptureSystem> capture_system, - media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback) + const media::VideoCaptureJpegDecoderFactoryCB& + jpeg_decoder_factory_callback) : service_ref_(std::move(service_ref)), capture_system_(std::move(capture_system)), - jpeg_decoder_factory_callback_(std::move(jpeg_decoder_factory_callback)), + jpeg_decoder_factory_callback_(jpeg_decoder_factory_callback), has_called_get_device_infos_(false), weak_factory_(this) {}
diff --git a/services/video_capture/device_factory_media_to_mojo_adapter.h b/services/video_capture/device_factory_media_to_mojo_adapter.h index 1104838..46c2206 100644 --- a/services/video_capture/device_factory_media_to_mojo_adapter.h +++ b/services/video_capture/device_factory_media_to_mojo_adapter.h
@@ -26,7 +26,8 @@ DeviceFactoryMediaToMojoAdapter( std::unique_ptr<service_manager::ServiceContextRef> service_ref, std::unique_ptr<media::VideoCaptureSystem> capture_system, - media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback); + const media::VideoCaptureJpegDecoderFactoryCB& + jpeg_decoder_factory_callback); ~DeviceFactoryMediaToMojoAdapter() override; // mojom::DeviceFactory implementation. @@ -63,8 +64,7 @@ const std::unique_ptr<service_manager::ServiceContextRef> service_ref_; const std::unique_ptr<media::VideoCaptureSystem> capture_system_; - const media::MojoJpegDecodeAcceleratorFactoryCB - jpeg_decoder_factory_callback_; + const media::VideoCaptureJpegDecoderFactoryCB jpeg_decoder_factory_callback_; std::map<std::string, ActiveDeviceEntry> active_devices_by_id_; bool has_called_get_device_infos_;
diff --git a/services/video_capture/device_factory_provider_impl.cc b/services/video_capture/device_factory_provider_impl.cc index 930f237..900903b 100644 --- a/services/video_capture/device_factory_provider_impl.cc +++ b/services/video_capture/device_factory_provider_impl.cc
@@ -7,36 +7,31 @@ #include "media/capture/video/fake_video_capture_device_factory.h" #include "media/capture/video/video_capture_buffer_pool.h" #include "media/capture/video/video_capture_buffer_tracker.h" +#include "media/capture/video/video_capture_jpeg_decoder.h" #include "media/capture/video/video_capture_system_impl.h" -#include "services/ui/public/cpp/gpu/client_gpu_memory_buffer_manager.h" -#include "services/ui/public/cpp/gpu/gpu.h" #include "services/video_capture/device_factory_media_to_mojo_adapter.h" #include "services/video_capture/virtual_device_enabled_device_factory.h" +namespace { + +// TODO(chfremer): Replace with an actual decoder factory. +// https://crbug.com/584797 +std::unique_ptr<media::VideoCaptureJpegDecoder> CreateJpegDecoder() { + return nullptr; +} + +} // anonymous namespace + namespace video_capture { DeviceFactoryProviderImpl::DeviceFactoryProviderImpl( std::unique_ptr<service_manager::ServiceContextRef> service_ref, base::Callback<void(float)> set_shutdown_delay_cb) : service_ref_(std::move(service_ref)), - set_shutdown_delay_cb_(std::move(set_shutdown_delay_cb)), - weak_factory_(this) {} + set_shutdown_delay_cb_(std::move(set_shutdown_delay_cb)) {} DeviceFactoryProviderImpl::~DeviceFactoryProviderImpl() {} -void DeviceFactoryProviderImpl::InjectGpuDependencies( - ui::mojom::GpuMemoryBufferFactoryPtr memory_buffer_factory, - mojom::AcceleratorFactoryPtr accelerator_factory) { - accelerator_factory_ = std::move(accelerator_factory); -// Since the instance of ui::ClientGpuMemoryBufferManager seems kind of -// expensive, we only create it on platforms where it gets actually used. -#if defined(OS_CHROMEOS) - gpu_memory_buffer_manager_ = - std::make_unique<ui::ClientGpuMemoryBufferManager>( - std::move(memory_buffer_factory)); -#endif -} - void DeviceFactoryProviderImpl::ConnectToDeviceFactory( mojom::DeviceFactoryRequest request) { LazyInitializeDeviceFactory(); @@ -57,13 +52,15 @@ // Chrome OS. std::unique_ptr<media::VideoCaptureDeviceFactory> media_device_factory = media::VideoCaptureDeviceFactory::CreateFactory( - base::ThreadTaskRunnerHandle::Get(), gpu_memory_buffer_manager_.get(), + base::ThreadTaskRunnerHandle::Get(), + // TODO(jcliang): Create a GpuMemoryBufferManager from GpuService + // here. + nullptr, + // TODO(mojahsu): Create a GpuJpegDecoderMojoFactoryCB here. base::BindRepeating( - &DeviceFactoryProviderImpl::CreateJpegDecodeAccelerator, - weak_factory_.GetWeakPtr()), + [](media::mojom::JpegDecodeAcceleratorRequest) {}), base::BindRepeating( - &DeviceFactoryProviderImpl::CreateJpegEncodeAccelerator, - weak_factory_.GetWeakPtr())); + [](media::mojom::JpegEncodeAcceleratorRequest) {})); auto video_capture_system = std::make_unique<media::VideoCaptureSystemImpl>( std::move(media_device_factory)); @@ -71,23 +68,7 @@ service_ref_->Clone(), std::make_unique<DeviceFactoryMediaToMojoAdapter>( service_ref_->Clone(), std::move(video_capture_system), - base::BindRepeating( - &DeviceFactoryProviderImpl::CreateJpegDecodeAccelerator, - weak_factory_.GetWeakPtr()))); -} - -void DeviceFactoryProviderImpl::CreateJpegDecodeAccelerator( - media::mojom::JpegDecodeAcceleratorRequest request) { - if (!accelerator_factory_) - return; - accelerator_factory_->CreateJpegDecodeAccelerator(std::move(request)); -} - -void DeviceFactoryProviderImpl::CreateJpegEncodeAccelerator( - media::mojom::JpegEncodeAcceleratorRequest request) { - if (!accelerator_factory_) - return; - accelerator_factory_->CreateJpegEncodeAccelerator(std::move(request)); + base::Bind(CreateJpegDecoder))); } } // namespace video_capture
diff --git a/services/video_capture/device_factory_provider_impl.h b/services/video_capture/device_factory_provider_impl.h index de633d4..5987091 100644 --- a/services/video_capture/device_factory_provider_impl.h +++ b/services/video_capture/device_factory_provider_impl.h
@@ -7,10 +7,7 @@ #include <memory> -#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" -#include "media/capture/video/video_capture_jpeg_decoder.h" #include "mojo/public/cpp/bindings/binding_set.h" -#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/cpp/service_context_ref.h" #include "services/video_capture/public/mojom/device_factory_provider.mojom.h" @@ -25,27 +22,17 @@ ~DeviceFactoryProviderImpl() override; // mojom::DeviceFactoryProvider implementation. - void InjectGpuDependencies( - ui::mojom::GpuMemoryBufferFactoryPtr memory_buffer_factory, - mojom::AcceleratorFactoryPtr accelerator_factory) override; void ConnectToDeviceFactory(mojom::DeviceFactoryRequest request) override; void SetShutdownDelayInSeconds(float seconds) override; private: void LazyInitializeDeviceFactory(); - void CreateJpegDecodeAccelerator( - media::mojom::JpegDecodeAcceleratorRequest request); - void CreateJpegEncodeAccelerator( - media::mojom::JpegEncodeAcceleratorRequest request); mojo::BindingSet<mojom::DeviceFactory> factory_bindings_; std::unique_ptr<mojom::DeviceFactory> device_factory_; const std::unique_ptr<service_manager::ServiceContextRef> service_ref_; - mojom::AcceleratorFactoryPtr accelerator_factory_; - std::unique_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager_; base::Callback<void(float)> set_shutdown_delay_cb_; - base::WeakPtrFactory<DeviceFactoryProviderImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(DeviceFactoryProviderImpl); };
diff --git a/services/video_capture/device_media_to_mojo_adapter.cc b/services/video_capture/device_media_to_mojo_adapter.cc index 26edf53..397cd0b 100644 --- a/services/video_capture/device_media_to_mojo_adapter.cc +++ b/services/video_capture/device_media_to_mojo_adapter.cc
@@ -8,33 +8,20 @@ #include "media/base/bind_to_current_loop.h" #include "media/capture/video/video_capture_buffer_pool_impl.h" #include "media/capture/video/video_capture_buffer_tracker_factory_impl.h" -#include "media/capture/video/video_capture_jpeg_decoder_impl.h" -#include "media/capture/video/video_frame_receiver_on_task_runner.h" +#include "media/capture/video/video_capture_jpeg_decoder.h" #include "mojo/public/cpp/bindings/callback_helpers.h" #include "services/video_capture/receiver_mojo_to_media_adapter.h" -namespace { - -std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder( - media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback, - media::VideoCaptureJpegDecoder::DecodeDoneCB decode_done_cb, - base::RepeatingCallback<void(const std::string&)> send_log_message_cb) { - return std::make_unique<media::VideoCaptureJpegDecoderImpl>( - jpeg_decoder_factory_callback, base::ThreadTaskRunnerHandle::Get(), - std::move(decode_done_cb), std::move(send_log_message_cb)); -} - -} // anonymous namespace - namespace video_capture { DeviceMediaToMojoAdapter::DeviceMediaToMojoAdapter( std::unique_ptr<service_manager::ServiceContextRef> service_ref, std::unique_ptr<media::VideoCaptureDevice> device, - media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback) + const media::VideoCaptureJpegDecoderFactoryCB& + jpeg_decoder_factory_callback) : service_ref_(std::move(service_ref)), device_(std::move(device)), - jpeg_decoder_factory_callback_(std::move(jpeg_decoder_factory_callback)), + jpeg_decoder_factory_callback_(jpeg_decoder_factory_callback), device_started_(false), weak_factory_(this) {} @@ -52,9 +39,10 @@ base::Bind(&DeviceMediaToMojoAdapter::OnClientConnectionErrorOrClose, weak_factory_.GetWeakPtr())); - receiver_ = std::make_unique<ReceiverMojoToMediaAdapter>(std::move(receiver)); - auto media_receiver = std::make_unique<media::VideoFrameReceiverOnTaskRunner>( - receiver_->GetWeakPtr(), base::ThreadTaskRunnerHandle::Get()); + auto receiver_adapter = + std::make_unique<ReceiverMojoToMediaAdapter>(std::move(receiver)); + auto media_receiver = std::make_unique<ReceiverOnTaskRunner>( + std::move(receiver_adapter), base::ThreadTaskRunnerHandle::Get()); // Create a dedicated buffer pool for the device usage session. auto buffer_tracker_factory = @@ -64,13 +52,7 @@ max_buffer_pool_buffer_count())); auto device_client = std::make_unique<media::VideoCaptureDeviceClient>( - std::move(media_receiver), buffer_pool, - base::BindRepeating( - &CreateGpuJpegDecoder, jpeg_decoder_factory_callback_, - base::BindRepeating(&media::VideoFrameReceiver::OnFrameReadyInBuffer, - receiver_->GetWeakPtr()), - base::BindRepeating(&media::VideoFrameReceiver::OnLog, - receiver_->GetWeakPtr()))); + std::move(media_receiver), buffer_pool, jpeg_decoder_factory_callback_); device_->AllocateAndStart(requested_settings, std::move(device_client)); device_started_ = true; @@ -131,7 +113,6 @@ device_started_ = false; weak_factory_.InvalidateWeakPtrs(); device_->StopAndDeAllocate(); - receiver_.reset(); } void DeviceMediaToMojoAdapter::OnClientConnectionErrorOrClose() {
diff --git a/services/video_capture/device_media_to_mojo_adapter.h b/services/video_capture/device_media_to_mojo_adapter.h index fb218bf..2d0f4de 100644 --- a/services/video_capture/device_media_to_mojo_adapter.h +++ b/services/video_capture/device_media_to_mojo_adapter.h
@@ -8,16 +8,12 @@ #include "base/threading/thread_checker.h" #include "media/capture/video/video_capture_device.h" #include "media/capture/video/video_capture_device_client.h" -#include "media/capture/video/video_capture_device_factory.h" -#include "media/capture/video/video_capture_jpeg_decoder.h" #include "media/capture/video_capture_types.h" #include "services/service_manager/public/cpp/service_context_ref.h" #include "services/video_capture/public/mojom/device.mojom.h" namespace video_capture { -class ReceiverMojoToMediaAdapter; - // Implementation of mojom::Device backed by a given instance of // media::VideoCaptureDevice. class DeviceMediaToMojoAdapter : public mojom::Device { @@ -25,7 +21,8 @@ DeviceMediaToMojoAdapter( std::unique_ptr<service_manager::ServiceContextRef> service_ref, std::unique_ptr<media::VideoCaptureDevice> device, - media::MojoJpegDecodeAcceleratorFactoryCB jpeg_decoder_factory_callback); + const media::VideoCaptureJpegDecoderFactoryCB& + jpeg_decoder_factory_callback); ~DeviceMediaToMojoAdapter() override; // mojom::Device implementation. @@ -51,9 +48,7 @@ private: const std::unique_ptr<service_manager::ServiceContextRef> service_ref_; const std::unique_ptr<media::VideoCaptureDevice> device_; - const media::MojoJpegDecodeAcceleratorFactoryCB - jpeg_decoder_factory_callback_; - std::unique_ptr<ReceiverMojoToMediaAdapter> receiver_; + media::VideoCaptureJpegDecoderFactoryCB jpeg_decoder_factory_callback_; bool device_started_; base::ThreadChecker thread_checker_; base::WeakPtrFactory<DeviceMediaToMojoAdapter> weak_factory_;
diff --git a/services/video_capture/device_media_to_mojo_adapter_unittest.cc b/services/video_capture/device_media_to_mojo_adapter_unittest.cc index 5c24915a6..f88f204 100644 --- a/services/video_capture/device_media_to_mojo_adapter_unittest.cc +++ b/services/video_capture/device_media_to_mojo_adapter_unittest.cc
@@ -28,7 +28,7 @@ mock_device_ptr_ = mock_device.get(); adapter_ = std::make_unique<DeviceMediaToMojoAdapter>( std::unique_ptr<service_manager::ServiceContextRef>(), - std::move(mock_device), base::DoNothing()); + std::move(mock_device), media::VideoCaptureJpegDecoderFactoryCB()); } void TearDown() override {
diff --git a/services/video_capture/public/mojom/BUILD.gn b/services/video_capture/public/mojom/BUILD.gn index c3b0257..6948edf 100644 --- a/services/video_capture/public/mojom/BUILD.gn +++ b/services/video_capture/public/mojom/BUILD.gn
@@ -20,7 +20,6 @@ "//media/capture/mojom:image_capture", "//media/capture/mojom:video_capture", "//media/mojo/interfaces", - "//services/ui/public/interfaces", "//ui/gfx/geometry/mojo", ] }
diff --git a/services/video_capture/public/mojom/device_factory_provider.mojom b/services/video_capture/public/mojom/device_factory_provider.mojom index 92fd783b..857251b 100644 --- a/services/video_capture/public/mojom/device_factory_provider.mojom +++ b/services/video_capture/public/mojom/device_factory_provider.mojom
@@ -6,26 +6,11 @@ import "services/video_capture/public/mojom/device_factory.mojom"; -import "media/mojo/interfaces/jpeg_decode_accelerator.mojom"; -import "media/mojo/interfaces/jpeg_encode_accelerator.mojom"; -import "services/ui/public/interfaces/gpu.mojom"; - -interface AcceleratorFactory { - // Creates a new JpegDecodeAccelerator and binds it to |jda|. - CreateJpegDecodeAccelerator(media.mojom.JpegDecodeAccelerator& jda); - - // Creates a new JpegEncodeAccelerator and binds it to |jea|. - CreateJpegEncodeAccelerator(media.mojom.JpegEncodeAccelerator& jea); -}; - // Entry point to the Video Capture Service API. // The factory provides access to the capture devices connected to the system. // By using command-line switches, it is possible to replace this with a "fake" // factory, which provides access to fake devices that generates test frames. interface DeviceFactoryProvider { - InjectGpuDependencies(ui.mojom.GpuMemoryBufferFactory memory_buffer_factory, - AcceleratorFactory accelerator_factory); - ConnectToDeviceFactory(DeviceFactory& request); // The service shuts down after a certain delay when no client is connected.
diff --git a/services/video_capture/receiver_mojo_to_media_adapter.cc b/services/video_capture/receiver_mojo_to_media_adapter.cc index 4212430b..927eaaf 100644 --- a/services/video_capture/receiver_mojo_to_media_adapter.cc +++ b/services/video_capture/receiver_mojo_to_media_adapter.cc
@@ -9,17 +9,75 @@ namespace video_capture { +ReceiverOnTaskRunner::ReceiverOnTaskRunner( + std::unique_ptr<media::VideoFrameReceiver> receiver, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : receiver_(std::move(receiver)), task_runner_(std::move(task_runner)) {} + +ReceiverOnTaskRunner::~ReceiverOnTaskRunner() { + task_runner_->DeleteSoon(FROM_HERE, receiver_.release()); +} + +void ReceiverOnTaskRunner::OnNewBuffer( + int buffer_id, + media::mojom::VideoBufferHandlePtr buffer_handle) { + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&media::VideoFrameReceiver::OnNewBuffer, + base::Unretained(receiver_.get()), buffer_id, + base::Passed(&buffer_handle))); +} + +void ReceiverOnTaskRunner::OnFrameReadyInBuffer( + int buffer_id, + int frame_feedback_id, + std::unique_ptr< + media::VideoCaptureDevice::Client::Buffer::ScopedAccessPermission> + buffer_read_permission, + media::mojom::VideoFrameInfoPtr frame_info) { + task_runner_->PostTask( + FROM_HERE, + base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer, + base::Unretained(receiver_.get()), buffer_id, + frame_feedback_id, base::Passed(&buffer_read_permission), + base::Passed(&frame_info))); +} + +void ReceiverOnTaskRunner::OnBufferRetired(int buffer_id) { + task_runner_->PostTask( + FROM_HERE, base::Bind(&media::VideoFrameReceiver::OnBufferRetired, + base::Unretained(receiver_.get()), buffer_id)); +} + +void ReceiverOnTaskRunner::OnError() { + task_runner_->PostTask(FROM_HERE, + base::Bind(&media::VideoFrameReceiver::OnError, + base::Unretained(receiver_.get()))); +} + +void ReceiverOnTaskRunner::OnLog(const std::string& message) { + task_runner_->PostTask( + FROM_HERE, base::Bind(&media::VideoFrameReceiver::OnLog, + base::Unretained(receiver_.get()), message)); +} + +void ReceiverOnTaskRunner::OnStarted() { + task_runner_->PostTask(FROM_HERE, + base::Bind(&media::VideoFrameReceiver::OnStarted, + base::Unretained(receiver_.get()))); +} + +void ReceiverOnTaskRunner::OnStartedUsingGpuDecode() { + task_runner_->PostTask( + FROM_HERE, base::Bind(&media::VideoFrameReceiver::OnStartedUsingGpuDecode, + base::Unretained(receiver_.get()))); +} + ReceiverMojoToMediaAdapter::ReceiverMojoToMediaAdapter( mojom::ReceiverPtr receiver) - : receiver_(std::move(receiver)), weak_factory_(this) {} + : receiver_(std::move(receiver)) {} ReceiverMojoToMediaAdapter::~ReceiverMojoToMediaAdapter() = default; -base::WeakPtr<media::VideoFrameReceiver> -ReceiverMojoToMediaAdapter::GetWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - void ReceiverMojoToMediaAdapter::OnNewBuffer( int buffer_id, media::mojom::VideoBufferHandlePtr buffer_handle) {
diff --git a/services/video_capture/receiver_mojo_to_media_adapter.h b/services/video_capture/receiver_mojo_to_media_adapter.h index 00609b4..e6eaa10 100644 --- a/services/video_capture/receiver_mojo_to_media_adapter.h +++ b/services/video_capture/receiver_mojo_to_media_adapter.h
@@ -11,6 +11,33 @@ namespace video_capture { +class ReceiverOnTaskRunner : public media::VideoFrameReceiver { + public: + ReceiverOnTaskRunner(std::unique_ptr<media::VideoFrameReceiver> receiver, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + ~ReceiverOnTaskRunner() override; + + // media::VideoFrameReceiver implementation. + void OnNewBuffer(int buffer_id, + media::mojom::VideoBufferHandlePtr buffer_handle) override; + void OnFrameReadyInBuffer( + int buffer_id, + int frame_feedback_id, + std::unique_ptr< + media::VideoCaptureDevice::Client::Buffer::ScopedAccessPermission> + buffer_read_permission, + media::mojom::VideoFrameInfoPtr frame_info) override; + void OnBufferRetired(int buffer_id) override; + void OnError() override; + void OnLog(const std::string& message) override; + void OnStarted() override; + void OnStartedUsingGpuDecode() override; + + private: + std::unique_ptr<media::VideoFrameReceiver> receiver_; + const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; +}; + // Adapter that allows a mojom::VideoFrameReceiver to be used in place of // a media::VideoFrameReceiver. class ReceiverMojoToMediaAdapter : public media::VideoFrameReceiver { @@ -18,8 +45,6 @@ ReceiverMojoToMediaAdapter(mojom::ReceiverPtr receiver); ~ReceiverMojoToMediaAdapter() override; - base::WeakPtr<media::VideoFrameReceiver> GetWeakPtr(); - // media::VideoFrameReceiver implementation. void OnNewBuffer(int buffer_id, media::mojom::VideoBufferHandlePtr buffer_handle) override; @@ -38,7 +63,6 @@ private: mojom::ReceiverPtr receiver_; - base::WeakPtrFactory<ReceiverMojoToMediaAdapter> weak_factory_; }; } // namespace video_capture
diff --git a/services/video_capture/test/mock_device_test.cc b/services/video_capture/test/mock_device_test.cc index 24c26466..62a25cd 100644 --- a/services/video_capture/test/mock_device_test.cc +++ b/services/video_capture/test/mock_device_test.cc
@@ -14,6 +14,14 @@ using testing::Invoke; using testing::InvokeWithoutArgs; +namespace { + +std::unique_ptr<media::VideoCaptureJpegDecoder> CreateJpegDecoder() { + return nullptr; +} + +} // anonymous namespace + namespace video_capture { MockDeviceTest::MockDeviceTest() : ref_factory_(base::DoNothing()) {} @@ -32,7 +40,7 @@ mock_device_factory_adapter_ = std::make_unique<DeviceFactoryMediaToMojoAdapter>( ref_factory_.CreateRef(), std::move(video_capture_system), - base::DoNothing()); + base::Bind(CreateJpegDecoder)); mock_factory_binding_ = std::make_unique<mojo::Binding<mojom::DeviceFactory>>( mock_device_factory_adapter_.get(), mojo::MakeRequest(&factory_));
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 69f40692..462be33 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -5207,11 +5207,6 @@ "results_handler": "layout tests", "swarming": { "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "os": "Ubuntu-14.04" - } - ], "shards": 12 } } @@ -5224,6 +5219,18 @@ "gtest_tests": [ { "args": [ + "--enable-features=NetworkService", + "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_browser_tests.filter" + ], + "name": "network_service_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "shards": 10 + }, + "test": "browser_tests" + }, + { + "args": [ "--enable-surface-synchronization" ], "name": "surface_sync_browser_tests", @@ -5247,6 +5254,27 @@ }, { "args": [ + "--enable-features=NetworkService" + ], + "name": "network_service_components_browsertests", + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "components_browsertests" + }, + { + "args": [ + "--enable-features=NetworkService", + "--test-launcher-filter-file=../../testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter" + ], + "name": "network_service_content_browsertests", + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "content_browsertests" + }, + { + "args": [ "--enable-surface-synchronization" ], "name": "surface_sync_content_browsertests", @@ -5280,11 +5308,53 @@ "test": "content_unittests" }, { + "args": [ + "--enable-features=NetworkService" + ], + "name": "network_service_extensions_browsertests", + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "extensions_browsertests" + }, + { + "args": [ + "--enable-features=NetworkService" + ], + "name": "network_service_interactive_ui_tests", + "swarming": { + "can_use_on_swarming_builders": true + }, + "test": "interactive_ui_tests" + }, + { "swarming": { "can_use_on_swarming_builders": true }, "test": "services_unittests" } + ], + "isolated_scripts": [ + { + "args": [ + "--additional-driver-flag=--enable-features=NetworkService", + "--zero-tests-executed-ok" + ], + "isolate_name": "webkit_layout_tests_exparchive", + "merge": { + "args": [ + "--verbose" + ], + "script": "//third_party/blink/tools/merge_web_test_results.py" + }, + "name": "webkit_layout_tests", + "only_retry_failed_tests": true, + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "shards": 12 + } + } ] }, "Out of Process Profiling Android": {
diff --git a/testing/buildbot/filters/mac_window_server_killers.browser_tests.filter b/testing/buildbot/filters/mac_window_server_killers.browser_tests.filter index dbfeee93a..7b5d4c1 100644 --- a/testing/buildbot/filters/mac_window_server_killers.browser_tests.filter +++ b/testing/buildbot/filters/mac_window_server_killers.browser_tests.filter
@@ -1,47 +1,7 @@ # https://crbug.com/828031 # Suites implicated in window_server deaths. -# -PDFExtensionTest.* -# -SubresourceFilterBrowserTest.* -# -DevToolsBeforeUnloadTest.* -# -PushMessagingBrowserTest.* -# -TaskManagerBrowserTest.* -# -AppBannerManagerBrowserTest.* -# -SpellingMenuObserverTest.* -# -PluginPowerSaverBrowserTest.* -# -SubresourceFilterPopupBrowserTest.* -# -FindInPageControllerTest.* -# -TestStatsDictionaryTest.* -# -PlatformAppWithFileBrowserTest.* -# -PermissionDialogTest.* -# -SecurityStateTabHelperTest.* -# -PrerenderBrowserTest.* -# -DomDistillerViewerSourceBrowserTest.* -# -PredictorBrowserTest.* -# -TabManagerTest.* -# -PasswordManagerBrowserTestBase.* -# -DevToolsSanityTest.* -# -WebRtcBrowserTest.* -# -LoginPromptBrowserTest.* -# -ReferrerPolicyTest.* -# -PlatformAppBrowserTest.* -# -BrowserNavigatorTest.* -# -ChromeResourceDispatcherHostDelegateBrowserTest.* -# -NoStatePrefetchBrowserTest.* -# -PageLoadMetricsBrowserTest.* -# -DnsProbeBrowserTest.* -# -FullscreenControllerTest.* -# -InfoBarUiTest.* -# -PrefsFunctionalTest.* -# -BrowserTest.* -# -DownloadTest.* -# -PolicyTest.* -# -SessionRestoreTest.* -# -InstallableManagerBrowserTest.* -# -ContextMenuBrowserTest.* -# -ChromeSitePerProcessTest.* -# -InterstitialUITest.* -#-ConstrainedWebDialogBrowserTest.BasicTest -#-ConstrainedWebDialogBrowserTest.ReleaseWebContents +# -ConstrainedWebDialogBrowserTest.BasicTest +-ConstrainedWebDialogBrowserTest.ReleaseWebContents -ConstrainedWebDialogBrowserTest.ContentResizeInAutoResizingDialog -ConstrainedWebDialogBrowserTest.ContentResizeInNonAutoResizingDialog
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter index 6acc1e97..eca129f 100644 --- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -14,8 +14,6 @@ -EnabledSignInIsolationBrowserTest.SyntheticTrial -ExpectCTBrowserTest.TestDynamicExpectCTHeaderProcessing -ExpectCTBrowserTest.TestDynamicExpectCTReporting --ExtensionApiTest.Debugger --ExtensionApiTestWithSwitch.ExtensionDebugger -ExtensionUnloadBrowserTest.UnloadWithContentScripts -MediaGalleriesPlatformAppBrowserTest.ToURL -NetInternalsTest.netInternalsSessionBandwidthSucceed @@ -150,6 +148,8 @@ -ExtensionWebRequestApiTest.WebRequestTypes -ExtensionWebRequestApiTest.WebRequestTestOSDD -ExtensionWebRequestApiTest.WebRequestURLFetcherInterception +# Note WebRequestUnloadImmediately is disabled on Linux +-ExtensionWebRequestApiTest.WebRequestUnloadImmediately # https://crbug.com/721400 # WebSocket with the network service @@ -215,6 +215,11 @@ -ServiceWorkerTestWithNativeBindings/ServiceWorkerTest.WebAccessibleResourcesFetch/0 -ServiceWorkerTestWithNativeBindings/ServiceWorkerTest.WebAccessibleResourcesIframeSrc/0 +# Support URLLoaderFactories from embedder in shared workers. +# https://crbug.com/839982 +-ExtensionApiTest.Debugger +-ExtensionApiTestWithSwitch.ExtensionDebugger + # https://crbug.com/832749 # Add DMServer header -ChromeResourceDispatcherHostDelegateBrowserTest.PolicyHeader @@ -255,6 +260,9 @@ -CertificateTransparencyBrowserTest.ProfileRequest -CertificateTransparencyBrowserTest.SystemRequest +# Fail on Windows only +-ConditionalCacheCountingHelperBrowserTest.Count + # NOTE: if adding an exclusion for an existing failure (e.g. additional test for # feature X that is already not working), please add it beside the existing # failures. Otherwise please reach out to network-service-dev@.
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 5734a4a..75ab68df 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -1096,7 +1096,7 @@ }, }, - 'mojo_linux_isolated_scripts': { + 'mojo_network_isolated_scripts': { 'webkit_layout_tests': { 'args': [ '--additional-driver-flag=--enable-features=NetworkService', @@ -1112,11 +1112,6 @@ 'only_retry_failed_tests': True, 'results_handler': 'layout tests', 'swarming': { - 'dimension_sets': [ - { - 'os': 'Ubuntu-14.04', - } - ], 'shards': 12, }, }, @@ -2252,6 +2247,7 @@ 'mojo_windows_gtests': [ 'mojo_windows_specific_gtests', + 'network_service_gtests', 'viz_fyi_gtests', ],
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 5a73d765..ed13bb9 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -1182,7 +1182,7 @@ 'Mojo Linux': { 'test_suites': { 'gtest_tests': 'network_service_gtests', - 'isolated_scripts': 'mojo_linux_isolated_scripts', + 'isolated_scripts': 'mojo_network_isolated_scripts', }, }, 'Mojo Windows': { @@ -1191,6 +1191,7 @@ ], 'test_suites': { 'gtest_tests': 'mojo_windows_gtests', + 'isolated_scripts': 'mojo_network_isolated_scripts', }, }, 'Out of Process Profiling Android': {
diff --git a/testing/libfuzzer/fuzzer_test.gni b/testing/libfuzzer/fuzzer_test.gni index 20f6ec93..1e41df2 100644 --- a/testing/libfuzzer/fuzzer_test.gni +++ b/testing/libfuzzer/fuzzer_test.gni
@@ -18,6 +18,7 @@ # - dict - a dictionary file for the fuzzer. # - libfuzzer_options - options for the fuzzer (e.g. -max_len or -timeout). # - seed_corpus - a directory with seed corpus. +# - seed_corpus_deps - dependencies for generating the seed corpus. # - skip_owners - if true, skips writing the owners file. # # If use_libfuzzer gn flag is defined, then proper fuzzer would be build. @@ -48,6 +49,12 @@ out = "$root_build_dir/$target_name" + "_seed_corpus.zip" + seed_corpus_deps = [] + + if (defined(invoker.seed_corpus_deps)) { + seed_corpus_deps += invoker.seed_corpus_deps + } + action(target_name + "_seed_corpus") { script = "//testing/libfuzzer/archive_corpus.py" @@ -70,9 +77,7 @@ out, ] - deps = [ - "//testing/libfuzzer:seed_corpus", - ] + deps = [ "//testing/libfuzzer:seed_corpus" ] + seed_corpus_deps } test_deps += [ ":" + target_name + "_seed_corpus" ] @@ -195,6 +200,9 @@ if (defined(invoker.seed_corpuses)) { assert(invoker.seed_corpuses == [] || invoker.seed_corpuses != []) } + if (defined(invoker.seed_corpus_deps)) { + assert(invoker.seed_corpus_deps == [] || invoker.seed_corpus_deps != []) + } assert(!defined(invoker.check_includes) || invoker.check_includes != []) assert(!defined(invoker.include_dirs) || invoker.include_dirs != []) assert(!defined(invoker.defines) || invoker.defines != [])
diff --git a/testing/trigger_scripts/perf_device_trigger.py b/testing/trigger_scripts/perf_device_trigger.py index f745833..29fb973 100755 --- a/testing/trigger_scripts/perf_device_trigger.py +++ b/testing/trigger_scripts/perf_device_trigger.py
@@ -222,9 +222,11 @@ # We queried with a limit of 1 so we could only get back # the most recent which is what we care about. task = tasks[0] + if 'bot_id' in task: + return task['bot_id'] for tag in task['tags']: - if 'id' in tag: - return tag[len('id;'):] + if tag.startswith('id:'): + return tag[len('id:'):] # No eligible shard for this bot return None
diff --git a/testing/trigger_scripts/perf_device_trigger_unittest.py b/testing/trigger_scripts/perf_device_trigger_unittest.py index ee8f8e6..b583cfe 100755 --- a/testing/trigger_scripts/perf_device_trigger_unittest.py +++ b/testing/trigger_scripts/perf_device_trigger_unittest.py
@@ -99,7 +99,7 @@ for i in xrange(num_shards): bot_id = previous_task_assignment_map.get(i) files['base_trigger_dimensions%d.json' % file_index] = ( - self.generate_last_task_to_shard_query_response(bot_id)) + self.generate_last_task_to_shard_query_response(i, bot_id)) file_index = file_index + 1 for i in xrange(num_shards): task = { @@ -120,9 +120,14 @@ file_index = file_index + 1 return files - def generate_last_task_to_shard_query_response(self, bot_id): + def generate_last_task_to_shard_query_response(self, shard, bot_id): if len(bot_id): - return {'items': [{'tags': [('id:%s' % bot_id)]}]} + # Test both cases where bot_id is present and you have to parse + # out of the tags. + if shard % 2: + return {'items': [{'bot_id': bot_id}]} + else: + return {'items': [{'tags': [('id:%s' % bot_id)]}]} return {} def generate_list_of_eligible_bots_query_response(
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 17e8fe3f..39c54f7 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -497,11 +497,11 @@ # Crashes/asserts due to inline item reuse. crbug.com/636993 virtual/layout_ng/fast/block/float/add-float-back-to-anonymous-block-previous.html [ Crash ] -crbug.com/636993 virtual/layout_ng/fast/inline/inline-empty-block-continuation-remove.html [ Crash ] -crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/remove-block-from-content-after-spanner.html [ Failure Crash ] -crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/remove-block-from-content-before-spanner.html [ Failure Crash ] -crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/remove-block-from-content-between-spanners.html [ Failure Crash ] -crbug.com/636993 virtual/layout_ng_experimental/fast/multicol/dynamic/remove-inline-and-spanner-after-spanner-foreignObject.html [ Crash ] +crbug.com/636993 virtual/layout_ng/fast/inline/inline-empty-block-continuation-remove.html [ Crash Timeout ] +crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/remove-block-from-content-after-spanner.html [ Failure Crash Timeout ] +crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/remove-block-from-content-before-spanner.html [ Failure Crash Timeout ] +crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/dynamic/remove-block-from-content-between-spanners.html [ Failure Crash Timeout ] +crbug.com/636993 virtual/layout_ng_experimental/fast/multicol/dynamic/remove-inline-and-spanner-after-spanner-foreignObject.html [ Crash Timeout ] ### 1px diff with ref files. crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/linebox/vertical-align-sub-001.xht [ Failure ] @@ -1720,7 +1720,6 @@ # ====== IncrementalShadowDOM-only failures from here ====== crbug.com/776656 virtual/incremental-shadow-dom/external/wpt/shadow-dom/untriaged/styles/test-003.html [ Failure ] -crbug.com/776656 virtual/incremental-shadow-dom/http/tests/devtools/elements/shadow/shadow-distribution.js [ Failure ] # ====== IncrementalShadowDOM-only failures until here ====== @@ -2360,66 +2359,23 @@ crbug.com/807152 vr/VRDisplay_rAF_fires_with_window_rAF.html [ Pass Failure ] crbug.com/813697 vr/getFrameData_oneframeupdate.html [ Pass Failure ] +crbug.com/806357 [ Win Debug ] fast/events/pointerevents/pointerevent_touch-action-pinch_zoom_touch.html [ Pass Failure ] +crbug.com/839038 [ Mac ] external/wpt/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-manual.html [ Skip ] + # These tests are skipped as there is no touch support on Mac. crbug.com/613672 [ Mac ] fast/events/touch/multi-touch-user-gesture.html [ Skip ] crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/touch/multi-touch-user-gesture.html [ Skip ] crbug.com/613672 [ Mac ] virtual/scroll_customization/fast/events/touch/multi-touch-user-gesture.html [ Skip ] crbug.com/613672 [ Mac ] fast/events/pointerevents/multi-pointer-event-in-slop-region.html [ Skip ] -crbug.com/613672 [ Mac ] fast/events/pointerevents/pointerevent_touch-action-pinch_zoom_touch.html [ Skip ] -crbug.com/806357 [ Win Debug ] fast/events/pointerevents/pointerevent_touch-action-pinch_zoom_touch.html [ Pass Failure ] -crbug.com/613672 [ Mac ] fast/events/pointerevents/pointerevent_touch-adjustment_click_target.html [ Skip ] -crbug.com/613672 [ Mac ] fast/events/pointerevents/pointer-event-consumed-touchstart-in-slop-region.html [ Skip ] -crbug.com/613672 [ Mac ] fast/events/pointerevents/pointer-event-in-slop-region.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerlock/pointerevent_movementxy-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/compat/pointerevent_touch-action_two-finger_interaction-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/extension/pointerevent_coalesced_events_attributes-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_sequence_at_implicit_release_on_drag-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_sequence_at_implicit_release_on_click-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_boundary_events_in_capturing-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_attributes_nohover_pointers-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_change-touch-action-onpointerdown_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_pointercancel_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_pointerout_after_pointercancel_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-auto-css_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/extension/pointerevent_touch-action-pan-left-css_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/extension/pointerevent_touch-action-pan-right-css_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/extension/pointerevent_touch-action-pan-up-css_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/extension/pointerevent_touch-action-pan-down-css_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-pan-x-css_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-button-test_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-pan-y-css_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-span-test_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-svg-test_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-none-css_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-inherit_parent-none_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-none_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html [ Skip ] -crbug.com/613672 [ Mac ] external/wpt/pointerevents/pointerevent_fractional_coordinates-manual.html [ Skip ] -crbug.com/613672 [ Mac ] fast/events/synthetic-events/tap-on-scaled-screen.html [ Skip ] -crbug.com/613672 [ Mac ] virtual/scalefactor150/fast/events/synthetic-events/tap-on-scaled-screen.html [ Skip ] crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/pointerevents/multi-pointer-event-in-slop-region.html [ Skip ] -crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/pointerevents/pointerevent_touch-action-pinch_zoom_touch.html [ Skip ] -crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/pointerevents/pointerevent_touch-adjustment_click_target.html [ Skip ] -crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/pointerevents/pointer-event-consumed-touchstart-in-slop-region.html [ Skip ] +crbug.com/613672 [ Mac ] fast/events/pointerevents/pointer-event-in-slop-region.html [ Skip ] crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/pointerevents/pointer-event-in-slop-region.html [ Skip ] -crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/synthetic-events/tap-on-scaled-screen.html [ Skip ] -crbug.com/613672 [ Mac ] virtual/scroll_customization/fast/scroll-behavior/scroll-customization/scroll-customization-property.html [ Skip ] -crbug.com/613672 [ Mac ] media/controls/modern/tap-to-hide-controls.html [ Skip ] -crbug.com/613672 [ Mac ] virtual/video-surface-layer/media/controls/modern/tap-to-hide-controls.html [ Skip ] -crbug.com/613672 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/tap-to-hide-controls.html [ Skip ] -crbug.com/613672 [ Mac ] media/controls/modern/singletouch-on-play-button.html [ Skip ] -crbug.com/613672 [ Mac ] virtual/video-surface-layer/media/controls/modern/singletouch-on-play-button.html [ Skip ] -crbug.com/613672 [ Mac ] virtual/new-remote-playback-pipeline/media/controls/modern/singletouch-on-play-button.html [ Skip ] +crbug.com/613672 [ Mac ] fast/events/pointerevents/pointerevent_touch-action-pinch_zoom_touch.html [ Skip ] +crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/pointerevents/pointerevent_touch-action-pinch_zoom_touch.html [ Skip ] +crbug.com/613672 [ Mac ] external/wpt/pointerevents/compat/pointerevent_touch-action_two-finger_interaction-manual.html [ Skip ] + +crbug.com/802067 [ Mac ] external/wpt/pointerlock/movementX_Y_basic-manual.html [ Failure ] +crbug.com/802067 [ Mac ] external/wpt/pointerevents/pointerlock/pointerevent_movementxy-manual.html [ Failure ] # We should send PointerLeave events for stylus devices. crbug.com/583413 external/wpt/pointerevents/pointerevent_pointerleave_pen-manual.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 659df7f..4d52231 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -103056,6 +103056,56 @@ {} ] ], + "cookies/prefix/__host.document-cookie.non-secure-expected.txt": [ + [ + {} + ] + ], + "cookies/prefix/__host.http.non-secure-expected.txt": [ + [ + {} + ] + ], + "cookies/prefix/__secure.document-cookie.non-secure-expected.txt": [ + [ + {} + ] + ], + "cookies/prefix/__secure.http.non-secure-expected.txt": [ + [ + {} + ] + ], + "cookies/prefix/__secure.http.secure-expected.txt": [ + [ + {} + ] + ], + "cookies/prefix/document-cookie.non-secure-expected.txt": [ + [ + {} + ] + ], + "cookies/resources/cookie-helper.sub.js": [ + [ + {} + ] + ], + "cookies/resources/drop.py": [ + [ + {} + ] + ], + "cookies/resources/dropSameSite.py": [ + [ + {} + ] + ], + "cookies/resources/dropSecure.py": [ + [ + {} + ] + ], "cookies/resources/echo-cookie.html": [ [ {} @@ -103066,16 +103116,116 @@ {} ] ], + "cookies/resources/helpers.py": [ + [ + {} + ] + ], + "cookies/resources/imgIfMatch.py": [ + [ + {} + ] + ], + "cookies/resources/list.py": [ + [ + {} + ] + ], + "cookies/resources/postToParent.py": [ + [ + {} + ] + ], + "cookies/resources/redirectWithCORSHeaders.py": [ + [ + {} + ] + ], "cookies/resources/set-cookie.py": [ [ {} ] ], + "cookies/resources/set.py": [ + [ + {} + ] + ], + "cookies/resources/setSameSite.py": [ + [ + {} + ] + ], + "cookies/resources/setSecure.py": [ + [ + {} + ] + ], "cookies/resources/testharness-helpers.js": [ [ {} ] ], + "cookies/samesite/fetch-expected.txt": [ + [ + {} + ] + ], + "cookies/samesite/form-get-blank-expected.txt": [ + [ + {} + ] + ], + "cookies/samesite/form-get-blank-reload-expected.txt": [ + [ + {} + ] + ], + "cookies/samesite/form-post-blank-expected.txt": [ + [ + {} + ] + ], + "cookies/samesite/form-post-blank-reload-expected.txt": [ + [ + {} + ] + ], + "cookies/samesite/iframe-expected.txt": [ + [ + {} + ] + ], + "cookies/samesite/iframe-reload-expected.txt": [ + [ + {} + ] + ], + "cookies/samesite/img-expected.txt": [ + [ + {} + ] + ], + "cookies/samesite/window-open-expected.txt": [ + [ + {} + ] + ], + "cookies/samesite/window-open-reload-expected.txt": [ + [ + {} + ] + ], + "cookies/secure/cookie-forcing-expected.txt": [ + [ + {} + ] + ], + "cookies/secure/create-cookie-http-expected.txt": [ + [ + {} + ] + ], "cookies/secure/set-from-http.https.sub.html.headers": [ [ {} @@ -164456,6 +164606,11 @@ {} ] ], + "web-animations/interfaces/Document/getAnimations-expected.txt": [ + [ + {} + ] + ], "web-animations/interfaces/KeyframeEffect/constructor-expected.txt": [ [ {} @@ -181786,6 +181941,114 @@ {} ] ], + "cookies/prefix/__host.document-cookie.non-secure.html": [ + [ + "/cookies/prefix/__host.document-cookie.non-secure.html", + {} + ] + ], + "cookies/prefix/__host.http.non-secure.html": [ + [ + "/cookies/prefix/__host.http.non-secure.html", + {} + ] + ], + "cookies/prefix/__secure.document-cookie.non-secure.html": [ + [ + "/cookies/prefix/__secure.document-cookie.non-secure.html", + {} + ] + ], + "cookies/prefix/__secure.http.non-secure.html": [ + [ + "/cookies/prefix/__secure.http.non-secure.html", + {} + ] + ], + "cookies/prefix/__secure.http.secure.html": [ + [ + "/cookies/prefix/__secure.http.secure.html", + {} + ] + ], + "cookies/prefix/document-cookie.non-secure.html": [ + [ + "/cookies/prefix/document-cookie.non-secure.html", + {} + ] + ], + "cookies/samesite/fetch.html": [ + [ + "/cookies/samesite/fetch.html", + {} + ] + ], + "cookies/samesite/form-get-blank-reload.html": [ + [ + "/cookies/samesite/form-get-blank-reload.html", + {} + ] + ], + "cookies/samesite/form-get-blank.html": [ + [ + "/cookies/samesite/form-get-blank.html", + {} + ] + ], + "cookies/samesite/form-post-blank-reload.html": [ + [ + "/cookies/samesite/form-post-blank-reload.html", + {} + ] + ], + "cookies/samesite/form-post-blank.html": [ + [ + "/cookies/samesite/form-post-blank.html", + {} + ] + ], + "cookies/samesite/iframe-reload.html": [ + [ + "/cookies/samesite/iframe-reload.html", + {} + ] + ], + "cookies/samesite/iframe.html": [ + [ + "/cookies/samesite/iframe.html", + {} + ] + ], + "cookies/samesite/img.html": [ + [ + "/cookies/samesite/img.html", + {} + ] + ], + "cookies/samesite/window-open-reload.html": [ + [ + "/cookies/samesite/window-open-reload.html", + {} + ] + ], + "cookies/samesite/window-open.html": [ + [ + "/cookies/samesite/window-open.html", + {} + ] + ], + "cookies/secure/cookie-forcing.html": [ + [ + "/cookies/secure/cookie-forcing.html", + {} + ] + ], + "cookies/secure/create-cookie-http.html": [ + [ + "/cookies/secure/create-cookie-http.html", + {} + ] + ], "cookies/secure/set-from-dom.https.sub.html": [ [ "/cookies/secure/set-from-dom.https.sub.html", @@ -250206,7 +250469,7 @@ "support" ], "./README.md": [ - "ab5642d1f91579c4a86fbc56a10de5dbe6623cf3", + "2ad80e88dfd9bd3ce7cf4d1b9e53b7d61c104881", "support" ], "./lint.whitelist": [ @@ -262349,6 +262612,70 @@ "a54ac9afd9c176da2c8844389feb3cb0150fcf5c", "testharness" ], + "cookies/prefix/__host.document-cookie.non-secure-expected.txt": [ + "8b49d4c16114f18a25ce9a7a8a0cf8a9df6cbc37", + "support" + ], + "cookies/prefix/__host.document-cookie.non-secure.html": [ + "a072be8d6f7759b238229a7da84f303a71972427", + "testharness" + ], + "cookies/prefix/__host.http.non-secure-expected.txt": [ + "2fd7bd684881edc2a531ff3878f22f9f86e74467", + "support" + ], + "cookies/prefix/__host.http.non-secure.html": [ + "9eaab5c903e5d43cdc5e370dd27de5a718185df9", + "testharness" + ], + "cookies/prefix/__secure.document-cookie.non-secure-expected.txt": [ + "8b49d4c16114f18a25ce9a7a8a0cf8a9df6cbc37", + "support" + ], + "cookies/prefix/__secure.document-cookie.non-secure.html": [ + "279ff6ce295ec02371c5cfc48b316cfc8536c375", + "testharness" + ], + "cookies/prefix/__secure.http.non-secure-expected.txt": [ + "2fd7bd684881edc2a531ff3878f22f9f86e74467", + "support" + ], + "cookies/prefix/__secure.http.non-secure.html": [ + "4e17d8f6a8bdf7f1cc9c2b4b37853a36a13fb19f", + "testharness" + ], + "cookies/prefix/__secure.http.secure-expected.txt": [ + "398e4a0746acf29f8ba426a9b36c3fca3688de42", + "support" + ], + "cookies/prefix/__secure.http.secure.html": [ + "5406914f2316c92381dc696f56d20880cd1c85c8", + "testharness" + ], + "cookies/prefix/document-cookie.non-secure-expected.txt": [ + "34effe9ed6dc641c6d44026916755537a6eb8c7c", + "support" + ], + "cookies/prefix/document-cookie.non-secure.html": [ + "24d3cd4ad985061202e51a2a78f0ad242c98f54a", + "testharness" + ], + "cookies/resources/cookie-helper.sub.js": [ + "a5cfe0b65ee4c71ea97731624974ab1b6077b60c", + "support" + ], + "cookies/resources/drop.py": [ + "aa45e485a184b8dd198961e44115d1d99055dc8e", + "support" + ], + "cookies/resources/dropSameSite.py": [ + "4307153c427b3e8f5f7648f2c8bb792e7993b87c", + "support" + ], + "cookies/resources/dropSecure.py": [ + "1a98ab7a248905451bca88cfd3aa0520bccb632a", + "support" + ], "cookies/resources/echo-cookie.html": [ "ac15291ad85804f61bf690525bad958bb2672ca0", "support" @@ -262357,14 +262684,142 @@ "c5b3d11bdfc3a4092d0ed53648d58e0e3bbd2d91", "support" ], + "cookies/resources/helpers.py": [ + "0556713af62d78b7bfcda814c798397346290e31", + "support" + ], + "cookies/resources/imgIfMatch.py": [ + "7a716e43648f8f9adcc4d04fdc10e278edd976fa", + "support" + ], + "cookies/resources/list.py": [ + "e979b357defcf76e9783d394943b8d31a64d7470", + "support" + ], + "cookies/resources/postToParent.py": [ + "01ee8dfd0c1c1261f46df1eb4198b8222a2e8507", + "support" + ], + "cookies/resources/redirectWithCORSHeaders.py": [ + "a49a81930eeb58c75a1a3eda7fdd813dbe151f55", + "support" + ], "cookies/resources/set-cookie.py": [ "6588680f5635aa742b8f0cb6956fe0a0521d6b09", "support" ], + "cookies/resources/set.py": [ + "a4140b21cd6e33dd862b9e0222b50726c85308f0", + "support" + ], + "cookies/resources/setSameSite.py": [ + "30bc88a6cea9468d3f09a41614d75798f62ed1e9", + "support" + ], + "cookies/resources/setSecure.py": [ + "bfa50db57417501b8594a22d1c9b957b35701842", + "support" + ], "cookies/resources/testharness-helpers.js": [ "f379feb76ff0d44c5ec32d4d5b3b0b443c85805f", "support" ], + "cookies/samesite/fetch-expected.txt": [ + "a32fd4eaa3120d52fb9c884a2b3470dacc48b084", + "support" + ], + "cookies/samesite/fetch.html": [ + "c0e779b35da6d159808e20e9bb33bdbf49710480", + "testharness" + ], + "cookies/samesite/form-get-blank-expected.txt": [ + "a32fd4eaa3120d52fb9c884a2b3470dacc48b084", + "support" + ], + "cookies/samesite/form-get-blank-reload-expected.txt": [ + "a32fd4eaa3120d52fb9c884a2b3470dacc48b084", + "support" + ], + "cookies/samesite/form-get-blank-reload.html": [ + "b99dcb698dcd9680dabf2d794cb64de35aded40c", + "testharness" + ], + "cookies/samesite/form-get-blank.html": [ + "28193985017094bb89ff73987f16a5b7493e21a4", + "testharness" + ], + "cookies/samesite/form-post-blank-expected.txt": [ + "a32fd4eaa3120d52fb9c884a2b3470dacc48b084", + "support" + ], + "cookies/samesite/form-post-blank-reload-expected.txt": [ + "a32fd4eaa3120d52fb9c884a2b3470dacc48b084", + "support" + ], + "cookies/samesite/form-post-blank-reload.html": [ + "c33495a3010b7a872592e0afb3c6aec1e072db30", + "testharness" + ], + "cookies/samesite/form-post-blank.html": [ + "040e6533a608448f6c184eb4aaea99594b2ff99c", + "testharness" + ], + "cookies/samesite/iframe-expected.txt": [ + "a32fd4eaa3120d52fb9c884a2b3470dacc48b084", + "support" + ], + "cookies/samesite/iframe-reload-expected.txt": [ + "a32fd4eaa3120d52fb9c884a2b3470dacc48b084", + "support" + ], + "cookies/samesite/iframe-reload.html": [ + "9004c0afa1c0938810fa6b127b5c74a668d252d8", + "testharness" + ], + "cookies/samesite/iframe.html": [ + "0b0de2fe93ae013f0339fc18ecc02b74139e7085", + "testharness" + ], + "cookies/samesite/img-expected.txt": [ + "a32fd4eaa3120d52fb9c884a2b3470dacc48b084", + "support" + ], + "cookies/samesite/img.html": [ + "0de8d54b2d3b19378de9b62273cd92e326f0eff4", + "testharness" + ], + "cookies/samesite/window-open-expected.txt": [ + "a32fd4eaa3120d52fb9c884a2b3470dacc48b084", + "support" + ], + "cookies/samesite/window-open-reload-expected.txt": [ + "a32fd4eaa3120d52fb9c884a2b3470dacc48b084", + "support" + ], + "cookies/samesite/window-open-reload.html": [ + "8effc29255860c066e7bb6e8355721fc14708674", + "testharness" + ], + "cookies/samesite/window-open.html": [ + "97bb86fc8d992f8d639c9cc0af8ec77d0f810843", + "testharness" + ], + "cookies/secure/cookie-forcing-expected.txt": [ + "47145d57050f1c9058a8c0954b497ece232b9a1d", + "support" + ], + "cookies/secure/cookie-forcing.html": [ + "2c556af03603bc1022780620336e9de42526d187", + "testharness" + ], + "cookies/secure/create-cookie-http-expected.txt": [ + "5fedc3c7e7bcaa5cccc55486d1aac3ddc7ccdafe", + "support" + ], + "cookies/secure/create-cookie-http.html": [ + "db6b86d508c4e3db703f190af579865b3a010fe9", + "testharness" + ], "cookies/secure/set-from-dom.https.sub.html": [ "6532cda9322290949bedc06cdc45ce80521068aa", "testharness" @@ -341854,7 +342309,7 @@ "support" ], "html/dom/elements/the-innertext-idl-attribute/getter-expected.txt": [ - "5e4ba8f6f21667ad950d8ef2f2ce04455ee8ca95", + "4a4bfed9f4bac0cfbb9582c3adb578c5bceefb70", "support" ], "html/dom/elements/the-innertext-idl-attribute/getter-tests.js": [ @@ -383805,8 +384260,12 @@ "d9fc177ebbc3fa0317125912e38a4bfd65f727c8", "testharness" ], + "web-animations/interfaces/Document/getAnimations-expected.txt": [ + "93fc114032d930aab86038c969ca7389faa49294", + "support" + ], "web-animations/interfaces/Document/getAnimations.html": [ - "41edbdf1f03889156068f38d87875387f129924f", + "6efcb382f3203dc51487b366c13d463d697ac100", "testharness" ], "web-animations/interfaces/Document/timeline.html": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/README.md b/third_party/WebKit/LayoutTests/external/wpt/README.md index 182e4e7..e43a05f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/README.md +++ b/third_party/WebKit/LayoutTests/external/wpt/README.md
@@ -44,10 +44,10 @@ ./wpt make-hosts-file | sudo tee -a /etc/hosts ``` -And on Windows (note this requires an Administrator privileged shell): +And on Windows (this must be run in a PowerShell session with Administrator privileges): ```bash -python wpt make-hosts-file >> %SystemRoot%\System32\drivers\etc\hosts +python wpt make-hosts-file | Out-File %SystemRoot%\System32\drivers\etc\hosts -Encoding ascii -Append ``` If you are behind a proxy, you also need to make sure the domains above are
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__host.document-cookie.non-secure-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__host.document-cookie.non-secure-expected.txt new file mode 100644 index 0000000..ba0c795 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__host.document-cookie.non-secure-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: set_prefixed_cookie_via_dom_test is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__host.document-cookie.non-secure.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__host.document-cookie.non-secure.html new file mode 100644 index 0000000..e1a272a2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__host.document-cookie.non-secure.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + ["", "domain="+document.location.hostname, "MaxAge=10", "HttpOnly"].forEach(extraParams => { + // Without 'secure' + set_prefixed_cookie_via_dom_test({ + prefix: "__Host-", + params: "Path=/;" + extraParams, + shouldExistInDOM: false, + shouldExistViaHTTP: false, + title: "__Host: Non-secure origin: 'Path=/;" + extraParams + "'" + }); + + // With 'secure' + set_prefixed_cookie_via_dom_test({ + prefix: "__Host-", + params: "Secure; Path=/;" + extraParams, + shouldExistInDOM: false, + shouldExistViaHTTP: false, + title: "__Host: Non-secure origin: 'Secure; Path=/;" + extraParams + "'" + }); + }); + + set_prefixed_cookie_via_dom_test({ + prefix: "__Host-", + params: "Secure; Path=/cookies/resources/list.py", + shouldExistInDOM: false, + shouldExistViaHTTP: false, + title: "__Host: Non-secure origin: 'Secure; Path=/cookies/resources/list.py'" + }); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__host.http.non-secure-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__host.http.non-secure-expected.txt new file mode 100644 index 0000000..4a03101 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__host.http.non-secure-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: set_prefixed_cookie_via_http_test is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__host.http.non-secure.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__host.http.non-secure.html new file mode 100644 index 0000000..3ce58735 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__host.http.non-secure.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + ["", "domain="+document.location.hostname, "MaxAge=10", "HttpOnly"].forEach(extraParams => { + // Without 'secure' + set_prefixed_cookie_via_http_test({ + prefix: "__Host-", + params: "Path=/;" + extraParams, + shouldExistInDOM: false, + shouldExistViaHTTP: false, + title: "__Host: Non-secure origin: 'Path=/;" + extraParams + "'" + }); + + // With 'secure' + set_prefixed_cookie_via_http_test({ + prefix: "__Host-", + params: "Secure; Path=/;" + extraParams, + shouldExistInDOM: false, + shouldExistViaHTTP: false, + title: "__Host: Non-secure origin: 'Secure; Path=/;" + extraParams + "'" + }); + }); + + set_prefixed_cookie_via_http_test({ + prefix: "__Host-", + params: "Secure; Path=/cookies/resources/list.py", + shouldExistInDOM: false, + shouldExistViaHTTP: false, + title: "__Host: Non-secure origin: 'Secure; Path=/cookies/resources/list.py'" + }); +</script> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.document-cookie.non-secure-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.document-cookie.non-secure-expected.txt new file mode 100644 index 0000000..ba0c795 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.document-cookie.non-secure-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: set_prefixed_cookie_via_dom_test is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.document-cookie.non-secure.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.document-cookie.non-secure.html new file mode 100644 index 0000000..bf898f4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.document-cookie.non-secure.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + ["", "domain="+document.location.hostname, "MaxAge=10", "HttpOnly"].forEach(extraParams => { + // Without 'secure' + set_prefixed_cookie_via_dom_test({ + prefix: "__Secure-", + params: "Path=/;" + extraParams, + shouldExistInDOM: false, + shouldExistViaHTTP: false, + title: "__Secure: Non-secure origin: 'Path=/;" + extraParams + "'" + }); + + // With 'secure' + set_prefixed_cookie_via_dom_test({ + prefix: "__Secure-", + params: "Secure; Path=/;" + extraParams, + shouldExistInDOM: false, + shouldExistViaHTTP: false, + title: "__Secure: Non-secure origin: 'Secure; Path=/;" + extraParams + "'" + }); + }); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.http.non-secure-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.http.non-secure-expected.txt new file mode 100644 index 0000000..4a03101 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.http.non-secure-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: set_prefixed_cookie_via_http_test is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.http.non-secure.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.http.non-secure.html new file mode 100644 index 0000000..af844a9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.http.non-secure.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + ["", "domain="+document.location.hostname, "MaxAge=10", "HttpOnly"].forEach(extraParams => { + // Without 'secure' + set_prefixed_cookie_via_http_test({ + prefix: "__Secure-", + params: "Path=/;" + extraParams, + shouldExistInDOM: false, + shouldExistViaHTTP: false, + title: "__Secure: Non-secure origin: 'Path=/;" + extraParams + "'" + }); + + // With 'secure' + set_prefixed_cookie_via_http_test({ + prefix: "__Secure-", + params: "Secure; Path=/;" + extraParams, + shouldExistInDOM: false, + shouldExistViaHTTP: false, + title: "__Secure: Non-secure origin: 'Secure; Path=/;" + extraParams + "'" + }); + }); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.http.secure-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.http.secure-expected.txt new file mode 100644 index 0000000..3c992678 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.http.secure-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: CROSS_SITE_HOST is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.http.secure.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.http.secure.html new file mode 100644 index 0000000..4b413e9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/__secure.http.secure.html
@@ -0,0 +1,27 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + ["", "domain="+CROSS_SITE_HOST, "MaxAge=10", "HttpOnly"].forEach(extraParams => { + // Without 'secure' + set_prefixed_cookie_via_http_test({ + origin: SECURE_CROSS_SITE_ORIGIN, + prefix: "__Secure-", + params: "Path=/;" + extraParams, + shouldExistInDOM: false, + shouldExistViaHTTP: false, + title: "__Secure: secure origin: 'Path=/;" + extraParams + "'" + }); + + // With 'secure' + set_prefixed_cookie_via_http_test({ + origin: SECURE_CROSS_SITE_ORIGIN, + prefix: "__Secure-", + params: "Secure;Path=/;" + extraParams, + shouldExistInDOM: false, + shouldExistViaHTTP: true, + title: "__Secure: secure origin: 'Secure;Path=/;" + extraParams + "'" + }); + }); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/document-cookie.non-secure-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/document-cookie.non-secure-expected.txt new file mode 100644 index 0000000..f7fc644 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/document-cookie.non-secure-expected.txt
@@ -0,0 +1,22 @@ +This is a testharness.js-based test. +FAIL No prefix, root path, no special behavior erase_cookie_from_js is not defined +FAIL No prefix, domain, no special behavior erase_cookie_from_js is not defined +FAIL __Secure: Non-secure origin: 'Path=/;' erase_cookie_from_js is not defined +FAIL __Secure: Non-secure origin: 'Secure; Path=/;' erase_cookie_from_js is not defined +FAIL __Secure: Non-secure origin: 'Path=/;domain=web-platform.test' erase_cookie_from_js is not defined +FAIL __Secure: Non-secure origin: 'Secure; Path=/;domain=web-platform.test' erase_cookie_from_js is not defined +FAIL __Secure: Non-secure origin: 'Path=/;MaxAge=10' erase_cookie_from_js is not defined +FAIL __Secure: Non-secure origin: 'Secure; Path=/;MaxAge=10' erase_cookie_from_js is not defined +FAIL __Secure: Non-secure origin: 'Path=/;HttpOnly' erase_cookie_from_js is not defined +FAIL __Secure: Non-secure origin: 'Secure; Path=/;HttpOnly' erase_cookie_from_js is not defined +FAIL __Host: Non-secure origin: 'Path=/; ' erase_cookie_from_js is not defined +FAIL __Host: Non-secure origin: 'Secure; Path=/; ' erase_cookie_from_js is not defined +FAIL __Host: Non-secure origin: 'Path=/; domain=web-platform.test' erase_cookie_from_js is not defined +FAIL __Host: Non-secure origin: 'Secure; Path=/; domain=web-platform.test' erase_cookie_from_js is not defined +FAIL __Host: Non-secure origin: 'Path=/; MaxAge=10' erase_cookie_from_js is not defined +FAIL __Host: Non-secure origin: 'Secure; Path=/; MaxAge=10' erase_cookie_from_js is not defined +FAIL __Host: Non-secure origin: 'Path=/; HttpOnly' erase_cookie_from_js is not defined +FAIL __Host: Non-secure origin: 'Secure; Path=/; HttpOnly' erase_cookie_from_js is not defined +FAIL __Host: Non-secure origin: 'Path=/cookies/resources/list.py;Secure' erase_cookie_from_js is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/document-cookie.non-secure.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/document-cookie.non-secure.html new file mode 100644 index 0000000..bc6832b15 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/prefix/document-cookie.non-secure.html
@@ -0,0 +1,37 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + function create_test(prefix, params, shouldExistInDOM, shouldExistViaHTTP, title) { + promise_test(t => { + var name = prefix + "prefixtestcookie"; + erase_cookie_from_js(name); + var value = "" + Math.random(); + document.cookie = name + "=" + value + ";" + params; + + assert_dom_cookie(name, value, shouldExistInDOM); + + return credFetch("/cookies/rfx6265bis/resources/list.py") + .then(r => r.json()) + .then(cookies => assert_equals(cookies[name], shouldExistViaHTTP ? value : undefined)); + }, title); + } + + // No prefix + create_test("", "path=/", true, true, "No prefix, root path, no special behavior"); + create_test("", "path=/;domain=" + document.location.hostname, true, true, "No prefix, domain, no special behavior"); + + // `__Secure-` Prefix + ["", "domain="+document.location.hostname, "MaxAge=10", "HttpOnly"].forEach(params => { + create_test("__Secure-", "Path=/;" + params, false, false, "__Secure: Non-secure origin: 'Path=/;" + params + "'"); + create_test("__Secure-", "Secure; Path=/;" + params, false, false, "__Secure: Non-secure origin: 'Secure; Path=/;" + params + "'"); + }); + + // `__Host-` Prefix + ["", "domain="+document.location.hostname, "MaxAge=10", "HttpOnly"].forEach(params => { + create_test("__Secure-", "Path=/;" + params, false, false, "__Host: Non-secure origin: 'Path=/; " + params + "'"); + create_test("__Secure-", "Secure; Path=/;" + params, false, false, "__Host: Non-secure origin: 'Secure; Path=/; " + params + "'"); + }); + create_test("__Secure-", "Path=/cookies/resources/list.py;Secure", false, false, "__Host: Non-secure origin: 'Path=/cookies/resources/list.py;Secure'"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/cookie-helper.sub.js b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/cookie-helper.sub.js new file mode 100644 index 0000000..852fbb6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/cookie-helper.sub.js
@@ -0,0 +1,206 @@ +// Set up exciting global variables for cookie tests. +(_ => { + var HOST = "{{host}}"; + var SECURE_PORT = ":{{ports[https][0]}}"; + var PORT = ":{{ports[http][0]}}"; + var CROSS_ORIGIN_HOST = "{{hosts[alt][]}}"; + var SECURE_CROSS_ORIGIN_HOST = "{{hosts[alt][]}}"; + + //For secure cookie verification + window.SECURE_ORIGIN = "https://" + HOST + SECURE_PORT; + window.INSECURE_ORIGIN = "http://" + HOST + PORT; + + //standard references + window.ORIGIN = "http://" + HOST + PORT; + window.WWW_ORIGIN = "http://{{domains[www]}}" + PORT; + window.SUBDOMAIN_ORIGIN = "http://{{domains[www1]}}" + PORT; + window.CROSS_SITE_ORIGIN = "http://" + CROSS_ORIGIN_HOST + PORT; + window.SECURE_CROSS_SITE_ORIGIN = "https://" + SECURE_CROSS_ORIGIN_HOST + SECURE_PORT; + window.CROSS_SITE_HOST = SECURE_CROSS_ORIGIN_HOST; + + // Set the global cookie name. + window.HTTP_COOKIE = "cookie_via_http"; + + // If we're not on |HOST|, move ourselves there: + if (window.location.hostname != HOST) + window.location.hostname = HOST; +})(); + +// A tiny helper which returns the result of fetching |url| with credentials. +function credFetch(url) { + return fetch(url, {"credentials": "include"}); +} + +// Returns a URL on |origin| which redirects to a given absolute URL. +function redirectTo(origin, url) { + return origin + "/cookies/resources/redirectWithCORSHeaders.py?status=307&location=" + encodeURIComponent(url); +} + +// Asserts that `document.cookie` contains or does not contain (according to +// the value of |present|) a cookie named |name| with a value of |value|. +function assert_dom_cookie(name, value, present) { + var re = new RegExp("(?:^|; )" + name + "=" + value + "(?:$|;)"); + assert_equals(re.test(document.cookie), present, "`" + name + "=" + value + "` in `document.cookie`"); +} + +function assert_cookie(origin, obj, name, value, present) { + assert_equals(obj[name], present ? value : undefined, "`" + name + "=" + value + "` in request to `" + origin + "`."); +} + +// Remove the cookie named |name| from |origin|, then set it on |origin| anew. +// If |origin| matches `document.origin`, also assert (via `document.cookie`) that +// the cookie was correctly removed and reset. +function create_cookie(origin, name, value, extras) { + alert("Create_cookie: " + origin + "/cookies/resources/drop.py?name=" + name); + return credFetch(origin + "/cookies/resources/drop.py?name=" + name) + .then(_ => { + if (origin == document.origin) + assert_dom_cookie(name, value, false); + }) + .then(_ => { + return credFetch(origin + "/cookies/resources/set.py?" + name + "=" + value + ";path=/;" + extras) + .then(_ => { + if (origin == document.origin) + assert_dom_cookie(name, value, true); + }); + }); +} + +// +// Prefix-specific test helpers +// +function set_prefixed_cookie_via_dom_test(options) { + promise_test(t => { + var name = options.prefix + "prefixtestcookie"; + erase_cookie_from_js(name); + var value = "" + Math.random(); + document.cookie = name + "=" + value + ";" + options.params; + + assert_dom_cookie(name, value, options.shouldExistInDOM); + + return credFetch("/cookies/resources/list.py") + .then(r => r.json()) + .then(cookies => assert_equals(cookies[name], options.shouldExistViaHTTP ? value : undefined)); + }, options.title); +} + +function set_prefixed_cookie_via_http_test(options) { + promise_test(t => { + var postDelete = _ => { + var value = "" + Math.random(); + return credFetch(options.origin + "/cookies/resources/set.py?" + name + "=" + value + ";" + options.params) + .then(_ => credFetch(options.origin + "/cookies/resources/list.py")) + .then(r => r.json()) + .then(cookies => assert_equals(cookies[name], options.shouldExistViaHTTP ? value : undefined)); + }; + + var name = options.prefix + "prefixtestcookie"; + if (!options.origin) { + options.origin = document.origin; + erase_cookie_from_js(name); + return postDelete; + } else { + return credFetch(options.origin + "/cookies/resources/drop.py?name=" + name) + .then(_ => postDelete()); + } + }, options.title); +} + +// +// SameSite-specific test helpers: +// + +window.SameSiteStatus = { + CROSS_SITE: "cross-site", + LAX: "lax", + STRICT: "strict" +}; + +// Reset SameSite test cookies on |origin|. If |origin| matches `document.origin`, assert +// (via `document.cookie`) that they were properly removed and reset. +function resetSameSiteCookies(origin, value) { + return credFetch(origin + "/cookies/resources/dropSameSite.py") + .then(_ => { + if (origin == document.origin) { + assert_dom_cookie("samesite_strict", value, false); + assert_dom_cookie("samesite_lax", value, false); + assert_dom_cookie("samesite_none", value, false); + } + }) + .then(_ => { + return credFetch(origin + "/cookies/resources/setSameSite.py?" + value) + .then(_ => { + if (origin == document.origin) { + assert_dom_cookie("samesite_strict", value, true); + assert_dom_cookie("samesite_lax", value, true); + assert_dom_cookie("samesite_none", value, true); + } + }) + }) +} + +// Given an |expectedStatus| and |expectedValue|, assert the |cookies| contains the +// proper set of cookie names and values. +function verifySameSiteCookieState(expectedStatus, expectedValue, cookies) { + assert_equals(cookies["samesite_none"], expectedValue, "Non-SameSite cookies are always sent."); + if (expectedStatus == SameSiteStatus.CROSS_SITE) { + assert_not_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are not sent with cross-site requests."); + assert_not_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are not sent with cross-site requests."); + } else if (expectedStatus == SameSiteStatus.LAX) { + assert_not_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are not sent with lax requests."); + assert_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are sent with lax requests."); + } else if (expectedStatus == SameSiteStatus.STRICT) { + assert_equals(cookies["samesite_strict"], expectedValue, "SameSite=Strict cookies are sent with strict requests."); + assert_equals(cookies["samesite_lax"], expectedValue, "SameSite=Lax cookies are sent with strict requests."); + } +} + +// +// LeaveSecureCookiesAlone-specific test helpers: +// + +window.SecureStatus = { + INSECURE_COOKIE_ONLY: "1", + BOTH_COOKIES: "2", +}; + +//Reset SameSite test cookies on |origin|. If |origin| matches `document.origin`, assert +//(via `document.cookie`) that they were properly removed and reset. +function resetSecureCookies(origin, value) { +return credFetch(origin + "/cookies/resources/dropSecure.py") + .then(_ => { + if (origin == document.origin) { + assert_dom_cookie("alone_secure", value, false); + assert_dom_cookie("alone_insecure", value, false); + } + }) + .then(_ => { + return credFetch(origin + "/cookie/resources/setSecure.py?" + value) + }) +} + +// +// DOM based cookie manipulation API's +// + +// borrowed from http://www.quirksmode.org/js/cookies.html +function create_cookie_from_js(name, value, days, secure_flag) { + if (days) { + var date = new Date(); + date.setTime(date.getTime()+(days*24*60*60*1000)); + var expires = "; expires="+date.toGMTString(); + } + else var expires = ""; + + var secure = ""; + if (secure_flag == true) { + secure = "secure; "; + } + document.cookie = name+"="+value+expires+"; "+secure+"path=/"; +} + +// erase cookie value and set for expiration +function erase_cookie_from_js(name) { + create_cookie_from_js(name,"",-1); + assert_dom_cookie(name, "", false); +}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/drop.py b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/drop.py new file mode 100644 index 0000000..7491dad --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/drop.py
@@ -0,0 +1,15 @@ +from helpers import makeDropCookie, readParameter, setNoCacheAndCORSHeaders + +def main(request, response): + """Respond to `/cookie/drop?name={name}` by expiring the cookie named `{name}`.""" + headers = setNoCacheAndCORSHeaders(request, response) + try: + # Expire the named cookie, and return a JSON-encoded success code. + name = readParameter(request, paramName="name", requireValue=True) + scheme = request.url_parts.scheme + headers.append(makeDropCookie(name, "https" == scheme)) + return headers, '{"success": true}' + except: + return 500, headers, '{"error" : "Empty or missing name parameter."}' + +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/dropSameSite.py b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/dropSameSite.py new file mode 100644 index 0000000..803dbeb --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/dropSameSite.py
@@ -0,0 +1,12 @@ +from helpers import makeDropCookie, readParameter, setNoCacheAndCORSHeaders + +def main(request, response): + """Respond to `/cookie/same-site/resources/dropSameSite.py by dropping the + three cookies set by setSameSiteCookies.py""" + headers = setNoCacheAndCORSHeaders(request, response) + + # Expire the cookies, and return a JSON-encoded success code. + headers.append(makeDropCookie("samesite_strict", False)) + headers.append(makeDropCookie("samesite_lax", False)) + headers.append(makeDropCookie("samesite_none", False)) + return headers, '{"success": true}'
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/dropSecure.py b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/dropSecure.py new file mode 100644 index 0000000..f95e9a9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/dropSecure.py
@@ -0,0 +1,11 @@ +from helpers import makeDropCookie, readParameter, setNoCacheAndCORSHeaders + +def main(request, response): + """Respond to `/cookie/drop/secure` by dropping the two cookie set by + `setSecureTestCookies()`""" + headers = setNoCacheAndCORSHeaders(request, response) + + # Expire the cookies, and return a JSON-encoded success code. + headers.append(makeDropCookie("alone_secure", False)) + headers.append(makeDropCookie("alone_insecure", False)) + return headers, '{"success": true}'
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/helpers.py b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/helpers.py new file mode 100644 index 0000000..145f2fe --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/helpers.py
@@ -0,0 +1,55 @@ +import urlparse + +def setNoCacheAndCORSHeaders(request, response): + """Set Cache-Control, CORS and Content-Type headers appropriate for the cookie tests.""" + headers = [("Content-Type", "application/json"), + ("Access-Control-Allow-Credentials", "true")] + + origin = "*" + if "origin" in request.headers: + origin = request.headers["origin"] + + headers.append(("Access-Control-Allow-Origin", origin)) + #headers.append(("Access-Control-Allow-Credentials", "true")) + headers.append(("Cache-Control", "no-cache")) + headers.append(("Expires", "Fri, 01 Jan 1990 00:00:00 GMT")) + + return headers + +def makeCookieHeader(name, value, otherAttrs): + """Make a Set-Cookie header for a cookie with the name, value and attributes provided.""" + def makeAV(a, v): + if None == v or "" == v: + return a + return "%s=%s" % (a, v) + + # ensure cookie name is always first + attrs = ["%s=%s" % (name, value)] + attrs.extend(makeAV(a, v) for (a,v) in otherAttrs.iteritems()) + return ("Set-Cookie", "; ".join(attrs)) + +def makeDropCookie(name, secure): + attrs = {"MaxAge": 0, "path": "/"} + if secure: + attrs["secure"] = "" + return makeCookieHeader(name, "", attrs) + +def readParameter(request, paramName, requireValue): + """Read a parameter from the request. Raise if requireValue is set and the + parameter has an empty value or is not present.""" + params = urlparse.parse_qs(request.url_parts.query) + param = params[paramName][0].strip() + if len(param) == 0: + raise Exception("Empty or missing name parameter.") + return param + +def readCookies(request): + """Read the cookies from the client present in the request.""" + cookies = {} + for key in request.cookies: + for cookie in request.cookies.get_list(key): + # do we care we'll clobber cookies here? If so, do we + # need to modify the test to take cookie names and value lists? + cookies[key] = cookie.value + return cookies +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/imgIfMatch.py b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/imgIfMatch.py new file mode 100644 index 0000000..08664415 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/imgIfMatch.py
@@ -0,0 +1,16 @@ +import helpers + +def main(request, response): + """Respond to `/cookie/imgIfMatch?name={name}&value={value}` with a 404 if + the cookie isn't present, and a transparent GIF otherwise.""" + headers = helpers.setNoCacheAndCORSHeaders(request, response) + name = helpers.readParameter(request, paramName="name", requireValue=True) + value = helpers.readParameter(request, paramName="value", requireValue=True) + cookiesWithMatchingNames = request.cookies.get_list(name) + for cookie in cookiesWithMatchingNames: + if cookie.value == value: + # From https://github.com/mathiasbynens/small/blob/master/gif-transparent.gif + headers.append(("Content-Type","image/gif")) + gif = "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\xFF\xFF\xFF\x00\x00\x00\x21\xF9\x04\x01\x00\x00\x00\x00\x2C\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02\x44\x01\x00\x3B" + return headers, gif + return 500, headers, '{"error": {"message": "The cookie\'s value did not match the given value."}}'
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/list.py b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/list.py new file mode 100644 index 0000000..3fe7dd6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/list.py
@@ -0,0 +1,7 @@ +import json +import helpers + +def main(request, response): + headers = helpers.setNoCacheAndCORSHeaders(request, response) + cookies = helpers.readCookies(request) + return headers, json.dumps(cookies)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/postToParent.py b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/postToParent.py new file mode 100644 index 0000000..68e85d3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/postToParent.py
@@ -0,0 +1,27 @@ +import json +import helpers + +def main(request, response): + headers = helpers.setNoCacheAndCORSHeaders(request, response) + cookies = helpers.readCookies(request) + headers.append(("Content-Type", "text/html; charset=utf-8")) + + tmpl = """ +<!DOCTYPE html> +<script> + var data = %s; + + if (window.parent != window) + window.parent.postMessage(data, "*"); + + if (window.opener) + window.opener.postMessage(data, "*"); + + window.addEventListener("message", e => { + console.log(e); + if (e.data == "reload") + window.location.reload(); + }); +</script> +""" + return headers, tmpl % json.dumps(cookies)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/redirectWithCORSHeaders.py b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/redirectWithCORSHeaders.py new file mode 100644 index 0000000..89ca1af --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/redirectWithCORSHeaders.py
@@ -0,0 +1,22 @@ +from helpers import setNoCacheAndCORSHeaders + +def main(request, response): + """Simple handler that causes redirection. + + The request should typically have two query parameters: + status - The status to use for the redirection. Defaults to 302. + location - The resource to redirect to. + """ + status = 302 + if "status" in request.GET: + try: + status = int(request.GET.first("status")) + except ValueError: + pass + headers = setNoCacheAndCORSHeaders(request, response) + + location = request.GET.first("location") + + headers.append(("Location", location)) + + return status, headers, ""
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/set.py b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/set.py new file mode 100644 index 0000000..abfb8c8d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/set.py
@@ -0,0 +1,7 @@ +import helpers + +def main(request, response): + """Respond to `/cookie/set?{cookie}` by echoing `{cookie}` as a `Set-Cookie` header.""" + headers = helpers.setNoCacheAndCORSHeaders(request, response) + headers.append(("Set-Cookie", request.url_parts.query)) + return headers, '{"success": true}'
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/setSameSite.py b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/setSameSite.py new file mode 100644 index 0000000..8ae1776 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/setSameSite.py
@@ -0,0 +1,14 @@ +from helpers import makeCookieHeader, readParameter, setNoCacheAndCORSHeaders + +def main(request, response): + """Respond to `/cookie/set/samesite?{value}` by setting three cookies: + 1. `samesite_strict={value};SameSite=Strict;path=/` + 2. `samesite_lax={value};SameSite=Lax;path=/` + 3. `samesite_none={value};path=/`""" + headers = setNoCacheAndCORSHeaders(request, response) + value = request.url_parts.query + + headers.append(makeCookieHeader("samesite_strict", value, {"SameSite":"Strict","path":"/"})) + headers.append(makeCookieHeader("samesite_lax", value, {"SameSite":"Lax","path":"/"})) + headers.append(makeCookieHeader("samesite_none", value, {"path":"/"})) + return headers, '{"success": true}'
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/setSecure.py b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/setSecure.py new file mode 100644 index 0000000..c8ec017 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/resources/setSecure.py
@@ -0,0 +1,12 @@ +from helpers import makeCookieHeader, readParameter, setNoCacheAndCORSHeaders + +def main(request, response): + """Respond to `/cookie/set/secure?{value}` by setting two cookies: + alone_secure={value};secure;path=/` + alone_insecure={value};path=/""" + headers = setNoCacheAndCORSHeaders(request, response) + value = request.url_parts.query + + headers.append(makeCookieHeader("alone_secure", value, {"secure": "","path": "/"})) + headers.append(makeCookieHeader("alone_insecure", value, {"path": "/"})) + return headers, '{"success": true}'
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/fetch-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/fetch-expected.txt new file mode 100644 index 0000000..88cc5d0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/fetch-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: ORIGIN is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/fetch.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/fetch.html new file mode 100644 index 0000000..734462a3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/fetch.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + function create_test(origin, target, expectedStatus, title) { + promise_test(t => { + var value = "" + Math.random(); + return resetSameSiteCookies(origin, value) + .then(_ => { + return credFetch(target + "/cookies/resources/list.py") + + .then(r => r.json()) + .then(cookies => verifySameSiteCookieState(expectedStatus, value, cookies)); + }); + }, title); + } + + // No redirect: + create_test(ORIGIN, ORIGIN, SameSiteStatus.STRICT, "Same-host fetches are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Subdomain fetches are strictly same-site"); + create_test(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, "Cross-site fetches are cross-site"); + + // Redirect from {same-host,subdomain,cross-site} to same-host: + create_test(ORIGIN, redirectTo(ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to same-host fetches are strictly same-site"); + create_test(ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to same-host fetches are strictly same-site"); + create_test(ORIGIN, redirectTo(CROSS_SITE_ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Cross-site redirecting to same-host fetches are strictly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to same-host: + create_test(SUBDOMAIN_ORIGIN, redirectTo(ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to subdomain fetches are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to subdomain fetches are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, redirectTo(CROSS_SITE_ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Cross-site redirecting to subdomain fetches are strictly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to cross-site: + create_test(CROSS_SITE_ORIGIN, redirectTo(ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Same-host redirecting to cross-site fetches are cross-site"); + create_test(CROSS_SITE_ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Subdomain redirecting to cross-site fetches are cross-site"); + create_test(CROSS_SITE_ORIGIN, redirectTo(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to cross-site fetches are cross-site"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-get-blank-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-get-blank-expected.txt new file mode 100644 index 0000000..88cc5d0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-get-blank-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: ORIGIN is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-get-blank-reload-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-get-blank-reload-expected.txt new file mode 100644 index 0000000..88cc5d0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-get-blank-reload-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: ORIGIN is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-get-blank-reload.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-get-blank-reload.html new file mode 100644 index 0000000..09f3ee9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-get-blank-reload.html
@@ -0,0 +1,57 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + function create_test(origin, target, expectedStatus, title) { + promise_test(t => { + var value = "" + Math.random(); + return resetSameSiteCookies(origin, value) + .then(_ => { + return new Promise((resolve, reject) => { + var f = document.createElement('form'); + f.action = target + "/cookies/resources/postToParent.py"; + f.target = "_blank"; + f.method = "GET"; + + // If |target| contains a `redir` parameter, extract it, and add it + // to the form so it doesn't get dropped in the submission. + var url = new URL(f.action); + if (url.pathname = "/cookies/rfc6265/resources/redirectWithCORSHeaders.py") { + var i = document.createElement("input"); + i.name = "location"; + i.value = url.searchParams.get("location"); + i.type = "hidden"; + f.appendChild(i); + } + var reloaded = false; + var msgHandler = e => { + try { + verifySameSiteCookieState(expectedStatus, value, e.data); + } catch (e) { + reject(e); + } + + if (reloaded) { + window.removeEventListener("message", msgHandler); + e.source.close(); + resolve("Popup received the cookie."); + } else { + reloaded = true; + e.source.postMessage("reload", "*"); + } + }; + window.addEventListener("message", msgHandler); + document.body.appendChild(f); + + f.submit(); + }); + }); + }, title); + } + + create_test(ORIGIN, ORIGIN, SameSiteStatus.STRICT, "Reloaded same-host top-level form GETs are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Reloaded subdomain top-level form GETs are strictly same-site"); + create_test(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN, SameSiteStatus.LAX, "Reloaded cross-site top-level form GETs are laxly same-site"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-get-blank.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-get-blank.html new file mode 100644 index 0000000..a86f34b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-get-blank.html
@@ -0,0 +1,66 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + function create_test(origin, target, expectedStatus, title) { + promise_test(t => { + var value = "" + Math.random(); + return resetSameSiteCookies(origin, value) + .then(_ => { + return new Promise((resolve, reject) => { + var f = document.createElement('form'); + f.action = target + "/cookies/resources/postToParent.py"; + f.target = "_blank"; + f.method = "GET"; + + // If |target| contains a `redir` parameter, extract it, and add it + // to the form so it doesn't get dropped in the submission. + var url = new URL(f.action); + if (url.pathname == "/cookies/resources/redirectWithCORSHeaders.py") { + var i = document.createElement("input"); + i.name = "location"; + i.type="hidden"; + i.value = url.searchParams.get("location"); + f.appendChild(i); + } + + var msgHandler = e => { + window.removeEventListener("message", msgHandler); + e.source.close(); + try { + verifySameSiteCookieState(expectedStatus, value, e.data); + resolve("Popup received the cookie."); + } catch (e) { + reject(e); + } + }; + window.addEventListener("message", msgHandler); + document.body.appendChild(f); + f.submit(); + }); + }); + }, title); + } + + // No redirect: + create_test(ORIGIN, ORIGIN, SameSiteStatus.STRICT, "Same-host top-level form GETs are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Subdomain top-level form GETs are strictly same-site"); + create_test(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN, SameSiteStatus.LAX, "Cross-site top-level form GETs are laxly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to same-host: + create_test(ORIGIN, redirectTo(ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to same-host top-level form GETs are strictly same-site"); + create_test(ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to same-host top-level form GETs are strictly same-site"); + create_test(ORIGIN, redirectTo(CROSS_SITE_ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Cross-site redirecting to same-host top-level form GETs are strictly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to same-host: + create_test(SUBDOMAIN_ORIGIN, redirectTo(ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to subdomain top-level form GETs are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to subdomain top-level form GETs are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, redirectTo(CROSS_SITE_ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Cross-site redirecting to subdomain top-level form GETs are strictly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to cross-site: + create_test(CROSS_SITE_ORIGIN, redirectTo(ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.LAX, "Same-host redirecting to cross-site top-level form GETs are laxly same-site"); + create_test(CROSS_SITE_ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.LAX, "Subdomain redirecting to cross-site top-level form GETs are laxly same-site"); + create_test(CROSS_SITE_ORIGIN, redirectTo(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.LAX, "Cross-site redirecting to cross-site top-level form GETs are laxly same-site"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-post-blank-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-post-blank-expected.txt new file mode 100644 index 0000000..88cc5d0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-post-blank-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: ORIGIN is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-post-blank-reload-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-post-blank-reload-expected.txt new file mode 100644 index 0000000..88cc5d0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-post-blank-reload-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: ORIGIN is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-post-blank-reload.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-post-blank-reload.html new file mode 100644 index 0000000..f9449bf --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-post-blank-reload.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + function create_test(origin, target, expectedStatus, title) { + promise_test(t => { + var value = "" + Math.random(); + return resetSameSiteCookies(origin, value) + .then(_ => { + return new Promise((resolve, reject) => { + var f = document.createElement('form'); + f.action = target + "/cookies/resources/postToParent.py"; + f.target = "_blank"; + f.method = "POST"; + + var reloaded = false; + var msgHandler = e => { + try { + verifySameSiteCookieState(expectedStatus, value, e.data); + } catch (e) { + reject(e); + } + + if (reloaded) { + window.removeEventListener("message", msgHandler); + e.source.close(); + resolve("Popup received the cookie."); + } else { + reloaded = true; + e.source.postMessage("reload", "*"); + } + }; + window.addEventListener("message", msgHandler); + + document.body.appendChild(f); + f.submit(); + }); + }); + }, title); + } + + create_test(ORIGIN, ORIGIN, SameSiteStatus.STRICT, "Reloaded same-host top-level form POSTs are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Reloaded subdomain top-level form POSTs are strictly same-site"); + create_test(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, "Reloaded cross-site top-level form POSTs are not same-site"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-post-blank.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-post-blank.html new file mode 100644 index 0000000..115c6a1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/form-post-blank.html
@@ -0,0 +1,55 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + function create_test(origin, target, expectedStatus, title) { + promise_test(t => { + var value = "" + Math.random(); + return resetSameSiteCookies(origin, value) + .then(_ => { + return new Promise((resolve, reject) => { + var f = document.createElement('form'); + f.action = target + "/cookies/resources/postToParent.py"; + f.target = "_blank"; + f.method = "POST"; + + var msgHandler = e => { + window.removeEventListener("message", msgHandler); + e.source.close(); + try { + verifySameSiteCookieState(expectedStatus, value, e.data); + resolve("Popup received the cookie."); + } catch (e) { + reject(e); + } + }; + window.addEventListener("message", msgHandler); + document.body.appendChild(f); + f.submit(); + }); + }); + }, title); + } + + // No redirect: + create_test(ORIGIN, ORIGIN, SameSiteStatus.STRICT, "Same-host top-level form POSTs are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Subdomain top-level form POSTs are strictly same-site"); + create_test(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, "Cross-site top-level form POSTs are cross-site"); + + // Redirect from {same-host,subdomain,cross-site} to same-host: + create_test(ORIGIN, redirectTo(ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to same-host top-level form POSTs are strictly same-site"); + create_test(ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to same-host top-level form POSTs are strictly same-site"); + create_test(ORIGIN, redirectTo(CROSS_SITE_ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Cross-site redirecting to same-host top-level form POSTs are strictly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to same-host: + create_test(SUBDOMAIN_ORIGIN, redirectTo(ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to subdomain top-level form POSTs are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to subdomain top-level form POSTs are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, redirectTo(CROSS_SITE_ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Cross-site redirecting to subdomain top-level form POSTs are strictly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to cross-site: + create_test(CROSS_SITE_ORIGIN, redirectTo(ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Same-host redirecting to cross-site top-level form POSTs are cross-site"); + create_test(CROSS_SITE_ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Subdomain redirecting to cross-site top-level form POSTs are cross-site"); + create_test(CROSS_SITE_ORIGIN, redirectTo(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to cross-site top-level form POSTs are cross-site"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/iframe-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/iframe-expected.txt new file mode 100644 index 0000000..88cc5d0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/iframe-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: ORIGIN is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/iframe-reload-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/iframe-reload-expected.txt new file mode 100644 index 0000000..88cc5d0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/iframe-reload-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: ORIGIN is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/iframe-reload.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/iframe-reload.html new file mode 100644 index 0000000..759fc7b0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/iframe-reload.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<!-- We're appending an <iframe> to the document's body, so execute tests after we have a body --> +<body> +<script> + function create_test(origin, target, expectedStatus, title) { + promise_test(t => { + var value = "" + Math.random(); + return resetSameSiteCookies(origin, value) + .then(_ => { + return new Promise((resolve, reject) => { + var iframe = document.createElement("iframe"); + iframe.onerror = _ => reject("IFrame could not be loaded."); + + var reloaded = false; + var msgHandler = e => { + try { + verifySameSiteCookieState(expectedStatus, value, e.data); + } catch (e) { + reject(e); + } + + if (reloaded) { + window.removeEventListener("message", msgHandler); + document.body.removeChild(iframe); + resolve("IFrame received the cookie."); + } else { + reloaded = true; + e.source.postMessage("reload", "*"); + } + }; + window.addEventListener("message", msgHandler); + + iframe.src = target + "/cookies/resources/postToParent.py"; + document.body.appendChild(iframe); + }); + }); + }, title); + } + + create_test(ORIGIN, ORIGIN, SameSiteStatus.STRICT, "Reloaded same-host fetches are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Reloaded subdomain fetches are strictly same-site"); + create_test(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, "Reloaded cross-site fetches are cross-site"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/iframe.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/iframe.html new file mode 100644 index 0000000..38a7701 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/iframe.html
@@ -0,0 +1,59 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<!-- We're appending an <iframe> to the document's body, so execute tests after we have a body --> +<body> +<script> + function create_test(origin, target, expectedStatus, title) { + promise_test(t => { + var value = "" + Math.random(); + return resetSameSiteCookies(origin, value) + .then(_ => { + return new Promise((resolve, reject) => { + var iframe = document.createElement("iframe"); + iframe.onerror = _ => reject("IFrame could not be loaded."); + + var msgHandler = e => { + if (e.source == iframe.contentWindow) { + // Cleanup, then verify cookie state: + document.body.removeChild(iframe); + window.removeEventListener("message", msgHandler); + try { + verifySameSiteCookieState(expectedStatus, value, e.data); + resolve(); + } catch(e) { + reject(e); + } + } + }; + window.addEventListener("message", msgHandler); + + iframe.src = target + "/cookies/resources/postToParent.py"; + document.body.appendChild(iframe); + }); + }); + }, title); + } + + // No redirect: + create_test(ORIGIN, ORIGIN, SameSiteStatus.STRICT, "Same-host fetches are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Subdomain fetches are strictly same-site"); + create_test(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, "Cross-site fetches are cross-site"); + + // Redirect from {same-host,subdomain,cross-site} to same-host: + create_test(ORIGIN, redirectTo(ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to same-host fetches are strictly same-site"); + create_test(ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to same-host fetches are strictly same-site"); + create_test(ORIGIN, redirectTo(CROSS_SITE_ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Cross-site redirecting to same-host fetches are strictly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to same-host: + create_test(SUBDOMAIN_ORIGIN, redirectTo(ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to subdomain fetches are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to subdomain fetches are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, redirectTo(CROSS_SITE_ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Cross-site redirecting to subdomain fetches are strictly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to cross-site: + create_test(CROSS_SITE_ORIGIN, redirectTo(ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Same-host redirecting to cross-site fetches are cross-site"); + create_test(CROSS_SITE_ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Subdomain redirecting to cross-site fetches are cross-site"); + create_test(CROSS_SITE_ORIGIN, redirectTo(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to cross-site fetches are cross-site"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/img-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/img-expected.txt new file mode 100644 index 0000000..88cc5d0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/img-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: ORIGIN is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/img.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/img.html new file mode 100644 index 0000000..b1b04340 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/img.html
@@ -0,0 +1,72 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + function assert_cookie_present(origin, name, value) { + return new Promise((resolve, reject) => { + var img = document.createElement("img"); + img.onload = _ => resolve("'" + name + "=" + value + "' present on " + origin); + img.onerror = _ => reject("'" + name + "=" + value + "' not present on " + origin); + + // We need to URL encode the destination path/query if we're redirecting: + if (origin.match(/\/redir/)) + img.src = origin + encodeURIComponent("/cookies/resources/imgIfMatch.py?name=" + name + "&value=" + value); + else + img.src = origin + "/cookies/resources/imgIfMatch.py?name=" + name + "&value=" + value; + }); + } + + function assert_cookie_absent(origin, name, value) { + return new Promise((resolve, reject) => { + var img = document.createElement("img"); + img.onload = _ => reject("'" + name + "=" + value + "' present on " + origin); + img.onerror = _ => resolve("'" + name + "=" + value + "' not present on " + origin); + + // We need to URL encode the destination path/query if we're redirecting: + if (origin.match(/\/redir/)) + img.src = origin + encodeURIComponent("/cookies/resources/imgIfMatch.py?name=" + name + "&value=" + value); + else + img.src = origin + "/cookies/resources/imgIfMatch.py?name=" + name + "&value=" + value; + }); + } + + function create_test(origin, target, expectedStatus, title) { + promise_test(t => { + var value = "" + Math.random(); + return resetSameSiteCookies(origin, value) + .then(_ => { + return Promise.all([ + assert_cookie_present(target, "samesite_none", value), + expectedStatus == SameSiteStatus.STRICT ? + assert_cookie_present(target, "samesite_strict", value) : + assert_cookie_absent(target, "samesite_strict", value), + expectedStatus == SameSiteStatus.CROSS_SITE ? + assert_cookie_absent(target, "samesite_lax", value) : + assert_cookie_present(target, "samesite_lax", value) + ]); + }); + }, title); + } + + // No redirect: + create_test(ORIGIN, ORIGIN, SameSiteStatus.STRICT, "Same-host images are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Subdomain images are strictly same-site"); + create_test(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN, SameSiteStatus.CROSS_SITE, "Cross-site images are cross-site"); + + // Redirect from {same-host,subdomain,cross-site} to same-host: + create_test(ORIGIN, redirectTo(ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to same-host images are strictly same-site"); + create_test(ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to same-host images are strictly same-site"); + create_test(ORIGIN, redirectTo(CROSS_SITE_ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Cross-site redirecting to same-host images are strictly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to same-host: + create_test(SUBDOMAIN_ORIGIN, redirectTo(ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to subdomain images are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to subdomain images are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, redirectTo(CROSS_SITE_ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Cross-site redirecting to subdomain images are strictly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to cross-site: + create_test(CROSS_SITE_ORIGIN, redirectTo(ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Same-host redirecting to cross-site images are cross-site"); + create_test(CROSS_SITE_ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Subdomain redirecting to cross-site images are cross-site"); + create_test(CROSS_SITE_ORIGIN, redirectTo(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.CROSS_SITE, "Cross-site redirecting to cross-site images are cross-site"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/window-open-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/window-open-expected.txt new file mode 100644 index 0000000..88cc5d0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/window-open-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: ORIGIN is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/window-open-reload-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/window-open-reload-expected.txt new file mode 100644 index 0000000..88cc5d0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/window-open-reload-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: ORIGIN is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/window-open-reload.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/window-open-reload.html new file mode 100644 index 0000000..b37cff8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/window-open-reload.html
@@ -0,0 +1,44 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + function create_test(origin, target, expectedStatus, title) { + promise_test(t => { + var value = "" + Math.random(); + return resetSameSiteCookies(origin, value) + .then(_ => { + return new Promise((resolve, reject) => { + var w = window.open(origin + "/cookies/resources/postToParent.py"); + + var reloaded = false; + var msgHandler = e => { + try { + verifySameSiteCookieState(expectedStatus, value, e.data); + } catch (e) { + reject(e); + } + + if (reloaded) { + window.removeEventListener("message", msgHandler); + w.close(); + resolve("Popup received the cookie."); + } else { + reloaded = true; + w.postMessage("reload", "*"); + } + }; + window.addEventListener("message", msgHandler); + + if (!w) + reject("Popup could not be opened (did you whitelist the test site in your popup blocker?)."); + }); + }); + }, title); + } + + create_test(ORIGIN, ORIGIN, SameSiteStatus.STRICT, "Reloaded same-host auxiliary navigations are strictly same-site."); + create_test(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Reloaded subdomain auxiliary navigations are strictly same-site."); + create_test(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN, SameSiteStatus.LAX, "Reloaded ross-site auxiliary navigations are laxly same-site"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/window-open.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/window-open.html new file mode 100644 index 0000000..1aa8e5e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/samesite/window-open.html
@@ -0,0 +1,53 @@ +<!DOCTYPE html> +<meta charset="utf-8"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + function create_test(origin, target, expectedStatus, title) { + promise_test(t => { + var value = "" + Math.random(); + return resetSameSiteCookies(origin, value) + .then(_ => { + return new Promise((resolve, reject) => { + var w = window.open(origin + "/cookies/resources/postToParent.py"); + + var msgHandler = e => { + window.removeEventListener("message", msgHandler); + w.close(); + try { + verifySameSiteCookieState(expectedStatus, value, e.data); + resolve("Popup received the cookie."); + } catch (e) { + reject(e); + } + }; + window.addEventListener("message", msgHandler); + + if (!w) + reject("Popup could not be opened (did you whitelist the test site in your popup blocker?)."); + }); + }); + }, title); + } + + // No redirect: + create_test(ORIGIN, ORIGIN, SameSiteStatus.STRICT, "Same-host auxiliary navigations are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN, SameSiteStatus.STRICT, "Subdomain auxiliary navigations are strictly same-site"); + create_test(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN, SameSiteStatus.LAX, "Cross-site auxiliary navigations are laxly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to same-host: + create_test(ORIGIN, redirectTo(ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to same-host auxiliary navigations are strictly same-site"); + create_test(ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to same-host auxiliary navigations are strictly same-site"); + create_test(ORIGIN, redirectTo(CROSS_SITE_ORIGIN, ORIGIN), SameSiteStatus.STRICT, "Cross-site redirecting to same-host auxiliary navigations are strictly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to same-host: + create_test(SUBDOMAIN_ORIGIN, redirectTo(ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Same-host redirecting to subdomain auxiliary navigations are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Subdomain redirecting to subdomain auxiliary navigations are strictly same-site"); + create_test(SUBDOMAIN_ORIGIN, redirectTo(CROSS_SITE_ORIGIN, SUBDOMAIN_ORIGIN), SameSiteStatus.STRICT, "Cross-site redirecting to subdomain auxiliary navigations are strictly same-site"); + + // Redirect from {same-host,subdomain,cross-site} to cross-site: + create_test(CROSS_SITE_ORIGIN, redirectTo(ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.LAX, "Same-host redirecting to cross-site auxiliary navigations are laxly same-site"); + create_test(CROSS_SITE_ORIGIN, redirectTo(SUBDOMAIN_ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.LAX, "Subdomain redirecting to cross-site auxiliary navigations are laxly same-site"); + create_test(CROSS_SITE_ORIGIN, redirectTo(CROSS_SITE_ORIGIN, CROSS_SITE_ORIGIN), SameSiteStatus.LAX, "Cross-site redirecting to cross-site auxiliary navigations are laxly same-site"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/secure/cookie-forcing-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/secure/cookie-forcing-expected.txt new file mode 100644 index 0000000..4b5d3f28 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/secure/cookie-forcing-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL non-secure origins should be able to force out insecure cookies. create_cookie_from_js is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/secure/cookie-forcing.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/secure/cookie-forcing.html new file mode 100644 index 0000000..3ea59e13 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/secure/cookie-forcing.html
@@ -0,0 +1,46 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + function cookie_force_test(secure_origin, secure_cookie, present, title) { + var counter = 0; + promise_test(t => { + + var testCookieValue = "" + Math.random(); + var markerCookieName = "marker"; + var markerCookieValue = "markerVal"; + + var brakes = 5000; //limit cookie setting limit in case browers are magic + + // Set an initial cookie as a marker + create_cookie_from_js(markerCookieName, markerCookieValue, 10, secure_cookie); + //TODO we cant trust document.cookie to set secure cookies. Need a round trip to a secure origin. + assert_dom_cookie(markerCookieName, markerCookieValue, true); + + // Set new cookies until marker is gone + try { + for (i = 0; i < brakes; i++) { + create_cookie_from_js(markerCookieName + counter++, markerCookieValue, 10, secure_cookie); + assert_dom_cookie(markerCookieName, markerCookieValue, true); + } + } catch(err) { + //shame on me, just fiddling for now + } + + assert_dom_cookie(markerCookieName, markerCookieValue, present); + + if (present == false) { + alert("It took " + counter + " cookies to force out the marker cookie"); + } else { + alert("Even after " + counter + " cookies the marker cookie was not forced out. Try incresing the current limit of " + brakes); + } + + }, title); + } + + + //actual tests to verify that non-secure origins should "leave secure cookies alone" + cookie_force_test(false, false, false, "non-secure origins should be able to force out insecure cookies."); + +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/secure/create-cookie-http-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/cookies/secure/create-cookie-http-expected.txt new file mode 100644 index 0000000..eccdfa58 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/secure/create-cookie-http-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Untitled Uncaught ReferenceError: INSECURE_ORIGIN is not defined +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/cookies/secure/create-cookie-http.html b/third_party/WebKit/LayoutTests/external/wpt/cookies/secure/create-cookie-http.html new file mode 100644 index 0000000..425f66f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/cookies/secure/create-cookie-http.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/cookies/resources/cookie-helper.sub.js"></script> +<script> + //origin is who sets the cookie + //target is who tries to send cookie + function create_test(origin, target, expectedStatus, title) { + promise_test(t => { + var value = "" + Math.random(); + return resetSecureCookies(origin, value) + .then(_ => { + return credFetch(target + "/cookies/resources/list.py") + .then(r => r.json()) + .then(cookies => verifySecureCookieState(expectedStatus, value, cookies)); + }); + }, title); + } + + //Given an |expectedStatus| and |expectedValue|, assert the |cookies| contains the + //proper set of cookie names and values. + function verifySecureCookieState(expectedStatus, expectedValue, cookies) { + assert_equals(cookies["alone_insecure"], expectedValue, "Insecure cookies are always present"); + if (expectedStatus == SecureStatus.INSECURE_COOKIE_ONLY) { + assert_equals(cookies["alone_secure"], undefined, "Secure cookies are not present"); + } else if (expectedStatus == SecureStatus.BOTH_COOKIES) { + assert_equals(cookies["alone_secure"], expectedValue, "Secure cookies are present"); + } + } + + //cookies set by insecure origins + create_test(INSECURE_ORIGIN, INSECURE_ORIGIN, SecureStatus.INSECURE_COOKIE_ONLY, "Secure cookies cannot be set by insecure origins"); + //create_test(INSECURE_ORIGIN, SECURE_ORIGIN, SecureStatus.INSECURE_COOKIE_ONLY, "Secure cookies cannot be set by insecure origins, even if read from a secure origin"); + + //This test should set the secure cookie right but not be able to read it from the secure origin + //create_test(SECURE_ORIGIN, INSECURE_ORIGIN, SecureStatus.INSECURE_COOKIE_ONLY, "Secure cookies should not be read by insecure origins"); + //create_test(SECURE_ORIGIN, SECURE_ORIGIN, SecureStatus.BOTH_COOKIES, "Secure cookies should be set and read by secure domains") +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/elements/the-innertext-idl-attribute/getter-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/dom/elements/the-innertext-idl-attribute/getter-expected.txt index 7055109..2bf5969 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/dom/elements/the-innertext-idl-attribute/getter-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/elements/the-innertext-idl-attribute/getter-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 213 tests; 132 PASS, 81 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 213 tests; 133 PASS, 80 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Simplest possible test ("<div>abc") PASS Leading whitespace removed ("<div> abc") PASS Trailing whitespace removed ("<div>abc ") @@ -50,7 +50,7 @@ PASS display:none child of svg ("<div style='display:none' id='target'>abc") PASS child of display:none child of svg ("<div style='display:none'><div id='target'>abc") PASS display:contents container ("<div style='display:contents'>abc") -FAIL display:contents container ("<div><div style='display:contents'>abc") assert_equals: expected "abc" but got "abc\n" +PASS display:contents container ("<div><div style='display:contents'>abc") PASS display:contents rendered ("<div>123<span style='display:contents'>abc") FAIL display:contents not processed via textContent ("<div style='display:contents'> ") assert_equals: expected "" but got " " PASS display:contents not processed via textContent ("<div><div style='display:contents'> ")
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getCapabilities.https.html b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getCapabilities.https.html index 257578f..d928370 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getCapabilities.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getCapabilities.https.html
@@ -15,6 +15,7 @@ assert_true(undefined !== audioCapabilities.autoGainControl, "MediaTrackCapabilities's autoGainControl should exist for an audio track."); assert_true(undefined !== audioCapabilities.noiseSuppression, "MediaTrackCapabilities's noiseSuppression should exist for an audio track."); assert_true(undefined !== videoCapabilities.deviceId, "MediaTrackCapabilities's deviceId should exist for a video track."); + assert_true(undefined !== videoCapabilities.groupId, "MediaTrackCapabilities's groupId should exist for a video track."); }); }); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Document/getAnimations-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Document/getAnimations-expected.txt new file mode 100644 index 0000000..92d85dc --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Document/getAnimations-expected.txt
@@ -0,0 +1,9 @@ +This is a testharness.js-based test. +PASS Test document.getAnimations for non-animated content +PASS Test document.getAnimations for script-generated animations +PASS Test the order of document.getAnimations with script generated animations +PASS Test document.getAnimations for a disconnected node +PASS Test document.getAnimations with null target +FAIL Test document.getAnimations for elements inside same-origin iframes assert_equals: expected 1 but got 0 +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Document/getAnimations.html b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Document/getAnimations.html index 381d954..6b8534b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Document/getAnimations.html +++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/interfaces/Document/getAnimations.html
@@ -64,5 +64,26 @@ 'elements in this document'); }, 'Test document.getAnimations with null target'); +async_test(t => { + const iframe = document.createElement('iframe'); + + iframe.addEventListener("load", t.step_func_done(function() { + const div = createDiv(t, iframe.contentDocument) + const effect = new KeyframeEffect(div, null, 100 * MS_PER_SEC); + const anim = new Animation(effect, document.timeline); + anim.play(); + + // The animation's timeline is from the main document, but the effect's + // target element is part of the iframe document and that is what matters + // for getAnimations. + assert_equals(document.getAnimations().length, 0); + assert_equals(iframe.contentDocument.getAnimations().length, 1); + anim.finish(); + })); + + document.body.appendChild(iframe); + t.add_cleanup(function() { document.body.removeChild(iframe); }); +}, 'Test document.getAnimations for elements inside same-origin iframes'); + </script> </body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/protocol/README.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/protocol/README.txt new file mode 100644 index 0000000..062db854 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/protocol/README.txt
@@ -0,0 +1,21 @@ +This directory contains files that test for behavior relevant to webrtc, +but which is specified in protocol specifications from the IETF, not in +API recommendations from the W3C. + +The main specifications are given in the following internet-drafts: + +- draft-ietf-rtcweb-overview +- draft-ietf-rtcweb-transports +- draft-ietf-rtcweb-security-arch +- draft-ietf-rtcweb-security +- draft-ietf-rtcweb-rtp-usage +- draft-ietf-rtcweb-jsep +- draft-ietf-rtcweb-ip-handling +- draft-ietf-rtcweb-fec +- draft-ietf-rtcweb-data-protocol +- draft-ietf-rtcweb-data-channel + +- RFC 7742, "WebRTC Video Processing and Codec Requirements" +- RFC 7874, "WebRTC Audio Codec and Processing Requirements" + +An overview of the dependencies involved is in draft-jennings-rtcweb-deps
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/protocol/video-codecs.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/protocol/video-codecs.html new file mode 100644 index 0000000..cc15ced --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/protocol/video-codecs.html
@@ -0,0 +1,63 @@ +<!doctype html> +<meta charset=utf-8> +<title>RTCPeerConnection.prototype.createOffer</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/webrtc/RTCPeerConnection-helper.js"></script> +<script> +'use strict'; + +// Tests for conformance to RFC 7742, +// "WebRTC Video Processing and Codec Requirements" +// The document was formerly known as draft-ietf-rtcweb-video-codecs. +// +// This tests that the browser is a WebRTC Browser as defined there. + +// TODO: Section 3.2: screen capture video MUST be prepared +// to handle resolution changes. + +// TODO: Section 4: MUST support generating CVO (orientation) + +// Section 5: Browsers MUST implement VP8 and H.264 Constrained Baseline +promise_test(async t => { + const pc = new RTCPeerConnection(); + const offer = await pc.createOffer({offerToReceiveVideo: true}); + let video_section_found = false; + for (let section of offer.sdp.split(/\r\nm=/)) { + if (section.search('video') != 0) { + continue; + } + video_section_found = true; + // RTPMAP lines have the format a=rtpmap:<pt> <codec>/<clock rate> + let rtpmap_regex = /\r\na=rtpmap:(\d+) (\S+)\/\d+\r\n/g; + let match = rtpmap_regex.exec(offer.sdp); + let payload_type_map = new Array(); + while (match) { + payload_type_map[match[1]] = match[2]; + match = rtpmap_regex.exec(offer.sdp); + } + assert_true(payload_type_map.indexOf('VP8') > -1, + 'VP8 is supported'); + assert_true(payload_type_map.indexOf('H264') > -1, + 'H.264 is supported'); + // TODO: Verify that one of the H.264 PTs supports constrained baseline + } + assert_true(video_section_found); +}, 'H.264 and VP8 should be supported in initial offer'); + +// TODO: Section 6: Recipients MUST be able to decode 320x240@20 fps +// TODO: Section 6.1: VP8 MUST support RFC 7741 payload formats +// TODO: Section 6.1: VP8 MUST respect max-fr/max-fs +// TODO: Section 6.1: VP8 MUST encode and decode square pixels +// TODO: Section 6.2: H.264 MUST support RFC 6184 payload formats +// TODO: Section 6.2: MUST support Constrained Baseline level 1.2 +// TODO: Section 6.2: SHOULD support Constrained High level 1.3 +// TODO: Section 6.2: MUST support packetization mode 1. +// TODO: Section 6.2: MUST include profile-level-id +// TODO: Section 6.2: SHOULD interpret max-mbps, max-smbps, max-fs et al +// TODO: Section 6.2: MUST NOT include sprop-parameter-sets +// TODO: Section 6.2: MUST support SEI "filler payload" +// TODO: Section 6.2: MUST support SEI "full frame freeze" +// TODO: Section 6.2: MUST be prepared to receive User Data messages +// TODO: Section 6.2: MUST encode and decode square pixels unless signaled +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html index 7ad96c5..78ccfb8 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html +++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html
@@ -18,6 +18,7 @@ var capabilities = stream.getVideoTracks()[0].getCapabilities(); assert_greater_than(Object.keys(capabilities).length, 0); assert_true(capabilities.hasOwnProperty('deviceId')); + assert_true(capabilities.hasOwnProperty('groupId')); assert_true(capabilities.hasOwnProperty('facingMode')); verifyVideoRangeProperties(capabilities); });
diff --git a/third_party/WebKit/LayoutTests/http/tests/misc/resource-timing-sizes-multipart.html b/third_party/WebKit/LayoutTests/http/tests/misc/resource-timing-sizes-multipart.html index d0606796..9edf5e6 100644 --- a/third_party/WebKit/LayoutTests/http/tests/misc/resource-timing-sizes-multipart.html +++ b/third_party/WebKit/LayoutTests/http/tests/misc/resource-timing-sizes-multipart.html
@@ -26,10 +26,8 @@ function checkTransferSize(entry) { // These comparisons are not strict because multipart responses are // non-standard. Any reasonable answer is acceptable. - // TODO(ricea): encodedBodySize and decodedBodySize don't pass. - // Fix the code or make this test even more relaxed. See crbug.com/631004. - // assert_greater_than(entry.encodedBodySize, abePngSize - 1, 'encodedBodySize'); - // assert_greater_than(entry.decodedBodySize, abePngSize - 1, 'decodedBodySize'); + assert_greater_than(entry.encodedBodySize, abePngSize - 1, 'encodedBodySize'); + assert_greater_than(entry.decodedBodySize, abePngSize - 1, 'decodedBodySize'); assert_greater_than(entry.transferSize, abePngSize + minHeaderSize, 'transferSize'); t.done(); }
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-block-crossorigin-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-block-crossorigin-expected.txt deleted file mode 100644 index 9881237..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-block-crossorigin-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -Downloading URL with suggested filename "foo.pdf" -Tests that a suggested filename on a download attribute is passed along even if the link is cross origin. - -The suggested filename at the top should be non-empty. The actual cross-origin check will be done in the browser process.
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-block-crossorigin.html b/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-block-crossorigin.html deleted file mode 100644 index 3366b33..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-block-crossorigin.html +++ /dev/null
@@ -1,38 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<script src="/js-test-resources/js-test.js"></script> -<script type='text/javascript'> -if (window.testRunner) { - // The test will end when loadURLExternally() is invoked. - testRunner.waitUntilExternalURLLoad(); -} -</script> -</head> -<body> -<p> -Tests that a suggested filename on a download attribute is passed along even if -<a id="dl" href="http://localhost:8080/security/resources/attachment.php" download="foo.pdf">the link</a> is cross origin. -<p> -The suggested filename at the top should be non-empty. The actual cross-origin -check will be done in the browser process. -<script> -function click(elmt) -{ - if (!window.eventSender) { - return; - } - eventSender.mouseMoveTo(elmt.offsetLeft + 5, elmt.offsetTop + 5); - eventSender.mouseDown(); - eventSender.mouseUp(); -} - -function runTest() -{ - var link = document.getElementById("dl"); - click(link); -} -runTest(); -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/pointerevents/extension/pointerevent_coalesced_events_attributes-manual-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/pointerevents/extension/pointerevent_coalesced_events_attributes-manual-expected.txt new file mode 100644 index 0000000..e84ebdb --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/pointerevents/extension/pointerevent_coalesced_events_attributes-manual-expected.txt
@@ -0,0 +1,16 @@ +This is a testharness.js-based test. +PASS touch coalesced events attributes in pointerevents +PASS PointerEvent Automation +PASS touch pointercancel should not have any coalesced events +PASS touch pointerover should not have any coalesced events +PASS touch pointerenter should not have any coalesced events +PASS touch pointerdown should not have any coalesced events +FAIL touch pointermove should have >2 coalesced events as main thread is busy. assert_greater_than: pointermove should have at least 2 coalesced events. expected a number greater than 1 but got 1 +PASS touch pointermove coalesced events should all be marked as trusted. +PASS touch time stamps of coalesced events must be ascending. +PASS touch pointermove coalesced events should all bubbles and cancelable as false. +PASS touch pointerup should not have any coalesced events +PASS touch pointerout should not have any coalesced events +PASS touch pointerleave should not have any coalesced events +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/virtual/incremental-shadow-dom/http/tests/devtools/elements/shadow/README.txt b/third_party/WebKit/LayoutTests/virtual/incremental-shadow-dom/http/tests/devtools/elements/shadow/README.txt index 06ee685f9..204f08b 100644 --- a/third_party/WebKit/LayoutTests/virtual/incremental-shadow-dom/http/tests/devtools/elements/shadow/README.txt +++ b/third_party/WebKit/LayoutTests/virtual/incremental-shadow-dom/http/tests/devtools/elements/shadow/README.txt
@@ -1,3 +1,4 @@ # This suite runs the tests in http/tests/devtools/elements/shadow with # --enable-blink-features=IncrementalShadowDOM. # See crbug.com/776656 for details. +# See crbug.com/840238 for http/tests/devtools/elements/shadow-distribution.js
diff --git a/third_party/WebKit/LayoutTests/virtual/incremental-shadow-dom/http/tests/devtools/elements/shadow/shadow-distribution-expected.txt b/third_party/WebKit/LayoutTests/virtual/incremental-shadow-dom/http/tests/devtools/elements/shadow/shadow-distribution-expected.txt new file mode 100644 index 0000000..0e10558 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/incremental-shadow-dom/http/tests/devtools/elements/shadow/shadow-distribution-expected.txt
@@ -0,0 +1,257 @@ +Tests that elements panel updates dom tree structure upon distribution in shadow dom. + + +Running: createHost1 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot1" name="slot1"> + </slot> + - <slot id="slot2" name="slot2"> + </slot> + - <slot id="slot3"> + </slot> + </div> + +Running: createChild1 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot1" name="slot1"> + </slot> + - <slot id="slot2" name="slot2"> + ↪ <span> + </slot> + - <slot id="slot3"> + </slot> + <span id="child1" slot="slot2"></span> + </div> + +Running: createChild2 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot1" name="slot1"> + </slot> + - <slot id="slot2" name="slot2"> + ↪ <span> + </slot> + - <slot id="slot3"> + ↪ <div> + </slot> + <span id="child1" slot="slot2"></span> + <div id="child2"></div> + </div> + +Running: createChild3 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot1" name="slot1"> + </slot> + - <slot id="slot2" name="slot2"> + ↪ <span> + ↪ <h1> + </slot> + - <slot id="slot3"> + ↪ <div> + </slot> + <span id="child1" slot="slot2"></span> + <div id="child2"></div> + <h1 id="child3" slot="slot2"></h1> + </div> + +Running: createChild4 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot1" name="slot1"> + ↪ <h2> + </slot> + - <slot id="slot2" name="slot2"> + ↪ <span> + ↪ <h1> + </slot> + - <slot id="slot3"> + ↪ <div> + </slot> + <span id="child1" slot="slot2"></span> + <div id="child2"></div> + <h1 id="child3" slot="slot2"></h1> + <h2 id="child4" slot="slot1"></h2> + </div> + +Running: createChild5 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot1" name="slot1"> + ↪ <h2> + </slot> + - <slot id="slot2" name="slot2"> + ↪ <span> + ↪ <h1> + </slot> + - <slot id="slot3"> + ↪ <div> + </slot> + <span id="child1" slot="slot2"></span> + <div id="child2"></div> + <h1 id="child3" slot="slot2"></h1> + <h2 id="child4" slot="slot1"></h2> + <h3 id="child5" slot="slot3"></h3> + </div> + +Running: modifyChild1 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot1" name="slot1"> + ↪ <h2> + </slot> + - <slot id="slot2" name="slot2"> + ↪ <span> + ↪ <h1> + </slot> + - <slot id="slot3"> + ↪ <div> + </slot> + <span id="child1" slot="slot1"></span> + <div id="child2"></div> + <h1 id="child3" slot="slot2"></h1> + <h2 id="child4" slot="slot1"></h2> + <h3 id="child5" slot="slot3"></h3> + </div> + +Running: modifyChild4 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot1" name="slot1"> + ↪ <h2> + </slot> + - <slot id="slot2" name="slot2"> + ↪ <span> + ↪ <h1> + </slot> + - <slot id="slot3"> + ↪ <div> + </slot> + <span id="child1" slot="slot1"></span> + <div id="child2"></div> + <h1 id="child3" slot="slot2"></h1> + <h2 id="child4"></h2> + <h3 id="child5" slot="slot3"></h3> + </div> + +Running: modifySlot1 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot1" name="slot3"> + ↪ <h2> + </slot> + - <slot id="slot2" name="slot2"> + ↪ <span> + ↪ <h1> + </slot> + - <slot id="slot3"> + ↪ <div> + </slot> + <span id="child1" slot="slot1"></span> + <div id="child2"></div> + <h1 id="child3" slot="slot2"></h1> + <h2 id="child4"></h2> + <h3 id="child5" slot="slot3"></h3> + </div> + +Running: modifySlot2 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot1" name="slot3"> + ↪ <h2> + </slot> + - <slot id="slot2" name="slot1"> + ↪ <span> + ↪ <h1> + </slot> + - <slot id="slot3"> + ↪ <div> + </slot> + <span id="child1" slot="slot1"></span> + <div id="child2"></div> + <h1 id="child3" slot="slot2"></h1> + <h2 id="child4"></h2> + <h3 id="child5" slot="slot3"></h3> + </div> + +Running: removeChild3 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot1" name="slot3"> + ↪ <h3> + </slot> + - <slot id="slot2" name="slot1"> + ↪ <span> + </slot> + - <slot id="slot3"> + ↪ <div> + ↪ <h2> + </slot> + <span id="child1" slot="slot1"></span> + <div id="child2"></div> + <h2 id="child4"></h2> + <h3 id="child5" slot="slot3"></h3> + </div> + +Running: removeChild1 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot1" name="slot3"> + ↪ <h3> + </slot> + - <slot id="slot2" name="slot1"> + </slot> + - <slot id="slot3"> + ↪ <div> + ↪ <h2> + </slot> + <div id="child2"></div> + <h2 id="child4"></h2> + <h3 id="child5" slot="slot3"></h3> + </div> + +Running: removeSlot1 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot2" name="slot1"> + </slot> + - <slot id="slot3"> + ↪ <div> + ↪ <h2> + </slot> + <div id="child2"></div> + <h2 id="child4"></h2> + <h3 id="child5" slot="slot3"></h3> + </div> + +Running: createHost2 +- <div id="host2"> + - #shadow-root (open) + - <slot id="slot1" name="slot3"> + </slot> + </div> + +Running: moveChild5FromHost1ToHost2 +- <div id="host2"> + - #shadow-root (open) + - <slot id="slot1" name="slot3"> + ↪ <h3> + </slot> + <h3 id="child5" slot="slot3"></h3> + </div> + +Running: modifyChild4 +- <div id="host1"> + - #shadow-root (open) + - <slot id="slot2" name="slot1"> + </slot> + - <slot id="slot3"> + ↪ <div> + ↪ <h2> + </slot> + <div id="child2"></div> + <h2 id="child4" slot="slot1"></h2> + </div> +
diff --git a/third_party/abseil-cpp/absl/base/dynamic_annotations.cc b/third_party/abseil-cpp/absl/base/dynamic_annotations.cc index 08c27e51..5be25338 100644 --- a/third_party/abseil-cpp/absl/base/dynamic_annotations.cc +++ b/third_party/abseil-cpp/absl/base/dynamic_annotations.cc
@@ -42,29 +42,29 @@ extern "C" { #endif -void AnnotateRWLockCreate(const char *, int, +void AbslAnnotateRWLockCreate(const char *, int, const volatile void *){} -void AnnotateRWLockDestroy(const char *, int, +void AbslAnnotateRWLockDestroy(const char *, int, const volatile void *){} -void AnnotateRWLockAcquired(const char *, int, +void AbslAnnotateRWLockAcquired(const char *, int, const volatile void *, long){} -void AnnotateRWLockReleased(const char *, int, +void AbslAnnotateRWLockReleased(const char *, int, const volatile void *, long){} -void AnnotateBenignRace(const char *, int, +void AbslAnnotateBenignRace(const char *, int, const volatile void *, const char *){} -void AnnotateBenignRaceSized(const char *, int, +void AbslAnnotateBenignRaceSized(const char *, int, const volatile void *, size_t, const char *) {} -void AnnotateThreadName(const char *, int, +void AbslAnnotateThreadName(const char *, int, const char *){} -void AnnotateIgnoreReadsBegin(const char *, int){} -void AnnotateIgnoreReadsEnd(const char *, int){} -void AnnotateIgnoreWritesBegin(const char *, int){} -void AnnotateIgnoreWritesEnd(const char *, int){} -void AnnotateEnableRaceDetection(const char *, int, int){} -void AnnotateMemoryIsInitialized(const char *, int, +void AbslAnnotateIgnoreReadsBegin(const char *, int){} +void AbslAnnotateIgnoreReadsEnd(const char *, int){} +void AbslAnnotateIgnoreWritesBegin(const char *, int){} +void AbslAnnotateIgnoreWritesEnd(const char *, int){} +void AbslAnnotateEnableRaceDetection(const char *, int, int){} +void AbslAnnotateMemoryIsInitialized(const char *, int, const volatile void *mem, size_t size) { #if __has_feature(memory_sanitizer) __msan_unpoison(mem, size); @@ -74,7 +74,7 @@ #endif } -void AnnotateMemoryIsUninitialized(const char *, int, +void AbslAnnotateMemoryIsUninitialized(const char *, int, const volatile void *mem, size_t size) { #if __has_feature(memory_sanitizer) __msan_allocated_memory(mem, size); @@ -84,7 +84,7 @@ #endif } -static int GetRunningOnValgrind(void) { +static int GetAbslRunningOnValgrind(void) { #ifdef RUNNING_ON_VALGRIND if (RUNNING_ON_VALGRIND) return 1; #endif @@ -96,24 +96,24 @@ } /* See the comments in dynamic_annotations.h */ -int RunningOnValgrind(void) { +int AbslRunningOnValgrind(void) { static volatile int running_on_valgrind = -1; int local_running_on_valgrind = running_on_valgrind; /* C doesn't have thread-safe initialization of statics, and we don't want to depend on pthread_once here, so hack it. */ ANNOTATE_BENIGN_RACE(&running_on_valgrind, "safe hack"); if (local_running_on_valgrind == -1) - running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind(); + running_on_valgrind = local_running_on_valgrind = GetAbslRunningOnValgrind(); return local_running_on_valgrind; } /* See the comments in dynamic_annotations.h */ -double ValgrindSlowdown(void) { - /* Same initialization hack as in RunningOnValgrind(). */ +double AbslValgrindSlowdown(void) { + /* Same initialization hack as in AbslRunningOnValgrind(). */ static volatile double slowdown = 0.0; double local_slowdown = slowdown; ANNOTATE_BENIGN_RACE(&slowdown, "safe hack"); - if (RunningOnValgrind() == 0) { + if (AbslRunningOnValgrind() == 0) { return 1.0; } if (local_slowdown == 0.0) {
diff --git a/third_party/abseil-cpp/absl/base/dynamic_annotations.h b/third_party/abseil-cpp/absl/base/dynamic_annotations.h index 3b6d6ef4..c7c36e2c 100644 --- a/third_party/abseil-cpp/absl/base/dynamic_annotations.h +++ b/third_party/abseil-cpp/absl/base/dynamic_annotations.h
@@ -81,26 +81,26 @@ point where "pointer" has been allocated, preferably close to the point where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC. */ #define ANNOTATE_BENIGN_RACE(pointer, description) \ - AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ + AbslAnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ sizeof(*(pointer)), description) /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to the memory range [address, address+size). */ #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ - AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) + AbslAnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) /* Enable (enable!=0) or disable (enable==0) race detection for all threads. This annotation could be useful if you want to skip expensive race analysis during some period of program execution, e.g. during initialization. */ #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ - AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) + AbslAnnotateEnableRaceDetection(__FILE__, __LINE__, enable) /* ------------------------------------------------------------- Annotations useful for debugging. */ /* Report the current thread name to a race detector. */ #define ANNOTATE_THREAD_NAME(name) \ - AnnotateThreadName(__FILE__, __LINE__, name) + AbslAnnotateThreadName(__FILE__, __LINE__, name) /* ------------------------------------------------------------- Annotations useful when implementing locks. They are not @@ -109,29 +109,29 @@ /* Report that a lock has been created at address "lock". */ #define ANNOTATE_RWLOCK_CREATE(lock) \ - AnnotateRWLockCreate(__FILE__, __LINE__, lock) + AbslAnnotateRWLockCreate(__FILE__, __LINE__, lock) /* Report that a linker initialized lock has been created at address "lock". */ #ifdef THREAD_SANITIZER #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ - AnnotateRWLockCreateStatic(__FILE__, __LINE__, lock) + AbslAnnotateRWLockCreateStatic(__FILE__, __LINE__, lock) #else #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) ANNOTATE_RWLOCK_CREATE(lock) #endif /* Report that the lock at address "lock" is about to be destroyed. */ #define ANNOTATE_RWLOCK_DESTROY(lock) \ - AnnotateRWLockDestroy(__FILE__, __LINE__, lock) + AbslAnnotateRWLockDestroy(__FILE__, __LINE__, lock) /* Report that the lock at address "lock" has been acquired. is_w=1 for writer lock, is_w=0 for reader lock. */ #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ - AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) + AbslAnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) /* Report that the lock at address "lock" is about to be released. */ #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ - AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) + AbslAnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ @@ -150,10 +150,10 @@ /* These annotations are also made available to LLVM's Memory Sanitizer */ #if DYNAMIC_ANNOTATIONS_ENABLED == 1 || defined(MEMORY_SANITIZER) #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ - AnnotateMemoryIsInitialized(__FILE__, __LINE__, address, size) + AbslAnnotateMemoryIsInitialized(__FILE__, __LINE__, address, size) #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ - AnnotateMemoryIsUninitialized(__FILE__, __LINE__, address, size) + AbslAnnotateMemoryIsUninitialized(__FILE__, __LINE__, address, size) #else #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) /* empty */ #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) /* empty */ @@ -190,19 +190,19 @@ other reads and all writes. See also ANNOTATE_UNPROTECTED_READ. */ #define ANNOTATE_IGNORE_READS_BEGIN() \ - AnnotateIgnoreReadsBegin(__FILE__, __LINE__) + AbslAnnotateIgnoreReadsBegin(__FILE__, __LINE__) /* Stop ignoring reads. */ #define ANNOTATE_IGNORE_READS_END() \ - AnnotateIgnoreReadsEnd(__FILE__, __LINE__) + AbslAnnotateIgnoreReadsEnd(__FILE__, __LINE__) /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead. */ #define ANNOTATE_IGNORE_WRITES_BEGIN() \ - AnnotateIgnoreWritesBegin(__FILE__, __LINE__) + AbslAnnotateIgnoreWritesBegin(__FILE__, __LINE__) /* Stop ignoring writes. */ #define ANNOTATE_IGNORE_WRITES_END() \ - AnnotateIgnoreWritesEnd(__FILE__, __LINE__) + AbslAnnotateIgnoreWritesEnd(__FILE__, __LINE__) /* Clang provides limited support for static thread-safety analysis through a feature called Annotalysis. We configure macro-definitions @@ -210,16 +210,16 @@ #elif defined(ANNOTALYSIS_ENABLED) #define ANNOTATE_IGNORE_READS_BEGIN() \ - StaticAnnotateIgnoreReadsBegin(__FILE__, __LINE__) + StaticAbslAnnotateIgnoreReadsBegin(__FILE__, __LINE__) #define ANNOTATE_IGNORE_READS_END() \ - StaticAnnotateIgnoreReadsEnd(__FILE__, __LINE__) + StaticAbslAnnotateIgnoreReadsEnd(__FILE__, __LINE__) #define ANNOTATE_IGNORE_WRITES_BEGIN() \ - StaticAnnotateIgnoreWritesBegin(__FILE__, __LINE__) + StaticAbslAnnotateIgnoreWritesBegin(__FILE__, __LINE__) #define ANNOTATE_IGNORE_WRITES_END() \ - StaticAnnotateIgnoreWritesEnd(__FILE__, __LINE__) + StaticAbslAnnotateIgnoreWritesEnd(__FILE__, __LINE__) #else #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */ @@ -256,41 +256,41 @@ #ifdef __cplusplus extern "C" { #endif -void AnnotateRWLockCreate(const char *file, int line, +void AbslAnnotateRWLockCreate(const char *file, int line, const volatile void *lock); -void AnnotateRWLockCreateStatic(const char *file, int line, +void AbslAnnotateRWLockCreateStatic(const char *file, int line, const volatile void *lock); -void AnnotateRWLockDestroy(const char *file, int line, +void AbslAnnotateRWLockDestroy(const char *file, int line, const volatile void *lock); -void AnnotateRWLockAcquired(const char *file, int line, +void AbslAnnotateRWLockAcquired(const char *file, int line, const volatile void *lock, long is_w); /* NOLINT */ -void AnnotateRWLockReleased(const char *file, int line, +void AbslAnnotateRWLockReleased(const char *file, int line, const volatile void *lock, long is_w); /* NOLINT */ -void AnnotateBenignRace(const char *file, int line, +void AbslAnnotateBenignRace(const char *file, int line, const volatile void *address, const char *description); -void AnnotateBenignRaceSized(const char *file, int line, +void AbslAnnotateBenignRaceSized(const char *file, int line, const volatile void *address, size_t size, const char *description); -void AnnotateThreadName(const char *file, int line, +void AbslAnnotateThreadName(const char *file, int line, const char *name); -void AnnotateEnableRaceDetection(const char *file, int line, int enable); -void AnnotateMemoryIsInitialized(const char *file, int line, +void AbslAnnotateEnableRaceDetection(const char *file, int line, int enable); +void AbslAnnotateMemoryIsInitialized(const char *file, int line, const volatile void *mem, size_t size); -void AnnotateMemoryIsUninitialized(const char *file, int line, +void AbslAnnotateMemoryIsUninitialized(const char *file, int line, const volatile void *mem, size_t size); /* Annotations expand to these functions, when Dynamic Annotations are enabled. These functions are either implemented as no-op calls, if no Sanitizer is attached, or provided with externally-linked implementations by a library like ThreadSanitizer. */ -void AnnotateIgnoreReadsBegin(const char *file, int line) +void AbslAnnotateIgnoreReadsBegin(const char *file, int line) ATTRIBUTE_IGNORE_READS_BEGIN; -void AnnotateIgnoreReadsEnd(const char *file, int line) +void AbslAnnotateIgnoreReadsEnd(const char *file, int line) ATTRIBUTE_IGNORE_READS_END; -void AnnotateIgnoreWritesBegin(const char *file, int line); -void AnnotateIgnoreWritesEnd(const char *file, int line); +void AbslAnnotateIgnoreWritesBegin(const char *file, int line); +void AbslAnnotateIgnoreWritesEnd(const char *file, int line); #if defined(ANNOTALYSIS_ENABLED) /* When Annotalysis is enabled without Dynamic Annotations, the use of @@ -301,13 +301,13 @@ allows IGNORE_READS_AND_WRITES to work properly. */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" -static inline void StaticAnnotateIgnoreReadsBegin(const char *file, int line) +static inline void StaticAbslAnnotateIgnoreReadsBegin(const char *file, int line) ATTRIBUTE_IGNORE_READS_BEGIN { (void)file; (void)line; } -static inline void StaticAnnotateIgnoreReadsEnd(const char *file, int line) +static inline void StaticAbslAnnotateIgnoreReadsEnd(const char *file, int line) ATTRIBUTE_IGNORE_READS_END { (void)file; (void)line; } -static inline void StaticAnnotateIgnoreWritesBegin( +static inline void StaticAbslAnnotateIgnoreWritesBegin( const char *file, int line) { (void)file; (void)line; } -static inline void StaticAnnotateIgnoreWritesEnd( +static inline void StaticAbslAnnotateIgnoreWritesEnd( const char *file, int line) { (void)file; (void)line; } #pragma GCC diagnostic pop #endif @@ -324,23 +324,23 @@ If for some reason you can't use "valgrind.h" or want to fake valgrind, there are two ways to make this function return non-zero: - Use environment variable: export RUNNING_ON_VALGRIND=1 - - Make your tool intercept the function RunningOnValgrind() and + - Make your tool intercept the function AbslRunningOnValgrind() and change its return value. */ -int RunningOnValgrind(void); +int AbslRunningOnValgrind(void); /* ValgrindSlowdown returns: - * 1.0, if (RunningOnValgrind() == 0) - * 50.0, if (RunningOnValgrind() != 0 && getenv("VALGRIND_SLOWDOWN") == NULL) + * 1.0, if (AbslRunningOnValgrind() == 0) + * 50.0, if (AbslRunningOnValgrind() != 0 && getenv("VALGRIND_SLOWDOWN") == NULL) * atof(getenv("VALGRIND_SLOWDOWN")) otherwise This function can be used to scale timeout values: EXAMPLE: for (;;) { DoExpensiveBackgroundTask(); - SleepForSeconds(5 * ValgrindSlowdown()); + SleepForSeconds(5 * AbslValgrindSlowdown()); } */ -double ValgrindSlowdown(void); +double AbslValgrindSlowdown(void); #ifdef __cplusplus }
diff --git a/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc b/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc index 44ec7c0..e8129e8 100644 --- a/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc +++ b/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc
@@ -79,7 +79,7 @@ // on stack, and so glibc works as if VDSO was not present. // But going directly to kernel via /proc/self/auxv below bypasses // Valgrind zapping. So we check for Valgrind separately. - if (RunningOnValgrind()) { + if (AbslRunningOnValgrind()) { vdso_base_.store(nullptr, std::memory_order_relaxed); getcpu_fn_.store(&GetCPUViaSyscall, std::memory_order_relaxed); return nullptr;
diff --git a/third_party/abseil-cpp/absl/strings/string_view_test.cc b/third_party/abseil-cpp/absl/strings/string_view_test.cc index bb149d5..41621024 100644 --- a/third_party/abseil-cpp/absl/strings/string_view_test.cc +++ b/third_party/abseil-cpp/absl/strings/string_view_test.cc
@@ -1052,7 +1052,7 @@ #ifndef THREAD_SANITIZER // Allocates too much memory for tsan. TEST(HugeStringView, TwoPointTwoGB) { - if (sizeof(size_t) <= 4 || RunningOnValgrind()) + if (sizeof(size_t) <= 4 || AbslRunningOnValgrind()) return; // Try a huge std::string piece. const size_t size = size_t{2200} * 1000 * 1000;
diff --git a/third_party/blink/public/platform/web_media_stream_source.h b/third_party/blink/public/platform/web_media_stream_source.h index 3f37effe..d5e1502 100644 --- a/third_party/blink/public/platform/web_media_stream_source.h +++ b/third_party/blink/public/platform/web_media_stream_source.h
@@ -88,6 +88,7 @@ WebMediaStreamTrack::FacingMode facing_mode = WebMediaStreamTrack::FacingMode::kNone; WebString device_id; + WebString group_id; }; WebMediaStreamSource() = default;
diff --git a/third_party/blink/public/platform/web_url_load_timing.h b/third_party/blink/public/platform/web_url_load_timing.h index a7dd594..389a8c6f 100644 --- a/third_party/blink/public/platform/web_url_load_timing.h +++ b/third_party/blink/public/platform/web_url_load_timing.h
@@ -31,6 +31,7 @@ #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_URL_LOAD_TIMING_H_ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_URL_LOAD_TIMING_H_ +#include "base/time/time.h" #include "third_party/blink/public/platform/web_common.h" #include "third_party/blink/public/platform/web_private_ptr.h" @@ -62,53 +63,53 @@ bool IsNull() const { return private_.IsNull(); } - BLINK_PLATFORM_EXPORT double RequestTime() const; - BLINK_PLATFORM_EXPORT void SetRequestTime(double); + BLINK_PLATFORM_EXPORT base::TimeTicks RequestTime() const; + BLINK_PLATFORM_EXPORT void SetRequestTime(base::TimeTicks); - BLINK_PLATFORM_EXPORT double ProxyStart() const; - BLINK_PLATFORM_EXPORT void SetProxyStart(double); + BLINK_PLATFORM_EXPORT base::TimeTicks ProxyStart() const; + BLINK_PLATFORM_EXPORT void SetProxyStart(base::TimeTicks); - BLINK_PLATFORM_EXPORT double ProxyEnd() const; - BLINK_PLATFORM_EXPORT void SetProxyEnd(double); + BLINK_PLATFORM_EXPORT base::TimeTicks ProxyEnd() const; + BLINK_PLATFORM_EXPORT void SetProxyEnd(base::TimeTicks); - BLINK_PLATFORM_EXPORT double DnsStart() const; - BLINK_PLATFORM_EXPORT void SetDNSStart(double); + BLINK_PLATFORM_EXPORT base::TimeTicks DnsStart() const; + BLINK_PLATFORM_EXPORT void SetDNSStart(base::TimeTicks); - BLINK_PLATFORM_EXPORT double DnsEnd() const; - BLINK_PLATFORM_EXPORT void SetDNSEnd(double); + BLINK_PLATFORM_EXPORT base::TimeTicks DnsEnd() const; + BLINK_PLATFORM_EXPORT void SetDNSEnd(base::TimeTicks); - BLINK_PLATFORM_EXPORT double ConnectStart() const; - BLINK_PLATFORM_EXPORT void SetConnectStart(double); + BLINK_PLATFORM_EXPORT base::TimeTicks ConnectStart() const; + BLINK_PLATFORM_EXPORT void SetConnectStart(base::TimeTicks); - BLINK_PLATFORM_EXPORT double ConnectEnd() const; - BLINK_PLATFORM_EXPORT void SetConnectEnd(double); + BLINK_PLATFORM_EXPORT base::TimeTicks ConnectEnd() const; + BLINK_PLATFORM_EXPORT void SetConnectEnd(base::TimeTicks); - BLINK_PLATFORM_EXPORT double WorkerStart() const; - BLINK_PLATFORM_EXPORT void SetWorkerStart(double); + BLINK_PLATFORM_EXPORT base::TimeTicks WorkerStart() const; + BLINK_PLATFORM_EXPORT void SetWorkerStart(base::TimeTicks); - BLINK_PLATFORM_EXPORT double WorkerReady() const; - BLINK_PLATFORM_EXPORT void SetWorkerReady(double); + BLINK_PLATFORM_EXPORT base::TimeTicks WorkerReady() const; + BLINK_PLATFORM_EXPORT void SetWorkerReady(base::TimeTicks); - BLINK_PLATFORM_EXPORT double SendStart() const; - BLINK_PLATFORM_EXPORT void SetSendStart(double); + BLINK_PLATFORM_EXPORT base::TimeTicks SendStart() const; + BLINK_PLATFORM_EXPORT void SetSendStart(base::TimeTicks); - BLINK_PLATFORM_EXPORT double SendEnd() const; - BLINK_PLATFORM_EXPORT void SetSendEnd(double); + BLINK_PLATFORM_EXPORT base::TimeTicks SendEnd() const; + BLINK_PLATFORM_EXPORT void SetSendEnd(base::TimeTicks); - BLINK_PLATFORM_EXPORT double ReceiveHeadersEnd() const; - BLINK_PLATFORM_EXPORT void SetReceiveHeadersEnd(double); + BLINK_PLATFORM_EXPORT base::TimeTicks ReceiveHeadersEnd() const; + BLINK_PLATFORM_EXPORT void SetReceiveHeadersEnd(base::TimeTicks); - BLINK_PLATFORM_EXPORT double SslStart() const; - BLINK_PLATFORM_EXPORT void SetSSLStart(double); + BLINK_PLATFORM_EXPORT base::TimeTicks SslStart() const; + BLINK_PLATFORM_EXPORT void SetSSLStart(base::TimeTicks); - BLINK_PLATFORM_EXPORT double SslEnd() const; - BLINK_PLATFORM_EXPORT void SetSSLEnd(double); + BLINK_PLATFORM_EXPORT base::TimeTicks SslEnd() const; + BLINK_PLATFORM_EXPORT void SetSSLEnd(base::TimeTicks); - BLINK_PLATFORM_EXPORT double PushStart() const; - BLINK_PLATFORM_EXPORT void SetPushStart(double); + BLINK_PLATFORM_EXPORT base::TimeTicks PushStart() const; + BLINK_PLATFORM_EXPORT void SetPushStart(base::TimeTicks); - BLINK_PLATFORM_EXPORT double PushEnd() const; - BLINK_PLATFORM_EXPORT void SetPushEnd(double); + BLINK_PLATFORM_EXPORT base::TimeTicks PushEnd() const; + BLINK_PLATFORM_EXPORT void SetPushEnd(base::TimeTicks); #if INSIDE_BLINK BLINK_PLATFORM_EXPORT WebURLLoadTiming(scoped_refptr<ResourceLoadTiming>);
diff --git a/third_party/blink/renderer/core/dom/idle_deadline_test.cc b/third_party/blink/renderer/core/dom/idle_deadline_test.cc index c5cd0f6a..4e46e7e 100644 --- a/third_party/blink/renderer/core/dom/idle_deadline_test.cc +++ b/third_party/blink/renderer/core/dom/idle_deadline_test.cc
@@ -23,7 +23,7 @@ base::SingleThreadTaskRunner* V8TaskRunner() override { return nullptr; } void Shutdown() override {} bool ShouldYieldForHighPriorityWork() override { return true; } - bool CanExceedIdleDeadlineIfRequired() override { return false; } + bool CanExceedIdleDeadlineIfRequired() const override { return false; } void PostIdleTask(const base::Location&, WebThread::IdleTask) override {} void PostNonNestableIdleTask(const base::Location&, WebThread::IdleTask) override {}
diff --git a/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc b/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc index 12bb5ec6..91cebebf 100644 --- a/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc +++ b/third_party/blink/renderer/core/dom/scripted_idle_task_controller_test.cc
@@ -30,7 +30,7 @@ base::SingleThreadTaskRunner* V8TaskRunner() override { return nullptr; } void Shutdown() override {} bool ShouldYieldForHighPriorityWork() override { return should_yield_; } - bool CanExceedIdleDeadlineIfRequired() override { return false; } + bool CanExceedIdleDeadlineIfRequired() const override { return false; } void PostIdleTask(const base::Location&, WebThread::IdleTask idle_task) override { idle_task_ = std::move(idle_task);
diff --git a/third_party/blink/renderer/core/editing/iterators/search_buffer_test.cc b/third_party/blink/renderer/core/editing/iterators/search_buffer_test.cc index 9e28b155..2a5d4864 100644 --- a/third_party/blink/renderer/core/editing/iterators/search_buffer_test.cc +++ b/third_party/blink/renderer/core/editing/iterators/search_buffer_test.cc
@@ -81,4 +81,25 @@ } } +TEST_F(SearchBufferTest, DisplayInline) { + SetBodyContent("<span>fi</span>nd"); + GetDocument().UpdateStyleAndLayout(); + auto match_range = FindPlainText(EphemeralRange(GetBodyRange()), "find", 0); + EXPECT_FALSE(match_range.IsCollapsed()); +} + +TEST_F(SearchBufferTest, DisplayBlock) { + SetBodyContent("<div>fi</div>nd"); + GetDocument().UpdateStyleAndLayout(); + auto match_range = FindPlainText(EphemeralRange(GetBodyRange()), "find", 0); + EXPECT_TRUE(match_range.IsCollapsed()); +} + +TEST_F(SearchBufferTest, DisplayContents) { + SetBodyContent("<div style='display: contents'>fi</div>nd"); + GetDocument().UpdateStyleAndLayout(); + auto match_range = FindPlainText(EphemeralRange(GetBodyRange()), "find", 0); + EXPECT_FALSE(match_range.IsCollapsed()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc b/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc index 79d4cb03..2590c93 100644 --- a/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc +++ b/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.cc
@@ -302,12 +302,11 @@ template <typename Strategy> bool SimplifiedBackwardsTextIteratorAlgorithm< Strategy>::HandleReplacedElement() { - unsigned index = Strategy::Index(*node_); // We want replaced elements to behave like punctuation for boundary // finding, and to simply take up space for the selection preservation // code in moveParagraphs, so we use a comma. Unconditionally emit // here because this iterator is only used for boundary finding. - EmitCharacter(',', Strategy::Parent(*node_), index, index + 1); + text_state_.EmitChar16AsNode(',', *node_); return true; } @@ -319,11 +318,10 @@ if (TextIterator::ShouldEmitNewlineForNode(*node_, false) || TextIterator::ShouldEmitNewlineAfterNode(*node_) || TextIterator::ShouldEmitTabBeforeNode(*node_)) { - unsigned index = Strategy::Index(*node_); - // The start of this emitted range is wrong. Ensuring correctness would - // require VisiblePositions and so would be slow. previousBoundary expects - // this. - EmitCharacter('\n', Strategy::Parent(*node_), index + 1, index + 1); + // TODO(editing-dev):The start of this emitted range is wrong. Ensuring + // correctness would require |VisiblePositions| and so would be slow. + // |previousBoundary expects this. + text_state_.EmitChar16AfterNode('\n', *node_); } return true; } @@ -333,23 +331,18 @@ if (TextIterator::ShouldEmitNewlineForNode(*node_, false) || TextIterator::ShouldEmitNewlineBeforeNode(*node_) || TextIterator::ShouldEmitTabBeforeNode(*node_)) { - // The start of this emitted range is wrong. Ensuring correctness would - // require VisiblePositions and so would be slow. previousBoundary expects - // this. - EmitCharacter('\n', node_, 0, 0); + // TODO(editing-dev): When we want to use |EmitChar16BeforeNode()| when + // test[1] and and test[2] failures are addressed. + // [1] readonly-disabled-text-selection.html + // [2] extend_selection_05_ltr_backward_word.html + // TODO(editing-dev): The start of this emitted range is wrong. Ensuring + // correctness would require |VisiblePositions| and so would be slow. + // previousBoundary expects this. + text_state_.EmitChar16BeforeChildren('\n', ToContainerNode(*node_)); } } template <typename Strategy> -void SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::EmitCharacter( - UChar c, - const Node* node, - int start_offset, - int end_offset) { - text_state_.SpliceBuffer(c, node, node, start_offset, end_offset); -} - -template <typename Strategy> bool SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::AdvanceRespectingRange( const Node* next) { if (!next) @@ -362,40 +355,54 @@ } template <typename Strategy> +void SimplifiedBackwardsTextIteratorAlgorithm< + Strategy>::EnsurePositionContainer() const { + DCHECK(text_state_.PositionNode()); + if (text_state_.PositionContainerNode()) + return; + const Node& node = *text_state_.PositionNode(); + const ContainerNode* parent = Strategy::Parent(node); + DCHECK(parent); + text_state_.UpdatePositionOffsets(*parent, Strategy::Index(node)); +} + +template <typename Strategy> const Node* SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::StartContainer() const { - if (text_state_.PositionNode()) - return text_state_.PositionNode(); - return start_node_; + if (!text_state_.PositionNode()) + return start_node_; + EnsurePositionContainer(); + return text_state_.PositionContainerNode(); +} + +template <typename Strategy> +int SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::StartOffset() const { + if (!text_state_.PositionNode()) + return start_offset_; + EnsurePositionContainer(); + return text_state_.PositionStartOffset(); } template <typename Strategy> int SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::EndOffset() const { - if (text_state_.PositionNode()) - return text_state_.PositionEndOffset(); - return start_offset_; + if (!text_state_.PositionNode()) + return start_offset_; + EnsurePositionContainer(); + return text_state_.PositionEndOffset(); } template <typename Strategy> PositionTemplate<Strategy> SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::StartPosition() const { - if (text_state_.PositionNode()) { - return PositionTemplate<Strategy>::EditingPositionOf( - text_state_.PositionNode(), text_state_.PositionStartOffset()); - } - return PositionTemplate<Strategy>::EditingPositionOf(start_node_.Get(), - start_offset_); + return PositionTemplate<Strategy>::EditingPositionOf(StartContainer(), + StartOffset()); } template <typename Strategy> PositionTemplate<Strategy> SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::EndPosition() const { - if (text_state_.PositionNode()) { - return PositionTemplate<Strategy>::EditingPositionOf( - text_state_.PositionNode(), text_state_.PositionEndOffset()); - } - return PositionTemplate<Strategy>::EditingPositionOf(start_node_.Get(), - start_offset_); + return PositionTemplate<Strategy>::EditingPositionOf(StartContainer(), + EndOffset()); } template <typename Strategy>
diff --git a/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h b/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h index 5eb6225f..ad1b8d6 100644 --- a/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h +++ b/third_party/blink/renderer/core/editing/iterators/simplified_backwards_text_iterator.h
@@ -73,6 +73,14 @@ int min_length) const; int CopyTextTo(BackwardsTextBuffer* output, int position = 0) const; + // TODO(editing-dev): We should consider code sharing between |TextIterator| + // and |SimplifiedBackwardsTextIterator| for + // - StartContainer() + // - EndOffset() + // - StartContainer() + // - EndPosition() + // TODO(editing-dev): We should rename |StartContainer()| to + // |CurrentContainer()| as |TextIterator|. const Node* StartContainer() const; int EndOffset() const; PositionTemplate<Strategy> StartPosition() const; @@ -88,11 +96,17 @@ LayoutText* HandleFirstLetter(int& start_offset, int& offset_in_node); bool HandleReplacedElement(); bool HandleNonTextNode(); - void EmitCharacter(UChar, const Node*, int start_offset, int end_offset); bool AdvanceRespectingRange(const Node*); bool IsBetweenSurrogatePair(int position) const; + // TODO(editing-dev): We should consider code sharing between |TextIterator| + // and |SimplifiedBackwardsTextIterator| for + // - EnsurePositionContainer() + // - StartOffset() + void EnsurePositionContainer() const; + int StartOffset() const; + TextIteratorBehavior behavior_; // Contains state of emitted text.
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc index de7d55a..5d28508 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator.cc +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator.cc
@@ -249,7 +249,7 @@ // iteration, instead of using m_needsAnotherNewline. Node* last_child = Strategy::LastChild(*node_); const Node* base_node = last_child ? last_child : node_.Get(); - SpliceBuffer('\n', Strategy::Parent(*base_node), base_node, 1, 1); + EmitChar16AfterNode('\n', *base_node); needs_another_newline_ = false; return true; } @@ -508,15 +508,13 @@ } if (EmitsObjectReplacementCharacter()) { - SpliceBuffer(kObjectReplacementCharacter, Strategy::Parent(*node_), node_, - 0, 1); + EmitChar16AsNode(kObjectReplacementCharacter, *node_); return; } DCHECK_EQ(last_text_node_, text_node_handler_.GetNode()); if (last_text_node_) { - if (text_node_handler_.FixLeadingWhiteSpaceForReplacedElement( - Strategy::Parent(*last_text_node_))) { + if (text_node_handler_.FixLeadingWhiteSpaceForReplacedElement()) { needs_handle_replaced_element_ = true; return; } @@ -531,17 +529,18 @@ // We want replaced elements to behave like punctuation for boundary // finding, and to simply take up space for the selection preservation // code in moveParagraphs, so we use a comma. - SpliceBuffer(',', Strategy::Parent(*node_), node_, 0, 1); + EmitChar16AsNode(',', *node_); return; } - text_state_.UpdateForReplacedElement(*Strategy::Parent(*node_), *node_); - if (EmitsImageAltText() && TextIterator::SupportsAltText(*node_)) { - text_state_.EmitAltText(node_); - if (text_state_.length()) - return; + text_state_.EmitAltText(ToHTMLElement(*node_)); + return; } + // TODO(editing-dev): We can remove |UpdateForReplacedElement()| call when + // we address layout test failures (text diff by newlines only) and unit + // tests, e.g. TextIteratorTest.IgnoreAltTextInTextControls. + text_state_.UpdateForReplacedElement(*node_); } template <typename Strategy> @@ -576,6 +575,8 @@ // a newline both before and after the element. LayoutObject* r = node.GetLayoutObject(); if (!r) { + if (HasDisplayContents(node)) + return false; return (node.HasTagName(blockquoteTag) || node.HasTagName(ddTag) || node.HasTagName(divTag) || node.HasTagName(dlTag) || node.HasTagName(dtTag) || node.HasTagName(h1Tag) || @@ -727,6 +728,8 @@ void TextIteratorAlgorithm<Strategy>::RepresentNodeOffsetZero() { // Emit a character to show the positioning of m_node. + // TODO(editing-dev): We should rewrite this below code fragment to utilize + // early-return style. // When we haven't been emitting any characters, // shouldRepresentNodeOffsetZero() can create VisiblePositions, which is // expensive. So, we perform the inexpensive checks on m_node to see if it @@ -734,23 +737,23 @@ // encountering shouldRepresentNodeOffsetZero()s worse case behavior. if (ShouldEmitTabBeforeNode(*node_)) { if (ShouldRepresentNodeOffsetZero()) - SpliceBuffer('\t', Strategy::Parent(*node_), node_, 0, 0); + EmitChar16BeforeNode('\t', *node_); } else if (ShouldEmitNewlineBeforeNode(*node_)) { if (ShouldRepresentNodeOffsetZero()) - SpliceBuffer('\n', Strategy::Parent(*node_), node_, 0, 0); + EmitChar16BeforeNode('\n', *node_); } else if (ShouldEmitSpaceBeforeAndAfterNode(*node_)) { if (ShouldRepresentNodeOffsetZero()) - SpliceBuffer(kSpaceCharacter, Strategy::Parent(*node_), node_, 0, 0); + EmitChar16BeforeNode(kSpaceCharacter, *node_); } } template <typename Strategy> void TextIteratorAlgorithm<Strategy>::HandleNonTextNode() { if (ShouldEmitNewlineForNode(*node_, EmitsOriginalText())) - SpliceBuffer('\n', Strategy::Parent(*node_), node_, 0, 1); + EmitChar16AsNode('\n', *node_); else if (EmitsCharactersBetweenAllVisiblePositions() && node_->GetLayoutObject() && node_->GetLayoutObject()->IsHR()) - SpliceBuffer(kSpaceCharacter, Strategy::Parent(*node_), node_, 0, 1); + EmitChar16AsNode(kSpaceCharacter, *node_); else RepresentNodeOffsetZero(); } @@ -784,32 +787,39 @@ // contain a VisiblePosition when doing selection preservation. if (text_state_.LastCharacter() != '\n') { // insert a newline with a position following this block's contents. - SpliceBuffer(kNewlineCharacter, Strategy::Parent(*base_node), base_node, - 1, 1); + EmitChar16AfterNode(kNewlineCharacter, *base_node); // remember whether to later add a newline for the current node DCHECK(!needs_another_newline_); needs_another_newline_ = add_newline; } else if (add_newline) { // insert a newline with a position following this block's contents. - SpliceBuffer(kNewlineCharacter, Strategy::Parent(*base_node), base_node, - 1, 1); + EmitChar16AfterNode(kNewlineCharacter, *base_node); } } // If nothing was emitted, see if we need to emit a space. if (!text_state_.PositionNode() && ShouldEmitSpaceBeforeAndAfterNode(*node_)) - SpliceBuffer(kSpaceCharacter, Strategy::Parent(*base_node), base_node, 1, - 1); + EmitChar16AfterNode(kSpaceCharacter, *base_node); } template <typename Strategy> -void TextIteratorAlgorithm<Strategy>::SpliceBuffer(UChar c, - const Node* text_node, - const Node* offset_base_node, - unsigned text_start_offset, - unsigned text_end_offset) { - text_state_.SpliceBuffer(c, text_node, offset_base_node, text_start_offset, - text_end_offset); +void TextIteratorAlgorithm<Strategy>::EmitChar16AfterNode(UChar code_unit, + const Node& node) { + text_state_.EmitChar16AfterNode(code_unit, node); + text_node_handler_.ResetCollapsedWhiteSpaceFixup(); +} + +template <typename Strategy> +void TextIteratorAlgorithm<Strategy>::EmitChar16AsNode(UChar code_unit, + const Node& node) { + text_state_.EmitChar16AsNode(code_unit, node); + text_node_handler_.ResetCollapsedWhiteSpaceFixup(); +} + +template <typename Strategy> +void TextIteratorAlgorithm<Strategy>::EmitChar16BeforeNode(UChar code_unit, + const Node& node) { + text_state_.EmitChar16BeforeNode(code_unit, node); text_node_handler_.ResetCollapsedWhiteSpaceFixup(); } @@ -842,30 +852,37 @@ template <typename Strategy> int TextIteratorAlgorithm<Strategy>::StartOffsetInCurrentContainer() const { - if (const Node* node = text_state_.PositionNode()) { - if (const Node* base_node = text_state_.PositionOffsetBaseNode()) - text_state_.UpdatePositionOffsets(Strategy::Index(*base_node)); - return text_state_.PositionStartOffset(); - } - return end_offset_; + if (!text_state_.PositionNode()) + return end_offset_; + EnsurePositionContainer(); + return text_state_.PositionStartOffset(); } template <typename Strategy> int TextIteratorAlgorithm<Strategy>::EndOffsetInCurrentContainer() const { - if (const Node* node = text_state_.PositionNode()) { - if (const Node* base_node = text_state_.PositionOffsetBaseNode()) - text_state_.UpdatePositionOffsets(Strategy::Index(*base_node)); - return text_state_.PositionEndOffset(); - } - return end_offset_; + if (!text_state_.PositionNode()) + return end_offset_; + EnsurePositionContainer(); + return text_state_.PositionEndOffset(); } template <typename Strategy> const Node* TextIteratorAlgorithm<Strategy>::CurrentContainer() const { - if (text_state_.PositionNode()) { - return text_state_.PositionNode(); - } - return end_container_; + if (!text_state_.PositionNode()) + return end_container_; + EnsurePositionContainer(); + return text_state_.PositionContainerNode(); +} + +template <typename Strategy> +void TextIteratorAlgorithm<Strategy>::EnsurePositionContainer() const { + DCHECK(text_state_.PositionNode()); + if (text_state_.PositionContainerNode()) + return; + const Node& node = *text_state_.PositionNode(); + const ContainerNode* parent = Strategy::Parent(node); + DCHECK(parent); + text_state_.UpdatePositionOffsets(*parent, Strategy::Index(node)); } template <typename Strategy>
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator.h b/third_party/blink/renderer/core/editing/iterators/text_iterator.h index 76031a378..6bf64aca 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator.h +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator.h
@@ -130,6 +130,10 @@ kHandledChildren }; + void EmitChar16AfterNode(UChar code_unit, const Node& node); + void EmitChar16AsNode(UChar code_unit, const Node& node); + void EmitChar16BeforeNode(UChar code_unit, const Node& node); + void ExitNode(); bool ShouldRepresentNodeOffsetZero(); bool ShouldEmitSpaceBeforeAndAfterNode(const Node&); @@ -141,11 +145,6 @@ void HandleTextNode(); void HandleReplacedElement(); void HandleNonTextNode(); - void SpliceBuffer(UChar, - const Node* text_node, - const Node* offset_base_node, - unsigned text_start_offset, - unsigned text_end_offset); // Used by selection preservation code. There should be one character emitted // between every VisiblePosition in the Range used to create the TextIterator. @@ -202,6 +201,9 @@ unsigned position, unsigned copy_length) const; + // Ensure container node of current text run for computing position. + void EnsurePositionContainer() const; + // The range. const Member<const Node> start_container_; const unsigned start_offset_;
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.cc index b743954..99118c4 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.cc +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.cc
@@ -181,7 +181,7 @@ HasVisibleTextNode(layout_object)) { if (!behavior_.CollapseTrailingSpace() || (offset_ > 0 && str[offset_ - 1] == ' ')) { - SpliceBuffer(kSpaceCharacter, text_node_, nullptr, offset_, offset_); + EmitChar16Before(kSpaceCharacter, offset_); needs_handle_pre_formatted_text_node_ = true; return; } @@ -377,8 +377,7 @@ --space_run_start; EmitText(layout_object, space_run_start, space_run_start + 1); } else { - SpliceBuffer(kSpaceCharacter, text_node_, nullptr, run_start, - run_start); + EmitChar16Before(kSpaceCharacter, run_start); } return; } @@ -416,10 +415,9 @@ // We need to preserve new lines in case of PreLine. // See bug crbug.com/317365. if (layout_object->Style()->WhiteSpace() == EWhiteSpace::kPreLine) { - SpliceBuffer('\n', text_node_, nullptr, run_start, run_start); + EmitChar16Before('\n', run_start); } else { - SpliceBuffer(kSpaceCharacter, text_node_, nullptr, run_start, - run_start + 1); + EmitReplacmentCodeUnit(kSpaceCharacter, run_start); } offset_ = text_start_offset + run_start + 1; } else { @@ -537,11 +535,10 @@ return offset_ > 0 && str[offset_ - 1] == ' '; } -bool TextIteratorTextNodeHandler::FixLeadingWhiteSpaceForReplacedElement( - const Node* parent) { +bool TextIteratorTextNodeHandler::FixLeadingWhiteSpaceForReplacedElement() { if (!ShouldFixLeadingWhiteSpaceForReplacedElement()) return false; - text_state_.SpliceBuffer(kSpaceCharacter, parent, text_node_, 1, 1); + text_state_.EmitChar16AfterNode(kSpaceCharacter, *text_node_); ResetCollapsedWhiteSpaceFixup(); return true; } @@ -552,13 +549,15 @@ last_text_node_ended_with_collapsed_space_ = false; } -void TextIteratorTextNodeHandler::SpliceBuffer(UChar c, - const Node* text_node, - const Node* offset_base_node, - unsigned text_start_offset, - unsigned text_end_offset) { - text_state_.SpliceBuffer(c, text_node, offset_base_node, text_start_offset, - text_end_offset); +void TextIteratorTextNodeHandler::EmitChar16Before(UChar code_unit, + unsigned offset) { + text_state_.EmitChar16Before(code_unit, *text_node_, offset); + ResetCollapsedWhiteSpaceFixup(); +} + +void TextIteratorTextNodeHandler::EmitReplacmentCodeUnit(UChar code_unit, + unsigned offset) { + text_state_.EmitReplacmentCodeUnit(code_unit, *text_node_, offset); ResetCollapsedWhiteSpaceFixup(); }
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h index 5dfe27d..d050895 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h
@@ -32,7 +32,7 @@ bool HandleRemainingTextRuns(); // Returns true if a leading white space is emitted before a replaced element. - bool FixLeadingWhiteSpaceForReplacedElement(const Node*); + bool FixLeadingWhiteSpaceForReplacedElement(); void ResetCollapsedWhiteSpaceFixup(); @@ -65,12 +65,12 @@ bool ShouldFixLeadingWhiteSpaceForReplacedElement() const; - // Emit a character before |offset| of characters in |text_node_|. - void SpliceBuffer(UChar, - const Node* text_node, - const Node* offset_base_node, - unsigned text_start_offset, - unsigned text_end_offset); + // Emits |code_unit| before |offset| of characters in |text_node_|. + void EmitChar16Before(UChar code_unit, unsigned offset); + // Emits |code_unit| as replacement of a code unit after |offset| in + // |text_node_|. + void EmitReplacmentCodeUnit(UChar code_unit, unsigned offset); + void EmitText(const LayoutText* layout_object, unsigned text_start_offset, unsigned text_end_offset);
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc index 101ade9..7d443a32 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.cc
@@ -49,6 +49,16 @@ const TextIteratorBehavior& behavior) : behavior_(behavior) {} +unsigned TextIteratorTextState::PositionStartOffset() const { + DCHECK(position_container_node_); + return position_start_offset_.value(); +} + +unsigned TextIteratorTextState::PositionEndOffset() const { + DCHECK(position_container_node_); + return position_end_offset_.value(); +} + UChar TextIteratorTextState::CharacterAt(unsigned index) const { SECURITY_DCHECK(index < length()); if (!(index < length())) @@ -93,59 +103,116 @@ } } -void TextIteratorTextState::UpdateForReplacedElement(const Node& parent_node, - const Node& base_node) { - has_emitted_ = true; - position_node_ = &parent_node; - position_offset_base_node_ = &base_node; +void TextIteratorTextState::UpdateForReplacedElement(const Node& node) { + ResetPositionContainerNode(PositionNodeType::kAsNode, node); + PopulateStringBuffer("", 0, 0); +} + +void TextIteratorTextState::ResetPositionContainerNode( + PositionNodeType node_type, + const Node& node) { + DCHECK_NE(node_type, PositionNodeType::kBeforeChildren); + DCHECK_NE(node_type, PositionNodeType::kInText); + DCHECK_NE(node_type, PositionNodeType::kNone); + position_node_type_ = node_type; + position_container_node_ = nullptr; + position_node_ = node; + position_start_offset_ = base::nullopt; + position_end_offset_ = base::nullopt; +} + +void TextIteratorTextState::UpdatePositionOffsets( + const ContainerNode& container_node, + unsigned node_index) const { + DCHECK(!position_container_node_); + DCHECK(!position_start_offset_.has_value()); + DCHECK(!position_end_offset_.has_value()); + switch (position_node_type_) { + case PositionNodeType::kAfterNode: + position_container_node_ = &container_node; + position_start_offset_ = node_index + 1; + position_end_offset_ = node_index + 1; + return; + case PositionNodeType::kAltText: + case PositionNodeType::kAsNode: + position_container_node_ = &container_node; + position_start_offset_ = node_index; + position_end_offset_ = node_index + 1; + return; + case PositionNodeType::kBeforeNode: + position_container_node_ = &container_node; + position_start_offset_ = node_index; + position_end_offset_ = node_index; + return; + case PositionNodeType::kBeforeChildren: + case PositionNodeType::kInText: + case PositionNodeType::kNone: + NOTREACHED(); + return; + } + NOTREACHED() << static_cast<int>(position_node_type_); +} + +void TextIteratorTextState::EmitAltText(const HTMLElement& element) { + ResetPositionContainerNode(PositionNodeType::kAltText, element); + const String text = element.AltText(); + PopulateStringBuffer(text, 0, text.length()); +} + +void TextIteratorTextState::EmitChar16AfterNode(UChar code_unit, + const Node& node) { + ResetPositionContainerNode(PositionNodeType::kAfterNode, node); + PopulateStringBufferFromChar16(code_unit); +} + +void TextIteratorTextState::EmitChar16AsNode(UChar code_unit, + const Node& node) { + ResetPositionContainerNode(PositionNodeType::kAsNode, node); + PopulateStringBufferFromChar16(code_unit); +} + +void TextIteratorTextState::EmitChar16BeforeChildren( + UChar code_unit, + const ContainerNode& container_node) { + position_node_type_ = PositionNodeType::kBeforeChildren; + position_container_node_ = &container_node; + position_node_ = &container_node; position_start_offset_ = 0; - position_end_offset_ = 1; - single_character_buffer_ = 0; - - text_length_ = 0; - text_start_offset_ = 0; - last_character_ = 0; + position_end_offset_ = 0; + PopulateStringBufferFromChar16(code_unit); } -void TextIteratorTextState::EmitAltText(const Node* node) { - text_ = ToHTMLElement(node)->AltText(); - text_start_offset_ = 0; - text_length_ = text_.length(); - last_character_ = text_length_ ? text_[text_length_ - 1] : 0; +void TextIteratorTextState::EmitChar16BeforeNode(UChar code_unit, + const Node& node) { + ResetPositionContainerNode(PositionNodeType::kBeforeNode, node); + PopulateStringBufferFromChar16(code_unit); } -void TextIteratorTextState::UpdatePositionOffsets(unsigned index) const { - DCHECK(position_offset_base_node_); - position_start_offset_ += index; - position_end_offset_ += index; - position_offset_base_node_ = nullptr; +void TextIteratorTextState::EmitChar16Before(UChar code_unit, + const Text& text_node, + unsigned offset) { + SetTextNodePosition(text_node, offset, offset); + PopulateStringBufferFromChar16(code_unit); } -void TextIteratorTextState::SpliceBuffer(UChar c, - const Node* text_node, - const Node* offset_base_node, - unsigned text_start_offset, - unsigned text_end_offset) { - DCHECK(text_node); +void TextIteratorTextState::EmitReplacmentCodeUnit(UChar code_unit, + const Text& text_node, + unsigned offset) { + SetTextNodePosition(text_node, offset, offset + 1); + PopulateStringBufferFromChar16(code_unit); +} + +void TextIteratorTextState::PopulateStringBufferFromChar16(UChar code_unit) { has_emitted_ = true; - - // Remember information with which to construct the TextIterator::range(). - // NOTE: textNode is often not a text node, so the range will specify child - // nodes of positionNode - position_node_ = text_node; - position_offset_base_node_ = offset_base_node; - position_start_offset_ = text_start_offset; - position_end_offset_ = text_end_offset; - // remember information with which to construct the TextIterator::characters() // and length() - single_character_buffer_ = c; + single_character_buffer_ = code_unit; DCHECK(single_character_buffer_); text_length_ = 1; text_start_offset_ = 0; // remember some iteration state - last_character_ = c; + last_character_ = code_unit; } void TextIteratorTextState::EmitText(const Text& text_node, @@ -155,31 +222,48 @@ unsigned text_start_offset, unsigned text_end_offset) { DCHECK_LE(position_start_offset, position_end_offset); - // TODO(editing-dev): text-transform:uppercase can make text longer, e.g. - // "U+00DF" to "SS". See "fast/css/case-transform.html" - // DCHECK_LE(position_end_offset, text_node.length()); - text_ = + const String text = behavior_.EmitsSmallXForTextSecurity() && IsTextSecurityNode(text_node) ? RepeatString("x", string.length()) - : string, + : string; - DCHECK(!text_.IsEmpty()); - DCHECK_LT(text_start_offset, text_.length()); - DCHECK_LE(text_end_offset, text_.length()); + DCHECK(!text.IsEmpty()); + DCHECK_LT(text_start_offset, text.length()); + DCHECK_LE(text_end_offset, text.length()); DCHECK_LE(text_start_offset, text_end_offset); - position_node_ = &text_node; - position_offset_base_node_ = nullptr; - position_start_offset_ = position_start_offset; - position_end_offset_ = position_end_offset; + SetTextNodePosition(text_node, position_start_offset, position_end_offset); + PopulateStringBuffer(text, text_start_offset, text_end_offset); +} + +void TextIteratorTextState::PopulateStringBuffer(const String& text, + unsigned text_start_offset, + unsigned text_end_offset) { + DCHECK_LE(text_start_offset, text_end_offset); + DCHECK_LE(text_end_offset, text.length()); + text_ = text; single_character_buffer_ = 0; text_start_offset_ = text_start_offset; text_length_ = text_end_offset - text_start_offset; - last_character_ = text_[text_end_offset - 1]; + last_character_ = text_end_offset == 0 ? 0 : text_[text_end_offset - 1]; has_emitted_ = true; } +void TextIteratorTextState::SetTextNodePosition(const Text& text_node, + unsigned position_start_offset, + unsigned position_end_offset) { + DCHECK_LE(position_start_offset, position_end_offset); + // TODO(editing-dev): text-transform:uppercase can make text longer, e.g. + // "U+00DF" to "SS". See "fast/css/case-transform.html" + // DCHECK_LE(position_end_offset, text_node.length()); + position_node_type_ = PositionNodeType::kInText; + position_container_node_ = &text_node; + position_node_ = &text_node; + position_start_offset_ = position_start_offset; + position_end_offset_ = position_end_offset; +} + void TextIteratorTextState::AppendTextTo(ForwardsTextBuffer* output, unsigned position, unsigned length_to_append) const {
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h index 0758992..8f1f040 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h
@@ -26,6 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_TEXT_ITERATOR_TEXT_STATE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_TEXT_ITERATOR_TEXT_STATE_H_ +#include "base/optional.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/editing/iterators/forwards_text_buffer.h" #include "third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h" @@ -35,6 +36,8 @@ namespace blink { class BackwardsTextBuffer; +class ContainerNode; +class HTMLElement; class Text; class CORE_EXPORT TextIteratorTextState { @@ -57,28 +60,37 @@ unsigned position, unsigned length_to_prepend) const; - void SpliceBuffer(UChar, - const Node* text_node, - const Node* offset_base_node, - unsigned text_start_offset, - unsigned text_end_offset); + // Emits code unit relative to |node|. + void EmitChar16AfterNode(UChar code_unit, const Node& node); + void EmitChar16AsNode(UChar code_unit, const Node& node); + void EmitChar16BeforeChildren(UChar code_unit, + const ContainerNode& container_node); + void EmitChar16BeforeNode(UChar code_unit, const Node& node); + + // Emits |code_unit| before |offset| in |text_node|. + void EmitChar16Before(UChar code_unit, + const Text& text_node, + unsigned offset); + // Emits |code_unit| as replacement of code unit at |offset| in |text_node|. + void EmitReplacmentCodeUnit(UChar code_unit, + const Text& text_node, + unsigned offset); void EmitText(const Text&, unsigned position_start_offset, unsigned position_end_offset, const String&, unsigned text_start_offset, unsigned text_end_offset); - void EmitAltText(const Node*); - void UpdateForReplacedElement(const Node& parent_node, const Node& base_node); + void EmitAltText(const HTMLElement&); + void UpdateForReplacedElement(const Node& node); // Return position of the current text. - void UpdatePositionOffsets(unsigned node_index) const; - unsigned PositionStartOffset() const { return position_start_offset_; } - unsigned PositionEndOffset() const { return position_end_offset_; } + void UpdatePositionOffsets(const ContainerNode& container_node, + unsigned index) const; + unsigned PositionStartOffset() const; + unsigned PositionEndOffset() const; const Node* PositionNode() const { return position_node_; } - const Node* PositionOffsetBaseNode() const { - return position_offset_base_node_; - } + const Node* PositionContainerNode() const { return position_container_node_; } bool HasEmitted() const { return has_emitted_; } UChar LastCharacter() const { return last_character_; } @@ -88,9 +100,29 @@ } private: + // Location of text run relative to |position_node_|. + enum class PositionNodeType { + kNone, + kAfterNode, + kAltText, + kAsNode, + kBeforeChildren, + kBeforeNode, + kInText, + }; + + void ResetPositionContainerNode(PositionNodeType node_type, const Node& node); + void SetTextNodePosition(const Text& text_node, + unsigned start_offset, + unsigned end_offset); + void PopulateStringBuffer(const String& text, unsigned start, unsigned end); + void PopulateStringBufferFromChar16(UChar code_unit); + const TextIteratorBehavior behavior_; unsigned text_length_ = 0; + // TODO(editing-dev): We should integrate single character buffer and + // string buffer. // Used for whitespace characters that aren't in the DOM, so we can point at // them. // If non-zero, overrides |text_|. @@ -99,13 +131,17 @@ // The current text when |single_character_buffer_| is zero, in which case it // is |text_.Substring(text_start_offset_, text_length_)|. String text_; + // TODO(editing-dev): We should make |text_| to hold substring instead of + // entire string with |text_start_offset_| and |text_length_|. unsigned text_start_offset_ = 0; // Position of the current text, in the form to be returned from the iterator. Member<const Node> position_node_; - mutable Member<const Node> position_offset_base_node_; - mutable unsigned position_start_offset_ = 0; - mutable unsigned position_end_offset_ = 0; + // |Text| node when |position_node_type_ == kInText| or |ContainerNode|. + mutable Member<const Node> position_container_node_; + mutable base::Optional<unsigned> position_start_offset_; + mutable base::Optional<unsigned> position_end_offset_; + PositionNodeType position_node_type_ = PositionNodeType::kNone; // Used when deciding whether to emit a "positioning" (e.g. newline) before // any other content
diff --git a/third_party/blink/renderer/core/html/html_slot_element.cc b/third_party/blink/renderer/core/html/html_slot_element.cc index 936d8dd..00e871b 100644 --- a/third_party/blink/renderer/core/html/html_slot_element.cc +++ b/third_party/blink/renderer/core/html/html_slot_element.cc
@@ -553,8 +553,6 @@ void HTMLSlotElement::LazyReattachDistributedNodesIfNeeded() { DCHECK(!RuntimeEnabledFeatures::IncrementalShadowDOMEnabled()); - // TODO(hayato): Move this probe to a better place. - probe::didPerformSlotDistribution(this); LazyReattachNodesIfNeeded(old_distributed_nodes_, distributed_nodes_); old_distributed_nodes_.clear(); @@ -565,6 +563,7 @@ const HeapVector<Member<Node>>& nodes2) { if (nodes1 == nodes2) return; + probe::didPerformSlotDistribution(this); if (nodes1.size() + 1 > kLCSTableSizeLimit || nodes2.size() + 1 > kLCSTableSizeLimit) {
diff --git a/third_party/blink/renderer/core/html/html_slot_element.h b/third_party/blink/renderer/core/html/html_slot_element.h index b7327f1..d3743d0 100644 --- a/third_party/blink/renderer/core/html/html_slot_element.h +++ b/third_party/blink/renderer/core/html/html_slot_element.h
@@ -145,8 +145,8 @@ const HeapVector<Member<Node>>& ChildrenInFlatTreeIfAssignmentIsSupported(); - static void LazyReattachNodesIfNeeded(const HeapVector<Member<Node>>& nodes1, - const HeapVector<Member<Node>>& nodes2); + void LazyReattachNodesIfNeeded(const HeapVector<Member<Node>>& nodes1, + const HeapVector<Member<Node>>& nodes2); static void LazyReattachNodesNaive(const HeapVector<Member<Node>>& nodes1, const HeapVector<Member<Node>>& nodes2); static void LazyReattachNodesByDynamicProgramming(
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc index f1e77c0..16e8a85 100644 --- a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
@@ -1656,12 +1656,25 @@ std::unique_ptr<protocol::Array<protocol::DOM::BackendNode>> InspectorDOMAgent::BuildDistributedNodesForSlot(HTMLSlotElement* slot_element) { + // TODO(hayato): In Shadow DOM v1, the concept of distributed nodes should + // not be used anymore. DistributedNodes should be replaced with + // AssignedNodes() when IncrementalShadowDOM becomes stable and Shadow DOM v0 + // is removed. std::unique_ptr<protocol::Array<protocol::DOM::BackendNode>> distributed_nodes = protocol::Array<protocol::DOM::BackendNode>::create(); if (RuntimeEnabledFeatures::IncrementalShadowDOMEnabled()) { - // TODO(hayato): Support distributed_nodes for IncrementalShadowDOM. - // We might use HTMLSlotElement::flat_tree_children here, however, we don't - // want to expose it, as of now. + for (auto& node : slot_element->AssignedNodes()) { + if (IsWhitespace(node)) + continue; + + std::unique_ptr<protocol::DOM::BackendNode> backend_node = + protocol::DOM::BackendNode::create() + .setNodeType(node->getNodeType()) + .setNodeName(node->nodeName()) + .setBackendNodeId(DOMNodeIds::IdForNode(node)) + .build(); + distributed_nodes->addItem(std::move(backend_node)); + } return distributed_nodes; } for (Node* node = slot_element->FirstDistributedNode(); node;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc index e473ae2..bfef042 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.cc
@@ -210,14 +210,4 @@ !ToLayoutInline(GetLayoutObject())->Continuation(); } -NGInlineItemRange::NGInlineItemRange(Vector<NGInlineItem>* items, - unsigned start_index, - unsigned end_index) - : start_item_(&(*items)[start_index]), - size_(end_index - start_index), - start_index_(start_index) { - CHECK_LE(start_index, end_index); - CHECK_LE(end_index, items->size()); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h index 7ca8834..f3111c7 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h
@@ -172,43 +172,6 @@ DCHECK_LE(offset, end_offset_); } -// A vector-like object that points to a subset of an array of |NGInlineItem|. -// The source vector must keep alive and must not resize while this object -// is alive. -class NGInlineItemRange { - STACK_ALLOCATED(); - - public: - NGInlineItemRange(Vector<NGInlineItem>*, - unsigned start_index, - unsigned end_index); - - unsigned StartIndex() const { return start_index_; } - unsigned EndIndex() const { return start_index_ + size_; } - unsigned Size() const { return size_; } - - NGInlineItem& operator[](unsigned index) { - CHECK_LT(index, size_); - return start_item_[index]; - } - const NGInlineItem& operator[](unsigned index) const { - CHECK_LT(index, size_); - return start_item_[index]; - } - - using iterator = NGInlineItem*; - using const_iterator = const NGInlineItem*; - iterator begin() { return start_item_; } - iterator end() { return start_item_ + size_; } - const_iterator begin() const { return start_item_; } - const_iterator end() const { return start_item_ + size_; } - - private: - NGInlineItem* start_item_; - unsigned size_; - unsigned start_index_; -}; - } // namespace blink #endif // NGInlineItem_h
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc index d343263..29dfb0a 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -205,10 +205,6 @@ return *data.first_line_items_; } -NGInlineItemRange NGInlineNode::Items(unsigned start, unsigned end) { - return NGInlineItemRange(&MutableData()->items_, start, end); -} - void NGInlineNode::InvalidatePrepareLayoutForTest() { GetLayoutBlockFlow()->ResetNGInlineNodeData(); DCHECK(!IsPrepareLayoutFinished());
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h index 81f1d59..81019b5 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h
@@ -22,7 +22,6 @@ struct MinMaxSize; class NGConstraintSpace; class NGInlineItem; -class NGInlineItemRange; using NGInlineItemsBuilder = NGInlineItemsBuilderTemplate<EmptyOffsetMappingBuilder>; struct NGInlineNodeData; @@ -64,7 +63,6 @@ } const Vector<NGInlineItem>& Items(bool is_first_line = false) const; - NGInlineItemRange Items(unsigned start_index, unsigned end_index); // Returns the DOM to text content offset mapping of this block. If it is not // computed before, compute and store it in NGInlineNodeData.
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 33d9b9e..d154a67fe 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -726,7 +726,6 @@ !request.GetResourceRequest().IsSameDocumentNavigation() && !frame_->Client()->AllowContentInitiatedDataUrlNavigations( request.OriginDocument()->Url()) && - !request.GetResourceRequest().GetSuggestedFilename().has_value() && (url.ProtocolIs("filesystem") || (url.ProtocolIsData() && NetworkUtils::IsDataURLMimeTypeSupported(url)))) {
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc index d1bf239..88430ca 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
@@ -318,6 +318,8 @@ auto platform_capabilities = component_->Source()->GetCapabilities(); capabilities.setDeviceId(platform_capabilities.device_id); + if (!platform_capabilities.group_id.IsNull()) + capabilities.setGroupId(platform_capabilities.group_id); if (component_->Source()->GetType() == MediaStreamSource::kTypeAudio) { Vector<bool> echo_cancellation, auto_gain_control, noise_suppression;
diff --git a/third_party/blink/renderer/platform/exported/web_url_load_timing.cc b/third_party/blink/renderer/platform/exported/web_url_load_timing.cc index 43310e1b..567469e 100644 --- a/third_party/blink/renderer/platform/exported/web_url_load_timing.cc +++ b/third_party/blink/renderer/platform/exported/web_url_load_timing.cc
@@ -47,148 +47,132 @@ private_ = other.private_; } -double WebURLLoadTiming::RequestTime() const { - return TimeTicksInSeconds(private_->RequestTime()); +base::TimeTicks WebURLLoadTiming::RequestTime() const { + return private_->RequestTime(); } -void WebURLLoadTiming::SetRequestTime(double time) { - DCHECK_GE(time, 0.0); - private_->SetRequestTime(TimeTicksFromSeconds(time)); +void WebURLLoadTiming::SetRequestTime(base::TimeTicks time) { + private_->SetRequestTime(time); } -double WebURLLoadTiming::ProxyStart() const { - return TimeTicksInSeconds(private_->ProxyStart()); +base::TimeTicks WebURLLoadTiming::ProxyStart() const { + return private_->ProxyStart(); } -void WebURLLoadTiming::SetProxyStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetProxyStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetProxyStart(base::TimeTicks start) { + private_->SetProxyStart(start); } -double WebURLLoadTiming::ProxyEnd() const { - return TimeTicksInSeconds(private_->ProxyEnd()); +base::TimeTicks WebURLLoadTiming::ProxyEnd() const { + return private_->ProxyEnd(); } -void WebURLLoadTiming::SetProxyEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetProxyEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetProxyEnd(base::TimeTicks end) { + private_->SetProxyEnd(end); } -double WebURLLoadTiming::DnsStart() const { - return TimeTicksInSeconds(private_->DnsStart()); +base::TimeTicks WebURLLoadTiming::DnsStart() const { + return private_->DnsStart(); } -void WebURLLoadTiming::SetDNSStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetDnsStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetDNSStart(base::TimeTicks start) { + private_->SetDnsStart(start); } -double WebURLLoadTiming::DnsEnd() const { - return TimeTicksInSeconds(private_->DnsEnd()); +base::TimeTicks WebURLLoadTiming::DnsEnd() const { + return private_->DnsEnd(); } -void WebURLLoadTiming::SetDNSEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetDnsEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetDNSEnd(base::TimeTicks end) { + private_->SetDnsEnd(end); } -double WebURLLoadTiming::ConnectStart() const { - return TimeTicksInSeconds(private_->ConnectStart()); +base::TimeTicks WebURLLoadTiming::ConnectStart() const { + return private_->ConnectStart(); } -void WebURLLoadTiming::SetConnectStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetConnectStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetConnectStart(base::TimeTicks start) { + private_->SetConnectStart(start); } -double WebURLLoadTiming::ConnectEnd() const { - return TimeTicksInSeconds(private_->ConnectEnd()); +base::TimeTicks WebURLLoadTiming::ConnectEnd() const { + return private_->ConnectEnd(); } -void WebURLLoadTiming::SetConnectEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetConnectEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetConnectEnd(base::TimeTicks end) { + private_->SetConnectEnd(end); } -double WebURLLoadTiming::WorkerStart() const { - return TimeTicksInSeconds(private_->WorkerStart()); +base::TimeTicks WebURLLoadTiming::WorkerStart() const { + return private_->WorkerStart(); } -void WebURLLoadTiming::SetWorkerStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetWorkerStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetWorkerStart(base::TimeTicks start) { + private_->SetWorkerStart(start); } -double WebURLLoadTiming::WorkerReady() const { - return TimeTicksInSeconds(private_->WorkerReady()); +base::TimeTicks WebURLLoadTiming::WorkerReady() const { + return private_->WorkerReady(); } -void WebURLLoadTiming::SetWorkerReady(double ready) { - DCHECK_GE(ready, 0.0); - private_->SetWorkerReady(TimeTicksFromSeconds(ready)); +void WebURLLoadTiming::SetWorkerReady(base::TimeTicks ready) { + private_->SetWorkerReady(ready); } -double WebURLLoadTiming::SendStart() const { - return TimeTicksInSeconds(private_->SendStart()); +base::TimeTicks WebURLLoadTiming::SendStart() const { + return private_->SendStart(); } -void WebURLLoadTiming::SetSendStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetSendStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetSendStart(base::TimeTicks start) { + private_->SetSendStart(start); } -double WebURLLoadTiming::SendEnd() const { - return TimeTicksInSeconds(private_->SendEnd()); +base::TimeTicks WebURLLoadTiming::SendEnd() const { + return private_->SendEnd(); } -void WebURLLoadTiming::SetSendEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetSendEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetSendEnd(base::TimeTicks end) { + private_->SetSendEnd(end); } -double WebURLLoadTiming::ReceiveHeadersEnd() const { - return TimeTicksInSeconds(private_->ReceiveHeadersEnd()); +base::TimeTicks WebURLLoadTiming::ReceiveHeadersEnd() const { + return private_->ReceiveHeadersEnd(); } -void WebURLLoadTiming::SetReceiveHeadersEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetReceiveHeadersEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetReceiveHeadersEnd(base::TimeTicks end) { + private_->SetReceiveHeadersEnd(end); } -double WebURLLoadTiming::SslStart() const { - return TimeTicksInSeconds(private_->SslStart()); +base::TimeTicks WebURLLoadTiming::SslStart() const { + return private_->SslStart(); } -void WebURLLoadTiming::SetSSLStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetSslStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetSSLStart(base::TimeTicks start) { + private_->SetSslStart(start); } -double WebURLLoadTiming::SslEnd() const { - return TimeTicksInSeconds(private_->SslEnd()); +base::TimeTicks WebURLLoadTiming::SslEnd() const { + return private_->SslEnd(); } -void WebURLLoadTiming::SetSSLEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetSslEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetSSLEnd(base::TimeTicks end) { + private_->SetSslEnd(end); } -double WebURLLoadTiming::PushStart() const { - return TimeTicksInSeconds(private_->PushStart()); +base::TimeTicks WebURLLoadTiming::PushStart() const { + return private_->PushStart(); } -void WebURLLoadTiming::SetPushStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetPushStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetPushStart(base::TimeTicks start) { + private_->SetPushStart(start); } -double WebURLLoadTiming::PushEnd() const { - return TimeTicksInSeconds(private_->PushEnd()); +base::TimeTicks WebURLLoadTiming::PushEnd() const { + return private_->PushEnd(); } -void WebURLLoadTiming::SetPushEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetPushEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetPushEnd(base::TimeTicks end) { + private_->SetPushEnd(end); } WebURLLoadTiming::WebURLLoadTiming(scoped_refptr<ResourceLoadTiming> value)
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn index d196bb5..4614d56 100644 --- a/third_party/blink/renderer/platform/heap/BUILD.gn +++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -8,14 +8,16 @@ import("//testing/test.gni") declare_args() { - # Build Blink with incremental marking infrastructure for Oilpan. + # Enables incremental marking in Oilpan. # - # To turn on incremental marking also use - # --enable-blink-features=HeapIncrementalMarking - enable_blink_heap_incremental_marking = true + # Note: Incremental marking is currently considered experimental and also + # enables 'enable_blink_heap_incremental_marking'. See default value below. + enable_blink_heap_incremental_marking = false +} +declare_args() { # Enables heap verification. - enable_blink_heap_verification = false + enable_blink_heap_verification = enable_blink_heap_incremental_marking } buildflag_header("blink_heap_buildflags") { @@ -30,6 +32,8 @@ blink_platform_sources("heap") { sources = [ + "address_cache.cc", + "address_cache.h", "blink_gc.h", "blink_gc_memory_dump_provider.cc", "blink_gc_memory_dump_provider.h", @@ -104,6 +108,7 @@ jumbo_source_set("blink_heap_unittests_sources") { testonly = true sources = [ + "address_cache_test.cc", "blink_gc_memory_dump_provider_test.cc", "heap_compact_test.cc", "heap_test.cc",
diff --git a/third_party/blink/renderer/platform/heap/address_cache.cc b/third_party/blink/renderer/platform/heap/address_cache.cc new file mode 100644 index 0000000..06c24e01 --- /dev/null +++ b/third_party/blink/renderer/platform/heap/address_cache.cc
@@ -0,0 +1,58 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/heap/address_cache.h" + +#include "third_party/blink/renderer/platform/heap/heap_page.h" + +namespace blink { + +void AddressCache::Flush() { + if (has_entries_) { + for (size_t i = 0; i < kNumberOfEntries; ++i) + entries_[i] = nullptr; + has_entries_ = false; + } + dirty_ = false; +} + +void AddressCache::FlushIfDirty() { + if (dirty_) { + Flush(); + dirty_ = false; + } +} + +size_t AddressCache::GetHash(Address address) { + size_t value = (reinterpret_cast<size_t>(address) >> kBlinkPageSizeLog2); + value ^= value >> kNumberOfEntriesLog2; + value ^= value >> (kNumberOfEntriesLog2 * 2); + value &= kNumberOfEntries - 1; + return value & ~1; // Returns only even number. +} + +bool AddressCache::Lookup(Address address) { + DCHECK(enabled_); + DCHECK(!dirty_); + + size_t index = GetHash(address); + DCHECK(!(index & 1)); + Address cache_page = RoundToBlinkPageStart(address); + if (entries_[index] == cache_page) + return entries_[index]; + if (entries_[index + 1] == cache_page) + return entries_[index + 1]; + return false; +} + +void AddressCache::AddEntry(Address address) { + has_entries_ = true; + size_t index = GetHash(address); + DCHECK(!(index & 1)); + Address cache_page = RoundToBlinkPageStart(address); + entries_[index + 1] = entries_[index]; + entries_[index] = cache_page; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/address_cache.h b/third_party/blink/renderer/platform/heap/address_cache.h new file mode 100644 index 0000000..85c676c --- /dev/null +++ b/third_party/blink/renderer/platform/heap/address_cache.h
@@ -0,0 +1,55 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_ADDRESS_CACHE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_ADDRESS_CACHE_H_ + +#include "third_party/blink/renderer/platform/heap/blink_gc.h" + +namespace blink { + +// Negative cache for addresses outside of Blink's garbage collected heap. +// - Internally maps to pages (NormalPage) to cover a larger range of addresses. +// - Requires flushing when adding new addresses. +class PLATFORM_EXPORT AddressCache { + USING_FAST_MALLOC(AddressCache); + + public: + AddressCache() : enabled_(false), has_entries_(false), dirty_(false) { + // Start by flushing the cache in a non-empty state to initialize all the + // cache entries. + for (size_t i = 0; i < kNumberOfEntries; ++i) + entries_[i] = nullptr; + } + + void EnableLookup() { enabled_ = true; } + void DisableLookup() { enabled_ = false; } + + void MarkDirty() { dirty_ = true; } + void Flush(); + void FlushIfDirty(); + bool IsEmpty() { return !has_entries_; } + + // Perform a lookup in the cache. Returns true if the address is guaranteed + // to not in Blink's heap and false otherwise. + bool Lookup(Address); + + // Add an entry to the cache. + void AddEntry(Address); + + private: + static constexpr size_t kNumberOfEntriesLog2 = 12; + static constexpr size_t kNumberOfEntries = 1 << kNumberOfEntriesLog2; + + static size_t GetHash(Address); + + Address entries_[kNumberOfEntries]; + bool enabled_ : 1; + bool has_entries_ : 1; + bool dirty_ : 1; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_ADDRESS_CACHE_H_
diff --git a/third_party/blink/renderer/platform/heap/address_cache_test.cc b/third_party/blink/renderer/platform/heap/address_cache_test.cc new file mode 100644 index 0000000..001b32ce --- /dev/null +++ b/third_party/blink/renderer/platform/heap/address_cache_test.cc
@@ -0,0 +1,74 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/heap/address_cache.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/heap/heap_page.h" + +namespace blink { + +namespace { + +const Address kObjectAddress = reinterpret_cast<Address>(kBlinkPageSize); + +} // namespace + +TEST(AddressCacheTest, InitialIsEmpty) { + AddressCache cache; + cache.EnableLookup(); + EXPECT_TRUE(cache.IsEmpty()); +} + +TEST(AddressCacheTest, LookupOnEmpty) { + AddressCache cache; + cache.EnableLookup(); + EXPECT_FALSE(cache.Lookup(kObjectAddress)); +} + +TEST(AddressCacheTest, LookupAfterAddEntry) { + AddressCache cache; + cache.EnableLookup(); + cache.AddEntry(kObjectAddress); + EXPECT_TRUE(cache.Lookup(kObjectAddress)); +} + +TEST(AddressCacheTest, AddEntryAddsWholePage) { + AddressCache cache; + cache.EnableLookup(); + cache.AddEntry(kObjectAddress); + for (Address current = kObjectAddress; + current < (kObjectAddress + kBlinkPageSize); current++) { + EXPECT_TRUE(cache.Lookup(current)); + } +} + +TEST(AddressCacheTest, AddEntryOnlyAddsPageForGivenAddress) { + AddressCache cache; + cache.EnableLookup(); + cache.AddEntry(kObjectAddress); + EXPECT_FALSE(cache.Lookup(kObjectAddress - 1)); + EXPECT_FALSE(cache.Lookup(kObjectAddress + kBlinkPageSize + 1)); +} + +TEST(AddressCacheTest, FlushIfDirtyIgnoresNonDirty) { + AddressCache cache; + cache.EnableLookup(); + cache.AddEntry(kObjectAddress); + cache.FlushIfDirty(); + // Cannot do lookup in dirty cache. + EXPECT_FALSE(cache.IsEmpty()); +} + +TEST(AddressCacheTest, FlushIfDirtyHandlesDirty) { + AddressCache cache; + cache.EnableLookup(); + cache.AddEntry(kObjectAddress); + cache.MarkDirty(); + cache.FlushIfDirty(); + // Cannot do lookup in dirty cache. + EXPECT_TRUE(cache.IsEmpty()); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/heap.cc b/third_party/blink/renderer/platform/heap/heap.cc index f4509a7e..77c074f 100644 --- a/third_party/blink/renderer/platform/heap/heap.cc +++ b/third_party/blink/renderer/platform/heap/heap.cc
@@ -37,6 +37,7 @@ #include "base/trace_event/process_memory_dump.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" +#include "third_party/blink/renderer/platform/heap/address_cache.h" #include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h" #include "third_party/blink/renderer/platform/heap/heap_compact.h" #include "third_party/blink/renderer/platform/heap/marking_visitor.h" @@ -58,10 +59,6 @@ HeapAllocHooks::AllocationHook* HeapAllocHooks::allocation_hook_ = nullptr; HeapAllocHooks::FreeHook* HeapAllocHooks::free_hook_ = nullptr; -void ThreadHeap::FlushHeapDoesNotContainCache() { - heap_does_not_contain_cache_->Flush(); -} - ThreadHeapStats::ThreadHeapStats() : allocated_space_(0), allocated_object_size_(0), @@ -132,14 +129,13 @@ ThreadHeap::ThreadHeap(ThreadState* thread_state) : thread_state_(thread_state), region_tree_(std::make_unique<RegionTree>()), - heap_does_not_contain_cache_(std::make_unique<HeapDoesNotContainCache>()), + address_cache_(std::make_unique<AddressCache>()), free_page_pool_(std::make_unique<PagePool>()), marking_worklist_(nullptr), not_fully_constructed_worklist_(nullptr), weak_callback_worklist_(nullptr), vector_backing_arena_index_(BlinkGC::kVector1ArenaIndex), - current_arena_ages_(0), - should_flush_heap_does_not_contain_cache_(false) { + current_arena_ages_(0) { if (ThreadState::Current()->IsMainThread()) main_thread_heap_ = this; @@ -164,7 +160,7 @@ DCHECK(thread_state_->InAtomicMarkingPause()); #if !DCHECK_IS_ON() - if (heap_does_not_contain_cache_->Lookup(address)) + if (address_cache_->Lookup(address)) return nullptr; #endif @@ -172,17 +168,17 @@ #if DCHECK_IS_ON() DCHECK(page->Contains(address)); #endif - DCHECK(!heap_does_not_contain_cache_->Lookup(address)); + DCHECK(!address_cache_->Lookup(address)); DCHECK(&visitor->Heap() == &page->Arena()->GetThreadState()->Heap()); visitor->ConservativelyMarkAddress(page, address); return address; } #if !DCHECK_IS_ON() - heap_does_not_contain_cache_->AddEntry(address); + address_cache_->AddEntry(address); #else - if (!heap_does_not_contain_cache_->Lookup(address)) - heap_does_not_contain_cache_->AddEntry(address); + if (!address_cache_->Lookup(address)) + address_cache_->AddEntry(address); #endif return nullptr; } @@ -199,13 +195,13 @@ if (BasePage* page = LookupPageForAddress(address)) { DCHECK(page->Contains(address)); - DCHECK(!heap_does_not_contain_cache_->Lookup(address)); + DCHECK(!address_cache_->Lookup(address)); DCHECK(&visitor->Heap() == &page->Arena()->GetThreadState()->Heap()); visitor->ConservativelyMarkAddress(page, address, callback); return address; } - if (!heap_does_not_contain_cache_->Lookup(address)) - heap_does_not_contain_cache_->AddEntry(address); + if (!address_cache_->Lookup(address)) + address_cache_->AddEntry(address); return nullptr; } #endif // DCHECK_IS_ON() @@ -449,26 +445,6 @@ return object_payload_size; } -void ThreadHeap::ShouldFlushHeapDoesNotContainCache() { - should_flush_heap_does_not_contain_cache_ = true; -} - -void ThreadHeap::FlushHeapDoesNotContainCacheIfNeeded() { - if (should_flush_heap_does_not_contain_cache_) { - FlushHeapDoesNotContainCache(); - should_flush_heap_does_not_contain_cache_ = false; - } -} - -bool ThreadHeap::IsAddressInHeapDoesNotContainCache(Address address) { - // If the cache has been marked as invalidated, it's cleared prior - // to performing the next GC. Hence, consider the cache as being - // effectively empty. - if (should_flush_heap_does_not_contain_cache_) - return false; - return heap_does_not_contain_cache_->Lookup(address); -} - void ThreadHeap::VisitPersistentRoots(Visitor* visitor) { DCHECK(thread_state_->InAtomicMarkingPause()); TRACE_EVENT0("blink_gc", "ThreadHeap::visitPersistentRoots"); @@ -478,7 +454,10 @@ void ThreadHeap::VisitStackRoots(MarkingVisitor* visitor) { DCHECK(thread_state_->InAtomicMarkingPause()); TRACE_EVENT0("blink_gc", "ThreadHeap::visitStackRoots"); + address_cache_->FlushIfDirty(); + address_cache_->EnableLookup(); thread_state_->VisitStack(visitor); + address_cache_->DisableLookup(); } BasePage* ThreadHeap::LookupPageForAddress(Address address) {
diff --git a/third_party/blink/renderer/platform/heap/heap.h b/third_party/blink/renderer/platform/heap/heap.h index f18a6f95..bb25750b 100644 --- a/third_party/blink/renderer/platform/heap/heap.h +++ b/third_party/blink/renderer/platform/heap/heap.h
@@ -55,6 +55,7 @@ class IncrementalMarkingScopeBase; } // namespace incremental_marking_test +class AddressCache; class PagePool; class RegionTree; @@ -358,10 +359,7 @@ size_t ObjectPayloadSizeForTesting(); - void FlushHeapDoesNotContainCache(); - bool IsAddressInHeapDoesNotContainCache(Address); - void FlushHeapDoesNotContainCacheIfNeeded(); - void ShouldFlushHeapDoesNotContainCache(); + AddressCache* address_cache() { return address_cache_.get(); } PagePool* GetFreePagePool() { return free_page_pool_.get(); } @@ -499,7 +497,7 @@ ThreadState* thread_state_; ThreadHeapStats stats_; std::unique_ptr<RegionTree> region_tree_; - std::unique_ptr<HeapDoesNotContainCache> heap_does_not_contain_cache_; + std::unique_ptr<AddressCache> address_cache_; std::unique_ptr<PagePool> free_page_pool_; std::unique_ptr<MarkingWorklist> marking_worklist_; std::unique_ptr<NotFullyConstructedWorklist> not_fully_constructed_worklist_; @@ -515,7 +513,6 @@ int vector_backing_arena_index_; size_t arena_ages_[BlinkGC::kNumberOfArenas]; size_t current_arena_ages_; - bool should_flush_heap_does_not_contain_cache_; // Ideally we want to allocate an array of size |gcInfoTableMax| but it will // waste memory. Thus we limit the array size to 2^8 and share one entry
diff --git a/third_party/blink/renderer/platform/heap/heap_page.cc b/third_party/blink/renderer/platform/heap/heap_page.cc index b73e828..181745da 100644 --- a/third_party/blink/renderer/platform/heap/heap_page.cc +++ b/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -33,6 +33,7 @@ #include "base/trace_event/process_memory_dump.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" +#include "third_party/blink/renderer/platform/heap/address_cache.h" #include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h" #include "third_party/blink/renderer/platform/heap/heap_compact.h" #include "third_party/blink/renderer/platform/heap/marking_verifier.h" @@ -659,7 +660,7 @@ } void NormalPageArena::AllocatePage() { - GetThreadState()->Heap().ShouldFlushHeapDoesNotContainCache(); + GetThreadState()->Heap().address_cache()->MarkDirty(); PageMemory* page_memory = GetThreadState()->Heap().GetFreePagePool()->Take(ArenaIndex()); @@ -1014,7 +1015,7 @@ large_object_size += kAllocationGranularity; #endif - GetThreadState()->Heap().ShouldFlushHeapDoesNotContainCache(); + GetThreadState()->Heap().address_cache()->MarkDirty(); PageMemory* page_memory = PageMemory::Allocate( large_object_size, GetThreadState()->Heap().GetRegionTree()); Address large_object_address = page_memory->WritableStart(); @@ -1775,44 +1776,4 @@ } #endif -void HeapDoesNotContainCache::Flush() { - if (has_entries_) { - for (size_t i = 0; i < kNumberOfEntries; ++i) - entries_[i] = nullptr; - has_entries_ = false; - } -} - -size_t HeapDoesNotContainCache::GetHash(Address address) { - size_t value = (reinterpret_cast<size_t>(address) >> kBlinkPageSizeLog2); - value ^= value >> kNumberOfEntriesLog2; - value ^= value >> (kNumberOfEntriesLog2 * 2); - value &= kNumberOfEntries - 1; - return value & ~1; // Returns only even number. -} - -bool HeapDoesNotContainCache::Lookup(Address address) { - DCHECK(ThreadState::Current()->InAtomicMarkingPause()); - - size_t index = GetHash(address); - DCHECK(!(index & 1)); - Address cache_page = RoundToBlinkPageStart(address); - if (entries_[index] == cache_page) - return entries_[index]; - if (entries_[index + 1] == cache_page) - return entries_[index + 1]; - return false; -} - -void HeapDoesNotContainCache::AddEntry(Address address) { - DCHECK(ThreadState::Current()->InAtomicMarkingPause()); - - has_entries_ = true; - size_t index = GetHash(address); - DCHECK(!(index & 1)); - Address cache_page = RoundToBlinkPageStart(address); - entries_[index + 1] = entries_[index]; - entries_[index] = cache_page; -} - } // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/heap_page.h b/third_party/blink/renderer/platform/heap/heap_page.h index 1aa7cf55..89943847 100644 --- a/third_party/blink/renderer/platform/heap/heap_page.h +++ b/third_party/blink/renderer/platform/heap/heap_page.h
@@ -646,54 +646,6 @@ #endif }; -// |HeapDoesNotContainCache| provides a fast way to determine whether an -// aribtrary pointer-sized word can be interpreted as a pointer to an area that -// is managed by the garbage collected Blink heap. This is a cache of 'pages' -// that have previously been determined to be wholly outside of the heap. The -// size of these pages must be smaller than the allocation alignment of the heap -// pages. We determine off-heap-ness by rounding down the pointer to the nearest -// page and looking up the page in the cache. If there is a miss in the cache we -// can determine the status of the pointer precisely using the heap -// |RegionTree|. -// -// This is a negative cache, so it must be flushed when memory is added to the -// heap. -class HeapDoesNotContainCache { - USING_FAST_MALLOC(HeapDoesNotContainCache); - - public: - HeapDoesNotContainCache() : has_entries_(false) { - // Start by flushing the cache in a non-empty state to initialize all the - // cache entries. - for (size_t i = 0; i < kNumberOfEntries; ++i) - entries_[i] = nullptr; - } - - void Flush(); - bool IsEmpty() { return !has_entries_; } - - // Perform a lookup in the cache. - // - // If lookup returns false, the argument address was not found in the cache - // and it is unknown if the address is in the Blink heap. - // - // If lookup returns true, the argument address was found in the cache which - // means the address is not in the heap. - PLATFORM_EXPORT bool Lookup(Address); - - // Add an entry to the cache. - PLATFORM_EXPORT void AddEntry(Address); - - private: - static constexpr size_t kNumberOfEntriesLog2 = 12; - static constexpr size_t kNumberOfEntries = 1 << kNumberOfEntriesLog2; - - static size_t GetHash(Address); - - Address entries_[kNumberOfEntries]; - bool has_entries_; -}; - class FreeList { DISALLOW_NEW();
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc index a42cd6c4..bc33272d 100644 --- a/third_party/blink/renderer/platform/heap/heap_test.cc +++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -38,6 +38,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h" +#include "third_party/blink/renderer/platform/heap/address_cache.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap_linked_stack.h" @@ -4010,7 +4011,8 @@ TestGCScope scope(BlinkGC::kHeapPointersOnStack); MarkingVisitor visitor(ThreadState::Current(), MarkingVisitor::kGlobalMarking); - heap.FlushHeapDoesNotContainCache(); + heap.address_cache()->EnableLookup(); + heap.address_cache()->Flush(); for (size_t i = 0; i < object_addresses.size(); i++) { EXPECT_TRUE(heap.CheckAndMarkPointer(&visitor, object_addresses[i], ReportMarkedPointer)); @@ -4034,7 +4036,8 @@ TestGCScope scope(BlinkGC::kHeapPointersOnStack); MarkingVisitor visitor(ThreadState::Current(), MarkingVisitor::kGlobalMarking); - heap.FlushHeapDoesNotContainCache(); + heap.address_cache()->EnableLookup(); + heap.address_cache()->Flush(); for (size_t i = 0; i < object_addresses.size(); i++) { // We would like to assert that checkAndMarkPointer returned false // here because the pointers no longer point into a valid object
diff --git a/third_party/blink/renderer/platform/heap/page_memory.h b/third_party/blink/renderer/platform/heap/page_memory.h index 7f4ca6ef..1fbed84 100644 --- a/third_party/blink/renderer/platform/heap/page_memory.h +++ b/third_party/blink/renderer/platform/heap/page_memory.h
@@ -169,15 +169,6 @@ WARN_UNUSED_RESULT bool Commit() { reserved_->MarkPageUsed(WritableStart()); - // Check that in-use page isn't also marked as being a non-heap page - // by the current heap's negative cache. That cache is invalidated - // when allocating new pages, but crbug.com/649485 suggests that - // we do get out of sync somehow. - // - // TODO(sof): consider removing check once bug has been diagnosed - // and addressed. - CHECK(!ThreadState::Current()->Heap().IsAddressInHeapDoesNotContainCache( - WritableStart())); return writable_.Commit(); }
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc index db409f1..31d89242 100644 --- a/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -1423,7 +1423,6 @@ DCHECK(InAtomicMarkingPause()); Heap().MakeConsistentForGC(); - Heap().FlushHeapDoesNotContainCacheIfNeeded(); Heap().ClearArenaAges(); if (marking_type != BlinkGC::kTakeSnapshot)
diff --git a/third_party/blink/renderer/platform/scheduler/BUILD.gn b/third_party/blink/renderer/platform/scheduler/BUILD.gn index 7d2372f9..704ab965 100644 --- a/third_party/blink/renderer/platform/scheduler/BUILD.gn +++ b/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -86,16 +86,35 @@ "common/throttling/throttled_time_domain.h", "common/throttling/wake_up_budget_pool.cc", "common/throttling/wake_up_budget_pool.h", + "main_thread/auto_advancing_virtual_time_domain.cc", + "main_thread/auto_advancing_virtual_time_domain.h", + "main_thread/deadline_task_runner.cc", + "main_thread/deadline_task_runner.h", "main_thread/frame_origin_type.cc", "main_thread/frame_origin_type.h", "main_thread/frame_scheduler_impl.cc", "main_thread/frame_scheduler_impl.h", + "main_thread/idle_time_estimator.cc", + "main_thread/idle_time_estimator.h", "main_thread/main_thread_scheduler_helper.cc", "main_thread/main_thread_scheduler_helper.h", "main_thread/main_thread_scheduler_impl.cc", "main_thread/main_thread_scheduler_impl.h", + "main_thread/main_thread_task_queue.cc", + "main_thread/main_thread_task_queue.h", "main_thread/page_scheduler_impl.cc", "main_thread/page_scheduler_impl.h", + "main_thread/queueing_time_estimator.cc", + "main_thread/queueing_time_estimator.h", + "main_thread/render_widget_signals.cc", + "main_thread/render_widget_signals.h", + "main_thread/renderer_metrics_helper.cc", + "main_thread/renderer_metrics_helper.h", + "main_thread/task_cost_estimator.cc", + "main_thread/task_cost_estimator.h", + "main_thread/use_case.h", + "main_thread/user_model.cc", + "main_thread/user_model.h", "main_thread/web_main_thread_scheduler.cc", "main_thread/web_render_widget_scheduling_state.cc", "public/frame_or_worker_scheduler.h", @@ -104,28 +123,10 @@ "public/page_scheduler.h", "public/thread_scheduler.h", "public/web_main_thread_scheduler.h", - "renderer/auto_advancing_virtual_time_domain.cc", - "renderer/auto_advancing_virtual_time_domain.h", - "renderer/deadline_task_runner.cc", - "renderer/deadline_task_runner.h", "renderer/frame_status.cc", "renderer/frame_status.h", - "renderer/idle_time_estimator.cc", - "renderer/idle_time_estimator.h", - "renderer/main_thread_task_queue.cc", - "renderer/main_thread_task_queue.h", - "renderer/queueing_time_estimator.cc", - "renderer/queueing_time_estimator.h", - "renderer/render_widget_signals.cc", - "renderer/render_widget_signals.h", - "renderer/renderer_metrics_helper.cc", - "renderer/renderer_metrics_helper.h", "renderer/renderer_web_scheduler_impl.cc", "renderer/renderer_web_scheduler_impl.h", - "renderer/task_cost_estimator.cc", - "renderer/task_cost_estimator.h", - "renderer/user_model.cc", - "renderer/user_model.h", "renderer/web_scoped_virtual_time_pauser.cc", "renderer/webthread_impl_for_renderer_scheduler.cc", "renderer/webthread_impl_for_renderer_scheduler.h", @@ -208,17 +209,17 @@ "common/scheduler_helper_unittest.cc", "common/throttling/budget_pool_unittest.cc", "common/throttling/task_queue_throttler_unittest.cc", + "main_thread/auto_advancing_virtual_time_domain_unittest.cc", + "main_thread/deadline_task_runner_unittest.cc", "main_thread/frame_scheduler_impl_unittest.cc", + "main_thread/idle_time_estimator_unittest.cc", "main_thread/main_thread_scheduler_impl_unittest.cc", "main_thread/page_scheduler_impl_unittest.cc", - "renderer/auto_advancing_virtual_time_domain_unittest.cc", - "renderer/deadline_task_runner_unittest.cc", - "renderer/idle_time_estimator_unittest.cc", - "renderer/queueing_time_estimator_unittest.cc", - "renderer/render_widget_signals_unittest.cc", - "renderer/renderer_metrics_helper_unittest.cc", - "renderer/task_cost_estimator_unittest.cc", - "renderer/user_model_unittest.cc", + "main_thread/queueing_time_estimator_unittest.cc", + "main_thread/render_widget_signals_unittest.cc", + "main_thread/renderer_metrics_helper_unittest.cc", + "main_thread/task_cost_estimator_unittest.cc", + "main_thread/user_model_unittest.cc", "renderer/webthread_impl_for_renderer_scheduler_unittest.cc", "util/task_duration_metric_reporter_unittest.cc", "util/thread_load_tracker_unittest.cc",
diff --git a/third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h b/third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h index e7025d3..a89da1c5 100644 --- a/third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h +++ b/third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h
@@ -28,8 +28,6 @@ // base::SingleThreadTaskRunner implementation: bool RunsTasksInCurrentSequence() const override; - TaskQueue* GetTaskQueue() const { return task_queue_.get(); } - protected: bool PostDelayedTask(const base::Location&, base::OnceClosure,
diff --git a/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.cc index eb441b5..869ca0a 100644 --- a/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.cc
@@ -34,7 +34,7 @@ return thread_scheduler_->ShouldYieldForHighPriorityWork(); } -bool WebSchedulerImpl::CanExceedIdleDeadlineIfRequired() { +bool WebSchedulerImpl::CanExceedIdleDeadlineIfRequired() const { return thread_scheduler_->CanExceedIdleDeadlineIfRequired(); }
diff --git a/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.h index 8cc6b4bf..fe9f863 100644 --- a/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.h
@@ -32,7 +32,7 @@ // ThreadScheduler implementation: void Shutdown() override; bool ShouldYieldForHighPriorityWork() override; - bool CanExceedIdleDeadlineIfRequired() override; + bool CanExceedIdleDeadlineIfRequired() const override; void PostIdleTask(const base::Location& location, WebThread::IdleTask task) override; void PostNonNestableIdleTask(const base::Location& location,
diff --git a/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc b/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc index 42bd5126..dbc9fef 100644 --- a/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc
@@ -11,7 +11,6 @@ #include "base/synchronization/waitable_event.h" #include "base/time/default_tick_clock.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy.h" #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h" @@ -65,10 +64,6 @@ non_main_thread_scheduler_->Init(); task_queue_ = non_main_thread_scheduler_->DefaultTaskQueue(); idle_task_runner_ = non_main_thread_scheduler_->IdleTaskRunner(); - web_scheduler_.reset( - new WebSchedulerImpl(non_main_thread_scheduler_.get(), - non_main_thread_scheduler_->IdleTaskRunner(), - non_main_thread_scheduler_->DefaultTaskQueue())); base::MessageLoopCurrent::Get()->AddDestructionObserver(this); completion->Signal(); } @@ -79,7 +74,6 @@ task_queue_ = nullptr; idle_task_runner_ = nullptr; - web_scheduler_ = nullptr; non_main_thread_scheduler_ = nullptr; if (completion) @@ -101,7 +95,7 @@ } blink::ThreadScheduler* WebThreadImplForWorkerScheduler::Scheduler() const { - return web_scheduler_.get(); + return non_main_thread_scheduler_.get(); } SingleThreadIdleTaskRunner* WebThreadImplForWorkerScheduler::GetIdleTaskRunner()
diff --git a/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h b/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h index a38fce4..89cbc3d 100644 --- a/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h
@@ -25,7 +25,6 @@ namespace scheduler { class SingleThreadIdleTaskRunner; class TaskQueue; -class WebSchedulerImpl; class NonMainThreadScheduler; class WorkerSchedulerProxy; @@ -76,7 +75,6 @@ const WebThreadType thread_type_; std::unique_ptr<scheduler::WorkerSchedulerProxy> worker_scheduler_proxy_; std::unique_ptr<scheduler::NonMainThreadScheduler> non_main_thread_scheduler_; - std::unique_ptr<scheduler::WebSchedulerImpl> web_scheduler_; scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner_; scoped_refptr<TaskQueue> task_queue_; scoped_refptr<scheduler::SingleThreadIdleTaskRunner> idle_task_runner_;
diff --git a/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc b/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc index c7c4470..3ec646d6 100644 --- a/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
@@ -62,9 +62,7 @@ } void ShutdownOnThread(WebThreadImplForWorkerScheduler* thread) { - WebSchedulerImpl* web_scheduler_impl = - static_cast<WebSchedulerImpl*>(thread->Scheduler()); - web_scheduler_impl->Shutdown(); + thread->Scheduler()->Shutdown(); } class WebThreadImplForWorkerSchedulerTest : public testing::Test {
diff --git a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc index 53ce2e1..6bfce5aed 100644 --- a/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler_unittest.cc
@@ -20,9 +20,9 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h" #include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" using testing::ElementsAre;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/DEPS b/third_party/blink/renderer/platform/scheduler/main_thread/DEPS index 0308a86..92b89d6e 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/DEPS +++ b/third_party/blink/renderer/platform/scheduler/main_thread/DEPS
@@ -1,6 +1,8 @@ include_rules = [ "+base/metrics/single_sample_metrics.h", + "+cc", "+components/viz/common", + "+services/resource_coordinator/public/cpp/resource_coordinator_features.h", ] specific_include_rules = {
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.cc b/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.cc similarity index 97% rename from third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.cc index 92390ab..1322636 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include "base/time/time_override.h" #include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h"
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h b/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h similarity index 93% rename from third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h rename to third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h index e32dea0..c31692f 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_AUTO_ADVANCING_VIRTUAL_TIME_DOMAIN_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_AUTO_ADVANCING_VIRTUAL_TIME_DOMAIN_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AUTO_ADVANCING_VIRTUAL_TIME_DOMAIN_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AUTO_ADVANCING_VIRTUAL_TIME_DOMAIN_H_ #include "base/macros.h" #include "base/message_loop/message_loop.h" @@ -117,4 +117,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_AUTO_ADVANCING_VIRTUAL_TIME_DOMAIN_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AUTO_ADVANCING_VIRTUAL_TIME_DOMAIN_H_
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc similarity index 98% rename from third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc index 0d78251..9aba100d8 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_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 "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include <memory> #include "base/test/simple_test_tick_clock.h" @@ -71,7 +71,7 @@ MOCK_METHOD0(OnVirtualTimeAdvanced, void()); }; -} // namesapce +} // namespace TEST_F(AutoAdvancingVirtualTimeDomainTest, VirtualTimeAdvances) { MockObserver mock_observer;
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.cc b/third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.cc similarity index 92% rename from third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.cc index e945595a..a9d758e2 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h" #include "base/bind.h"
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.h b/third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h similarity index 85% rename from third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.h rename to third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h index c37ec85dc..2cf9c70a 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_DEADLINE_TASK_RUNNER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_DEADLINE_TASK_RUNNER_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_DEADLINE_TASK_RUNNER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_DEADLINE_TASK_RUNNER_H_ #include "base/callback.h" #include "base/macros.h" @@ -48,4 +48,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_DEADLINE_TASK_RUNNER_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_DEADLINE_TASK_RUNNER_H_
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner_unittest.cc similarity index 97% rename from third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner_unittest.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner_unittest.cc index 7cf087a..f56d0e87 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner_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 "third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h" #include <memory>
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc index 6e616f4..daea9dfbf 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -17,9 +17,9 @@ #include "third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h" #include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.cc b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc similarity index 96% rename from third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc index 4ee87d3..c58b6b6c 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h" #include "base/time/default_tick_clock.h"
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.h b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h similarity index 87% rename from third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.h rename to third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h index 43cdbcb8..f4b3942 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_IDLE_TIME_ESTIMATOR_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_IDLE_TIME_ESTIMATOR_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_IDLE_TIME_ESTIMATOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_IDLE_TIME_ESTIMATOR_H_ #include "base/macros.h" #include "base/message_loop/message_loop.h" @@ -57,4 +57,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_IDLE_TIME_ESTIMATOR_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_IDLE_TIME_ESTIMATOR_H_
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc similarity index 98% rename from third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator_unittest.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc index f02498c..55a617e 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_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 "third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h" #include <memory> #include "base/memory/scoped_refptr.h"
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc index 5d23977..dcd5de0 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc
@@ -4,7 +4,7 @@ #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" namespace blink { namespace scheduler {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h index f82acb3..8f76304 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" namespace blink { namespace scheduler {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc index 46b3900..4162f4a 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -34,8 +34,8 @@ #include "third_party/blink/renderer/platform/scheduler/child/features.h" #include "third_party/blink/renderer/platform/scheduler/child/process_state.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h index f221d9d0..271353e 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -23,18 +23,18 @@ #include "third_party/blink/renderer/platform/scheduler/child/idle_canceled_delayed_task_sweeper.h" #include "third_party/blink/renderer/platform/scheduler/child/idle_helper.h" #include "third_party/blink/renderer/platform/scheduler/child/pollable_thread_safe_flag.h" -#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/use_case.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/user_model.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/use_case.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/user_model.h" #include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h" namespace base {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc index 0fa0f8c..9b7fefc 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
@@ -25,8 +25,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/child/features.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc similarity index 98% rename from third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc index a5a3f8a..34c19f7 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h similarity index 95% rename from third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h rename to third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h index 507284e0..6662138c1 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_MAIN_THREAD_TASK_QUEUE_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_MAIN_THREAD_TASK_QUEUE_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_TASK_QUEUE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_TASK_QUEUE_H_ #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" @@ -221,4 +221,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_MAIN_THREAD_TASK_QUEUE_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_TASK_QUEUE_H_
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc index 0493fbe..16c5bf0 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -12,10 +12,10 @@ #include "third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/child/default_params.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" namespace blink { namespace scheduler {
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.cc b/third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.cc similarity index 98% rename from third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.cc index a509852..b31f398 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.h b/third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.h similarity index 91% rename from third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.h rename to third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.h index 7fdde94..976998e6 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.h
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_QUEUEING_TIME_ESTIMATOR_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_QUEUEING_TIME_ESTIMATOR_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_QUEUEING_TIME_ESTIMATOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_QUEUEING_TIME_ESTIMATOR_H_ #include "base/macros.h" #include "base/time/time.h" #include "third_party/blink/public/common/page/launching_process_state.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper.h" #include <array> #include <vector> @@ -141,4 +141,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_QUEUEING_TIME_ESTIMATOR_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_QUEUEING_TIME_ESTIMATOR_H_
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator_unittest.cc similarity index 99% rename from third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator_unittest.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator_unittest.cc index f8a7c06..bc489ae9 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator_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 "third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.h" #include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.cc b/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.cc similarity index 95% rename from third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.cc index fc1f003..b1f8cb8a 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h" #include "base/logging.h" #include "base/memory/ptr_util.h"
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.h b/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h similarity index 86% rename from third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.h rename to third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h index e19b213..453e3b6 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDER_WIDGET_SIGNALS_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDER_WIDGET_SIGNALS_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_RENDER_WIDGET_SIGNALS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_RENDER_WIDGET_SIGNALS_H_ #include <memory> @@ -58,4 +58,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDER_WIDGET_SIGNALS_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_RENDER_WIDGET_SIGNALS_H_
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals_unittest.cc similarity index 98% rename from third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals_unittest.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals_unittest.cc index ff80c051..478e09f5 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals_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 "third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h" #include "base/macros.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.cc b/third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper.cc similarity index 99% rename from third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper.cc index eda829c..03b129c 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper.h" #include "base/bind.h" #include "base/metrics/histogram_macros.h"
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.h b/third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper.h similarity index 92% rename from third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.h rename to third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper.h index f1f1167..72b66f8 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDERER_METRICS_HELPER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDERER_METRICS_HELPER_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_RENDERER_METRICS_HELPER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_RENDERER_METRICS_HELPER_H_ #include "base/macros.h" #include "base/optional.h" @@ -12,9 +12,9 @@ #include "third_party/blink/public/platform/web_thread_type.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/child/metrics_helper.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/use_case.h" #include "third_party/blink/renderer/platform/scheduler/renderer/frame_status.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/use_case.h" #include "third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h" #include "third_party/blink/renderer/platform/scheduler/util/thread_load_tracker.h" @@ -141,4 +141,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDERER_METRICS_HELPER_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_RENDERER_METRICS_HELPER_H_
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper_unittest.cc similarity index 99% rename from third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper_unittest.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper_unittest.cc index a4ee590e..f8655c9 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper_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 "third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/renderer_metrics_helper.h" #include <memory> #include "base/macros.h"
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.cc b/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.cc similarity index 93% rename from third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.cc index f9ce0c4..0686a1eb 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h" #include "base/time/default_tick_clock.h"
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.h b/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h similarity index 83% rename from third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.h rename to third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h index 2214c772..c3e54a3 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_TASK_COST_ESTIMATOR_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_TASK_COST_ESTIMATOR_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_TASK_COST_ESTIMATOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_TASK_COST_ESTIMATOR_H_ #include "base/macros.h" #include "base/message_loop/message_loop.h" @@ -49,4 +49,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_TASK_COST_ESTIMATOR_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_TASK_COST_ESTIMATOR_H_
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator_unittest.cc similarity index 95% rename from third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator_unittest.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator_unittest.cc index 45ff499..6d7b3bf 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator_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 "third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h" #include <memory>
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/use_case.h b/third_party/blink/renderer/platform/scheduler/main_thread/use_case.h similarity index 85% rename from third_party/blink/renderer/platform/scheduler/renderer/use_case.h rename to third_party/blink/renderer/platform/scheduler/main_thread/use_case.h index ce4ad48..7ab1c4d 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/use_case.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/use_case.h
@@ -1,5 +1,5 @@ -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_USE_CASE_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_USE_CASE_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USE_CASE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USE_CASE_H_ namespace blink { namespace scheduler { @@ -39,4 +39,4 @@ } // namespace scheduler } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USE_CASE_H_
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/user_model.cc b/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc similarity index 98% rename from third_party/blink/renderer/platform/scheduler/renderer/user_model.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc index aeb7ba5..361b57e 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/user_model.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/renderer/platform/scheduler/renderer/user_model.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/user_model.h" namespace blink { namespace scheduler {
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/user_model.h b/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h similarity index 92% rename from third_party/blink/renderer/platform/scheduler/renderer/user_model.h rename to third_party/blink/renderer/platform/scheduler/main_thread/user_model.h index 247acf43..afbab65cd 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/user_model.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_USER_MODEL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_USER_MODEL_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USER_MODEL_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USER_MODEL_H_ #include "base/macros.h" #include "base/trace_event/trace_event.h" @@ -83,4 +83,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_USER_MODEL_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USER_MODEL_H_
diff --git a/third_party/blink/renderer/platform/scheduler/renderer/user_model_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/user_model_unittest.cc similarity index 98% rename from third_party/blink/renderer/platform/scheduler/renderer/user_model_unittest.cc rename to third_party/blink/renderer/platform/scheduler/main_thread/user_model_unittest.cc index 6d75270..b0ae0e3 100644 --- a/third_party/blink/renderer/platform/scheduler/renderer/user_model_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/user_model_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 "third_party/blink/renderer/platform/scheduler/renderer/user_model.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/user_model.h" #include "base/test/simple_test_tick_clock.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/web_render_widget_scheduling_state.cc b/third_party/blink/renderer/platform/scheduler/main_thread/web_render_widget_scheduling_state.cc index 2cfea4a..1b645c39 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/web_render_widget_scheduling_state.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/web_render_widget_scheduling_state.cc
@@ -4,7 +4,7 @@ #include "third_party/blink/public/platform/scheduler/web_render_widget_scheduling_state.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h" namespace blink { namespace scheduler {
diff --git a/third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h index 038aea8b..cf5205a 100644 --- a/third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h
@@ -14,13 +14,19 @@ #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/child/worker_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h" namespace blink { namespace scheduler { +class TaskRunnerImpl; class WorkerSchedulerProxy; -class PLATFORM_EXPORT NonMainThreadScheduler : public WebThreadScheduler { +// TODO(yutak): Remove the dependency to WebThreadScheduler. We want to +// separate interfaces to Chromium (in blink/public/platform/scheduler) from +// interfaces to Blink (in blink/renderer/platform/scheduler/public). +class PLATFORM_EXPORT NonMainThreadScheduler : public WebThreadScheduler, + public ThreadScheduler { public: ~NonMainThreadScheduler() override; @@ -34,7 +40,7 @@ // Must be called before the scheduler can be used. Does any post construction // initialization needed such as initializing idle period detection. - virtual void Init() = 0; + void Init(); virtual void OnTaskCompleted(WorkerTaskQueue* worker_task_queue, const TaskQueue::Task& task, @@ -42,14 +48,54 @@ base::TimeTicks end, base::Optional<base::TimeDelta> thread_time) = 0; + // ThreadScheduler implementation. + // TODO(yutak): Some functions are only meaningful in main thread. Move them + // to MainThreadScheduler. + void PostIdleTask(const base::Location& location, + WebThread::IdleTask task) override; + void PostNonNestableIdleTask(const base::Location& location, + WebThread::IdleTask task) override; + base::SingleThreadTaskRunner* V8TaskRunner() override; + base::SingleThreadTaskRunner* CompositorTaskRunner() override; + std::unique_ptr<PageScheduler> CreatePageScheduler( + PageScheduler::Delegate*) override; + std::unique_ptr<RendererPauseHandle> PauseScheduler() override + WARN_UNUSED_RESULT; + void AddPendingNavigation( + scheduler::WebMainThreadScheduler::NavigatingFrameType type) override {} + void RemovePendingNavigation( + scheduler::WebMainThreadScheduler::NavigatingFrameType type) override {} + + // Returns TimeTicks::Now() by default. + base::TimeTicks MonotonicallyIncreasingVirtualTime() const override; + + // The following virtual methods are defined in *both* WebThreadScheduler + // and ThreadScheduler, with identical interfaces and semantics. They are + // overriden in a subclass, effectively implementing the virtual methods + // in both classes at the same time. This is allowed in C++, as long as + // there is only one final overrider (i.e. definitions in base classes are + // not used in instantiated objects, since otherwise they may have multiple + // definitions of the virtual function in question). + // + // virtual void Shutdown(); + // virtual bool ShouldYieldForHighPriorityWork(); + // virtual bool CanExceedIdleDeadlineIfRequired() const; + scoped_refptr<WorkerTaskQueue> CreateTaskRunner(); protected: explicit NonMainThreadScheduler( std::unique_ptr<NonMainThreadSchedulerHelper> helper); + // Called during Init() for delayed initialization for subclasses. + virtual void InitImpl() = 0; + std::unique_ptr<NonMainThreadSchedulerHelper> helper_; + private: + static void RunIdleTask(WebThread::IdleTask task, base::TimeTicks deadline); + scoped_refptr<TaskRunnerImpl> v8_task_runner_; + DISALLOW_COPY_AND_ASSIGN(NonMainThreadScheduler); };
diff --git a/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h index 154103f..964ad9d 100644 --- a/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h
@@ -42,7 +42,7 @@ // its deadline has expired - post a new idle task for the continuation of // the work in this case. // Must be called from the associated WebThread. - virtual bool CanExceedIdleDeadlineIfRequired() = 0; + virtual bool CanExceedIdleDeadlineIfRequired() const = 0; // Schedule an idle task to run the associated WebThread. For non-critical // tasks which may be reordered relative to other task types and may be
diff --git a/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h b/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h index 1a5a51f..0f830e82 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h
@@ -8,8 +8,8 @@ #include <deque> #include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" namespace blink { namespace scheduler {
diff --git a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc index 419b349f..f25fee3d 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc
@@ -31,7 +31,7 @@ return helper_->DefaultWorkerTaskQueue(); } -void CompositorThreadScheduler::Init() {} +void CompositorThreadScheduler::InitImpl() {} void CompositorThreadScheduler::OnTaskCompleted( WorkerTaskQueue* worker_task_queue,
diff --git a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h index 8768e3b..8ef09729 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.h
@@ -32,16 +32,15 @@ ~CompositorThreadScheduler() override; - // WorkerScheduler: + // NonMainThreadScheduler: scoped_refptr<WorkerTaskQueue> DefaultTaskQueue() override; - void Init() override; void OnTaskCompleted(WorkerTaskQueue* worker_task_queue, const TaskQueue::Task& task, base::TimeTicks start, base::TimeTicks end, base::Optional<base::TimeDelta> thread_time) override; - // ChildScheduler: + // WebThreadScheduler: scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override; scoped_refptr<scheduler::SingleThreadIdleTaskRunner> IdleTaskRunner() override; @@ -59,6 +58,10 @@ void DidProcessIdleTask() override; base::TimeTicks NowTicks() override; + protected: + // NonMainThreadScheduler: + void InitImpl() override; + private: base::Thread* thread_;
diff --git a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler.cc index 37474106..370ffada 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h" #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h" namespace blink { @@ -25,6 +26,17 @@ thread_type, TaskQueueManager::TakeOverCurrentThread(), proxy); } +void NonMainThreadScheduler::Init() { + InitImpl(); + + // DefaultTaskQueue() is a virtual function, so it can't be called in the + // constructor. Also, DefaultTaskQueue() checks if InitImpl() is called. + // Therefore, v8_task_runner_ needs to be initialized here. + // TODO(kraynov): Ditch kDeprecatedNone here. + v8_task_runner_ = + TaskRunnerImpl::Create(DefaultTaskQueue(), TaskType::kDeprecatedNone); +} + scoped_refptr<WorkerTaskQueue> NonMainThreadScheduler::CreateTaskRunner() { helper_->CheckOnValidThread(); return helper_->NewTaskQueue(TaskQueue::Spec("worker_tq") @@ -32,5 +44,49 @@ .SetTimeDomain(nullptr)); } +void NonMainThreadScheduler::RunIdleTask(blink::WebThread::IdleTask task, + base::TimeTicks deadline) { + std::move(task).Run((deadline - base::TimeTicks()).InSecondsF()); +} + +void NonMainThreadScheduler::PostIdleTask(const base::Location& location, + blink::WebThread::IdleTask task) { + IdleTaskRunner()->PostIdleTask( + location, + base::BindOnce(&NonMainThreadScheduler::RunIdleTask, std::move(task))); +} + +void NonMainThreadScheduler::PostNonNestableIdleTask( + const base::Location& location, + blink::WebThread::IdleTask task) { + IdleTaskRunner()->PostNonNestableIdleTask( + location, + base::BindOnce(&NonMainThreadScheduler::RunIdleTask, std::move(task))); +} + +base::SingleThreadTaskRunner* NonMainThreadScheduler::V8TaskRunner() { + return v8_task_runner_.get(); +} + +base::SingleThreadTaskRunner* NonMainThreadScheduler::CompositorTaskRunner() { + return nullptr; +} + +std::unique_ptr<blink::PageScheduler> +NonMainThreadScheduler::CreatePageScheduler(PageScheduler::Delegate* delegate) { + NOTREACHED(); + return nullptr; +} + +std::unique_ptr<NonMainThreadScheduler::RendererPauseHandle> +NonMainThreadScheduler::PauseScheduler() { + return nullptr; +} + +base::TimeTicks NonMainThreadScheduler::MonotonicallyIncreasingVirtualTime() + const { + return base::TimeTicks::Now(); +} + } // namespace scheduler } // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc index ab47029..d552717 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
@@ -145,7 +145,7 @@ return helper_->DefaultWorkerTaskQueue(); } -void WorkerThreadScheduler::Init() { +void WorkerThreadScheduler::InitImpl() { initialized_ = true; idle_helper_.EnableLongIdlePeriod(); }
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h index 7391e257..45dd4d2 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h
@@ -47,7 +47,6 @@ // NonMainThreadScheduler implementation: scoped_refptr<WorkerTaskQueue> DefaultTaskQueue() override; - void Init() override; void OnTaskCompleted(WorkerTaskQueue* worker_task_queue, const TaskQueue::Task& task, base::TimeTicks start, @@ -71,6 +70,9 @@ scoped_refptr<WorkerTaskQueue> ControlTaskQueue(); protected: + // NonMainThreadScheduler implementation: + void InitImpl() override; + // IdleHelper::Delegate implementation: bool CanEnterLongIdlePeriod( base::TimeTicks now,
diff --git a/third_party/blink/renderer/platform/timer_test.cc b/third_party/blink/renderer/platform/timer_test.cc index def75ee..a1ed6d6 100644 --- a/third_party/blink/renderer/platform/timer_test.cc +++ b/third_party/blink/renderer/platform/timer_test.cc
@@ -15,8 +15,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h" #include "third_party/blink/renderer/platform/wtf/time.h"
diff --git a/third_party/closure_compiler/externs/file_manager_private.js b/third_party/closure_compiler/externs/file_manager_private.js index fdbdf8e9..b500ea18 100644 --- a/third_party/closure_compiler/externs/file_manager_private.js +++ b/third_party/closure_compiler/externs/file_manager_private.js
@@ -30,6 +30,7 @@ * thumbnailUrl: (string|undefined), * croppedThumbnailUrl: (string|undefined), * externalFileUrl: (string|undefined), + * alternateUrl: (string|undefined), * imageWidth: (number|undefined), * imageHeight: (number|undefined), * imageRotation: (number|undefined),
diff --git a/third_party/rnnoise/README.chromium b/third_party/rnnoise/README.chromium index 2c2d316..8efe059 100644 --- a/third_party/rnnoise/README.chromium +++ b/third_party/rnnoise/README.chromium
@@ -25,3 +25,4 @@ * rnn_vad_weights.h: output layer sizes + weights scaling factor * removing unwanted extern from constants in rnn_vad_weights.h and using constants to declare array sizes +* Add braces around arrays in unit test. \ No newline at end of file
diff --git a/third_party/rnnoise/src/kiss_fft_unittest.cc b/third_party/rnnoise/src/kiss_fft_unittest.cc index fd99052e..3132445 100644 --- a/third_party/rnnoise/src/kiss_fft_unittest.cc +++ b/third_party/rnnoise/src/kiss_fft_unittest.cc
@@ -94,50 +94,41 @@ TEST(RnnVadTest, KissFftBitExactness) { constexpr std::array<float, 32> samples = { - 0.3524301946163177490234375f, 0.891803801059722900390625f, - 0.07706542313098907470703125f, 0.699530780315399169921875f, - 0.3789891898632049560546875f, 0.5438187122344970703125f, - 0.332781612873077392578125f, 0.449340641498565673828125f, - 0.105229437351226806640625f, 0.722373783588409423828125f, - 0.13155306875705718994140625f, 0.340857982635498046875f, - 0.970204889774322509765625f, 0.53061950206756591796875f, - 0.91507828235626220703125f, 0.830274522304534912109375f, - 0.74468600749969482421875f, 0.24320767819881439208984375f, - 0.743998110294342041015625f, 0.17574800550937652587890625f, - 0.1834825575351715087890625f, 0.63317775726318359375f, - 0.11414264142513275146484375f, 0.1612723171710968017578125f, - 0.80316197872161865234375f, 0.4979794919490814208984375f, - 0.554282128810882568359375f, 0.67189347743988037109375f, - 0.06660757958889007568359375f, 0.89568817615509033203125f, - 0.29327380657196044921875f, 0.3472573757171630859375f}; + {0.3524301946163177490234375f, 0.891803801059722900390625f, + 0.07706542313098907470703125f, 0.699530780315399169921875f, + 0.3789891898632049560546875f, 0.5438187122344970703125f, + 0.332781612873077392578125f, 0.449340641498565673828125f, + 0.105229437351226806640625f, 0.722373783588409423828125f, + 0.13155306875705718994140625f, 0.340857982635498046875f, + 0.970204889774322509765625f, 0.53061950206756591796875f, + 0.91507828235626220703125f, 0.830274522304534912109375f, + 0.74468600749969482421875f, 0.24320767819881439208984375f, + 0.743998110294342041015625f, 0.17574800550937652587890625f, + 0.1834825575351715087890625f, 0.63317775726318359375f, + 0.11414264142513275146484375f, 0.1612723171710968017578125f, + 0.80316197872161865234375f, 0.4979794919490814208984375f, + 0.554282128810882568359375f, 0.67189347743988037109375f, + 0.06660757958889007568359375f, 0.89568817615509033203125f, + 0.29327380657196044921875f, 0.3472573757171630859375f}}; constexpr std::array<float, 17> expected_real = { - 0.4813065826892852783203125f, -0.0246877372264862060546875f, - 0.04095232486724853515625f, -0.0401695556938648223876953125f, - 0.00500857271254062652587890625f, 0.0160773508250713348388671875f, - -0.011385642923414707183837890625f, -0.008461721241474151611328125f, - 0.01383177936077117919921875f, 0.0117270611226558685302734375f, - -0.0164460353553295135498046875f, 0.0585579685866832733154296875f, - 0.02038039825856685638427734375f, -0.0209107734262943267822265625f, - 0.01046995259821414947509765625f, -0.09019653499126434326171875f, - -0.0583711564540863037109375f}; + {0.4813065826892852783203125f, -0.0246877372264862060546875f, + 0.04095232486724853515625f, -0.0401695556938648223876953125f, + 0.00500857271254062652587890625f, 0.0160773508250713348388671875f, + -0.011385642923414707183837890625f, -0.008461721241474151611328125f, + 0.01383177936077117919921875f, 0.0117270611226558685302734375f, + -0.0164460353553295135498046875f, 0.0585579685866832733154296875f, + 0.02038039825856685638427734375f, -0.0209107734262943267822265625f, + 0.01046995259821414947509765625f, -0.09019653499126434326171875f, + -0.0583711564540863037109375f}}; constexpr std::array<float, 17> expected_imag = { - 0.f, - -0.010482530109584331512451171875f, - 0.04762755334377288818359375f, - -0.0558677613735198974609375f, - 0.007908363826572895050048828125f, - -0.0071932487189769744873046875f, - 0.01322011835873126983642578125f, - -0.011227893643081188201904296875f, - -0.0400779247283935546875f, - -0.0290451310575008392333984375f, - 0.01519204117357730865478515625f, - -0.09711246192455291748046875f, - -0.00136523949913680553436279296875f, - 0.038602568209171295166015625f, - -0.009693108499050140380859375f, - -0.0183933563530445098876953125f, - 0.f}; + {0.f, -0.010482530109584331512451171875f, 0.04762755334377288818359375f, + -0.0558677613735198974609375f, 0.007908363826572895050048828125f, + -0.0071932487189769744873046875f, 0.01322011835873126983642578125f, + -0.011227893643081188201904296875f, -0.0400779247283935546875f, + -0.0290451310575008392333984375f, 0.01519204117357730865478515625f, + -0.09711246192455291748046875f, -0.00136523949913680553436279296875f, + 0.038602568209171295166015625f, -0.009693108499050140380859375f, + -0.0183933563530445098876953125f, 0.f}}; KissFft fft(32); std::array<std::complex<float>, 32> fft_buf_in;
diff --git a/tools/clang/traffic_annotation_extractor/traffic_annotation_extractor.cpp b/tools/clang/traffic_annotation_extractor/traffic_annotation_extractor.cpp index 3a93a90..5d68093 100644 --- a/tools/clang/traffic_annotation_extractor/traffic_annotation_extractor.cpp +++ b/tools/clang/traffic_annotation_extractor/traffic_annotation_extractor.cpp
@@ -12,13 +12,7 @@ // 2) Extracts all calls of the following network request creation functions // and returns their source location and availability of a // net::[Partial]NetworkTrafficAnnotation parameter in them: -// - SSLClientSocket::SSLClientSocket -// - TCPClientSocket::TCPClientSocket -// - UDPClientSocket::UDPClientSocket // - URLFetcher::Create -// - ClientSocketFactory::CreateDatagramClientSocket -// - ClientSocketFactory::CreateSSLClientSocket -// - ClientSocketFactory::CreateTransportClientSocket // - URLRequestContext::CreateRequest // 3) Finds all instances of initializing any of the following classes with list // expressions or assignment of a value to |unique_id_hash_code| of the @@ -349,18 +343,11 @@ // Setup patterns to find functions that should be monitored. match_finder.addMatcher( - callExpr( - hasDeclaration(functionDecl( - anyOf(hasName("SSLClientSocket::SSLClientSocket"), - hasName("TCPClientSocket::TCPClientSocket"), - hasName("UDPClientSocket::UDPClientSocket"), - hasName("URLFetcher::Create"), - hasName("ClientSocketFactory::CreateDatagramClientSocket"), - hasName("ClientSocketFactory::CreateSSLClientSocket"), - hasName("ClientSocketFactory::CreateTransportClientSocket"), - hasName("URLRequestContext::CreateRequest")), - has_annotation_parameter)), - bind_function_context_if_present) + callExpr(hasDeclaration(functionDecl( + anyOf(hasName("URLFetcher::Create"), + hasName("URLRequestContext::CreateRequest")), + has_annotation_parameter)), + bind_function_context_if_present) .bind("monitored_function"), &callback);
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index ede841c..056b0424 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -11122,6 +11122,14 @@ <description>Please enter the description of this user action.</description> </action> +<action name="Mobile_FocusedDefocusedOmnibox_WithNoAction"> + <owner>stkhapugin@chromium.org</owner> + <description> + Records when a user focuses the omnibox and then defocuses it without + modifying or copying the URL. iOS only. + </description> +</action> + <action name="MobileActionBarShown"> <owner>donnd@chromium.org</owner> <description>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index d2cf623..04f9c87 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -19489,6 +19489,8 @@ <int value="11" label="DRIVE_RECENT"/> <int value="12" label="MEDIA_VIEW"/> <int value="13" label="RECENT"/> + <int value="14" label="DRIVE_FAKE_ROOT"/> + <int value="15" label="ADD_NEW_SERVICES_MENU"/> </enum> <enum name="FileManagerTaskType">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 8fd68f7..4fdd2a2 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -27932,6 +27932,44 @@ </summary> </histogram> +<histogram name="FileBrowser.Location.OnEntryExpandedOrCollapsed.NonTopLevel" + enum="FileManagerRootType"> + <owner>sashab@google.com</owner> + <summary> + Chrome OS Files App: The locations (root types) of non-top-level entries + when they are expanded or collapsed (expand icon clicked) in the directory + tree. + </summary> +</histogram> + +<histogram name="FileBrowser.Location.OnEntryExpandedOrCollapsed.TopLevel" + enum="FileManagerRootType"> + <owner>sashab@google.com</owner> + <summary> + Chrome OS Files App: The locations (root types) of top-level entries (root + entries) when they are expanded or collapsed (expand icon clicked) in the + directory tree. + </summary> +</histogram> + +<histogram name="FileBrowser.Location.OnEntrySelected.NonTopLevel" + enum="FileManagerRootType"> + <owner>sashab@google.com</owner> + <summary> + Chrome OS Files App: The locations (root types) of non-top-level entries + when they are clicked in the directory tree. + </summary> +</histogram> + +<histogram name="FileBrowser.Location.OnEntrySelected.TopLevel" + enum="FileManagerRootType"> + <owner>sashab@google.com</owner> + <summary> + Chrome OS Files App: The locations (root types) of top-level entries (root + entries) when they are clicked in the directory tree. + </summary> +</histogram> + <histogram name="FileBrowser.MenuItemSelected" enum="FileManagerMenuCommands"> <owner>sashab@chromium.org</owner> <summary>
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_exporter.cc b/tools/traffic_annotation/auditor/traffic_annotation_exporter.cc index d47a101..3ac5342 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_exporter.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_exporter.cc
@@ -276,6 +276,7 @@ std::string TrafficAnnotationExporter::GenerateSerializedXML() const { XmlWriter writer; writer.StartWriting(); + writer.AppendElementContent(kXmlComment); writer.StartElement("annotations"); for (const auto& item : archive_) { @@ -334,11 +335,8 @@ writer.EndElement(); writer.StopWriting(); - std::string xml_content = writer.GetWrittenString(); - // Add comment before annotation tag (and after xml version). - xml_content.insert(xml_content.find("<annotations>"), kXmlComment); - return xml_content; + return writer.GetWrittenString(); } bool TrafficAnnotationExporter::SaveAnnotationsXML() const {
diff --git a/ui/base/models/table_model.h b/ui/base/models/table_model.h index 110ae3c..088cda5 100644 --- a/ui/base/models/table_model.h +++ b/ui/base/models/table_model.h
@@ -22,16 +22,19 @@ // The model driving the TableView. class UI_BASE_EXPORT TableModel { public: + // Size of the table row icon, if used. + static constexpr int kIconSize = 16; + // Number of rows in the model. virtual int RowCount() = 0; // Returns the value at a particular location in text. virtual base::string16 GetText(int row, int column_id) = 0; - // Returns the small icon (16x16) that should be displayed in the first - // column before the text. This is only used when the TableView was created - // with the ICON_AND_TEXT table type. Returns an isNull() image if there is - // no image. + // Returns the small icon (|kIconSize| x |kIconSize|) that should be displayed + // in the first column before the text. This is only used when the TableView + // was created with the ICON_AND_TEXT table type. Returns an isNull() image if + // there is no image. virtual gfx::ImageSkia GetIcon(int row); // Returns the tooltip, if any, to show for a particular row. If there are
diff --git a/ui/events/BUILD.gn b/ui/events/BUILD.gn index 6c856cb..4e07d1b 100644 --- a/ui/events/BUILD.gn +++ b/ui/events/BUILD.gn
@@ -130,6 +130,7 @@ "event_modifiers.h", "event_processor.cc", "event_processor.h", + "event_rewriter.cc", "event_rewriter.h", "event_sink.h", "event_source.cc",
diff --git a/ui/events/event_rewriter.cc b/ui/events/event_rewriter.cc new file mode 100644 index 0000000..d9efe7e --- /dev/null +++ b/ui/events/event_rewriter.cc
@@ -0,0 +1,16 @@ +// 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 "ui/events/event_rewriter.h" + +#include "ui/events/event_source.h" + +namespace ui { + +EventDispatchDetails EventRewriter::SendEventToEventSource(EventSource* source, + Event* event) const { + return source->SendEventToSinkFromRewriter(event, this); +} + +} // namespace ui
diff --git a/ui/events/event_rewriter.h b/ui/events/event_rewriter.h index dbdb9e61..a096aa9 100644 --- a/ui/events/event_rewriter.h +++ b/ui/events/event_rewriter.h
@@ -7,11 +7,14 @@ #include <memory> +#include "base/macros.h" +#include "ui/events/event_dispatcher.h" #include "ui/events/events_export.h" namespace ui { class Event; +class EventSource; // Return status of EventRewriter operations; see that class below. enum EventRewriteStatus { @@ -42,7 +45,8 @@ // before being dispatched from EventSource to EventSink. class EVENTS_EXPORT EventRewriter { public: - virtual ~EventRewriter() {} + EventRewriter() = default; + virtual ~EventRewriter() = default; // Potentially rewrites (replaces) an event, or requests it be discarded. // or discards an event. If the rewriter wants to rewrite an event, and @@ -62,6 +66,15 @@ virtual EventRewriteStatus NextDispatchEvent( const Event& last_event, std::unique_ptr<Event>* new_event) = 0; + + protected: + // A helper that calls a protected EventSource function, which sends the event + // to subsequent event rewriters on the source and onto its event sink. + EventDispatchDetails SendEventToEventSource(EventSource* source, + Event* event) const; + + private: + DISALLOW_COPY_AND_ASSIGN(EventRewriter); }; } // namespace ui
diff --git a/ui/events/event_source.cc b/ui/events/event_source.cc index e45be7c..21e160b3 100644 --- a/ui/events/event_source.cc +++ b/ui/events/event_source.cc
@@ -41,6 +41,12 @@ } EventDispatchDetails EventSource::SendEventToSink(Event* event) { + return SendEventToSinkFromRewriter(event, nullptr); +} + +EventDispatchDetails EventSource::SendEventToSinkFromRewriter( + Event* event, + const EventRewriter* rewriter) { std::unique_ptr<ui::Event> event_for_rewriting_ptr; Event* event_for_rewriting = event; if (!rewriter_list_.empty() && IsLocatedEventWithDifferentLocations(*event)) { @@ -56,7 +62,13 @@ EventRewriteStatus status = EVENT_REWRITE_CONTINUE; EventRewriterList::const_iterator it = rewriter_list_.begin(), end = rewriter_list_.end(); + // If a rewriter reposted |event|, only send it to subsequent rewriters. + bool send_to_rewriter = rewriter == nullptr; for (; it != end; ++it) { + if (!send_to_rewriter) { + send_to_rewriter |= (*it == rewriter); + continue; + } status = (*it)->RewriteEvent(*event_for_rewriting, &rewritten_event); if (status == EVENT_REWRITE_DISCARD) { CHECK(!rewritten_event);
diff --git a/ui/events/event_source.h b/ui/events/event_source.h index d2f223dc..d5b9b1c 100644 --- a/ui/events/event_source.h +++ b/ui/events/event_source.h
@@ -34,15 +34,25 @@ void RemoveEventRewriter(EventRewriter* rewriter); protected: + // Sends the event through all rewriters and onto the source's EventSink. EventDispatchDetails SendEventToSink(Event* event); + // Sends the event through the rewriters and onto the source's EventSink. + // If |rewriter| is valid, |event| is only sent to the subsequent rewriters. + // This is used for asynchronous reposting of events processed by |rewriter|. + EventDispatchDetails SendEventToSinkFromRewriter( + Event* event, + const EventRewriter* rewriter); + private: + friend class EventRewriter; friend class EventSourceTestApi; EventDispatchDetails DeliverEventToSink(Event* event); typedef std::vector<EventRewriter*> EventRewriterList; EventRewriterList rewriter_list_; + DISALLOW_COPY_AND_ASSIGN(EventSource); };
diff --git a/ui/file_manager/file_manager/common/js/volume_manager_common.js b/ui/file_manager/file_manager/common/js/volume_manager_common.js index ddf8357..ad8df50 100644 --- a/ui/file_manager/file_manager/common/js/volume_manager_common.js +++ b/ui/file_manager/file_manager/common/js/volume_manager_common.js
@@ -95,6 +95,13 @@ // Fake root for the mixed "Recent" view. RECENT: 'recent', + + // 'Google Drive' fake parent entry of 'My Drive', 'Shared with me' and + // 'Offline'. + DRIVE_FAKE_ROOT: 'drive_fake_root', + + // 'Add new services' menu item. + ADD_NEW_SERVICES_MENU: 'add_new_services_menu', }; Object.freeze(VolumeManagerCommon.RootType); @@ -122,6 +129,8 @@ VolumeManagerCommon.RootType.DRIVE_RECENT, VolumeManagerCommon.RootType.MEDIA_VIEW, VolumeManagerCommon.RootType.RECENT, + VolumeManagerCommon.RootType.DRIVE_FAKE_ROOT, + VolumeManagerCommon.RootType.ADD_NEW_SERVICES_MENU, ]; console.assert( Object.keys(VolumeManagerCommon.RootType).length ===
diff --git a/ui/file_manager/file_manager/foreground/js/actions_model.js b/ui/file_manager/file_manager/foreground/js/actions_model.js index bb1d033..54e0cb3 100644 --- a/ui/file_manager/file_manager/foreground/js/actions_model.js +++ b/ui/file_manager/file_manager/foreground/js/actions_model.js
@@ -3,16 +3,22 @@ // found in the LICENSE file. /** + * A single action, that can be taken on a set of entries. * @interface */ function Action() { } +/** + * Executes this action on the set of entries. + */ Action.prototype.execute = function() { }; /** - * @return {boolean} + * Checks whether this action can execute on the set of entries. + * + * @return {boolean} True if the function can execute, false if not. */ Action.prototype.canExecute = function() { }; @@ -400,7 +406,97 @@ return null; }; + /** + * Opens the entry in Drive Web for the user to manage permissions etc. + * + * @param {!Entry} entry The entry to open the 'Manage' page for. + * @param {!ActionModelUI} ui + * @param {!VolumeManagerWrapper} volumeManager + * @implements {Action} + * @constructor + * @struct + */ +function DriveManageAction(entry, volumeManager, ui) { + /** + * The entry to open the 'Manage' page for. + * + * @private {!Entry} + * @const + */ + this.entry_ = entry; + + /** + * @private {!VolumeManagerWrapper} + * @const + */ + this.volumeManager_ = volumeManager; + + /** + * @private {!ActionModelUI} + * @const + */ + this.ui_ = ui; +} + +/** + * Creates a new DriveManageAction object. + * |entries| must contain only a single entry. + * + * @param {!Array<!Entry>} entries + * @param {!ActionModelUI} ui + * @param {!VolumeManagerWrapper} volumeManager + * @return {DriveManageAction} + */ +DriveManageAction.create = function(entries, volumeManager, ui) { + if (entries.length !== 1) + return null; + + return new DriveManageAction(entries[0], volumeManager, ui); +}; + +/** + * @override + */ +DriveManageAction.prototype.execute = function() { + chrome.fileManagerPrivate.getEntryProperties( + [this.entry_], ['alternateUrl'], function(results) { + if (chrome.runtime.lastError) { + console.error(chrome.runtime.lastError.message); + return; + } + if (results.length == 1) { + console.error( + 'getEntryProperties for alternateUrl should return 1 entry ' + + '(returned ' + results.length + ')'); + return; + } + util.visitURL(results[0].alternateUrl); + }.bind(this)); +}; + +/** + * @override + */ +DriveManageAction.prototype.canExecute = function() { + // For now, only allow managing of regular files (not directories). + return !this.entry_.isDirectory && + this.volumeManager_.getDriveConnectionState().type !== + VolumeManagerCommon.DriveConnectionType.OFFLINE && + !util.isTeamDriveRoot(this.entry_); +}; + +/** + * @return {?string} + */ +DriveManageAction.prototype.getTitle = function() { + return null; +}; + + +/** + * A custom action set by the FSP API. + * * @param {!Array<!Entry>} entries * @param {string} id * @param {?string} title @@ -464,7 +560,8 @@ }; /** - * Represents a set of actions for a set of entries. + * Represents a set of actions for a set of entries. Includes actions set + * locally in JS, as well as those retrieved from the FSP API. * * @param {!VolumeManagerWrapper} volumeManager * @param {!MetadataModel} metadataModel @@ -556,10 +653,13 @@ */ ActionsModel.InternalActionId = { CREATE_FOLDER_SHORTCUT: 'create-folder-shortcut', - REMOVE_FOLDER_SHORTCUT: 'remove-folder-shortcut' + REMOVE_FOLDER_SHORTCUT: 'remove-folder-shortcut', + MANAGE_IN_DRIVE: 'manage-in-drive' }; /** + * Initializes the ActionsModel, including populating the list of available + * actions for the given entries. * @return {!Promise} */ ActionsModel.prototype.initialize = function() { @@ -632,6 +732,14 @@ actions[ActionsModel.InternalActionId.REMOVE_FOLDER_SHORTCUT] = removeFolderShortcutAction; } + + var manageInDriveAction = DriveManageAction.create( + this.entries_, this.volumeManager_, this.ui_); + if (manageInDriveAction) { + actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE] = + manageInDriveAction; + } + fulfill(actions); break;
diff --git a/ui/file_manager/file_manager/foreground/js/actions_model_unittest.js b/ui/file_manager/file_manager/foreground/js/actions_model_unittest.js index 6fbf6b04..8ef31746 100644 --- a/ui/file_manager/file_manager/foreground/js/actions_model_unittest.js +++ b/ui/file_manager/file_manager/foreground/js/actions_model_unittest.js
@@ -66,7 +66,7 @@ showHtml: function() { } }; -}; +} function setUp() { window.chrome = { @@ -99,6 +99,9 @@ ui = new MockUI(); } +/** + * Tests that the correct actions are available for a directory in Google Drive. + */ function testDriveDirectoryEntry(callback) { driveFileSystem.entries['/test'] = new MockDirectoryEntry(driveFileSystem, '/test', {}); @@ -111,8 +114,9 @@ }); return reportPromise(model.initialize().then(function() { var actions = model.getActions(); - assertEquals(2, Object.keys(actions).length); + assertEquals(3, Object.keys(actions).length); + // 'Share' should be disabled in offline mode. var shareAction = actions[ActionsModel.CommonActionId.SHARE]; assertTrue(!!shareAction); volumeManager.driveConnectionState = { @@ -120,6 +124,13 @@ }; assertFalse(shareAction.canExecute()); + // 'Manage in Drive' should be disabled for directories. + var manageInDriveAction = + actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; + assertTrue(!!manageInDriveAction); + assertFalse(manageInDriveAction.canExecute()); + + // 'Create Shortcut' should be enabled, until it's executed, then disabled. var createFolderShortcutAction = actions[ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT]; assertTrue(!!createFolderShortcutAction); @@ -138,8 +149,12 @@ return model.initialize(); }).then(function() { var actions = model.getActions(); - assertEquals(3, Object.keys(actions).length); + assertEquals(4, Object.keys(actions).length); + assertTrue(!!actions[ActionsModel.CommonActionId.SHARE]); + assertTrue(!!actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]); + assertTrue(!!actions[ActionsModel.InternalActionId.REMOVE_FOLDER_SHORTCUT]); + // 'Create shortcut' should be disabled. var createFolderShortcutAction = actions[ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT]; assertTrue(!!createFolderShortcutAction); @@ -148,6 +163,9 @@ }), callback); } +/** + * Tests that the correct actions are available for a file in Google Drive. + */ function testDriveFileEntry(callback) { driveFileSystem.entries['/test.txt'] = new MockFileEntry(driveFileSystem, '/test.txt', {}); @@ -161,14 +179,21 @@ }; return reportPromise(model.initialize().then(function() { var actions = model.getActions(); - assertEquals(2, Object.keys(actions).length); + assertEquals(3, Object.keys(actions).length); assertTrue(!!actions[ActionsModel.CommonActionId.SHARE]); + // 'Save for Offline' should be enabled. var saveForOfflineAction = actions[ActionsModel.CommonActionId.SAVE_FOR_OFFLINE]; assertTrue(!!saveForOfflineAction); assertTrue(saveForOfflineAction.canExecute()); + // 'Manage in Drive' should be enabled. + var manageInDriveAction = + actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; + assertTrue(!!manageInDriveAction); + assertTrue(manageInDriveAction.canExecute()); + chrome.fileManagerPrivate.pinDriveFile = function(entry, pin, callback) { metadataModel.properties.pinned = true; assertEquals(driveFileSystem.entries['/test.txt'], entry); @@ -196,14 +221,21 @@ return model.initialize(); }).then(function() { var actions = model.getActions(); - assertEquals(2, Object.keys(actions).length); + assertEquals(3, Object.keys(actions).length); assertTrue(!!actions[ActionsModel.CommonActionId.SHARE]); + // 'Offline not Necessary' should be enabled. var offlineNotNecessaryAction = actions[ActionsModel.CommonActionId.OFFLINE_NOT_NECESSARY]; assertTrue(!!offlineNotNecessaryAction); assertTrue(offlineNotNecessaryAction.canExecute()); + // 'Manage in Drive' should be enabled. + var manageInDriveAction = + actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; + assertTrue(!!manageInDriveAction); + assertTrue(manageInDriveAction.canExecute()); + chrome.fileManagerPrivate.pinDriveFile = function(entry, pin, callback) { metadataModel.properties.pinned = false; assertEquals(driveFileSystem.entries['/test.txt'], entry); @@ -224,7 +256,10 @@ }), callback); } -function testTeamDriveEntry(callback) { +/** + * Tests that a Team Drive Root entry has the correct actions available. + */ +function testTeamDriveRootEntry(callback) { driveFileSystem.entries['/team_drives/ABC Team'] = new MockDirectoryEntry(driveFileSystem, '/team_drives/ABC Team', {}); @@ -234,16 +269,99 @@ return reportPromise( model.initialize().then(function() { var actions = model.getActions(); - assertEquals(1, Object.keys(actions).length); + assertEquals(2, Object.keys(actions).length); - // "share" action is disabled for Team Drive entries. + // "share" action is disabled for Team Drive Root entries. var shareAction = actions[ActionsModel.CommonActionId.SHARE]; assertTrue(!!shareAction); assertFalse(shareAction.canExecute()); + + // "manage in drive" action is disabled for Team Drive Root entries. + var manageAction = + actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; + assertTrue(!!manageAction); + assertFalse(manageAction.canExecute()); }), callback); } +/** + * Tests that a Team Drive directory entry has the correct actions available. + */ +function testTeamDriveDirectoryEntry(callback) { + driveFileSystem.entries['/team_drives/ABC Team/Folder 1'] = + new MockDirectoryEntry( + driveFileSystem, '/team_drives/ABC Team/Folder 1', {}); + + var model = new ActionsModel( + volumeManager, metadataModel, shortcutsModel, driveSyncHandler, ui, + [driveFileSystem.entries['/team_drives/ABC Team/Folder 1']]); + return reportPromise( + model.initialize().then(function() { + var actions = model.getActions(); + assertEquals(3, Object.keys(actions).length); + + // "share" action is enabled for Team Drive directories. + var shareAction = actions[ActionsModel.CommonActionId.SHARE]; + assertTrue(!!shareAction); + assertTrue(shareAction.canExecute()); + + // "manage in drive" action is disabled for Team Drive directories. + var manageAction = + actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; + assertTrue(!!manageAction); + assertFalse(manageAction.canExecute()); + + // 'Create shortcut' should be enabled. + var createFolderShortcutAction = + actions[ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT]; + assertTrue(!!createFolderShortcutAction); + assertTrue(createFolderShortcutAction.canExecute()); + }), + callback); +} + +/** + * Tests that a Team Drive file entry has the correct actions available. + */ +function testTeamDriveFileEntry(callback) { + driveFileSystem.entries['/team_drives/ABC Team/Folder 1/test.txt'] = + new MockFileEntry( + driveFileSystem, '/team_drives/ABC Team/Folder 1/test.txt', {}); + + var model = new ActionsModel( + volumeManager, metadataModel, shortcutsModel, driveSyncHandler, ui, + [driveFileSystem.entries['/team_drives/ABC Team/Folder 1/test.txt']]); + metadataModel.properties = {hosted: false, pinned: false}; + return reportPromise( + model.initialize().then(function() { + var actions = model.getActions(); + assertEquals(3, Object.keys(actions).length); + + // "save for offline" action is enabled for Team Drive file entries. + var saveForOfflineAction = + actions[ActionsModel.CommonActionId.SAVE_FOR_OFFLINE]; + assertTrue(!!saveForOfflineAction); + assertTrue(saveForOfflineAction.canExecute()); + + // "share" action is enabled for Team Drive file entries. + var shareAction = actions[ActionsModel.CommonActionId.SHARE]; + assertTrue(!!shareAction); + assertTrue(shareAction.canExecute()); + + // "manage in drive" action is enabled for Team Drive file entries. + var manageAction = + actions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; + assertTrue(!!manageAction); + assertTrue(manageAction.canExecute()); + }), + callback); +} + +/** + * Tests that if actions are provided with getCustomActions(), they appear + * correctly for the file. + */ function testProvidedEntry(callback) { providedFileSystem.entries['/test'] = new MockDirectoryEntry(providedFileSystem, '/test', {}); @@ -311,6 +429,9 @@ }), callback); } +/** + * Tests that no actions are available when getCustomActions() throws an error. + */ function testProvidedEntryWithError(callback) { providedFileSystem.entries['/test'] = new MockDirectoryEntry(providedFileSystem, '/test', {});
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js index 45c82ce..5046ba8 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -1505,6 +1505,41 @@ }); /** + * Opens the file in Drive for the user to manage sharing permissions etc. + * @type {Command} + */ +CommandHandler.COMMANDS_['manage-in-drive'] = /** @type {Command} */ ({ + /** + * @param {!Event} event Command event. + * @param {!CommandHandlerDeps} fileManager The file manager instance. + */ + execute: function(event, fileManager) { + var actionsModel = + fileManager.actionsController.getActionsModelFor(event.target); + var action = actionsModel ? + actionsModel.getAction(ActionsModel.InternalActionId.MANAGE_IN_DRIVE) : + null; + if (action) + action.execute(); + }, + /** + * @param {!Event} event Command event. + * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use. + */ + canExecute: function(event, fileManager) { + var actionsModel = + fileManager.actionsController.getActionsModelFor(event.target); + var action = actionsModel ? + actionsModel.getAction(ActionsModel.InternalActionId.MANAGE_IN_DRIVE) : + null; + event.canExecute = action && action.canExecute(); + if (actionsModel) + event.command.setHidden(!action); + } +}); + + +/** * Creates a shortcut of the selected folder (single only). * @type {Command} */
diff --git a/ui/file_manager/file_manager/foreground/js/ui/actions_submenu.js b/ui/file_manager/file_manager/foreground/js/ui/actions_submenu.js index 98238a95..147a74bb 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/actions_submenu.js +++ b/ui/file_manager/file_manager/foreground/js/ui/actions_submenu.js
@@ -67,6 +67,18 @@ } util.queryDecoratedElement('#share', cr.ui.Command).canExecuteChange(); + // Then add the Manage in Drive item (if available). + var manageInDriveAction = + remainingActions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; + if (manageInDriveAction) { + var menuItem = this.addMenuItem_({}); + menuItem.command = '#manage-in-drive'; + menuItem.classList.toggle('hide-on-toolbar', true); + delete remainingActions[ActionsModel.InternalActionId.MANAGE_IN_DRIVE]; + } + util.queryDecoratedElement('#manage-in-drive', cr.ui.Command) + .canExecuteChange(); + // Managing shortcuts is shown just before custom actions. var createFolderShortcutAction = remainingActions[ ActionsModel.InternalActionId.CREATE_FOLDER_SHORTCUT];
diff --git a/ui/file_manager/file_manager/foreground/js/ui/actions_submenu_unittest.html b/ui/file_manager/file_manager/foreground/js/ui/actions_submenu_unittest.html index 0f3313a..f78fc34 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/actions_submenu_unittest.html +++ b/ui/file_manager/file_manager/foreground/js/ui/actions_submenu_unittest.html
@@ -13,6 +13,7 @@ </script> <command id="share" label="Share"></command> +<command id="manage-in-drive" i18n-values="Manage in Drive"></command> <command id="toggle-pinned" label="Toggle pinned"></command> <command id="create-folder-shortcut" label="Create folder shortcut"></command> <command id="remove-folder-shortcut" label="Remove folder shortcut"></command>
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js index 73400f6..3c44789 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js +++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -69,6 +69,32 @@ } return false; }; +/** + * Records UMA for the selected entry at {@code location}. Records slightly + * differently if the expand icon is selected and {@code expandIconSelected} is + * true. + * + * @param {Event} e The click event. + * @param {VolumeManagerCommon.RootType} rootType The root type to record. + * @param {boolean} isRootEntry Whether the entry selected was a root entry. + * @return + */ +DirectoryItemTreeBaseMethods.recordUMASelectedEntry = function( + e, rootType, isRootEntry) { + var expandIconSelected = e.target.classList.contains('expand-icon'); + var metricName = 'Location.OnEntrySelected.TopLevel'; + if (!expandIconSelected && isRootEntry) { + metricName = 'Location.OnEntrySelected.TopLevel'; + } else if (!expandIconSelected && !isRootEntry) { + metricName = 'Location.OnEntrySelected.NonTopLevel'; + } else if (expandIconSelected && isRootEntry) { + metricName = 'Location.OnEntryExpandedOrCollapsed.TopLevel'; + } else if (expandIconSelected && !isRootEntry) { + metricName = 'Location.OnEntryExpandedOrCollapsed.NonTopLevel'; + } + + metrics.recordEnum(metricName, rootType, VolumeManagerCommon.RootTypesForUMA); +}; Object.freeze(DirectoryItemTreeBaseMethods); @@ -324,12 +350,20 @@ DirectoryItem.prototype.handleClick = function(e) { cr.ui.TreeItem.prototype.handleClick.call(this, e); - if (!this.entry || e.button === 2 || - e.target.classList.contains('expand-icon')) { + if (!this.entry || e.button === 2) { return; } - this.directoryModel_.activateDirectoryEntry(this.entry); + if (!e.target.classList.contains('expand-icon')) { + this.directoryModel_.activateDirectoryEntry(this.entry); + } + + // If this is DriveVolumeItem, the UMA has already been recorded. + if (!(this instanceof DriveVolumeItem)) { + var location = this.tree.volumeManager.getLocationInfo(this.entry); + DirectoryItemTreeBaseMethods.recordUMASelectedEntry.call( + this, e, location.rootType, location.isRootEntry); + } }; /** @@ -761,6 +795,9 @@ this.searchAndSelectByEntry(displayRoot); }.bind(this)); } + + DirectoryItemTreeBaseMethods.recordUMASelectedEntry.call( + this, e, VolumeManagerCommon.RootType.DRIVE_FAKE_ROOT, true); }; /** @@ -923,10 +960,14 @@ // Do not activate with right click. if (e.button === 2) return; - this.activate(); + // Resets file selection when a volume is clicked. this.parentTree_.directoryModel.clearSelection(); + + var location = this.tree.volumeManager.getLocationInfo(this.entry); + DirectoryItemTreeBaseMethods.recordUMASelectedEntry.call( + this, e, location.rootType, location.isRootEntry); }; /** @@ -1035,6 +1076,9 @@ */ MenuItem.prototype.handleClick = function(e) { this.activate(); + + DirectoryItemTreeBaseMethods.recordUMASelectedEntry.call( + this, e, VolumeManagerCommon.RootType.ADD_NEW_SERVICES_MENU, true); }; /** @@ -1111,6 +1155,9 @@ */ RecentItem.prototype.handleClick = function(e) { this.activate(); + + DirectoryItemTreeBaseMethods.recordUMASelectedEntry.call( + this, e, VolumeManagerCommon.RootType.RECENT, true); }; /**
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html index 22b9307..b745cd9 100644 --- a/ui/file_manager/file_manager/main.html +++ b/ui/file_manager/file_manager/main.html
@@ -152,6 +152,8 @@ <command id="share" i18n-values="label:SHARE_BUTTON_LABEL" disabled hidden shortcut="." hide-shortcut-text> + <command id="manage-in-drive" + i18n-values="label:MANAGE_IN_DRIVE_BUTTON_LABEL" disabled hidden> <command id="zoom-in" shortcut="=|Ctrl"> <command id="zoom-out" shortcut="-|Ctrl">
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc index d7f37cf1..c4325de2 100644 --- a/ui/views/controls/table/table_view.cc +++ b/ui/views/controls/table/table_view.cc
@@ -31,15 +31,12 @@ #include "ui/views/layout/layout_provider.h" #include "ui/views/style/typography.h" -// Size of images. -static const int kImageSize = 16; - -static const int kGroupingIndicatorSize = 6; - namespace views { namespace { +constexpr int kGroupingIndicatorSize = 6; + // Returns result, unless ascending is false in which case -result is returned. int SwapCompareResult(int result, bool ascending) { return ascending ? result : -result; @@ -588,14 +585,15 @@ if (j == 0 && table_type_ == ICON_AND_TEXT) { gfx::ImageSkia image = model_->GetIcon(model_index); if (!image.isNull()) { - int image_x = GetMirroredXWithWidthInView(text_x, kImageSize); + int image_x = + GetMirroredXWithWidthInView(text_x, ui::TableModel::kIconSize); canvas->DrawImageInt( - image, 0, 0, image.width(), image.height(), - image_x, - cell_bounds.y() + (cell_bounds.height() - kImageSize) / 2, - kImageSize, kImageSize, true); + image, 0, 0, image.width(), image.height(), image_x, + cell_bounds.y() + + (cell_bounds.height() - ui::TableModel::kIconSize) / 2, + ui::TableModel::kIconSize, ui::TableModel::kIconSize, true); } - text_x += kImageSize + cell_element_spacing; + text_x += ui::TableModel::kIconSize + cell_element_spacing; } if (text_x < cell_bounds.right() - cell_margin) { canvas->DrawStringRectWithFlags( @@ -743,7 +741,7 @@ if (grouper_) text_x += kGroupingIndicatorSize + cell_element_spacing; if (table_type_ == ICON_AND_TEXT) - text_x += kImageSize + cell_element_spacing; + text_x += ui::TableModel::kIconSize + cell_element_spacing; } bounds->set_x(text_x); bounds->set_width(std::max(0, bounds->right() - cell_margin - text_x)); @@ -770,7 +768,7 @@ const int cell_element_spacing = GetCellElementSpacing(); int first_column_padding = 0; if (table_type_ == ICON_AND_TEXT && header_) - first_column_padding += kImageSize + cell_element_spacing; + first_column_padding += ui::TableModel::kIconSize + cell_element_spacing; if (grouper_) first_column_padding += kGroupingIndicatorSize + cell_element_spacing;